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

Legend:
Removed from v.1.52  
changed lines
  Added in v.1.53

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