/[oroborus]/oroborus/src/client.c
ViewVC logotype

Diff of /oroborus/src/client.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.26 by dreamind, Wed Jul 10 02:12:21 2002 UTC revision 1.27 by dreamind, Mon Jul 15 08:23:07 2002 UTC
# Line 24  Line 24 
24  void  void
25  clientInitPosition (Client * c)  clientInitPosition (Client * c)
26  {  {
27    int mx, my, min_x, min_y, max_x, max_y;          int mx, my, min_x, min_y, max_x, max_y;
28    
29  #ifdef DEBUG  #ifdef DEBUG
30    printf ("entering clientInitPosition\n");          printf ("entering clientInitPosition\n");
31  #endif  #endif
32    
33    clientGravitate (c, APPLY);          clientGravitate (c, APPLY);
34    min_x = margins[MARGIN_LEFT];          min_x = margins[MARGIN_LEFT];
35    min_y = margins[MARGIN_TOP];          min_y = margins[MARGIN_TOP];
36    max_x = XDisplayWidth (dpy, screen) - margins[MARGIN_RIGHT];          max_x = XDisplayWidth (dpy, screen) - margins[MARGIN_RIGHT];
37    max_y = XDisplayHeight (dpy, screen) - margins[MARGIN_BOTTOM];          max_y = XDisplayHeight (dpy, screen) - margins[MARGIN_BOTTOM];
38    
39    if (!(c->size->flags & (PPosition | USPosition)))          if (!(c->size->flags & (PPosition | USPosition)))
40      {                  {
41        getMouseXY (dpy, root, &mx, &my);                          getMouseXY (dpy, root, &mx, &my);
42        c->x = mx - (frameWidth (c) / 2);                          c->x = mx - (frameWidth (c) / 2);
43        c->y = my - (frameHeight (c) / 2);                          c->y = my - (frameHeight (c) / 2);
44    
45        if (window_placement == PLACEMENT_ROOT)                          if (window_placement == PLACEMENT_ROOT)
46          {                                  {
47            c->x = (max_x - min_x) / 2 - (frameWidth (c) / 2);                                          c->x = (max_x - min_x) / 2 - (frameWidth (c) / 2);
48            c->y = (max_y - min_y) / 2 - (frameHeight (c) / 2);                                          c->y = (max_y - min_y) / 2 - (frameHeight (c) / 2);
49          }                                  }
50      }                  }
51    
52    if (c->x > max_x - frameWidth (c) + frameLeft (c))          if (c->x > max_x - frameWidth (c) + frameLeft (c))
53      c->x = max_x - frameWidth (c) + frameLeft (c);                  c->x = max_x - frameWidth (c) + frameLeft (c);
54    if (c->y > max_y - frameHeight (c) + frameTop (c))          if (c->y > max_y - frameHeight (c) + frameTop (c))
55      c->y = max_y - frameHeight (c) + frameTop (c);                  c->y = max_y - frameHeight (c) + frameTop (c);
56    if (c->x < min_x + frameLeft (c))          if (c->x < min_x + frameLeft (c))
57      c->x = min_x + frameLeft (c);                  c->x = min_x + frameLeft (c);
58    if (c->y < min_y + frameTop (c))          if (c->y < min_y + frameTop (c))
59      c->y = min_y + frameTop (c);                  c->y = min_y + frameTop (c);
60  }  }
61    
62  void  void
63  clientGrabKeys (Client * c)  clientGrabKeys (Client * c)
64  {  {
65    int i;          int i;
66  #ifdef DEBUG  #ifdef DEBUG
67    printf ("entering clientGrabKeys\n");          printf ("entering clientGrabKeys\n");
68    printf ("grabbing keys for client (%#lx)\n", c->window);          printf ("grabbing keys for client (%#lx)\n", c->window);
69  #endif  #endif
70    
71    for (i = 0; i < KEY_COUNT; i++)          for (i = 0; i < KEY_COUNT; i++)
72      grabKey (dpy, &keys[i], c->window);                  grabKey (dpy, &keys[i], c->window);
73  }  }
74    
75  void  void
76  clientUngrabKeys (Client * c)  clientUngrabKeys (Client * c)
77  {  {
78  #ifdef DEBUG  #ifdef DEBUG
79    printf ("entering clientUngrabKeys\n");          printf ("entering clientUngrabKeys\n");
80    printf ("ungrabing keys for client (%#lx)\n", c->window);          printf ("ungrabing keys for client (%#lx)\n", c->window);
81  #endif  #endif
82    
83    ungrabKeys (dpy, c->window);          ungrabKeys (dpy, c->window);
84  }  }
85    
86  void  void
87  clientGravitate (Client * c, int mode)  clientGravitate (Client * c, int mode)
88  {  {
89    int gravity, dx = 0, dy = 0;          int gravity, dx = 0, dy = 0;
90    
91  #ifdef DEBUG  #ifdef DEBUG
92    printf ("entering clientGravitate\n");          printf ("entering clientGravitate\n");
93  #endif  #endif
94    
95    gravity =          gravity =
96      c->size->flags & PWinGravity ? c->size->win_gravity : NorthWestGravity;                  c->size->flags & PWinGravity ? c->size->win_gravity : NorthWestGravity;
97    switch (gravity)          switch (gravity)
98      {                  {
99      case CenterGravity:                  case CenterGravity:
100        dx = (c->border_width * 2) - ((frameLeft (c) + frameRight (c)) / 2);                          dx = (c->border_width * 2) - ((frameLeft (c) + frameRight (c)) / 2);
101        dy = (c->border_width * 2) - ((frameTop (c) + frameBottom (c)) / 2);                          dy = (c->border_width * 2) - ((frameTop (c) + frameBottom (c)) / 2);
102        break;                          break;
103      case NorthGravity:                  case NorthGravity:
104        dx = (c->border_width * 2) - ((frameLeft (c) + frameRight (c)) / 2);                          dx = (c->border_width * 2) - ((frameLeft (c) + frameRight (c)) / 2);
105        dy = frameTop (c);                          dy = frameTop (c);
106        break;                          break;
107      case SouthGravity:                  case SouthGravity:
108        dx = (c->border_width * 2) - ((frameLeft (c) + frameRight (c)) / 2);                          dx = (c->border_width * 2) - ((frameLeft (c) + frameRight (c)) / 2);
109        dy = (c->border_width * 2) - frameBottom (c);                          dy = (c->border_width * 2) - frameBottom (c);
110        break;                          break;
111      case EastGravity:                  case EastGravity:
112        dx = (c->border_width * 2) - frameRight (c);                          dx = (c->border_width * 2) - frameRight (c);
113        dy = (c->border_width * 2) - ((frameTop (c) + frameBottom (c)) / 2);                          dy = (c->border_width * 2) - ((frameTop (c) + frameBottom (c)) / 2);
114        break;                          break;
115      case WestGravity:                  case WestGravity:
116        dx = frameLeft (c);                          dx = frameLeft (c);
117        dy = (c->border_width * 2) - ((frameTop (c) + frameBottom (c)) / 2);                          dy = (c->border_width * 2) - ((frameTop (c) + frameBottom (c)) / 2);
118        break;                          break;
119      case NorthWestGravity:                  case NorthWestGravity:
120        dx = frameLeft (c);                          dx = frameLeft (c);
121        dy = frameTop (c);                          dy = frameTop (c);
122        break;                          break;
123      case NorthEastGravity:                  case NorthEastGravity:
124        dx = (c->border_width * 2) - frameRight (c);                          dx = (c->border_width * 2) - frameRight (c);
125        dy = frameTop (c);                          dy = frameTop (c);
126        break;                          break;
127      case SouthWestGravity:                  case SouthWestGravity:
128        dx = frameLeft (c);                          dx = frameLeft (c);
129        dy = (c->border_width * 2) - frameBottom (c);                          dy = (c->border_width * 2) - frameBottom (c);
130        break;                          break;
131      case SouthEastGravity:                  case SouthEastGravity:
132        dx = (c->border_width * 2) - frameRight (c);                          dx = (c->border_width * 2) - frameRight (c);
133        dy = (c->border_width * 2) - frameBottom (c);                          dy = (c->border_width * 2) - frameBottom (c);
134        break;                          break;
135      }                  }
136    c->x = c->x + (dx * mode);          c->x = c->x + (dx * mode);
137    c->y = c->y + (dy * mode);          c->y = c->y + (dy * mode);
138  }  }
139    
140  void  void
141  clientAddToList (Client * c)  clientAddToList (Client * c)
142  {  {
143    int i;          int i;
144    CARD32 *new;          CARD32 *new;
145    
146  #ifdef DEBUG  #ifdef DEBUG
147    printf ("entering clientAddToList\n");          printf ("entering clientAddToList\n");
148  #endif  #endif
149    
150    new = (CARD32 *) xmalloc (sizeof (CARD32) * client_count);          new = (CARD32 *) xmalloc (sizeof (CARD32) * client_count);
151    if (new)          if (new)
152      {                  {
153        for (i = 0; i < client_count - 1; i++)                          for (i = 0; i < client_count - 1; i++)
154          new[i] = client_list[i];                                  new[i] = client_list[i];
155        new[i] = c->window;                          new[i] = c->window;
156        XChangeProperty (dpy, root, win_client_list, XA_CARDINAL, 32,                          XChangeProperty (dpy, root, win_client_list, XA_CARDINAL, 32,
157                         PropModeReplace, (unsigned char *) new, client_count);                                                                                           PropModeReplace, (unsigned char *) new, client_count);
158        XChangeProperty (dpy, root, net_atoms[NET_CLIENT_LIST], XA_WINDOW, 32,                          XChangeProperty (dpy, root, net_atoms[NET_CLIENT_LIST], XA_WINDOW, 32,
159                         PropModeReplace, (unsigned char *) new, client_count);                                                                                           PropModeReplace, (unsigned char *) new, client_count);
160        XChangeProperty (dpy, root, net_atoms[NET_CLIENT_LIST_STACKING],                          XChangeProperty (dpy, root, net_atoms[NET_CLIENT_LIST_STACKING],
161                         XA_WINDOW, 32, PropModeReplace,                                                                                           XA_WINDOW, 32, PropModeReplace,
162                         (unsigned char *) new, client_count);                                                                                           (unsigned char *) new, client_count);
163        if (client_list)                          if (client_list)
164          free (client_list);                                  free (client_list);
165        client_list = new;                          client_list = new;
166      }                  }
167  }  }
168    
169  void  void
170  clientRemoveFromList (Client * c)  clientRemoveFromList (Client * c)
171  {  {
172    int i, j;          int i, j;
173    CARD32 *new;          CARD32 *new;
174    
175  #ifdef DEBUG  #ifdef DEBUG
176    printf ("entering clientRemoveFromList\n");          printf ("entering clientRemoveFromList\n");
177  #endif  #endif
178    
179    new = (CARD32 *) xmalloc (sizeof (CARD32) * client_count);          new = (CARD32 *) xmalloc (sizeof (CARD32) * client_count);
180    if (new)          if (new)
181      {                  {
182        for (i = 0, j = 0; i < client_count; i++)                          for (i = 0, j = 0; i < client_count; i++)
183          if (client_list[i] != c->window)                                  if (client_list[i] != c->window)
184            new[j++] = client_list[i];                                          new[j++] = client_list[i];
185        XChangeProperty (dpy, root, win_client_list, XA_CARDINAL, 32,                          XChangeProperty (dpy, root, win_client_list, XA_CARDINAL, 32,
186                         PropModeReplace, (unsigned char *) new,                                                                                           PropModeReplace, (unsigned char *) new,
187                         client_count - 1);                                                                                           client_count - 1);
188        XChangeProperty (dpy, root, net_atoms[NET_CLIENT_LIST], XA_WINDOW, 32,                          XChangeProperty (dpy, root, net_atoms[NET_CLIENT_LIST], XA_WINDOW, 32,
189                         PropModeReplace, (unsigned char *) new,                                                                                           PropModeReplace, (unsigned char *) new,
190                         client_count - 1);                                                                                           client_count - 1);
191        XChangeProperty (dpy, root, net_atoms[NET_CLIENT_LIST_STACKING],                          XChangeProperty (dpy, root, net_atoms[NET_CLIENT_LIST_STACKING],
192                         XA_WINDOW, 32, PropModeReplace,                                                                                           XA_WINDOW, 32, PropModeReplace,
193                         (unsigned char *) new, client_count - 1);                                                                                           (unsigned char *) new, client_count - 1);
194        if (client_list)                          if (client_list)
195          free (client_list);                                  free (client_list);
196        client_list = new;                          client_list = new;
197      }                  }
198  }  }
199    
200  int  int
201  clientGetWidthInc (Client * c)  clientGetWidthInc (Client * c)
202  {  {
203    if (c->size->flags & PResizeInc)          if (c->size->flags & PResizeInc)
204      return c->size->width_inc;                  return c->size->width_inc;
205    return 1;          return 1;
206  }  }
207    
208  int  int
209  clientGetHeightInc (Client * c)  clientGetHeightInc (Client * c)
210  {  {
211    if (c->size->flags & PResizeInc)          if (c->size->flags & PResizeInc)
212      return c->size->height_inc;                  return c->size->height_inc;
213    return 1;          return 1;
214  }  }
215    
216  void  void
217  clientSetWidth (Client * c, int w1)  clientSetWidth (Client * c, int w1)
218  {  {
219    int w2;          int w2;
220    
221    if (c->size->flags & PResizeInc)          if (c->size->flags & PResizeInc)
222      {                  {
223        if (c->size->width_inc == 0)                          if (c->size->width_inc == 0)
224          c->size->width_inc = 1;                                  c->size->width_inc = 1;
225        w2 = (w1 - c->size->min_width) / c->size->width_inc;                          w2 = (w1 - c->size->min_width) / c->size->width_inc;
226        w1 = c->size->min_width + (w2 * c->size->width_inc);                          w1 = c->size->min_width + (w2 * c->size->width_inc);
227      }                  }
228    if (c->size->flags & PMinSize)          if (c->size->flags & PMinSize)
229      if (w1 < c->size->min_width)                  if (w1 < c->size->min_width)
230        w1 = c->size->min_width;                          w1 = c->size->min_width;
231    if (c->size->flags & PMaxSize)          if (c->size->flags & PMaxSize)
232      if (w1 > c->size->max_width)                  if (w1 > c->size->max_width)
233        w1 = c->size->max_width;                          w1 = c->size->max_width;
234    if (w1 < 1)          if (w1 < 1)
235      w1 = 1;                  w1 = 1;
236    c->width = w1;          c->width = w1;
237  }  }
238    
239  void  void
240  clientSetHeight (Client * c, int h1)  clientSetHeight (Client * c, int h1)
241  {  {
242    int h2;          int h2;
243    
244    if (c->size->flags & PResizeInc)          if (c->size->flags & PResizeInc)
245      {                  {
246        if (c->size->height_inc == 0)                          if (c->size->height_inc == 0)
247          c->size->height_inc = 1;                                  c->size->height_inc = 1;
248        h2 = (h1 - c->size->min_height) / c->size->height_inc;                          h2 = (h1 - c->size->min_height) / c->size->height_inc;
249        h1 = c->size->min_height + (h2 * c->size->height_inc);                          h1 = c->size->min_height + (h2 * c->size->height_inc);
250      }                  }
251    if (c->size->flags & PMinSize)          if (c->size->flags & PMinSize)
252      if (h1 < c->size->min_height)                  if (h1 < c->size->min_height)
253        h1 = c->size->min_height;                          h1 = c->size->min_height;
254    if (c->size->flags & PMaxSize)          if (c->size->flags & PMaxSize)
255      if (h1 > c->size->max_height)                  if (h1 > c->size->max_height)
256        h1 = c->size->max_height;                          h1 = c->size->max_height;
257    if (h1 < 1)          if (h1 < 1)
258      h1 = 1;                  h1 = 1;
259    c->height = h1;          c->height = h1;
260  }  }
261    
262  Client *  Client *
263  clientGetTopMost (int layer)  clientGetTopMost (int layer)
264  {  {
265    Window w1, w2, *wins;          Window w1, w2, *wins;
266    unsigned int i, count;          unsigned int i, count;
267    XWindowAttributes attr;          XWindowAttributes attr;
268    Client *top = NULL, *c;          Client *top = NULL, *c;
269    
270  #ifdef DEBUG  #ifdef DEBUG
271    printf ("entering clientGetTopMost\n");          printf ("entering clientGetTopMost\n");
272  #endif  #endif
273    
274    XQueryTree (dpy, root, &w1, &w2, &wins, &count);          XQueryTree (dpy, root, &w1, &w2, &wins, &count);
275    for (i = 0; i < count; i++)          for (i = 0; i < count; i++)
276      {                  {
277        XGetWindowAttributes (dpy, wins[i], &attr);                          XGetWindowAttributes (dpy, wins[i], &attr);
278        c = clientGetFromWindow (wins[i], FRAME);                          c = clientGetFromWindow (wins[i], FRAME);
279        if (c && attr.map_state == IsViewable)                          if (c && attr.map_state == IsViewable)
280          {                                  {
281            if (c->win_layer <= layer)                                          if (c->win_layer <= layer)
282              top = c;                                                  top = c;
283            else                                          else
284              break;                                                  break;
285          }                                  }
286      }                  }
287    if (wins)          if (wins)
288      XFree (wins);                  XFree (wins);
289    return top;          return top;
290  }  }
291    
292  Client *  Client *
293  clientGetBottomMost (int layer)  clientGetBottomMost (int layer)
294  {  {
295    Window w1, w2, *wins;          Window w1, w2, *wins;
296    unsigned int i, count;          unsigned int i, count;
297    XWindowAttributes attr;          XWindowAttributes attr;
298    Client *c = NULL;          Client *c = NULL;
299    
300  #ifdef DEBUG  #ifdef DEBUG
301    printf ("entering clientGetBottomMost\n");          printf ("entering clientGetBottomMost\n");
302  #endif  #endif
303    
304    XQueryTree (dpy, root, &w1, &w2, &wins, &count);          XQueryTree (dpy, root, &w1, &w2, &wins, &count);
305    for (i = 0; i < count; i++)          for (i = 0; i < count; i++)
306      {                  {
307        XGetWindowAttributes (dpy, wins[i], &attr);                          XGetWindowAttributes (dpy, wins[i], &attr);
308        c = clientGetFromWindow (wins[i], FRAME);                          c = clientGetFromWindow (wins[i], FRAME);
309        if (c && attr.map_state == IsViewable                          if (c && attr.map_state == IsViewable
310            && !(c->win_hints & WIN_HINTS_SKIP_FOCUS))                                          && !(c->win_hints & WIN_HINTS_SKIP_FOCUS))
311          {                                  {
312            if (c->win_layer >= layer)                                          if (c->win_layer >= layer)
313              break;                                                  break;
314          }                                  }
315      }                  }
316    if (wins)          if (wins)
317      XFree (wins);                  XFree (wins);
318    return c;          return c;
319  }  }
320    
321  void  void
322  clientConfigure (Client * c, XWindowChanges * wc, int mask)  clientConfigure (Client * c, XWindowChanges * wc, int mask)
323  {  {
324    XConfigureEvent ce;          XConfigureEvent ce;
325    Client *sibling = NULL;          Client *sibling = NULL;
326    
327  #ifdef DEBUG  #ifdef DEBUG
328    printf ("entering clientConfigure\n");          printf ("entering clientConfigure\n");
329    printf ("configuring client (%#lx)\n", c->window);          printf ("configuring client (%#lx)\n", c->window);
330  #endif  #endif
331    
332    if (mask & CWX)          if (mask & CWX)
333      c->x = wc->x;                  c->x = wc->x;
334    if (mask & CWY)          if (mask & CWY)
335      c->y = wc->y;                  c->y = wc->y;
336    if (mask & CWWidth)          if (mask & CWWidth)
337      clientSetWidth (c, wc->width);                  clientSetWidth (c, wc->width);
338    if (mask & CWHeight)          if (mask & CWHeight)
339      clientSetHeight (c, wc->height);                  clientSetHeight (c, wc->height);
340    if (mask & CWBorderWidth)          if (mask & CWBorderWidth)
341      c->border_width = wc->border_width;                  c->border_width = wc->border_width;
342    if (mask & CWStackMode)          if (mask & CWStackMode)
343      {                  {
344        switch (wc->stack_mode)                          switch (wc->stack_mode)
345          {                                  {
346          case Above:                                  case Above:
347            sibling = clientGetTopMost (c->win_layer);                                          sibling = clientGetTopMost (c->win_layer);
348            if (!sibling)                                          if (!sibling)
349              wc->stack_mode = Below;                                                  wc->stack_mode = Below;
350            break;                                          break;
351          case Below:                                  case Below:
352            sibling = clientGetBottomMost (c->win_layer);                                          sibling = clientGetBottomMost (c->win_layer);
353            break;                                          break;
354          }                                  }
355        if (sibling)                          if (sibling)
356          {                                  {
357            if (sibling != c)                                          if (sibling != c)
358              {                                                  {
359                wc->sibling = sibling->frame;                                                          wc->sibling = sibling->frame;
360                mask = mask | CWSibling;                                                          mask = mask | CWSibling;
361              }                                                  }
362            else                                          else
363              mask = mask & ~(CWSibling | CWStackMode);                                                  mask = mask & ~(CWSibling | CWStackMode);
364          }                                  }
365        else                          else
366                                    mask = mask & ~CWSibling;
367                    }
368    
369            wc->x = frameX (c);
370            wc->y = frameY (c);
371            wc->width = frameWidth (c);
372            wc->height = frameHeight (c);
373            wc->border_width = 0;
374            XConfigureWindow (dpy, c->frame, mask, wc);
375            wc->x = frameLeft (c);
376            wc->y = frameTop (c);
377            wc->width = c->width;
378            wc->height = c->height;
379            mask = mask & ~CWStackMode;
380          mask = mask & ~CWSibling;          mask = mask & ~CWSibling;
381      }          XConfigureWindow (dpy, c->window, mask, wc);
382    
383    wc->x = frameX (c);          if (mask & (CWWidth | CWHeight))
384    wc->y = frameY (c);                  frameDraw (c);
385    wc->width = frameWidth (c);  
386    wc->height = frameHeight (c);          if (mask)
387    wc->border_width = 0;                  {
388    XConfigureWindow (dpy, c->frame, mask, wc);                          ce.type = ConfigureNotify;
389    wc->x = frameLeft (c);                          ce.event = c->window;
390    wc->y = frameTop (c);                          ce.window = c->window;
391    wc->width = c->width;                          ce.x = c->x;
392    wc->height = c->height;                          ce.y = c->y;
393    mask = mask & ~CWStackMode;                          ce.width = c->width;
394    mask = mask & ~CWSibling;                          ce.height = c->height;
395    XConfigureWindow (dpy, c->window, mask, wc);                          ce.border_width = 0;
396                            ce.above = None;
397    if (mask & (CWWidth | CWHeight))                          ce.override_redirect = False;
398      frameDraw (c);                          XSendEvent (dpy, c->window, False, StructureNotifyMask,
399                                                                            (XEvent *) & ce);
400    if (mask)                  }
     {  
       ce.type = ConfigureNotify;  
       ce.event = c->window;  
       ce.window = c->window;  
       ce.x = c->x;  
       ce.y = c->y;  
       ce.width = c->width;  
       ce.height = c->height;  
       ce.border_width = 0;  
       ce.above = None;  
       ce.override_redirect = False;  
       XSendEvent (dpy, c->window, False, StructureNotifyMask,  
                   (XEvent *) & ce);  
     }  
401  }  }
402    
403  void  void
404  clientFrame (Window w)  clientFrame (Window w)
405  {  {
406    Client *c;          Client *c;
407    XWindowAttributes attr;          XWindowAttributes attr;
408    XWindowChanges wc;          XWindowChanges wc;
409    long dummy;          long dummy;
410    PropMwmHints *mwm_hints;          PropMwmHints *mwm_hints;
411    Window transientWindow;          Window transientWindow;
412    int i;          int i;
413    
414  #ifdef DEBUG  #ifdef DEBUG
415    printf ("entering clientFrame\n");          printf ("entering clientFrame\n");
416    printf ("framing client (%#lx)\n", w);          printf ("framing client (%#lx)\n", w);
417  #endif  #endif
418    
419    c = xmalloc (sizeof (*c));          c = xmalloc (sizeof (*c));
420    
421    c->size = XAllocSizeHints ();          c->size = XAllocSizeHints ();
422    XGetWMNormalHints (dpy, w, c->size, &dummy);          XGetWMNormalHints (dpy, w, c->size, &dummy);
423    XGetWindowAttributes (dpy, w, &attr);          XGetWindowAttributes (dpy, w, &attr);
424    c->window = w;          c->window = w;
425    c->x = c->old_x = attr.x;          c->x = c->old_x = attr.x;
426    c->y = c->old_y = attr.y;          c->y = c->old_y = attr.y;
427    c->width = c->old_width = attr.width;          c->width = c->old_width = attr.width;
428    c->height = c->old_height = attr.height;          c->height = c->old_height = attr.height;
429    c->border_width = attr.border_width;          c->border_width = attr.border_width;
430    for (i = 0; i < BUTTON_COUNT; i++)          for (i = 0; i < BUTTON_COUNT; i++)
431      c->button_pressed[i] = False;                  c->button_pressed[i] = False;
432    if (!getGnomeHint (w, win_hints, &c->win_hints))          if (!getGnomeHint (w, win_hints, &c->win_hints))
433      c->win_hints = 0;                  c->win_hints = 0;
434    if (!getGnomeHint (w, win_state, &c->win_state))          if (!getGnomeHint (w, win_state, &c->win_state))
435      c->win_state = 0;                  c->win_state = 0;
436    getEWMHState (w, &c->win_state);          getEWMHState (w, &c->win_state);
437    if (!getGnomeHint (w, win_layer, &c->win_layer))          if (!getGnomeHint (w, win_layer, &c->win_layer))
438      c->win_layer = WIN_LAYER_NORMAL;                  c->win_layer = WIN_LAYER_NORMAL;
439    if (!getGnomeHint (w, win_workspace, &c->win_workspace))          if (!getGnomeHint (w, win_workspace, &c->win_workspace))
440      {                  {
441        setGnomeHint (w, win_workspace, workspace);                          setGnomeHint (w, win_workspace, workspace);
442        setGnomeHint (w, net_atoms[NET_WM_DESKTOP], workspace);                          setGnomeHint (w, net_atoms[NET_WM_DESKTOP], workspace);
443        c->win_workspace = workspace;                          c->win_workspace = workspace;
444      }                  }
445    if (c->win_workspace > workspace_count - 1)          if (c->win_workspace > workspace_count - 1)
446      {                  {
447        setGnomeHint (w, win_workspace, workspace_count - 1);                          setGnomeHint (w, win_workspace, workspace_count - 1);
448        setGnomeHint (w, net_atoms[NET_WM_DESKTOP], workspace_count - 1);                          setGnomeHint (w, net_atoms[NET_WM_DESKTOP], workspace_count - 1);
449        c->win_workspace = workspace_count - 1;                          c->win_workspace = workspace_count - 1;
450      }                  }
451    
452    if (clientInBorderlessList (c))          if (clientInBorderlessList (c))
453      c->has_border = False;                  c->has_border = False;
454    else          else
455      c->has_border = True;                  c->has_border = True;
456    
457    if (typeDesktop (c->window))          if (typeDesktop (c->window))
458      {                  {
459        c->win_hints = c->win_hints | WIN_HINTS_SKIP_FOCUS;                          c->win_hints = c->win_hints | WIN_HINTS_SKIP_FOCUS;
460        c->win_state = c->win_state | WIN_STATE_STICKY;                          c->win_state = c->win_state | WIN_STATE_STICKY;
461        c->has_border = False;                          c->has_border = False;
462        c->win_layer = WIN_LAYER_DESKTOP;                          c->win_layer = WIN_LAYER_DESKTOP;
463      }                  }
464    
465    if (typeDock (c->window))          if (typeDock (c->window))
466      {                  {
467        c->win_hints = c->win_hints | WIN_HINTS_SKIP_FOCUS;                          c->win_hints = c->win_hints | WIN_HINTS_SKIP_FOCUS;
468      }                  }
469    
470    c->ignore_unmap = attr.map_state == IsViewable ? 1 : 0;          c->ignore_unmap = attr.map_state == IsViewable ? 1 : 0;
471    c->focus = False;          c->focus = False;
472    getWindowName (dpy, c->window, &c->name);          getWindowName (dpy, c->window, &c->name);
473    
474    mwm_hints = getMotifHints (c->window);          mwm_hints = getMotifHints (c->window);
475    if (mwm_hints)          if (mwm_hints)
476      {                  {
477        if (mwm_hints->flags & MWM_HINTS_DECORATIONS &&                          if (mwm_hints->flags & MWM_HINTS_DECORATIONS &&
478            !(mwm_hints->decorations & MWM_DECOR_ALL))                                          !(mwm_hints->decorations & MWM_DECOR_ALL))
479          c->has_border = mwm_hints->decorations & MWM_DECOR_BORDER;                                  c->has_border = mwm_hints->decorations & MWM_DECOR_BORDER;
480        XFree (mwm_hints);                          XFree (mwm_hints);
481      }                  }
482    
483    if (attr.map_state != IsViewable)          if (attr.map_state != IsViewable)
484      clientInitPosition (c);                  clientInitPosition (c);
485    else          else
486      clientGravitate (c, APPLY);                  clientGravitate (c, APPLY);
487    
488    c->frame =          c->frame =
489      XCreateSimpleWindow (dpy, root, frameX (c), frameY (c), frameWidth (c),                  XCreateSimpleWindow (dpy, root, frameX (c), frameY (c), frameWidth (c),
490                           frameHeight (c), 0, 0, 0);                                                                                                   frameHeight (c), 0, 0, 0);
491    XSelectInput (dpy, c->frame,          XSelectInput (dpy, c->frame,
492                  SubstructureNotifyMask | SubstructureRedirectMask |                                                                  SubstructureNotifyMask | SubstructureRedirectMask |
493                  EnterWindowMask);                                                                  EnterWindowMask);
494    XSelectInput (dpy, c->window, FocusChangeMask | PropertyChangeMask);          XSelectInput (dpy, c->window, FocusChangeMask | PropertyChangeMask);
495    if (shape)          if (shape)
496      XShapeSelectInput (dpy, c->window, ShapeNotifyMask);                  XShapeSelectInput (dpy, c->window, ShapeNotifyMask);
497    XSetWindowBorderWidth (dpy, w, 0);          XSetWindowBorderWidth (dpy, w, 0);
498    XReparentWindow (dpy, w, c->frame, frameLeft (c), frameTop (c));          XReparentWindow (dpy, w, c->frame, frameLeft (c), frameTop (c));
499    XGrabButton (dpy, AnyButton, AnyModifier, c->frame, False, ButtonPressMask,          XGrabButton (dpy, AnyButton, AnyModifier, c->frame, False, ButtonPressMask,
500                 GrabModeSync, GrabModeAsync, None, None);                                                           GrabModeSync, GrabModeAsync, None, None);
501    
502    c->sides[SIDE_LEFT] =          c->sides[SIDE_LEFT] =
503      XCreateSimpleWindow (dpy, c->frame, 0, 0, 1, 1, 0, 0, 0);                  XCreateSimpleWindow (dpy, c->frame, 0, 0, 1, 1, 0, 0, 0);
504    c->sides[SIDE_RIGHT] =          c->sides[SIDE_RIGHT] =
505      XCreateSimpleWindow (dpy, c->frame, 0, 0, 1, 1, 0, 0, 0);                  XCreateSimpleWindow (dpy, c->frame, 0, 0, 1, 1, 0, 0, 0);
506    c->sides[SIDE_BOTTOM] =          c->sides[SIDE_BOTTOM] =
507      XCreateSimpleWindow (dpy, c->frame, 0, 0, 1, 1, 0, 0, 0);                  XCreateSimpleWindow (dpy, c->frame, 0, 0, 1, 1, 0, 0, 0);
508    c->corners[CORNER_BOTTOM_LEFT] =          c->corners[CORNER_BOTTOM_LEFT] =
509      XCreateSimpleWindow (dpy, c->frame, 0, 0, 1, 1, 0, 0, 0);                  XCreateSimpleWindow (dpy, c->frame, 0, 0, 1, 1, 0, 0, 0);
510    c->corners[CORNER_BOTTOM_RIGHT] =          c->corners[CORNER_BOTTOM_RIGHT] =
511      XCreateSimpleWindow (dpy, c->frame, 0, 0, 1, 1, 0, 0, 0);                  XCreateSimpleWindow (dpy, c->frame, 0, 0, 1, 1, 0, 0, 0);
512    c->title = XCreateSimpleWindow (dpy, c->frame, 0, 0, 1, 1, 0, 0, 0);          c->title = XCreateSimpleWindow (dpy, c->frame, 0, 0, 1, 1, 0, 0, 0);
513    c->corners[CORNER_TOP_LEFT] =          c->corners[CORNER_TOP_LEFT] =
514      XCreateSimpleWindow (dpy, c->frame, 0, 0, 1, 1, 0, 0, 0);                  XCreateSimpleWindow (dpy, c->frame, 0, 0, 1, 1, 0, 0, 0);
515    c->corners[CORNER_TOP_RIGHT] =          c->corners[CORNER_TOP_RIGHT] =
516      XCreateSimpleWindow (dpy, c->frame, 0, 0, 1, 1, 0, 0, 0);                  XCreateSimpleWindow (dpy, c->frame, 0, 0, 1, 1, 0, 0, 0);
517    for (i = 0; i < 4; i++)          for (i = 0; i < 4; i++)
518      XDefineCursor (dpy, c->corners[i], resize_cursor[i]);                  XDefineCursor (dpy, c->corners[i], resize_cursor[i]);
519    
520    for (i = 0; i < BUTTON_COUNT; i++)          for (i = 0; i < BUTTON_COUNT; i++)
521      c->buttons[i] = XCreateSimpleWindow (dpy, c->frame, 0, 0, 1, 1, 0, 0, 0);                  c->buttons[i] = XCreateSimpleWindow (dpy, c->frame, 0, 0, 1, 1, 0, 0, 0);
522    
523    if (clients)          if (clients)
524      {                  {
525        c->prev = clients->prev;                          c->prev = clients->prev;
526        c->next = clients;                          c->next = clients;
527        clients->prev->next = c;                          clients->prev->next = c;
528        clients->prev = c;                          clients->prev = c;
529      }                  }
530    else          else
531      {                  {
532        clients = c;                          clients = c;
533        c->next = c;                          c->next = c;
534        c->prev = c;                          c->prev = c;
535      }                  }
536    
537    XGetTransientForHint (dpy, c->window, &transientWindow);          XGetTransientForHint (dpy, c->window, &transientWindow);
538    c->transientFor = clientGetFromWindow (transientWindow, WINDOW);          c->transientFor = clientGetFromWindow (transientWindow, WINDOW);
539    
540    client_count++;          client_count++;
541    clientAddToList (c);          clientAddToList (c);
542    clientGrabKeys (c);          clientGrabKeys (c);
543    frameDraw (c);          frameDraw (c);
544    wc.x = c->x;          wc.x = c->x;
545    wc.y = c->y;          wc.y = c->y;
546    wc.height = c->height;          wc.height = c->height;
547    wc.width = c->width;          wc.width = c->width;
548    wc.stack_mode = Above;          wc.stack_mode = Above;
549    clientConfigure (c, &wc, CWX | CWY | CWHeight | CWWidth | CWStackMode);          clientConfigure (c, &wc, CWX | CWY | CWHeight | CWWidth | CWStackMode);
550    
551    if (getWMState (c->window) != IconicState)          if (getWMState (c->window) != IconicState)
552      {                  {
553        clientShow (c, True);                          clientShow (c, True);
554        if (focus_new && !(c->win_hints & WIN_HINTS_SKIP_FOCUS))                          if (focus_new && !(c->win_hints & WIN_HINTS_SKIP_FOCUS))
555          {                                  {
556            clientSetFocus (c, True);                                          clientSetFocus (c, True);
557          }                                  }
558      }                  }
559    else          else
560      setWMState (c->window, IconicState);                  setWMState (c->window, IconicState);
561    
562  #ifdef DEBUG  #ifdef DEBUG
563    printf ("client_count=%d\n", client_count);          printf ("client_count=%d\n", client_count);
564  #endif  #endif
565  }  }
566    
# Line 568  void Line 568  void
568  clientUnframe (Client * c, int remap)  clientUnframe (Client * c, int remap)
569  {  {
570  #ifdef DEBUG  #ifdef DEBUG
571    printf ("entering clientUnframe\n");          printf ("entering clientUnframe\n");
572    printf ("unframing client (%#lx)\n", c->window);          printf ("unframing client (%#lx)\n", c->window);
573  #endif  #endif
574    
575    clientGravitate (c, REMOVE);          clientGravitate (c, REMOVE);
576    clientUngrabKeys (c);          clientUngrabKeys (c);
577    XSetWindowBorderWidth (dpy, c->window, c->border_width);          XSetWindowBorderWidth (dpy, c->window, c->border_width);
578    XReparentWindow (dpy, c->window, root, c->x, c->y);          XReparentWindow (dpy, c->window, root, c->x, c->y);
579    if (remap)          if (remap)
580      XMapWindow (dpy, c->window);                  XMapWindow (dpy, c->window);
581    else          else
582      setWMState (c->window, WithdrawnState);                  setWMState (c->window, WithdrawnState);
583    XDestroyWindow (dpy, c->frame);          XDestroyWindow (dpy, c->frame);
584    
585    clientRemoveFromList (c);          clientRemoveFromList (c);
586    if (client_count == 1)          if (client_count == 1)
587      clients = NULL;                  clients = NULL;
588    else          else
589      {                  {
590        c->next->prev = c->prev;                          c->next->prev = c->prev;
591        c->prev->next = c->next;                          c->prev->next = c->next;
592        if (c == clients)                          if (c == clients)
593          clients = clients->next;                                  clients = clients->next;
594      }                  }
595    
596    if (c->name)          if (c->name)
597      free (c->name);                  free (c->name);
598    if (c->size)          if (c->size)
599      XFree (c->size);                  XFree (c->size);
600    free (c);          free (c);
601    client_count--;          client_count--;
602    
603  #ifdef DEBUG  #ifdef DEBUG
604    printf ("client_count=%d\n", client_count);          printf ("client_count=%d\n", client_count);
605  #endif  #endif
606  }  }
607    
608  void  void
609  clientFrameAll ()  clientFrameAll ()
610  {  {
611    unsigned int count, i;          unsigned int count, i;
612    Window w1, w2, *wins = NULL;          Window w1, w2, *wins = NULL;
613    XWindowAttributes attr;          XWindowAttributes attr;
614    
615  #ifdef DEBUG  #ifdef DEBUG
616    printf ("entering clientFrameAll\n");          printf ("entering clientFrameAll\n");
617  #endif  #endif
618    
619    XQueryTree (dpy, root, &w1, &w2, &wins, &count);          XQueryTree (dpy, root, &w1, &w2, &wins, &count);
620    for (i = 0; i < count; i++)          for (i = 0; i < count; i++)
621      {                  {
622        XGetWindowAttributes (dpy, wins[i], &attr);                          XGetWindowAttributes (dpy, wins[i], &attr);
623        if (!attr.override_redirect && attr.map_state == IsViewable)                          if (!attr.override_redirect && attr.map_state == IsViewable)
624          clientFrame (wins[i]);                                  clientFrame (wins[i]);
625      }                  }
626    if (wins)          if (wins)
627      XFree (wins);                  XFree (wins);
628  }  }
629    
630  void  void
631  clientUnframeAll ()  clientUnframeAll ()
632  {  {
633    Client *c;          Client *c;
634    unsigned int count, i;          unsigned int count, i;
635    Window w1, w2, *wins = NULL;          Window w1, w2, *wins = NULL;
636    
637  #ifdef DEBUG  #ifdef DEBUG
638    printf ("entering clientUnframeAll\n");          printf ("entering clientUnframeAll\n");
639  #endif  #endif
640    
641    XQueryTree (dpy, root, &w1, &w2, &wins, &count);          XQueryTree (dpy, root, &w1, &w2, &wins, &count);
642    for (i = 0; i < count; i++)          for (i = 0; i < count; i++)
643      {                  {
644        c = clientGetFromWindow (wins[i], FRAME);                          c = clientGetFromWindow (wins[i], FRAME);
645        if (c)                          if (c)
646          clientUnframe (c, True);                                  clientUnframe (c, True);
647      }                  }
648    if (wins)          if (wins)
649      XFree (wins);                  XFree (wins);
650  }  }
651    
652  Client *  Client *
653  clientGetFromWindow (Window w, int mode)  clientGetFromWindow (Window w, int mode)
654  {  {
655    Client *c;          Client *c;
656    int i;          int i;
657    
658  #ifdef DEBUG  #ifdef DEBUG
659    printf ("entering clientGetFromWindow\n");          printf ("entering clientGetFromWindow\n");
660  #endif  #endif
661    
662    for (c = clients, i = 0; i < client_count; c = c->next, i++)          for (c = clients, i = 0; i < client_count; c = c->next, i++)
663      {                  {
664        if (c->window == w && mode == WINDOW)                          if (c->window == w && mode == WINDOW)
665          return c;                                  return c;
666        if (c->frame == w && mode == FRAME)                          if (c->frame == w && mode == FRAME)
667          return c;                                  return c;
668      }                  }
669    
670  #ifdef DEBUG  #ifdef DEBUG
671    printf ("no client found\n");          printf ("no client found\n");
672  #endif  #endif
673    
674    return NULL;          return NULL;
675  }  }
676    
677  void  void
678  clientShow (Client * c, int change_state)  clientShow (Client * c, int change_state)
679  {  {
680  #ifdef DEBUG  #ifdef DEBUG
681    printf ("entering clientShow\n");          printf ("entering clientShow\n");
682    printf ("showing client (%#lx)\n", c->window);          printf ("showing client (%#lx)\n", c->window);
683  #endif  #endif
684    
685    if (c->win_workspace == workspace || c->win_state & WIN_STATE_STICKY)          if (c->win_workspace == workspace || c->win_state & WIN_STATE_STICKY)
686      {                  {
687        XMapWindow (dpy, c->window);                          XMapWindow (dpy, c->window);
688        XMapWindow (dpy, c->frame);                          XMapWindow (dpy, c->frame);
689      }                  }
690    if (change_state)          if (change_state)
691      setWMState (c->window, NormalState);                  setWMState (c->window, NormalState);
692  }  }
693    
694  void  void
695  clientHide (Client * c, int change_state)  clientHide (Client * c, int change_state)
696  {  {
697  #ifdef DEBUG  #ifdef DEBUG
698    printf ("entering clientHide\n");          printf ("entering clientHide\n");
699    printf ("hiding client (%#lx)\n", c->window);          printf ("hiding client (%#lx)\n", c->window);
700  #endif  #endif
701    
702    XUnmapWindow (dpy, c->window);          XUnmapWindow (dpy, c->window);
703    XUnmapWindow (dpy, c->frame);          XUnmapWindow (dpy, c->frame);
704    if (change_state)          if (change_state)
705      setWMState (c->window, IconicState);                  setWMState (c->window, IconicState);
706    c->ignore_unmap++;          c->ignore_unmap++;
707  }  }
708    
709  void  void
710  clientClose (Client * c)  clientClose (Client * c)
711  {  {
712  #ifdef DEBUG  #ifdef DEBUG
713    printf ("entering clientClose\n");          printf ("entering clientClose\n");
714  #endif  #endif
715    
716    sendClientMessage (dpy, c->window, wm_protocols, wm_delete_window,          sendClientMessage (dpy, c->window, wm_protocols, wm_delete_window,
717                       NoEventMask);                                                                                   NoEventMask);
718  }  }
719    
720  void  void
721  clientKill (Client * c)  clientKill (Client * c)
722  {  {
723  #ifdef DEBUG  #ifdef DEBUG
724    printf ("entering clientKill\n");          printf ("entering clientKill\n");
725  #endif  #endif
726    
727    XKillClient (dpy, c->window);          XKillClient (dpy, c->window);
728  }  }
729    
730  void  void
731  clientRaise (Client * c)  clientRaise (Client * c)
732  {  {
733    XWindowChanges wc;          XWindowChanges wc;
734    Client *c2;          Client *c2;
735    int i;          int i;
736    
737  #ifdef DEBUG  #ifdef DEBUG
738    printf ("entering clientRaise\n");          printf ("entering clientRaise\n");
739  #endif  #endif
740    
741    if (c->win_hints & WIN_HINTS_SKIP_FOCUS)          if (c->win_hints & WIN_HINTS_SKIP_FOCUS)
742      {                  {
743  #ifdef DEBUG  #ifdef DEBUG
744        printf ("NOT raising client (%#lx)\n", c->window);                          printf ("NOT raising client (%#lx)\n", c->window);
745  #endif  #endif
746        return;                          return;
747      }                  }
748    
749  #ifdef DEBUG  #ifdef DEBUG
750    printf ("raising client (%#lx)\n", c->window);          printf ("raising client (%#lx)\n", c->window);
751  #endif  #endif
752    
753    wc.stack_mode = Above;          wc.stack_mode = Above;
754    clientConfigure (c, &wc, CWStackMode);          clientConfigure (c, &wc, CWStackMode);
755    
756    for (c2 = clients, i = 0; i < client_count; c2 = c2->next, i++)          for (c2 = clients, i = 0; i < client_count; c2 = c2->next, i++)
757      if (c2->transientFor == c)                  if (c2->transientFor == c)
758        clientRaise (c2);                          clientRaise (c2);
759  }  }
760    
761  void  void
762  clientLower (Client * c)  clientLower (Client * c)
763  {  {
764    XWindowChanges wc;          XWindowChanges wc;
765    
766  #ifdef DEBUG  #ifdef DEBUG
767    printf ("entering clientLower\n");          printf ("entering clientLower\n");
768    printf ("lowering client (%#lx)\n", c->window);          printf ("lowering client (%#lx)\n", c->window);
769  #endif  #endif
770    
771    wc.stack_mode = Below;          wc.stack_mode = Below;
772    clientConfigure (c, &wc, CWStackMode);          clientConfigure (c, &wc, CWStackMode);
773  }  }
774    
775  void  void
776  clientSetLayer (Client * c, int l)  clientSetLayer (Client * c, int l)
777  {  {
778    int old_layer = c->win_layer;          int old_layer = c->win_layer;
779    
780  #ifdef DEBUG  #ifdef DEBUG
781    printf ("entering clientSetLayer\n");          printf ("entering clientSetLayer\n");
782    printf ("setting client (%#lx) layer to %d\n", c->window, l);          printf ("setting client (%#lx) layer to %d\n", c->window, l);
783  #endif  #endif
784    
785    if (l == old_layer)          if (l == old_layer)
786      return;                  return;
787    
788    setGnomeHint (c->window, win_layer, l);          setGnomeHint (c->window, win_layer, l);
789    c->win_layer = l;          c->win_layer = l;
790    if (l > old_layer)          if (l > old_layer)
791      clientRaise (c);                  clientRaise (c);
792    else          else
793      clientLower (c);                  clientLower (c);
794  }  }
795    
796  void  void
797  clientSetWorkspace (Client * c, int ws)  clientSetWorkspace (Client * c, int ws)
798  {  {
799  #ifdef DEBUG  #ifdef DEBUG
800    printf ("entering clientSetWorkspace\n");          printf ("entering clientSetWorkspace\n");
801    printf ("setting client (%#lx) to workspace %d\n", ws);          printf ("setting client (%#lx) to workspace %d\n", ws);
802  #endif  #endif
803    
804    if (c->win_workspace == ws)          if (c->win_workspace == ws)
805      return;                  return;
806    
807    setGnomeHint (c->window, win_workspace, ws);          setGnomeHint (c->window, win_workspace, ws);
808    setGnomeHint (c->window, net_atoms[NET_WM_DESKTOP], ws);          setGnomeHint (c->window, net_atoms[NET_WM_DESKTOP], ws);
809    c->win_workspace = ws;          c->win_workspace = ws;
810    if (getWMState (c->window) != IconicState)          if (getWMState (c->window) != IconicState)
811      {                  {
812        if (c->win_state & WIN_STATE_STICKY)                          if (c->win_state & WIN_STATE_STICKY)
813          clientShow (c, False);                                  clientShow (c, False);
814        else                          else
815          {                                  {
816            if (ws == workspace)                                          if (ws == workspace)
817              clientShow (c, False);                                                  clientShow (c, False);
818            else                                          else
819              clientHide (c, False);                                                  clientHide (c, False);
820          }                                  }
821      }                  }
822  }  }
823    
824  void  void
825  clientSetState (Client * c, CARD32 mask, CARD32 value)  clientSetState (Client * c, CARD32 mask, CARD32 value)
826  {  {
827    XWindowChanges wc;          XWindowChanges wc;
828    
829  #ifdef DEBUG  #ifdef DEBUG
830    printf ("entering clientSetState\n");          printf ("entering clientSetState\n");
831    printf ("changing state for client (%#lx)\n", c->window);          printf ("changing state for client (%#lx)\n", c->window);
832  #endif  #endif
833    
834    c->win_state = (c->win_state & ~mask) | value;          c->win_state = (c->win_state & ~mask) | value;
835    setGnomeHint (c->window, win_state, c->win_state);          setGnomeHint (c->window, win_state, c->win_state);
836    if (mask & ~WIN_STATE_STICKY)          if (mask & ~WIN_STATE_STICKY)
837      {                  {
838        wc.width = c->width;                          wc.width = c->width;
839        wc.height = c->height;                          wc.height = c->height;
840        clientConfigure (c, &wc, CWWidth | CWHeight);                          clientConfigure (c, &wc, CWWidth | CWHeight);
841      }                  }
842  }  }
843    
844  void  void
845  clientToggleShaded (Client * c)  clientToggleShaded (Client * c)
846  {  {
847    XWindowChanges wc;          XWindowChanges wc;
848    
849  #ifdef DEBUG  #ifdef DEBUG
850    printf ("entering clientToggleShaded\n");          printf ("entering clientToggleShaded\n");
851    printf ("shading/unshading client (%#lx)\n", c->window);          printf ("shading/unshading client (%#lx)\n", c->window);
852  #endif  #endif
853    
854    c->win_state = c->win_state ^ WIN_STATE_SHADED;          c->win_state = c->win_state ^ WIN_STATE_SHADED;
855    setGnomeHint (c->window, win_state, c->win_state);          setGnomeHint (c->window, win_state, c->win_state);
856    wc.width = c->width;          wc.width = c->width;
857    wc.height = c->height;          wc.height = c->height;
858    clientConfigure (c, &wc, CWWidth | CWHeight);          clientConfigure (c, &wc, CWWidth | CWHeight);
859  }  }
860    
861  void  void
862  clientToggleSticky (Client * c)  clientToggleSticky (Client * c)
863  {  {
864  #ifdef DEBUG  #ifdef DEBUG
865    printf ("entering clientToggleSticky\n");          printf ("entering clientToggleSticky\n");
866    printf ("sticking/unsticking client (%#lx)\n", c->window);          printf ("sticking/unsticking client (%#lx)\n", c->window);
867  #endif  #endif
868    
869    c->win_state = c->win_state ^ WIN_STATE_STICKY;          c->win_state = c->win_state ^ WIN_STATE_STICKY;
870    setGnomeHint (c->window, win_state, c->win_state);          setGnomeHint (c->window, win_state, c->win_state);
871    clientSetWorkspace (c, workspace);          clientSetWorkspace (c, workspace);
872  }  }
873    
874  void  void
875  clientToggleMaximized (Client * c, int mode)  clientToggleMaximized (Client * c, int mode)
876  {  {
877    XWindowChanges wc;          XWindowChanges wc;
878    
879  #ifdef DEBUG  #ifdef DEBUG
880    printf ("entering clientToggleMaximized\n");          printf ("entering clientToggleMaximized\n");
881    printf ("maximzing/unmaximizing client (%#lx)\n", c->window);          printf ("maximzing/unmaximizing client (%#lx)\n", c->window);
882  #endif  #endif
883    
884    if (c->size->flags & (PMinSize | PMaxSize) &&          if (c->size->flags & (PMinSize | PMaxSize) &&
885        c->size->min_width == c->size->max_width &&                          c->size->min_width == c->size->max_width &&
886        c->size->min_height == c->size->max_height)                          c->size->min_height == c->size->max_height)
887      return;                  return;
888    
889    if (c->win_state & WIN_STATE_MAXIMIZED)          if (c->win_state & WIN_STATE_MAXIMIZED)
890      {                  {
891        wc.width = c->old_width;                          wc.width = c->old_width;
892        wc.height = c->old_height;                          wc.height = c->old_height;
893        wc.x = c->old_x;                          wc.x = c->old_x;
894        wc.y = c->old_y;                          wc.y = c->old_y;
895        c->win_state &= ~WIN_STATE_MAXIMIZED;                          c->win_state &= ~WIN_STATE_MAXIMIZED;
896      }                  }
897    else          else
898      {                  {
899        c->old_x = c->x;                          c->old_x = c->x;
900        c->old_y = c->y;                          c->old_y = c->y;
901        c->old_width = c->width;                          c->old_width = c->width;
902        c->old_height = c->height;                          c->old_height = c->height;
903    
904        if (mode != WIN_STATE_MAXIMIZED_VERT)                          if (mode != WIN_STATE_MAXIMIZED_VERT)
905          {                                  {
906            wc.x = frameLeft (c) + margins[MARGIN_LEFT];                                          wc.x = frameLeft (c) + margins[MARGIN_LEFT];
907            wc.width =                                          wc.width =
908              XDisplayWidth (dpy,                                                  XDisplayWidth (dpy,
909                             screen) - frameLeft (c) - frameRight (c) -                                                                                                           screen) - frameLeft (c) - frameRight (c) -
910              margins[MARGIN_LEFT] - margins[MARGIN_RIGHT];                                                  margins[MARGIN_LEFT] - margins[MARGIN_RIGHT];
911            c->win_state |= WIN_STATE_MAXIMIZED_HORIZ;                                          c->win_state |= WIN_STATE_MAXIMIZED_HORIZ;
912          }                                  }
913        else                          else
914          {                                  {
915            wc.x = c->x;                                          wc.x = c->x;
916            wc.width = c->width;                                          wc.width = c->width;
917          }                                  }
918        if (mode != WIN_STATE_MAXIMIZED_HORIZ)                          if (mode != WIN_STATE_MAXIMIZED_HORIZ)
919          {                                  {
920            wc.y = frameTop (c) + margins[MARGIN_TOP];                                          wc.y = frameTop (c) + margins[MARGIN_TOP];
921            wc.height =                                          wc.height =
922              XDisplayHeight (dpy,                                                  XDisplayHeight (dpy,
923                              screen) - frameTop (c) - frameBottom (c) -                                                                                                                  screen) - frameTop (c) - frameBottom (c) -
924              margins[MARGIN_TOP] - margins[MARGIN_BOTTOM];                                                  margins[MARGIN_TOP] - margins[MARGIN_BOTTOM];
925            c->win_state |= WIN_STATE_MAXIMIZED_VERT;                                          c->win_state |= WIN_STATE_MAXIMIZED_VERT;
926          }                                  }
927        else                          else
928          {                                  {
929            wc.y = c->y;                                          wc.y = c->y;
930            wc.height = c->height;                                          wc.height = c->height;
931          }                                  }
932    
933      }                  }
934    setGnomeHint (c->window, win_state, c->win_state);          setGnomeHint (c->window, win_state, c->win_state);
935    clientConfigure (c, &wc, CWX | CWY | CWWidth | CWHeight);          clientConfigure (c, &wc, CWX | CWY | CWWidth | CWHeight);
936  }  }
937    
938  void  void
939  clientSetFocus (Client * c, int sort)  clientSetFocus (Client * c, int sort)
940  {  {
941    Client *tmp;          Client *tmp;
942    
943  #ifdef DEBUG  #ifdef DEBUG
944    printf ("entering clientSetFocus\n");          printf ("entering clientSetFocus\n");
945    if (c)          if (c)
946      printf ("setting focus to client (%#lx)\n", c->window);                  printf ("setting focus to client (%#lx)\n", c->window);
947    else          else
948      printf ("setting focus to none\n");                  printf ("setting focus to none\n");
949  #endif  #endif
950    
951    if (c)          if (c)
952      {                  {
953        if (c->win_hints & WIN_HINTS_SKIP_FOCUS)                          if (c->win_hints & WIN_HINTS_SKIP_FOCUS)
954          return;                                  return;
955    
956        if (sort)                          if (sort)
957          {                                  {
958            if (client_count > 2 && c != clients)                                          if (client_count > 2 && c != clients)
959              {                                                  {
960                tmp = c;                                                          tmp = c;
961                c->prev->next = c->next;                                                          c->prev->next = c->next;
962                c->next->prev = c->prev;                                                          c->next->prev = c->prev;
963    
964                c->prev = clients->prev;                                                          c->prev = clients->prev;
965                c->next = clients;                                                          c->next = clients;
966                clients->prev->next = c;                                                          clients->prev->next = c;
967                clients->prev = c;                                                          clients->prev = c;
968              }                                                  }
969            clients = c;                                          clients = c;
970          }                                  }
971    
972        XSetInputFocus (dpy, c->window, RevertToNone, CurrentTime);                          XSetInputFocus (dpy, c->window, RevertToNone, CurrentTime);
973        setFocusHint (c->window);                          setFocusHint (c->window);
974      }                  }
975    else          else
976      {                  {
977        XSetInputFocus (dpy, gnome_win, RevertToNone, CurrentTime);                          XSetInputFocus (dpy, gnome_win, RevertToNone, CurrentTime);
978        setFocusHint (None);                          setFocusHint (None);
979      }                  }
980  }  }
981    
982  Client *  Client *
983  clientGetFocus ()  clientGetFocus ()
984  {  {
985    Window w;          Window w;
986    int dummy;          int dummy;
987    
988  #ifdef DEBUG  #ifdef DEBUG
989    printf ("entering clientGetFocus\n");          printf ("entering clientGetFocus\n");
990  #endif  #endif
991    
992    XGetInputFocus (dpy, &w, &dummy);          XGetInputFocus (dpy, &w, &dummy);
993    return clientGetFromWindow (w, WINDOW);          return clientGetFromWindow (w, WINDOW);
994  }  }
995    
996  void  void
997  clientDrawOutline (Client * c)  clientDrawOutline (Client * c)
998  {  {
999  #ifdef DEBUG  #ifdef DEBUG
1000    printf ("entering clientDrawOutline\n");          printf ("entering clientDrawOutline\n");
1001  #endif  #endif
1002    
1003    XDrawRectangle (dpy, root, box_gc, frameX (c), frameY (c),          XDrawRectangle (dpy, root, box_gc, frameX (c), frameY (c),
1004                    frameWidth (c) - 1, frameHeight (c) - 1);                                                                          frameWidth (c) - 1, frameHeight (c) - 1);
1005  }  }
1006    
1007  void  void
1008  clientMove (Client * c, XEvent * e)  clientMove (Client * c, XEvent * e)
1009  {  {
1010    int mx, my, moving = True, grab = False, use_keys = False, g1, g2;          int mx, my, moving = True, grab = False, use_keys = False, g1, g2;
1011    Client *closestx, *closesty, *c2;          Client *closestx, *closesty, *c2;
1012    XWindowChanges wc;          XWindowChanges wc;
1013    XEvent ev;          XEvent ev;
1014    int i;          int i;
1015    int ox, oy;          int ox, oy;
1016    int cx, cy, dx, dy;          int cx, cy, dx, dy;
1017    
1018    #ifdef DEBUG
1019            printf ("entering clientDoMove\n");
1020            printf ("moving client (%#lx)\n", c->window);
1021    #endif
1022    
1023            if ((c->win_state & WIN_STATE_MAXIMIZED) == WIN_STATE_MAXIMIZED
1024                            || typeDesktop (c->window))
1025                    return;
1026    
1027            g1 = XGrabKeyboard (dpy, c->window, False, GrabModeAsync, GrabModeAsync,
1028                                                                                            CurrentTime);
1029            g2 = XGrabPointer (dpy, c->frame, False,
1030                                                                                     PointerMotionMask | ButtonReleaseMask, GrabModeAsync,
1031                                                                                     GrabModeAsync, None, move_cursor, CurrentTime);
1032    
1033            if (g1 != GrabSuccess || g2 != GrabSuccess)
1034                    {
1035  #ifdef DEBUG  #ifdef DEBUG
1036    printf ("entering clientDoMove\n");                          printf ("grab failed in clientMove\n");
   printf ("moving client (%#lx)\n", c->window);  
1037  #endif  #endif
1038                            if (g1 == GrabSuccess)
1039                                    XUngrabKeyboard (dpy, CurrentTime);
1040                            if (g2 == GrabSuccess)
1041                                    XUngrabPointer (dpy, CurrentTime);
1042                            return;
1043                    }
1044    
1045            if (e->type == KeyPress)
1046                    {
1047                            use_keys = True;
1048                            XPutBackEvent (dpy, e);
1049                    }
1050    
1051            getMouseXY (dpy, root, &mx, &my);
1052            ox = c->x;
1053            oy = c->y;
1054    
1055    if ((c->win_state & WIN_STATE_MAXIMIZED) == WIN_STATE_MAXIMIZED  #ifdef DEBUG
1056        || typeDesktop (c->window))          printf ("entering move loop\n");
1057      return;  #endif
1058    
1059    g1 = XGrabKeyboard (dpy, c->window, False, GrabModeAsync, GrabModeAsync,          while (moving)
1060                        CurrentTime);                  {
1061    g2 = XGrabPointer (dpy, c->frame, False,                          XNextEvent (dpy, &ev);
                      PointerMotionMask | ButtonReleaseMask, GrabModeAsync,  
                      GrabModeAsync, None, move_cursor, CurrentTime);  
1062    
1063    if (g1 != GrabSuccess || g2 != GrabSuccess)                          if (ev.type == KeyPress)
1064      {                                  {
1065                                            if (!grab && box_move)
1066                                                    {
1067                                                            XGrabServer (dpy);
1068                                                            grab = True;
1069                                                            clientDrawOutline (c);
1070                                                    }
1071                                            if (box_move)
1072                                                    clientDrawOutline (c);
1073                                            if (!(c->win_state & WIN_STATE_MAXIMIZED_HORIZ))
1074                                                    {
1075                                                            if (ev.xkey.keycode == keys[KEY_MOVE_LEFT].keycode)
1076                                                                    c->x = c->x - 16;
1077                                                            if (ev.xkey.keycode == keys[KEY_MOVE_RIGHT].keycode)
1078                                                                    c->x = c->x + 16;
1079                                                    }
1080                                            if (!(c->win_state & WIN_STATE_MAXIMIZED_VERT))
1081                                                    {
1082                                                            if (ev.xkey.keycode == keys[KEY_MOVE_UP].keycode)
1083                                                                    c->y = c->y - 16;
1084                                                            if (ev.xkey.keycode == keys[KEY_MOVE_DOWN].keycode)
1085                                                                    c->y = c->y + 16;
1086                                                    }
1087                                            if (box_move)
1088                                                    clientDrawOutline (c);
1089                                            else
1090                                                    {
1091                                                            wc.x = c->x;
1092                                                            wc.y = c->y;
1093                                                            clientConfigure (c, &wc, CWX | CWY);
1094                                                    }
1095                                    }
1096                            else if (use_keys && ev.type == KeyRelease)
1097                                    {
1098                                            if (IsModifierKey (XKeycodeToKeysym (dpy, ev.xkey.keycode, 0)))
1099                                                    moving = False;
1100                                    }
1101                            else if (ev.type == MotionNotify)
1102                                    {
1103                                            while (XCheckTypedEvent (dpy, MotionNotify, &ev));
1104    
1105                                            if (!grab && box_move)
1106                                                    {
1107                                                            XGrabServer (dpy);
1108                                                            grab = True;
1109                                                            clientDrawOutline (c);
1110                                                    }
1111                                            if (box_move)
1112                                                    clientDrawOutline (c);
1113    
1114                                            if (workspace_count > 1)
1115                                                    {
1116                                                            int msx, msy;
1117    
1118                                                            getMouseXY (dpy, root, &msx, &msy);
1119                                                            if (msx == 0 && !(workspace == 0 && !wrap_workspaces))
1120                                                                    {
1121                                                                            workspaceSwitch (workspace - 1, c);
1122                                                                            if (!click_to_focus)
1123                                                                                    XWarpPointer (dpy, None, root, 0, 0, 0, 0,
1124                                                                                                                                            XDisplayWidth (dpy, screen) - 11, msy);
1125                                                                            ev.xmotion.x_root = XDisplayWidth (dpy, screen) - 11;
1126                                                                    }
1127                                                            else if (msx == XDisplayWidth (dpy, screen) - 1 &&
1128                                                                                             !(workspace == workspace_count - 1
1129                                                                                                     && !wrap_workspaces))
1130                                                                    {
1131                                                                            workspaceSwitch (workspace + 1, c);
1132                                                                            if (!click_to_focus)
1133                                                                                    XWarpPointer (dpy, None, root, 0, 0, 0, 0, 10, msy);
1134                                                                            ev.xmotion.x_root = 10;
1135                                                                    }
1136                                                    }
1137    
1138                                            if (!(c->win_state & WIN_STATE_MAXIMIZED_HORIZ))
1139                                                    {
1140                                                            c->x = ox + (ev.xmotion.x_root - mx);
1141                                                            if (snap_to_border)
1142                                                                    {
1143                                                                            if (abs (frameX (c) - margins[MARGIN_LEFT]) < snap_width)
1144                                                                                    c->x = frameLeft (c) + margins[MARGIN_LEFT];
1145                                                                            if (abs (frameX (c) - XDisplayWidth (dpy, screen) +
1146                                                                                                             frameWidth (c) + margins[MARGIN_RIGHT]) <
1147                                                                                            snap_width)
1148                                                                                    c->x =
1149                                                                                            (XDisplayWidth (dpy, screen) - frameRight (c) -
1150                                                                                             c->width - margins[MARGIN_RIGHT]);
1151                                                                    }
1152                                                    }
1153    
1154                                            if (!(c->win_state & WIN_STATE_MAXIMIZED_VERT))
1155                                                    {
1156                                                            c->y = oy + (ev.xmotion.y_root - my);
1157                                                            if (snap_to_border)
1158                                                                    {
1159                                                                            if (abs (frameY (c) - margins[MARGIN_TOP]) < snap_width)
1160                                                                                    c->y = frameTop (c) + margins[MARGIN_TOP];
1161                                                                            if (abs (frameY (c) - XDisplayHeight (dpy, screen) +
1162                                                                                                             frameHeight (c) + margins[MARGIN_BOTTOM]) <
1163                                                                                            snap_width)
1164                                                                                    c->y =
1165                                                                                            (XDisplayHeight (dpy, screen) -
1166                                                                                             margins[MARGIN_BOTTOM] - frameHeight (c) +
1167                                                                                             frameTop (c));
1168                                                                    }
1169    
1170                                                            if (snap_to_windows)
1171                                                                    {
1172                                                                            cx = cy = snap_width + 1;
1173                                                                            closestx = closesty = NULL;
1174    
1175                                                                            for (c2 = clients, i = 0; i < client_count;
1176                                                                                             c2 = c2->next, i++)
1177                                                                                    {
1178                                                                                            if (c2->win_workspace != c->win_workspace)
1179                                                                                                    continue;
1180    
1181                                                                                            if (c2->win_hints & WIN_HINTS_SKIP_FOCUS)
1182                                                                                                    continue;
1183    
1184                                                                                            /* Are we touching the bottom of a window? */
1185                                                                                            dy =
1186                                                                                                    abs (frameY (c) - (frameY (c2) + frameHeight (c2)));
1187                                                                                            if (dy < snap_width && dy < cy)
1188                                                                                                    {
1189                                                                                                            cy = dy;
1190                                                                                                            closesty = c2;
1191                                                                                                    }
1192    
1193                                                                                            /* Top? */
1194                                                                                            dy = abs (frameY (c2) - (frameY (c) + frameHeight (c)));
1195                                                                                            if (dy < snap_width && dy < cy)
1196                                                                                                    {
1197                                                                                                            cy = dy;
1198                                                                                                            closesty = c2;
1199                                                                                                    }
1200    
1201                                                                                            /* Left? */
1202                                                                                            dx = abs (frameX (c2) - (frameX (c) + frameWidth (c)));
1203                                                                                            if (dx < snap_width && dx < cx)
1204                                                                                                    {
1205                                                                                                            cx = dx;
1206                                                                                                            closestx = c2;
1207                                                                                                    }
1208    
1209                                                                                            /* Right */
1210                                                                                            dx = abs (frameX (c) - (frameX (c2) + frameWidth (c2)));
1211                                                                                            if (dx < snap_width && dx < cx)
1212                                                                                                    {
1213                                                                                                            cx = dx;
1214                                                                                                            closestx = c2;
1215                                                                                                    }
1216                                                                                    }
1217    
1218                                                                            if (closesty)
1219                                                                                    {
1220                                                                                            if (cy ==
1221                                                                                                            abs (frameY (c) -
1222                                                                                                                             (frameY (closesty) + frameHeight (closesty))))
1223                                                                                                    {
1224                                                                                                            c->y =
1225                                                                                                                    frameY (closesty) + frameHeight (closesty) +
1226                                                                                                                    frameTop (c);
1227                                                                                                    }
1228                                                                                            else
1229                                                                                                    {
1230                                                                                                            c->y =
1231                                                                                                                    frameY (closesty) - (frameHeight (c) -
1232                                                                                                                                                                                                     frameTop (c));
1233                                                                                                    }
1234                                                                                    }
1235    
1236                                                                            if (closestx)
1237                                                                                    {
1238                                                                                            if (cx ==
1239                                                                                                            abs (frameX (c) -
1240                                                                                                                             (frameX (closestx) + frameWidth (closestx))))
1241                                                                                                    {
1242                                                                                                            c->x =
1243                                                                                                                    frameX (closestx) + frameWidth (closestx) +
1244                                                                                                                    frameLeft (c);
1245                                                                                                    }
1246                                                                                            else
1247                                                                                                    {
1248                                                                                                            c->x =
1249                                                                                                                    (frameX (closestx) - frameWidth (c)) +
1250                                                                                                                    frameRight (c);
1251                                                                                                    }
1252                                                                                    }
1253                                                                    }
1254                                                    }
1255    
1256                                            if (box_move)
1257                                                    clientDrawOutline (c);
1258                                            else
1259                                                    {
1260                                                            wc.x = c->x;
1261                                                            wc.y = c->y;
1262                                                            clientConfigure (c, &wc, CWX | CWY);
1263                                                    }
1264                                    }
1265                            else if (!use_keys && ev.type == ButtonRelease)
1266                                    moving = False;
1267                            else if (ev.type == UnmapNotify && ev.xunmap.window == c->window)
1268                                    moving = False;
1269                            else
1270                                    handleEvent (&ev);
1271                    }
1272  #ifdef DEBUG  #ifdef DEBUG
1273        printf ("grab failed in clientMove\n");          printf ("leaving move loop\n");
1274  #endif  #endif
1275        if (g1 == GrabSuccess)  
1276          XUngrabKeyboard (dpy, CurrentTime);          XUngrabKeyboard (dpy, CurrentTime);
       if (g2 == GrabSuccess)  
1277          XUngrabPointer (dpy, CurrentTime);          XUngrabPointer (dpy, CurrentTime);
       return;  
     }  
1278    
1279    if (e->type == KeyPress)          if (grab && box_move)
1280      {                  clientDrawOutline (c);
1281        use_keys = True;  
1282        XPutBackEvent (dpy, e);          wc.x = c->x;
1283      }          wc.y = c->y;
1284            clientConfigure (c, &wc, CWX | CWY);
   getMouseXY (dpy, root, &mx, &my);  
   ox = c->x;  
   oy = c->y;  
   
 #ifdef DEBUG  
   printf ("entering move loop\n");  
 #endif  
   
   while (moving)  
     {  
       XNextEvent (dpy, &ev);  
   
       if (ev.type == KeyPress)  
         {  
           if (!grab && box_move)  
             {  
               XGrabServer (dpy);  
               grab = True;  
               clientDrawOutline (c);  
             }  
           if (box_move)  
             clientDrawOutline (c);  
           if (!(c->win_state & WIN_STATE_MAXIMIZED_HORIZ))  
             {  
               if (ev.xkey.keycode == keys[KEY_MOVE_LEFT].keycode)  
                 c->x = c->x - 16;  
               if (ev.xkey.keycode == keys[KEY_MOVE_RIGHT].keycode)  
                 c->x = c->x + 16;  
             }  
           if (!(c->win_state & WIN_STATE_MAXIMIZED_VERT))  
             {  
               if (ev.xkey.keycode == keys[KEY_MOVE_UP].keycode)  
                 c->y = c->y - 16;  
               if (ev.xkey.keycode == keys[KEY_MOVE_DOWN].keycode)  
                 c->y = c->y + 16;  
             }  
           if (box_move)  
             clientDrawOutline (c);  
           else  
             {  
               wc.x = c->x;  
               wc.y = c->y;  
               clientConfigure (c, &wc, CWX | CWY);  
             }  
         }  
       else if (use_keys && ev.type == KeyRelease)  
         {  
           if (IsModifierKey (XKeycodeToKeysym (dpy, ev.xkey.keycode, 0)))  
             moving = False;  
         }  
       else if (ev.type == MotionNotify)  
         {  
           while (XCheckTypedEvent (dpy, MotionNotify, &ev));  
   
           if (!grab && box_move)  
             {  
               XGrabServer (dpy);  
               grab = True;  
               clientDrawOutline (c);  
             }  
           if (box_move)  
             clientDrawOutline (c);  
   
           if (workspace_count > 1)  
             {  
               int msx, msy;  
   
               getMouseXY (dpy, root, &msx, &msy);  
               if (msx == 0 && !(workspace == 0 && !wrap_workspaces))  
                 {  
                   workspaceSwitch (workspace - 1, c);  
                   if (!click_to_focus)  
                     XWarpPointer (dpy, None, root, 0, 0, 0, 0,  
                                   XDisplayWidth (dpy, screen) - 11, msy);  
                   ev.xmotion.x_root = XDisplayWidth (dpy, screen) - 11;  
                 }  
               else if (msx == XDisplayWidth (dpy, screen) - 1 &&  
                        !(workspace == workspace_count - 1  
                          && !wrap_workspaces))  
                 {  
                   workspaceSwitch (workspace + 1, c);  
                   if (!click_to_focus)  
                     XWarpPointer (dpy, None, root, 0, 0, 0, 0, 10, msy);  
                   ev.xmotion.x_root = 10;  
                 }  
             }  
   
           if (!(c->win_state & WIN_STATE_MAXIMIZED_HORIZ))  
             {  
               c->x = ox + (ev.xmotion.x_root - mx);  
               if (snap_to_border)  
                 {  
                   if (abs (frameX (c) - margins[MARGIN_LEFT]) < snap_width)  
                     c->x = frameLeft (c) + margins[MARGIN_LEFT];  
                   if (abs (frameX (c) - XDisplayWidth (dpy, screen) +  
                            frameWidth (c) + margins[MARGIN_RIGHT]) <  
                       snap_width)  
                     c->x =  
                       (XDisplayWidth (dpy, screen) - frameRight (c) -  
                        c->width - margins[MARGIN_RIGHT]);  
                 }  
             }  
   
           if (!(c->win_state & WIN_STATE_MAXIMIZED_VERT))  
             {  
               c->y = oy + (ev.xmotion.y_root - my);  
               if (snap_to_border)  
                 {  
                   if (abs (frameY (c) - margins[MARGIN_TOP]) < snap_width)  
                     c->y = frameTop (c) + margins[MARGIN_TOP];  
                   if (abs (frameY (c) - XDisplayHeight (dpy, screen) +  
                            frameHeight (c) + margins[MARGIN_BOTTOM]) <  
                       snap_width)  
                     c->y =  
                       (XDisplayHeight (dpy, screen) -  
                        margins[MARGIN_BOTTOM] - frameHeight (c) +  
                        frameTop (c));  
                 }  
   
               if (snap_to_windows)  
                 {  
                   cx = cy = snap_width + 1;  
                   closestx = closesty = NULL;  
   
                   for (c2 = clients, i = 0; i < client_count;  
                        c2 = c2->next, i++)  
                     {  
                       if (c2->win_workspace != c->win_workspace)  
                         continue;  
   
                       if (c2->win_hints & WIN_HINTS_SKIP_FOCUS)  
                         continue;  
   
                       /* Are we touching the bottom of a window? */  
                       dy =  
                         abs (frameY (c) - (frameY (c2) + frameHeight (c2)));  
                       if (dy < snap_width && dy < cy)  
                         {  
                           cy = dy;  
                           closesty = c2;  
                         }  
   
                       /* Top? */  
                       dy = abs (frameY (c2) - (frameY (c) + frameHeight (c)));  
                       if (dy < snap_width && dy < cy)  
                         {  
                           cy = dy;  
                           closesty = c2;  
                         }  
   
                       /* Left? */  
                       dx = abs (frameX (c2) - (frameX (c) + frameWidth (c)));  
                       if (dx < snap_width && dx < cx)  
                         {  
                           cx = dx;  
                           closestx = c2;  
                         }  
   
                       /* Right */  
                       dx = abs (frameX (c) - (frameX (c2) + frameWidth (c2)));  
                       if (dx < snap_width && dx < cx)  
                         {  
                           cx = dx;  
                           closestx = c2;  
                         }  
                     }  
   
                   if (closesty)  
                     {  
                       if (cy ==  
                           abs (frameY (c) -  
                                (frameY (closesty) + frameHeight (closesty))))  
                         {  
                           c->y =  
                             frameY (closesty) + frameHeight (closesty) +  
                             frameTop (c);  
                         }  
                       else  
                         {  
                           c->y =  
                             frameY (closesty) - (frameHeight (c) -  
                                                  frameTop (c));  
                         }  
                     }  
   
                   if (closestx)  
                     {  
                       if (cx ==  
                           abs (frameX (c) -  
                                (frameX (closestx) + frameWidth (closestx))))  
                         {  
                           c->x =  
                             frameX (closestx) + frameWidth (closestx) +  
                             frameLeft (c);  
                         }  
                       else  
                         {  
                           c->x =  
                             (frameX (closestx) - frameWidth (c)) +  
                             frameRight (c);  
                         }  
                     }  
                 }  
             }  
   
           if (box_move)  
             clientDrawOutline (c);  
           else  
             {  
               wc.x = c->x;  
               wc.y = c->y;  
               clientConfigure (c, &wc, CWX | CWY);  
             }  
         }  
       else if (!use_keys && ev.type == ButtonRelease)  
         moving = False;  
       else if (ev.type == UnmapNotify && ev.xunmap.window == c->window)  
         moving = False;  
       else  
         handleEvent (&ev);  
     }  
 #ifdef DEBUG  
   printf ("leaving move loop\n");  
 #endif  
   
   XUngrabKeyboard (dpy, CurrentTime);  
   XUngrabPointer (dpy, CurrentTime);  
   
   if (grab && box_move)  
     clientDrawOutline (c);  
   
   wc.x = c->x;  
   wc.y = c->y;  
   clientConfigure (c, &wc, CWX | CWY);  
1285    
1286    XUngrabServer (dpy);          XUngrabServer (dpy);
1287  }  }
1288    
1289  void  void
1290  clientResize (Client * c, XEvent * e)  clientResize (Client * c, XEvent * e)
1291  {  {
1292    int mx, my, oldw, oldh, resizing = True, grab = False, corner =          int mx, my, oldw, oldh, resizing = True, grab = False, corner =
1293      CORNER_BOTTOM_RIGHT, use_keys = False, g1, g2;                  CORNER_BOTTOM_RIGHT, use_keys = False, g1, g2;
1294    XEvent ev;          XEvent ev;
1295    XWindowChanges wc;          XWindowChanges wc;
   
 #ifdef DEBUG  
   printf ("entering clientResize\n");  
   printf ("resizing client (%#lx)\n", c->window);  
 #endif  
   
   if ((c->win_state & WIN_STATE_SHADED) ||  
       ((c->win_state & WIN_STATE_MAXIMIZED) == WIN_STATE_MAXIMIZED))  
     return;  
   
   getMouseXY (dpy, c->frame, &mx, &my);  
   if (e->type == KeyPress)  
     {  
       corner = CORNER_BOTTOM_RIGHT;  
       use_keys = True;  
     }  
   else  
     {  
       if (mx < frameWidth (c) / 2 && my < frameHeight (c) / 2)  
         corner = CORNER_TOP_LEFT;  
       else if (mx < frameWidth (c) / 2)  
         corner = CORNER_BOTTOM_LEFT;  
       else if (my < frameHeight (c) / 2)  
         corner = CORNER_TOP_RIGHT;  
     }  
   
   g1 = XGrabKeyboard (dpy, c->window, False, GrabModeAsync, GrabModeAsync,  
                       CurrentTime);  
   g2 = XGrabPointer (dpy, c->frame, False,  
                      PointerMotionMask | ButtonReleaseMask, GrabModeAsync,  
                      GrabModeAsync, None, resize_cursor[corner], CurrentTime);  
1296    
   if (g1 != GrabSuccess || g2 != GrabSuccess)  
     {  
1297  #ifdef DEBUG  #ifdef DEBUG
1298        printf ("grab failed in clientResize\n");          printf ("entering clientResize\n");
1299            printf ("resizing client (%#lx)\n", c->window);
1300  #endif  #endif
1301        if (g1 == GrabSuccess)  
1302            if ((c->win_state & WIN_STATE_SHADED) ||
1303                            ((c->win_state & WIN_STATE_MAXIMIZED) == WIN_STATE_MAXIMIZED))
1304                    return;
1305    
1306            getMouseXY (dpy, c->frame, &mx, &my);
1307            if (e->type == KeyPress)
1308                    {
1309                            corner = CORNER_BOTTOM_RIGHT;
1310                            use_keys = True;
1311                    }
1312            else
1313                    {
1314                            if (mx < frameWidth (c) / 2 && my < frameHeight (c) / 2)
1315                                    corner = CORNER_TOP_LEFT;
1316                            else if (mx < frameWidth (c) / 2)
1317                                    corner = CORNER_BOTTOM_LEFT;
1318                            else if (my < frameHeight (c) / 2)
1319                                    corner = CORNER_TOP_RIGHT;
1320                    }
1321    
1322            g1 = XGrabKeyboard (dpy, c->window, False, GrabModeAsync, GrabModeAsync,
1323                                                                                            CurrentTime);
1324            g2 = XGrabPointer (dpy, c->frame, False,
1325                                                                                     PointerMotionMask | ButtonReleaseMask, GrabModeAsync,
1326                                                                                     GrabModeAsync, None, resize_cursor[corner], CurrentTime);
1327    
1328            if (g1 != GrabSuccess || g2 != GrabSuccess)
1329                    {
1330    #ifdef DEBUG
1331                            printf ("grab failed in clientResize\n");
1332    #endif
1333                            if (g1 == GrabSuccess)
1334                                    XUngrabKeyboard (dpy, CurrentTime);
1335                            if (g2 == GrabSuccess)
1336                                    XUngrabPointer (dpy, CurrentTime);
1337                            return;
1338                    }
1339    
1340            if (use_keys)
1341                    XPutBackEvent (dpy, e);
1342    
1343            if (corner == CORNER_TOP_RIGHT || corner == CORNER_BOTTOM_RIGHT)
1344                    mx = frameWidth (c) - mx;
1345            if (corner == CORNER_BOTTOM_LEFT || corner == CORNER_BOTTOM_RIGHT)
1346                    my = frameHeight (c) - my;
1347    
1348    #ifdef DEBUG
1349            printf ("entering resize loop\n");
1350    #endif
1351    
1352            while (resizing)
1353                    {
1354                            XNextEvent (dpy, &ev);
1355    
1356                            if (ev.type == KeyPress)
1357                                    {
1358                                            if (!grab && box_resize)
1359                                                    {
1360                                                            XGrabServer (dpy);
1361                                                            grab = True;
1362                                                            clientDrawOutline (c);
1363                                                    }
1364                                            if (box_resize)
1365                                                    clientDrawOutline (c);
1366                                            if (!(c->win_state & WIN_STATE_MAXIMIZED_VERT))
1367                                                    {
1368                                                            if (ev.xkey.keycode == keys[KEY_MOVE_UP].keycode)
1369                                                                    c->height =
1370                                                                            c->height - (clientGetHeightInc (c) <
1371                                                                                                                             10 ? 10 : clientGetHeightInc (c));
1372                                                            if (ev.xkey.keycode == keys[KEY_MOVE_DOWN].keycode)
1373                                                                    c->height =
1374                                                                            c->height + (clientGetHeightInc (c) <
1375                                                                                                                             10 ? 10 : clientGetHeightInc (c));
1376                                                    }
1377                                            if (!(c->win_state & WIN_STATE_MAXIMIZED_HORIZ))
1378                                                    {
1379                                                            if (ev.xkey.keycode == keys[KEY_MOVE_LEFT].keycode)
1380                                                                    c->width =
1381                                                                            c->width - (clientGetWidthInc (c) <
1382                                                                                                                            10 ? 10 : clientGetWidthInc (c));
1383                                                            if (ev.xkey.keycode == keys[KEY_MOVE_RIGHT].keycode)
1384                                                                    c->width =
1385                                                                            c->width + (clientGetWidthInc (c) <
1386                                                                                                                            10 ? 10 : clientGetWidthInc (c));
1387                                                    }
1388                                            if (box_resize)
1389                                                    clientDrawOutline (c);
1390                                            else
1391                                                    {
1392                                                            wc.x = c->x;
1393                                                            wc.y = c->y;
1394                                                            wc.width = c->width;
1395                                                            wc.height = c->height;
1396                                                            clientConfigure (c, &wc, CWX | CWY | CWWidth | CWHeight);
1397                                                    }
1398                                    }
1399                            else if (use_keys && ev.type == KeyRelease)
1400                                    {
1401                                            if (IsModifierKey (XKeycodeToKeysym (dpy, ev.xkey.keycode, 0)))
1402                                                    resizing = False;
1403                                    }
1404                            else if (ev.type == MotionNotify)
1405                                    {
1406                                            while (XCheckTypedEvent (dpy, MotionNotify, &ev));
1407    
1408                                            if (!grab && box_resize)
1409                                                    {
1410                                                            XGrabServer (dpy);
1411                                                            grab = True;
1412                                                            clientDrawOutline (c);
1413                                                    }
1414                                            if (box_resize)
1415                                                    clientDrawOutline (c);
1416                                            oldw = c->width;
1417                                            oldh = c->height;
1418                                            if (!(c->win_state & WIN_STATE_MAXIMIZED_HORIZ))
1419                                                    {
1420                                                            if (corner == CORNER_TOP_LEFT || corner == CORNER_BOTTOM_LEFT)
1421                                                                    c->width =
1422                                                                            (c->x + c->width) - ev.xmotion.x_root + mx - frameLeft (c);
1423                                                            if (corner == CORNER_BOTTOM_RIGHT || corner == CORNER_TOP_RIGHT)
1424                                                                    c->width = (ev.xmotion.x_root - c->x) + mx - frameRight (c);
1425                                                    }
1426                                            if (!(c->win_state & WIN_STATE_MAXIMIZED_VERT))
1427                                                    {
1428                                                            if (corner == CORNER_TOP_LEFT || corner == CORNER_TOP_RIGHT)
1429                                                                    c->height =
1430                                                                            (c->y + c->height) - ev.xmotion.y_root + my - frameTop (c);
1431                                                            if (corner == CORNER_BOTTOM_RIGHT ||
1432                                                                            corner == CORNER_BOTTOM_LEFT)
1433                                                                    c->height = (ev.xmotion.y_root - c->y) + my - frameBottom (c);
1434                                                    }
1435                                            clientSetWidth (c, c->width);
1436                                            clientSetHeight (c, c->height);
1437                                            if (!(c->win_state & WIN_STATE_MAXIMIZED_HORIZ) &&
1438                                                            (corner == CORNER_TOP_LEFT || corner == CORNER_BOTTOM_LEFT))
1439                                                    c->x = c->x - (c->width - oldw);
1440                                            if (!(c->win_state & WIN_STATE_MAXIMIZED_VERT) &&
1441                                                            (corner == CORNER_TOP_LEFT || corner == CORNER_TOP_RIGHT))
1442                                                    c->y = c->y - (c->height - oldh);
1443                                            if (box_resize)
1444                                                    clientDrawOutline (c);
1445                                            else
1446                                                    {
1447                                                            wc.x = c->x;
1448                                                            wc.y = c->y;
1449                                                            wc.width = c->width;
1450                                                            wc.height = c->height;
1451                                                            clientConfigure (c, &wc, CWX | CWY | CWWidth | CWHeight);
1452                                                    }
1453                                    }
1454                            else if (ev.type == ButtonRelease)
1455                                    resizing = False;
1456                            else if (ev.type == UnmapNotify && ev.xunmap.window == c->window)
1457                                    resizing = False;
1458                            else
1459                                    handleEvent (&ev);
1460                    }
1461    #ifdef DEBUG
1462            printf ("leaving resize loop\n");
1463    #endif
1464    
1465          XUngrabKeyboard (dpy, CurrentTime);          XUngrabKeyboard (dpy, CurrentTime);
       if (g2 == GrabSuccess)  
1466          XUngrabPointer (dpy, CurrentTime);          XUngrabPointer (dpy, CurrentTime);
       return;  
     }  
1467    
1468    if (use_keys)          if (grab && box_resize)
1469      XPutBackEvent (dpy, e);                  clientDrawOutline (c);
1470    
1471    if (corner == CORNER_TOP_RIGHT || corner == CORNER_BOTTOM_RIGHT)          wc.x = c->x;
1472      mx = frameWidth (c) - mx;          wc.y = c->y;
1473    if (corner == CORNER_BOTTOM_LEFT || corner == CORNER_BOTTOM_RIGHT)          wc.width = c->width;
1474      my = frameHeight (c) - my;          wc.height = c->height;
1475            clientConfigure (c, &wc, (CWX | CWY | CWHeight | CWWidth));
 #ifdef DEBUG  
   printf ("entering resize loop\n");  
 #endif  
   
   while (resizing)  
     {  
       XNextEvent (dpy, &ev);  
   
       if (ev.type == KeyPress)  
         {  
           if (!grab && box_resize)  
             {  
               XGrabServer (dpy);  
               grab = True;  
               clientDrawOutline (c);  
             }  
           if (box_resize)  
             clientDrawOutline (c);  
           if (!(c->win_state & WIN_STATE_MAXIMIZED_VERT))  
             {  
               if (ev.xkey.keycode == keys[KEY_MOVE_UP].keycode)  
                 c->height =  
                   c->height - (clientGetHeightInc (c) <  
                                10 ? 10 : clientGetHeightInc (c));  
               if (ev.xkey.keycode == keys[KEY_MOVE_DOWN].keycode)  
                 c->height =  
                   c->height + (clientGetHeightInc (c) <  
                                10 ? 10 : clientGetHeightInc (c));  
             }  
           if (!(c->win_state & WIN_STATE_MAXIMIZED_HORIZ))  
             {  
               if (ev.xkey.keycode == keys[KEY_MOVE_LEFT].keycode)  
                 c->width =  
                   c->width - (clientGetWidthInc (c) <  
                               10 ? 10 : clientGetWidthInc (c));  
               if (ev.xkey.keycode == keys[KEY_MOVE_RIGHT].keycode)  
                 c->width =  
                   c->width + (clientGetWidthInc (c) <  
                               10 ? 10 : clientGetWidthInc (c));  
             }  
           if (box_resize)  
             clientDrawOutline (c);  
           else  
             {  
               wc.x = c->x;  
               wc.y = c->y;  
               wc.width = c->width;  
               wc.height = c->height;  
               clientConfigure (c, &wc, CWX | CWY | CWWidth | CWHeight);  
             }  
         }  
       else if (use_keys && ev.type == KeyRelease)  
         {  
           if (IsModifierKey (XKeycodeToKeysym (dpy, ev.xkey.keycode, 0)))  
             resizing = False;  
         }  
       else if (ev.type == MotionNotify)  
         {  
           while (XCheckTypedEvent (dpy, MotionNotify, &ev));  
   
           if (!grab && box_resize)  
             {  
               XGrabServer (dpy);  
               grab = True;  
               clientDrawOutline (c);  
             }  
           if (box_resize)  
             clientDrawOutline (c);  
           oldw = c->width;  
           oldh = c->height;  
           if (!(c->win_state & WIN_STATE_MAXIMIZED_HORIZ))  
             {  
               if (corner == CORNER_TOP_LEFT || corner == CORNER_BOTTOM_LEFT)  
                 c->width =  
                   (c->x + c->width) - ev.xmotion.x_root + mx - frameLeft (c);  
               if (corner == CORNER_BOTTOM_RIGHT || corner == CORNER_TOP_RIGHT)  
                 c->width = (ev.xmotion.x_root - c->x) + mx - frameRight (c);  
             }  
           if (!(c->win_state & WIN_STATE_MAXIMIZED_VERT))  
             {  
               if (corner == CORNER_TOP_LEFT || corner == CORNER_TOP_RIGHT)  
                 c->height =  
                   (c->y + c->height) - ev.xmotion.y_root + my - frameTop (c);  
               if (corner == CORNER_BOTTOM_RIGHT ||  
                   corner == CORNER_BOTTOM_LEFT)  
                 c->height = (ev.xmotion.y_root - c->y) + my - frameBottom (c);  
             }  
           clientSetWidth (c, c->width);  
           clientSetHeight (c, c->height);  
           if (!(c->win_state & WIN_STATE_MAXIMIZED_HORIZ) &&  
               (corner == CORNER_TOP_LEFT || corner == CORNER_BOTTOM_LEFT))  
             c->x = c->x - (c->width - oldw);  
           if (!(c->win_state & WIN_STATE_MAXIMIZED_VERT) &&  
               (corner == CORNER_TOP_LEFT || corner == CORNER_TOP_RIGHT))  
             c->y = c->y - (c->height - oldh);  
           if (box_resize)  
             clientDrawOutline (c);  
           else  
             {  
               wc.x = c->x;  
               wc.y = c->y;  
               wc.width = c->width;  
               wc.height = c->height;  
               clientConfigure (c, &wc, CWX | CWY | CWWidth | CWHeight);  
             }  
         }  
       else if (ev.type == ButtonRelease)  
         resizing = False;  
       else if (ev.type == UnmapNotify && ev.xunmap.window == c->window)  
         resizing = False;  
       else  
         handleEvent (&ev);  
     }  
 #ifdef DEBUG  
   printf ("leaving resize loop\n");  
 #endif  
   
   XUngrabKeyboard (dpy, CurrentTime);  
   XUngrabPointer (dpy, CurrentTime);  
   
   if (grab && box_resize)  
     clientDrawOutline (c);  
   
   wc.x = c->x;  
   wc.y = c->y;  
   wc.width = c->width;  
   wc.height = c->height;  
   clientConfigure (c, &wc, (CWX | CWY | CWHeight | CWWidth));  
1476    
1477    XUngrabServer (dpy);          XUngrabServer (dpy);
1478  }  }
1479    
1480  Client *  Client *
1481  clientGetNext (Client * c, int mask)  clientGetNext (Client * c, int mask)
1482  {  {
1483    Client *c2;          Client *c2;
1484    unsigned int i, okay;          unsigned int i, okay;
1485    
1486  #ifdef DEBUG  #ifdef DEBUG
1487    printf ("entering clientGetNext\n");          printf ("entering clientGetNext\n");
1488  #endif  #endif
1489    
1490    if (c)          if (c)
1491      {                  {
1492        for (c2 = c->next, i = 0; i < client_count; c2 = c2->next, i++)                          for (c2 = c->next, i = 0; i < client_count; c2 = c2->next, i++)
1493          {                                  {
1494            okay = True;                                          okay = True;
1495            if (c2->win_hints & WIN_HINTS_SKIP_FOCUS &&                                          if (c2->win_hints & WIN_HINTS_SKIP_FOCUS &&
1496                !(mask & INCLUDE_SKIP_FOCUS))                                                          !(mask & INCLUDE_SKIP_FOCUS))
1497              okay = False;                                                  okay = False;
1498            if (getWMState (c2->window) == IconicState &&                                          if (getWMState (c2->window) == IconicState &&
1499                !(mask & INCLUDE_HIDDEN))                                                          !(mask & INCLUDE_HIDDEN))
1500              okay = False;                                                  okay = False;
1501            if (c2->win_workspace != workspace &&                                          if (c2->win_workspace != workspace &&
1502                !(mask & INCLUDE_ALL_WORKSPACES))                                                          !(mask & INCLUDE_ALL_WORKSPACES))
1503              okay = False;                                                  okay = False;
1504            if (okay)                                          if (okay)
1505              return c2;                                                  return c2;
1506          }                                  }
1507      }                  }
1508    return NULL;          return NULL;
1509  }  }
1510    
1511  void  void
1512  clientCycle (Client * c)  clientCycle (Client * c)
1513  {  {
1514    Client *c2 = c;          Client *c2 = c;
1515    int cycling = True, g1, g2;          int cycling = True, g1, g2;
1516    XEvent ev;          XEvent ev;
1517    
1518  #ifdef DEBUG  #ifdef DEBUG
1519    printf ("entering clientCycle\n");          printf ("entering clientCycle\n");
1520  #endif  #endif
1521    
1522    if (!c)          if (!c)
1523      return;                  return;
1524    
1525    g1 = XGrabKeyboard (dpy, gnome_win, False, GrabModeAsync, GrabModeAsync,          g1 = XGrabKeyboard (dpy, gnome_win, False, GrabModeAsync, GrabModeAsync,
1526                        CurrentTime);                                                                                          CurrentTime);
1527    g2 = XGrabPointer (dpy, gnome_win, False, NoEventMask, GrabModeAsync,          g2 = XGrabPointer (dpy, gnome_win, False, NoEventMask, GrabModeAsync,
1528                       GrabModeAsync, None, None, CurrentTime);                                                                                   GrabModeAsync, None, None, CurrentTime);
1529    if (g1 != GrabSuccess || g2 != GrabSuccess)          if (g1 != GrabSuccess || g2 != GrabSuccess)
1530      {                  {
1531  #ifdef DEBUG  #ifdef DEBUG
1532        printf ("grab failed in clientCycle\n");                          printf ("grab failed in clientCycle\n");
1533  #endif  #endif
1534        if (g1 == GrabSuccess)                          if (g1 == GrabSuccess)
1535                                    XUngrabKeyboard (dpy, CurrentTime);
1536                            if (g2 == GrabSuccess)
1537                                    XUngrabPointer (dpy, CurrentTime);
1538                            return;
1539                    }
1540    
1541            c2 = clientGetNext (c2, INCLUDE_HIDDEN);
1542            if (!c2)
1543                    cycling = False;
1544    
1545    #ifdef DEBUG
1546            printf ("entering cycle loop\n");
1547    #endif
1548    
1549            while (cycling)
1550                    {
1551                            clientShow (c2, False);
1552                            clientRaise (c2);
1553                            clientSetFocus (c2, False);
1554    
1555                            XNextEvent (dpy, &ev);
1556                            if (ev.type == KeyPress)
1557                                    {
1558                                            if (ev.xkey.keycode == keys[KEY_CYCLE_WINDOWS].keycode)
1559                                                    {
1560                                                            if (getWMState (c2->window) == IconicState)
1561                                                                    clientHide (c2, False);
1562                                                            c2 = clientGetNext (c2, INCLUDE_HIDDEN);
1563                                                            if (!c2)
1564                                                                    cycling = False;
1565                                                    }
1566                                            else
1567                                                    {
1568                                                            XPutBackEvent (dpy, &ev);
1569                                                            cycling = False;
1570                                                    }
1571                                    }
1572                            else if (ev.type == KeyRelease)
1573                                    {
1574                                            if (IsModifierKey (XKeycodeToKeysym (dpy, ev.xkey.keycode, 0)))
1575                                                    cycling = False;
1576                                    }
1577                            else
1578                                    handleEvent (&ev);
1579                    }
1580    #ifdef DEBUG
1581            printf ("leaving cycle loop\n");
1582    #endif
1583    
1584          XUngrabKeyboard (dpy, CurrentTime);          XUngrabKeyboard (dpy, CurrentTime);
       if (g2 == GrabSuccess)  
1585          XUngrabPointer (dpy, CurrentTime);          XUngrabPointer (dpy, CurrentTime);
       return;  
     }  
1586    
1587    c2 = clientGetNext (c2, INCLUDE_HIDDEN);          if (c2)
1588    if (!c2)                  {
1589      cycling = False;                          clientShow (c2, True);
1590                            clientSetFocus (c2, True);
1591  #ifdef DEBUG                          clientWarpMouse (c2);
1592    printf ("entering cycle loop\n");                  }
 #endif  
   
   while (cycling)  
     {  
       clientShow (c2, False);  
       clientRaise (c2);  
       clientSetFocus (c2, False);  
   
       XNextEvent (dpy, &ev);  
       if (ev.type == KeyPress)  
         {  
           if (ev.xkey.keycode == keys[KEY_CYCLE_WINDOWS].keycode)  
             {  
               if (getWMState (c2->window) == IconicState)  
                 clientHide (c2, False);  
               c2 = clientGetNext (c2, INCLUDE_HIDDEN);  
               if (!c2)  
                 cycling = False;  
             }  
           else  
             {  
               XPutBackEvent (dpy, &ev);  
               cycling = False;  
             }  
         }  
       else if (ev.type == KeyRelease)  
         {  
           if (IsModifierKey (XKeycodeToKeysym (dpy, ev.xkey.keycode, 0)))  
             cycling = False;  
         }  
       else  
         handleEvent (&ev);  
     }  
 #ifdef DEBUG  
   printf ("leaving cycle loop\n");  
 #endif  
   
   XUngrabKeyboard (dpy, CurrentTime);  
   XUngrabPointer (dpy, CurrentTime);  
   
   if (c2)  
     {  
       clientShow (c2, True);  
       clientSetFocus (c2, True);  
       clientWarpMouse (c2);  
     }  
1593  }  }
1594    
1595  void  void
1596  clientButtonPress (Client * c, Window w, XButtonEvent * bev)  clientButtonPress (Client * c, Window w, XButtonEvent * bev)
1597  {  {
1598    int pressed = True, b, g1, g2;          int pressed = True, b, g1, g2;
1599    XEvent ev;          XEvent ev;
1600    
1601  #ifdef DEBUG  #ifdef DEBUG
1602    printf ("entering clientButtonPress\n");          printf ("entering clientButtonPress\n");
1603  #endif  #endif
1604    
1605    for (b = 0; b < BUTTON_COUNT; b++)          for (b = 0; b < BUTTON_COUNT; b++)
1606      if (c->buttons[b] == w)                  if (c->buttons[b] == w)
1607        break;                          break;
1608    
1609    g1 = XGrabKeyboard (dpy, c->window, False, GrabModeAsync, GrabModeAsync,          g1 = XGrabKeyboard (dpy, c->window, False, GrabModeAsync, GrabModeAsync,
1610                        CurrentTime);                                                                                          CurrentTime);
1611    g2 = XGrabPointer (dpy, w, False,          g2 = XGrabPointer (dpy, w, False,
1612                       ButtonReleaseMask | EnterWindowMask | LeaveWindowMask,                                                                                   ButtonReleaseMask | EnterWindowMask | LeaveWindowMask,
1613                       GrabModeAsync, GrabModeAsync, None, None, CurrentTime);                                                                                   GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
1614    
1615    if (g1 != GrabSuccess || g2 != GrabSuccess)          if (g1 != GrabSuccess || g2 != GrabSuccess)
1616      {                  {
1617  #ifdef DEBUG  #ifdef DEBUG
1618        printf ("grab failed in clientButtonPress\n");                          printf ("grab failed in clientButtonPress\n");
1619  #endif  #endif
1620        if (g1 == GrabSuccess)                          if (g1 == GrabSuccess)
1621          XUngrabKeyboard (dpy, CurrentTime);                                  XUngrabKeyboard (dpy, CurrentTime);
1622        if (g2 == GrabSuccess)                          if (g2 == GrabSuccess)
1623          XUngrabPointer (dpy, CurrentTime);                                  XUngrabPointer (dpy, CurrentTime);
1624        return;                          return;
1625      }                  }
1626    
1627    #ifdef DEBUG
1628            printf ("entering button press loop\n");
1629    #endif
1630    
1631            c->button_pressed[b] = True;
1632            frameDraw (c);
1633    
1634            while (pressed)
1635                    {
1636                            XNextEvent (dpy, &ev);
1637    
1638                            if (ev.type == EnterNotify)
1639                                    {
1640                                            c->button_pressed[b] = True;
1641                                            frameDraw (c);
1642                                    }
1643                            else if (ev.type == LeaveNotify)
1644                                    {
1645                                            c->button_pressed[b] = False;
1646                                            frameDraw (c);
1647                                    }
1648                            else if (ev.type == ButtonRelease)
1649                                    pressed = False;
1650                            else if (ev.type == UnmapNotify && ev.xunmap.window == c->window)
1651                                    {
1652                                            pressed = False;
1653                                            c->button_pressed[b] = False;
1654                                    }
1655                            else if (ev.type == KeyPress || ev.type == KeyRelease)
1656                                    {
1657                                    }
1658                            else
1659                                    handleEvent (&ev);
1660                    }
1661  #ifdef DEBUG  #ifdef DEBUG
1662    printf ("entering button press loop\n");          printf ("leaving button press loop\n");
1663  #endif  #endif
1664    
1665    c->button_pressed[b] = True;          XUngrabPointer (dpy, CurrentTime);
1666    frameDraw (c);          XUngrabKeyboard (dpy, CurrentTime);
1667    
1668    while (pressed)          if (c->button_pressed[b])
1669      {                  {
1670        XNextEvent (dpy, &ev);                          c->button_pressed[b] = False;
1671                            frameDraw (c);
1672        if (ev.type == EnterNotify)  
1673          {                          switch (b)
1674            c->button_pressed[b] = True;                                  {
1675            frameDraw (c);                                  case HIDE_BUTTON:
1676          }                                          clientHide (c, True);
1677        else if (ev.type == LeaveNotify)                                          break;
1678          {                                  case CLOSE_BUTTON:
1679            c->button_pressed[b] = False;                                          if (bev->button == Button3)
1680            frameDraw (c);                                                  clientKill (c);
1681          }                                          else
1682        else if (ev.type == ButtonRelease)                                                  clientClose (c);
1683          pressed = False;                                          break;
1684        else if (ev.type == UnmapNotify && ev.xunmap.window == c->window)                                  case MAXIMIZE_BUTTON:
1685          {                                          if (bev->button == Button1)
1686            pressed = False;                                                  clientToggleMaximized (c, WIN_STATE_MAXIMIZED);
1687            c->button_pressed[b] = False;                                          else if (bev->button == Button2)
1688          }                                                  clientToggleMaximized (c, WIN_STATE_MAXIMIZED_VERT);
1689        else if (ev.type == KeyPress || ev.type == KeyRelease)                                          else if (bev->button == Button3)
1690          {                                                  clientToggleMaximized (c, WIN_STATE_MAXIMIZED_HORIZ);
1691          }                                          break;
1692        else                                  case SHADE_BUTTON:
1693          handleEvent (&ev);                                          clientToggleShaded (c);
1694      }                                          break;
1695  #ifdef DEBUG                                  }
1696    printf ("leaving button press loop\n");                  }
 #endif  
   
   XUngrabPointer (dpy, CurrentTime);  
   XUngrabKeyboard (dpy, CurrentTime);  
   
   if (c->button_pressed[b])  
     {  
       c->button_pressed[b] = False;  
       frameDraw (c);  
   
       switch (b)  
         {  
         case HIDE_BUTTON:  
           clientHide (c, True);  
           break;  
         case CLOSE_BUTTON:  
           if (bev->button == Button3)  
             clientKill (c);  
           else  
             clientClose (c);  
           break;  
         case MAXIMIZE_BUTTON:  
           if (bev->button == Button1)  
             clientToggleMaximized (c, WIN_STATE_MAXIMIZED);  
           else if (bev->button == Button2)  
             clientToggleMaximized (c, WIN_STATE_MAXIMIZED_VERT);  
           else if (bev->button == Button3)  
             clientToggleMaximized (c, WIN_STATE_MAXIMIZED_HORIZ);  
           break;  
         case SHADE_BUTTON:  
           clientToggleShaded (c);  
           break;  
         }  
     }  
1697  }  }
1698    
1699  void  void
1700  clientWarpMouse (Client * c)  clientWarpMouse (Client * c)
1701  {  {
1702    if (!c)          if (!c)
1703      return;                  return;
1704    else if (!click_to_focus && c->win_state & WIN_STATE_SHADED)          else if (!click_to_focus && c->win_state & WIN_STATE_SHADED)
1705      XWarpPointer (dpy, None, c->window, 0, 0, 0, 0,                  XWarpPointer (dpy, None, c->window, 0, 0, 0, 0,
1706                    (frameWidth (c) / 2), (frameHeight (c) / 2) * -1);                                                                          (frameWidth (c) / 2), (frameHeight (c) / 2) * -1);
1707    else if (!click_to_focus)          else if (!click_to_focus)
1708      XWarpPointer (dpy, None, c->window, 0, 0, 0, 0,                  XWarpPointer (dpy, None, c->window, 0, 0, 0, 0,
1709                    (frameWidth (c) / 2), (frameHeight (c) / 2));                                                                          (frameWidth (c) / 2), (frameHeight (c) / 2));
1710  }  }
1711    
1712  int  int
1713  clientInBorderlessList (Client * c)  clientInBorderlessList (Client * c)
1714  {  {
1715    XClassHint *class_res;          XClassHint *class_res;
1716    char *win_class_name;          char *win_class_name;
1717    char *tok;          char *tok;
1718    char *buf;          char *buf;
1719    size_t strSize;          size_t strSize;
1720    
1721  #ifdef DEBUG  #ifdef DEBUG
1722    printf ("entering clientInBorderlessList\n");          printf ("entering clientInBorderlessList\n");
1723  #endif  #endif
1724    
1725    class_res = xmalloc (sizeof (XClassHint));          class_res = xmalloc (sizeof (XClassHint));
1726    
1727    XGetClassHint (dpy, c->window, class_res);          class_res->res_name = NULL;
1728    
1729    if (class_res->res_name)          if (XGetClassHint (dpy, c->window, class_res) && class_res->res_name)
1730      win_class_name = class_res->res_name;                  win_class_name = class_res->res_name;
1731    else          else
1732      {                  {
1733        XFree (class_res);                          XFree (class_res);
1734        return False;                          return False;
1735      }                  }
1736    
1737    strSize = sizeof (char) * (strlen (borderless_windows) + 1);          strSize = sizeof (char) * (strlen (borderless_windows) + 1);
1738    buf = xmalloc (strSize);          buf = xmalloc (strSize);
1739    snprintf (buf, strSize, "%s", borderless_windows);          snprintf (buf, strSize, "%s", borderless_windows);
1740    
1741    tok = strtok (buf, ";");          tok = strtok (buf, ";");
1742    
1743    while (tok)          while (tok)
1744      {                  {
1745        if (strcasecmp (tok, win_class_name) == 0)                          if (strcasecmp (tok, win_class_name) == 0)
1746          {                                  {
1747            XFree (class_res);                                          XFree (class_res);
1748            free (buf);                                          free (buf);
1749            return True;                                          return True;
1750          }                                  }
1751        tok = strtok (NULL, ";");                          tok = strtok (NULL, ";");
1752      }                  }
1753    
1754    XFree (class_res);          XFree (class_res);
1755    free (buf);          free (buf);
1756    return False;          return False;
1757  }  }
1758    
1759  /**This must remain at the end of the file.**********  /**This must remain at the end of the file.**********
1760   * vim600:set sw=2 ts=8:                            *   * vim600:set sw=2 ts=2:                            *
1761   * vim600:set cindent cinoptions={1s,>2s,^-1s,n-1s: *   * vim600:set cindent cinoptions={1s,>2s,^-1s,n-1s: *
1762   * vim600:set foldmethod=marker:                    *   * vim600:set foldmethod=marker:                    *
1763   ****************************************************/   ****************************************************/

Legend:
Removed from v.1.26  
changed lines
  Added in v.1.27

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26