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>
27 #include <X11/keysym.h>
29 // TODO: remove non-MOX_CYCLING junk
30 // fix the stacking/window raising during alt-tabbing
31 // allow selection of icons with mouse
35 #include "WindowMaker.h"
46 #include "switchpanel.h"
49 extern WPreferences wPreferences
;
51 extern WShortKey wKeyBindings
[WKBD_LAST
];
59 nextToFocusAfter(WWindow
*wwin
)
61 WWindow
*tmp
= wwin
->prev
;
64 if (wWindowCanReceiveFocus(tmp
) && !WFLAGP(tmp
, skip_window_list
)) {
71 /* start over from the beginning of the list */
75 while (tmp
&& tmp
!= wwin
) {
76 if (wWindowCanReceiveFocus(tmp
) && !WFLAGP(tmp
, skip_window_list
)) {
87 nextToFocusBefore(WWindow
*wwin
)
89 WWindow
*tmp
= wwin
->next
;
92 if (wWindowCanReceiveFocus(tmp
) && !WFLAGP(tmp
, skip_window_list
)) {
98 /* start over from the beginning of the list */
103 while (tmp
&& tmp
!= wwin
) {
104 if (wWindowCanReceiveFocus(tmp
) && !WFLAGP(tmp
, skip_window_list
)) {
118 nextFocusWindow(WWindow
*wwin
)
120 WWindow
*tmp
, *closest
, *min
;
130 if (wWindowCanReceiveFocus(tmp
)
131 && (!WFLAGP(tmp
, skip_window_list
)|| tmp
->flags
.internal_window
)) {
132 if (min
->client_win
> tmp
->client_win
)
134 if (tmp
->client_win
> wwin
->client_win
136 || (tmp
->client_win
- wwin
->client_win
) < d
)) {
138 d
= tmp
->client_win
- wwin
->client_win
;
143 if (!closest
||closest
==wwin
)
150 prevFocusWindow(WWindow
*wwin
)
152 WWindow
*tmp
, *closest
, *max
;
162 if (wWindowCanReceiveFocus(tmp
) &&
163 (!WFLAGP(tmp
, skip_window_list
) || tmp
->flags
.internal_window
)) {
164 if (max
->client_win
< tmp
->client_win
)
166 if (tmp
->client_win
< wwin
->client_win
168 || (wwin
->client_win
- tmp
->client_win
) < d
)) {
170 d
= wwin
->client_win
- tmp
->client_win
;
175 if (!closest
||closest
==wwin
)
179 #endif /* !MOX_CYCLING */
183 StartWindozeCycle(WWindow
*wwin
, XEvent
*event
, Bool next
)
185 WScreen
*scr
= wScreenForRootWindow(event
->xkey
.root
);
190 XModifierKeymap
*keymap
= NULL
;
192 Bool somethingElse
= False
;
195 WSwitchPanel
*swpanel
= NULL
;
197 KeyCode leftKey
, rightKey
, homeKey
, endKey
;
202 leftKey
= XKeysymToKeycode(dpy
, XK_Left
);
203 rightKey
= XKeysymToKeycode(dpy
, XK_Right
);
204 homeKey
= XKeysymToKeycode(dpy
, XK_Home
);
205 endKey
= XKeysymToKeycode(dpy
, XK_End
);
208 hasModifier
= (wKeyBindings
[WKBD_FOCUSNEXT
].modifier
!= 0);
210 hasModifier
= (wKeyBindings
[WKBD_FOCUSPREV
].modifier
!= 0);
213 keymap
= XGetModifierMapping(dpy
);
216 printf("Grabbing keyboard\n");
218 XGrabKeyboard(dpy
, scr
->root_win
, False
, GrabModeAsync
, GrabModeAsync
,
222 scr
->flags
.doing_alt_tab
= 1;
225 swpanel
= wInitSwitchPanel(scr
, wwin
, scr
->current_workspace
);
229 newFocused
= wSwitchPanelSelectNext(swpanel
, !next
);
231 wWindowFocus(newFocused
, oldFocused
);
232 oldFocused
= newFocused
;
237 #else /* !MOX_CYCLING */
239 if (wPreferences
.windows_cycling
)
240 newFocused
= nextToFocusAfter(wwin
);
242 newFocused
= nextFocusWindow(wwin
);
244 if (wPreferences
.windows_cycling
)
245 newFocused
= nextToFocusBefore(wwin
);
247 newFocused
= prevFocusWindow(wwin
);
250 if (wPreferences
.circ_raise
)
251 XRaiseWindow(dpy
, newFocused
->frame
->core
->window
);
252 wWindowFocus(newFocused
, scr
->focused_window
);
253 oldFocused
= newFocused
;
254 #endif /* !MOX_CYCLING */
256 while (hasModifier
&& !done
) {
257 WMMaskEvent(dpy
, KeyPressMask
|KeyReleaseMask
|ExposureMask
|PointerMotionMask
, &ev
);
259 if (ev
.type
!= KeyRelease
&& ev
.type
!= KeyPress
) {
263 /* ignore CapsLock */
264 modifiers
= ev
.xkey
.state
& ValidModMask
;
266 if (ev
.type
== KeyPress
) {
268 printf("Got key press\n");
270 if ((wKeyBindings
[WKBD_FOCUSNEXT
].keycode
== ev
.xkey
.keycode
271 && wKeyBindings
[WKBD_FOCUSNEXT
].modifier
== modifiers
)
272 || ev
.xkey
.keycode
== rightKey
) {
276 newFocused
= wSwitchPanelSelectNext(swpanel
, False
);
278 wWindowFocus(newFocused
, oldFocused
);
279 oldFocused
= newFocused
;
282 #else /* !MOX_CYCLING */
283 newFocused
= nextToFocusAfter(newFocused
);
284 wWindowFocus(newFocused
, oldFocused
);
285 oldFocused
= newFocused
;
287 if (wPreferences
.circ_raise
) {
290 XRaiseWindow(dpy
, newFocused
->frame
->core
->window
);
292 #endif /* !MOX_CYCLING */
293 } else if ((wKeyBindings
[WKBD_FOCUSPREV
].keycode
== ev
.xkey
.keycode
294 && wKeyBindings
[WKBD_FOCUSPREV
].modifier
== modifiers
)
295 || ev
.xkey
.keycode
== leftKey
) {
299 newFocused
= wSwitchPanelSelectNext(swpanel
, True
);
301 wWindowFocus(newFocused
, oldFocused
);
302 oldFocused
= newFocused
;
305 #else /* !MOX_CYCLING */
306 newFocused
= nextToFocusBefore(newFocused
);
307 wWindowFocus(newFocused
, oldFocused
);
308 oldFocused
= newFocused
;
310 if (wPreferences
.circ_raise
) {
313 XRaiseWindow(dpy
, newFocused
->frame
->core
->window
);
315 #endif /* !MOX_CYCLING */
316 } else if (ev
.xkey
.keycode
== homeKey
|| ev
.xkey
.keycode
== endKey
) {
318 newFocused
= wSwitchPanelSelectFirst(swpanel
, ev
.xkey
.keycode
!= homeKey
);
320 wWindowFocus(newFocused
, oldFocused
);
321 oldFocused
= newFocused
;
324 } else if (ev
.type
== MotionNotify
) {
327 tmp
= wSwitchPanelHandleEvent(swpanel
, &ev
);
330 wWindowFocus(newFocused
, oldFocused
);
331 oldFocused
= newFocused
;
336 printf("Got something else\n");
338 somethingElse
= True
;
341 } else if (ev
.type
== KeyRelease
) {
345 printf("Got key release\n");
347 for (i
= 0; i
< 8 * keymap
->max_keypermod
; i
++) {
348 if (keymap
->modifiermap
[i
] == ev
.xkey
.keycode
&&
349 wKeyBindings
[WKBD_FOCUSNEXT
].modifier
350 & 1<<(i
/keymap
->max_keypermod
)) {
358 XFreeModifiermap(keymap
);
362 printf("Ungrabbing keyboard\n");
364 XUngrabKeyboard(dpy
, CurrentTime
);
368 wSetFocusTo(scr
, newFocused
);
369 wMakeWindowVisible(newFocused
);
374 wSwitchPanelDestroy(swpanel
);
377 if (wPreferences
.circ_raise
&& newFocused
) {
378 wRaiseFrame(newFocused
->frame
->core
);
382 scr
->flags
.doing_alt_tab
= 0;