1 /* cycling.c- window cycling
3 * Window Maker window manager
5 * Copyright (c) 2000-2003 Alfredo K. Kojima
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
26 #include <X11/Xutil.h>
29 #include "WindowMaker.h"
42 extern WPreferences wPreferences
;
44 extern WShortKey wKeyBindings
[WKBD_LAST
];
52 nextToFocusAfter(WWindow
*wwin
)
54 WWindow
*tmp
= wwin
->prev
;
57 if (wWindowCanReceiveFocus(tmp
) && !WFLAGP(tmp
, skip_window_list
)) {
64 /* start over from the beginning of the list */
68 while (tmp
&& tmp
!= wwin
) {
69 if (wWindowCanReceiveFocus(tmp
) && !WFLAGP(tmp
, skip_window_list
)) {
80 nextToFocusBefore(WWindow
*wwin
)
82 WWindow
*tmp
= wwin
->next
;
85 if (wWindowCanReceiveFocus(tmp
) && !WFLAGP(tmp
, skip_window_list
)) {
91 /* start over from the beginning of the list */
96 while (tmp
&& tmp
!= wwin
) {
97 if (wWindowCanReceiveFocus(tmp
) && !WFLAGP(tmp
, skip_window_list
)) {
111 nextFocusWindow(WWindow
*wwin
)
113 WWindow
*tmp
, *closest
, *min
;
123 if (wWindowCanReceiveFocus(tmp
)
124 && (!WFLAGP(tmp
, skip_window_list
)|| tmp
->flags
.internal_window
)) {
125 if (min
->client_win
> tmp
->client_win
)
127 if (tmp
->client_win
> wwin
->client_win
129 || (tmp
->client_win
- wwin
->client_win
) < d
)) {
131 d
= tmp
->client_win
- wwin
->client_win
;
136 if (!closest
||closest
==wwin
)
143 prevFocusWindow(WWindow
*wwin
)
145 WWindow
*tmp
, *closest
, *max
;
155 if (wWindowCanReceiveFocus(tmp
) &&
156 (!WFLAGP(tmp
, skip_window_list
) || tmp
->flags
.internal_window
)) {
157 if (max
->client_win
< tmp
->client_win
)
159 if (tmp
->client_win
< wwin
->client_win
161 || (wwin
->client_win
- tmp
->client_win
) < d
)) {
163 d
= wwin
->client_win
- tmp
->client_win
;
168 if (!closest
||closest
==wwin
)
177 StartWindozeCycle(WWindow
*wwin
, XEvent
*event
, Bool next
)
179 WScreen
*scr
= wScreenForRootWindow(event
->xkey
.root
);
181 Bool openedSwitchMenu
= False
;
185 XModifierKeymap
*keymap
= NULL
;
187 Bool somethingElse
= False
;
194 hasModifier
= (wKeyBindings
[WKBD_FOCUSNEXT
].modifier
!= 0);
196 hasModifier
= (wKeyBindings
[WKBD_FOCUSPREV
].modifier
!= 0);
199 keymap
= XGetModifierMapping(dpy
);
202 printf("Grabbing keyboard\n");
204 XGrabKeyboard(dpy
, scr
->root_win
, False
, GrabModeAsync
, GrabModeAsync
,
209 if (wPreferences
.windows_cycling
)
210 newFocused
= nextToFocusAfter(wwin
);
212 newFocused
= nextFocusWindow(wwin
);
214 if (wPreferences
.windows_cycling
)
215 newFocused
= nextToFocusBefore(wwin
);
217 newFocused
= prevFocusWindow(wwin
);
220 scr
->flags
.doing_alt_tab
= 1;
223 if (wPreferences
.circ_raise
)
224 XRaiseWindow(dpy
, newFocused
->frame
->core
->window
);
225 wWindowFocus(newFocused
, scr
->focused_window
);
226 oldFocused
= newFocused
;
229 if (wPreferences
.popup_switchmenu
&&
230 (!scr
->switch_menu
|| !scr
->switch_menu
->flags
.mapped
)) {
232 OpenSwitchMenu(scr
, scr
->scr_width
/2, scr
->scr_height
/2, False
);
233 openedSwitchMenu
= True
;
237 while (hasModifier
&& !done
) {
238 WMMaskEvent(dpy
, KeyPressMask
|KeyReleaseMask
|ExposureMask
, &ev
);
240 if (ev
.type
!= KeyRelease
&& ev
.type
!= KeyPress
) {
244 /* ignore CapsLock */
245 modifiers
= ev
.xkey
.state
& ValidModMask
;
247 if (ev
.type
== KeyPress
) {
249 printf("Got key press\n");
251 if (wKeyBindings
[WKBD_FOCUSNEXT
].keycode
== ev
.xkey
.keycode
252 && wKeyBindings
[WKBD_FOCUSNEXT
].modifier
== modifiers
) {
254 newFocused
= nextToFocusAfter(newFocused
);
255 wWindowFocus(newFocused
, oldFocused
);
256 oldFocused
= newFocused
;
258 if (wPreferences
.circ_raise
) {
261 XRaiseWindow(dpy
, newFocused
->frame
->core
->window
);
264 } else if (wKeyBindings
[WKBD_FOCUSPREV
].keycode
== ev
.xkey
.keycode
265 && wKeyBindings
[WKBD_FOCUSPREV
].modifier
== modifiers
) {
267 newFocused
= nextToFocusBefore(newFocused
);
268 wWindowFocus(newFocused
, oldFocused
);
269 oldFocused
= newFocused
;
271 if (wPreferences
.circ_raise
) {
274 XRaiseWindow(dpy
, newFocused
->frame
->core
->window
);
279 printf("Got something else\n");
281 somethingElse
= True
;
284 } else if (ev
.type
== KeyRelease
) {
288 printf("Got key release\n");
290 for (i
= 0; i
< 8 * keymap
->max_keypermod
; i
++) {
291 if (keymap
->modifiermap
[i
] == ev
.xkey
.keycode
&&
292 wKeyBindings
[WKBD_FOCUSNEXT
].modifier
293 & 1<<(i
/keymap
->max_keypermod
)) {
301 XFreeModifiermap(keymap
);
305 printf("Ungrabbing keyboard\n");
307 XUngrabKeyboard(dpy
, CurrentTime
);
309 wSetFocusTo(scr
, newFocused
);
311 if (wPreferences
.circ_raise
) {
312 wRaiseFrame(newFocused
->frame
->core
);
316 scr
->flags
.doing_alt_tab
= 0;
317 if (openedSwitchMenu
) {
319 * place window in center of current head
321 WMPoint center
= wGetPointToCenterRectInHead(scr
,
322 wGetHeadForPointerLocation(scr
),
324 OpenSwitchMenu(scr
, center
.x
, center
.y
, False
);