JWM Source Documentation
clientlist.c
Go to the documentation of this file.
1 
10 #include "jwm.h"
11 #include "clientlist.h"
12 #include "client.h"
13 #include "key.h"
14 #include "event.h"
15 #include "tray.h"
16 #include "settings.h"
17 
20 
21 static Window *windowStack = NULL;
22 static int windowStackSize = 0;
23 static int windowStackCurrent = 0;
24 static char walkingWindows = 0;
25 static char wasMinimized = 0;
28 char ShouldFocus(const ClientNode *np, char current)
29 {
30 
31  /* Only display clients on the current desktop or clients that are sticky. */
32  if(!settings.listAllTasks || current) {
33  if(!IsClientOnCurrentDesktop(np)) {
34  return 0;
35  }
36  }
37 
38  /* Don't display a client if it doesn't want to be displayed. */
39  if(np->state.status & STAT_NOLIST) {
40  return 0;
41  }
42 
43  /* Don't display a client on the tray if it has an owner. */
44  if(np->owner != None) {
45  return 0;
46  }
47 
49  return 0;
50  }
51 
52  return 1;
53 
54 }
55 
57 void StartWindowWalk(void)
58 {
59  JXGrabKeyboard(display, rootWindow, False, GrabModeAsync,
60  GrabModeAsync, CurrentTime);
61  RaiseTrays();
62  walkingWindows = 1;
63 }
64 
67 {
68 
69  /* Get an image of the window stack.
70  * Here we get the Window IDs rather than client pointers so
71  * clients can be added/removed without disrupting the stack walk.
72  */
73 
74  ClientNode *np;
75  int layer;
76  int count;
77 
78  /* If we are already walking the stack, just return. */
79  if(windowStack != NULL) {
80  return;
81  }
82 
83  /* First determine how much space to allocate for windows. */
84  count = 0;
85  for(layer = LAST_LAYER; layer >= FIRST_LAYER; layer--) {
86  for(np = nodes[layer]; np; np = np->next) {
87  if(ShouldFocus(np, 1)) {
88  ++count;
89  }
90  }
91  }
92 
93  /* If there were no windows to walk, don't even start. */
94  if(count == 0) {
95  return;
96  }
97 
98  /* Allocate space for the windows. */
99  windowStack = Allocate(sizeof(Window) * count);
100 
101  /* Copy windows into the array. */
102  windowStackSize = 0;
103  for(layer = LAST_LAYER; layer >= FIRST_LAYER; layer--) {
104  for(np = nodes[layer]; np; np = np->next) {
105  if(ShouldFocus(np, 1)) {
107  }
108  }
109  }
110 
111  Assert(windowStackSize == count);
112 
113  windowStackCurrent = 0;
114 
115  JXGrabKeyboard(display, rootWindow, False, GrabModeAsync,
116  GrabModeAsync, CurrentTime);
117 
118  RaiseTrays();
119 
120  walkingWindows = 1;
121  wasMinimized = 0;
122 
123 }
124 
126 void WalkWindowStack(char forward)
127 {
128 
129  ClientNode *np;
130 
131  if(windowStack != NULL) {
132  int x;
133 
134  if(wasMinimized) {
136  if(np) {
137  MinimizeClient(np, 1);
138  }
139  }
140 
141  /* Loop until we either raise a window or go through them all. */
142  for(x = 0; x < windowStackSize; x++) {
143 
144  /* Move to the next/previous window (wrap if needed). */
145  if(forward) {
146  windowStackCurrent = (windowStackCurrent + 1) % windowStackSize;
147  } else {
148  if(windowStackCurrent == 0) {
150  }
151  windowStackCurrent -= 1;
152  }
153 
154  /* Look up the window. */
156 
157  /* Skip this window if it no longer exists or is currently in
158  * a state that doesn't allow focus.
159  */
160  if(np == NULL || !ShouldFocus(np, 1)
161  || (np->state.status & STAT_ACTIVE)) {
162  continue;
163  }
164 
165  /* Show the window.
166  * Only when the walk completes do we update the stacking order. */
167  RestackClients();
168  if(np->state.status & STAT_MINIMIZED) {
169  RestoreClient(np, 1);
170  wasMinimized = 1;
171  } else {
172  wasMinimized = 0;
173  }
174  JXRaiseWindow(display, np->parent ? np->parent : np->window);
175  FocusClient(np);
176  break;
177 
178  }
179 
180  }
181 
182 }
183 
185 void StopWindowWalk(void)
186 {
187 
188  ClientNode *np;
189 
190  /* Raise the selected window and free the window array. */
191  if(windowStack != NULL) {
192 
193  /* Look up the current window. */
195  if(np) {
196  if(np->state.status & STAT_MINIMIZED) {
197  RestoreClient(np, 1);
198  } else {
199  RaiseClient(np);
200  }
201  }
202 
204  windowStack = NULL;
205 
206  windowStackSize = 0;
207  windowStackCurrent = 0;
208 
209  }
210 
211  if(walkingWindows) {
212  JXUngrabKeyboard(display, CurrentTime);
213  LowerTrays();
214  walkingWindows = 0;
215  }
216 
217 }
218 
221 {
222 
223  int x;
224  ClientNode *tp;
225 
226  Assert(np);
227 
228  for(tp = np->next; tp; tp = tp->next) {
229  if((tp->state.status & (STAT_MAPPED | STAT_SHADED))
230  && !(tp->state.status & STAT_HIDDEN)) {
231  FocusClient(tp);
232  return;
233  }
234  }
235  for(x = np->state.layer - 1; x >= FIRST_LAYER; x--) {
236  for(tp = nodes[x]; tp; tp = tp->next) {
237  if((tp->state.status & (STAT_MAPPED | STAT_SHADED))
238  && !(tp->state.status & STAT_HIDDEN)) {
239  FocusClient(tp);
240  return;
241  }
242  }
243  }
244 
245  /* No client to focus. */
246  JXSetInputFocus(display, rootWindow, RevertToParent, eventTime);
247 
248 }
249 

joewing.net / Projects / JWM