2 * client.c - client management
4 * Copyright © 2007 Julien Danjou <julien@danjou.info>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include <X11/Xatom.h>
24 #include <X11/Xutil.h>
25 #include <X11/extensions/shape.h>
32 #include "statusbar.h"
34 #include "layouts/floating.h"
37 extern Client
*clients
, *sel
, *stack
; /* global client list and stack */
39 /** Attach client stack to clients stacks
43 attachstack(Client
* c
)
49 /** Detach client from stack
53 detachstack(Client
* c
)
57 for(tc
= &stack
; *tc
&& *tc
!= c
; tc
= &(*tc
)->snext
);
61 /** Grab or ungrab buttons when a client is focused
63 * \param focused True if client is focused
64 * \param modkey Mod key mask
65 * \param numlockmask Numlock mask
68 grabbuttons(Client
* c
, Bool focused
, KeySym modkey
, unsigned int numlockmask
)
70 XUngrabButton(c
->display
, AnyButton
, AnyModifier
, c
->win
);
74 XGrabButton(c
->display
, Button1
, modkey
, c
->win
, False
, BUTTONMASK
,
75 GrabModeAsync
, GrabModeSync
, None
, None
);
76 XGrabButton(c
->display
, Button1
, modkey
| LockMask
, c
->win
, False
,
77 BUTTONMASK
, GrabModeAsync
, GrabModeSync
, None
, None
);
78 XGrabButton(c
->display
, Button1
, modkey
| numlockmask
, c
->win
, False
,
79 BUTTONMASK
, GrabModeAsync
, GrabModeSync
, None
, None
);
80 XGrabButton(c
->display
, Button1
, modkey
| numlockmask
| LockMask
,
81 c
->win
, False
, BUTTONMASK
, GrabModeAsync
, GrabModeSync
, None
, None
);
83 XGrabButton(c
->display
, Button2
, modkey
, c
->win
, False
, BUTTONMASK
,
84 GrabModeAsync
, GrabModeSync
, None
, None
);
85 XGrabButton(c
->display
, Button2
, modkey
| LockMask
, c
->win
, False
,
86 BUTTONMASK
, GrabModeAsync
, GrabModeSync
, None
, None
);
87 XGrabButton(c
->display
, Button2
, modkey
| numlockmask
, c
->win
, False
,
88 BUTTONMASK
, GrabModeAsync
, GrabModeSync
, None
, None
);
89 XGrabButton(c
->display
, Button2
, modkey
| numlockmask
| LockMask
,
90 c
->win
, False
, BUTTONMASK
, GrabModeAsync
, GrabModeSync
, None
, None
);
92 XGrabButton(c
->display
, Button3
, modkey
, c
->win
, False
, BUTTONMASK
,
93 GrabModeAsync
, GrabModeSync
, None
, None
);
94 XGrabButton(c
->display
, Button3
, modkey
| LockMask
, c
->win
, False
,
95 BUTTONMASK
, GrabModeAsync
, GrabModeSync
, None
, None
);
96 XGrabButton(c
->display
, Button3
, modkey
| numlockmask
, c
->win
, False
,
97 BUTTONMASK
, GrabModeAsync
, GrabModeSync
, None
, None
);
98 XGrabButton(c
->display
, Button3
, modkey
| numlockmask
| LockMask
,
99 c
->win
, False
, BUTTONMASK
, GrabModeAsync
, GrabModeSync
, None
, None
);
101 XUngrabButton(c
->display
, AnyButton
, AnyModifier
, RootWindow(c
->display
, c
->phys_screen
));
105 XGrabButton(c
->display
, AnyButton
, AnyModifier
, c
->win
, False
, BUTTONMASK
,
106 GrabModeAsync
, GrabModeSync
, None
, None
);
107 XGrabButton(c
->display
, Button4
, NoSymbol
, RootWindow(c
->display
, c
->phys_screen
), False
, BUTTONMASK
,
108 GrabModeAsync
, GrabModeSync
, None
, None
);
109 XGrabButton(c
->display
, Button4
, LockMask
, RootWindow(c
->display
, c
->phys_screen
), False
, BUTTONMASK
,
110 GrabModeAsync
, GrabModeSync
, None
, None
);
111 XGrabButton(c
->display
, Button4
, numlockmask
, RootWindow(c
->display
, c
->phys_screen
), False
, BUTTONMASK
,
112 GrabModeAsync
, GrabModeSync
, None
, None
);
113 XGrabButton(c
->display
, Button4
, numlockmask
| LockMask
, RootWindow(c
->display
, c
->phys_screen
), False
, BUTTONMASK
,
114 GrabModeAsync
, GrabModeSync
, None
, None
);
116 XGrabButton(c
->display
, Button5
, NoSymbol
, RootWindow(c
->display
, c
->phys_screen
), False
, BUTTONMASK
,
117 GrabModeAsync
, GrabModeSync
, None
, None
);
118 XGrabButton(c
->display
, Button5
, LockMask
, RootWindow(c
->display
, c
->phys_screen
), False
, BUTTONMASK
,
119 GrabModeAsync
, GrabModeSync
, None
, None
);
120 XGrabButton(c
->display
, Button5
, numlockmask
, RootWindow(c
->display
, c
->phys_screen
), False
, BUTTONMASK
,
121 GrabModeAsync
, GrabModeSync
, None
, None
);
122 XGrabButton(c
->display
, Button5
, numlockmask
| LockMask
, RootWindow(c
->display
, c
->phys_screen
), False
, BUTTONMASK
,
123 GrabModeAsync
, GrabModeSync
, None
, None
);
128 /** Check if client supports protocol WM_DELETE_WINDOW
129 * \param c the client
130 * \return True if client has WM_DELETE_WINDOW
133 isprotodel(Client
* c
)
139 if(XGetWMProtocols(c
->display
, c
->win
, &protocols
, &n
))
141 for(i
= 0; !ret
&& i
< n
; i
++)
142 if(protocols
[i
] == XInternAtom(c
->display
, "WM_DELETE_WINDOW", False
))
149 /** Set client WM_STATE property
150 * \param c the client
151 * \param state no idea
154 setclientstate(Client
* c
, long state
)
156 long data
[] = { state
, None
};
158 XChangeProperty(c
->display
, c
->win
, XInternAtom(c
->display
, "WM_STATE", False
),
159 XInternAtom(c
->display
, "WM_STATE", False
), 32,
160 PropModeReplace
, (unsigned char *) data
, 2);
163 /** Set client transparency using composite
165 * \param opacity opacity percentage
168 setclienttrans(Client
*c
, double opacity
)
170 unsigned int real_opacity
= 0xffffffff;
172 if(opacity
>= 0 && opacity
<= 100)
174 real_opacity
= ((opacity
/ 100.0) * 0xffffffff);
175 XChangeProperty(c
->display
, c
->win
,
176 XInternAtom(c
->display
, "_NET_WM_WINDOW_OPACITY", False
),
177 XA_CARDINAL
, 32, PropModeReplace
, (unsigned char *) &real_opacity
, 1L);
180 XDeleteProperty(c
->display
, c
->win
, XInternAtom(c
->display
, "_NET_WM_WINDOW_OPACITY", False
));
182 XSync(c
->display
, False
);
185 /** Swap two client in the linked list clients
186 * \param c1 first client
187 * \param c2 second client
190 client_swap(Client
*c1
, Client
*c2
)
196 c2
->next
= (tmp
== c2
? c1
: tmp
);
200 c1
->prev
= (tmp
== c1
? c2
: tmp
);
218 /** Attach client to the beginning of the clients stack
219 * \param c the client
231 updatetitle(Client
* c
)
233 if(!xgettextprop(c
->display
, c
->win
, XInternAtom(c
->display
, "_NET_WM_NAME", False
), c
->name
, sizeof c
->name
))
234 xgettextprop(c
->display
, c
->win
, XInternAtom(c
->display
, "WM_NAME", False
), c
->name
, sizeof c
->name
);
237 /** Ban client and unmapped it
238 * \param c the client
243 XUnmapWindow(c
->display
, c
->win
);
244 setclientstate(c
, IconicState
);
250 * \param c the client
253 configure(Client
* c
)
257 ce
.type
= ConfigureNotify
;
258 ce
.display
= c
->display
;
265 ce
.border_width
= c
->border
;
267 ce
.override_redirect
= False
;
268 XSendEvent(c
->display
, c
->win
, False
, StructureNotifyMask
, (XEvent
*) & ce
);
271 /** Detach client from clients list
272 * \param c client to detach
278 c
->prev
->next
= c
->next
;
280 c
->next
->prev
= c
->prev
;
283 c
->next
= c
->prev
= NULL
;
286 /** Give focus to client, or to first client if c is NULL
287 * \param disp Display ref
288 * \param drawcontext drawcontext ref
290 * \param selscreen True if current screen is selected
291 * \param awesomeconf awesome config
294 focus(Display
*disp
, DC
*drawcontext
, Client
* c
, Bool selscreen
, awesome_config
*awesomeconf
)
296 /* if c is NULL or invisible, take next client in the stack */
297 if((!c
&& selscreen
) || (c
&& !isvisible(c
, awesomeconf
->screen
, awesomeconf
->tags
, awesomeconf
->ntags
)))
298 for(c
= stack
; c
&& !isvisible(c
, awesomeconf
->screen
, awesomeconf
->tags
, awesomeconf
->ntags
); c
= c
->snext
);
300 /* if a client was selected but it's not the current client, unfocus it */
303 grabbuttons(sel
, False
, awesomeconf
->modkey
, awesomeconf
->numlockmask
);
304 XSetWindowBorder(sel
->display
, sel
->win
, drawcontext
->norm
[ColBorder
]);
305 setclienttrans(sel
, awesomeconf
->opacity_unfocused
);
311 grabbuttons(c
, True
, awesomeconf
->modkey
, awesomeconf
->numlockmask
);
316 drawstatusbar(disp
, drawcontext
, awesomeconf
);
319 XSetWindowBorder(sel
->display
, sel
->win
, drawcontext
->sel
[ColBorder
]);
320 XSetInputFocus(sel
->display
, sel
->win
, RevertToPointerRoot
, CurrentTime
);
321 for(c
= stack
; c
; c
= c
->snext
)
323 setclienttrans(c
, awesomeconf
->opacity_unfocused
);
324 setclienttrans(sel
, -1);
327 XSetInputFocus(disp
, RootWindow(disp
, awesomeconf
->screen
), RevertToPointerRoot
, CurrentTime
);
331 /** Load windows properties, restoring client's tag
332 * and floating state before awesome was restarted if any
333 * \todo this may bug if number of tags is != than before
334 * \param c Client ref
335 * \param ntags tags number
338 loadprops(Client
* c
, int ntags
)
344 prop
= p_new(char, ntags
+ 2);
346 if(xgettextprop(c
->display
, c
->win
, AWESOMEPROPS_ATOM(c
->display
), prop
, ntags
+ 2))
348 for(i
= 0; i
< ntags
&& prop
[i
]; i
++)
349 if((c
->tags
[i
] = prop
[i
] == '1'))
351 if(i
<= ntags
&& prop
[i
])
352 c
->isfloating
= prop
[i
] == '1';
360 /** Manage a new client
361 * \param disp Display ref
362 * \param drawcontext Drawcontext ref
363 * \param w The window
364 * \param wa Window attributes
365 * \param awesomeconf awesome config
368 manage(Display
*disp
, DC
*drawcontext
, Window w
, XWindowAttributes
*wa
, awesome_config
*awesomeconf
)
371 Client
*c
, *t
= NULL
;
375 ScreenInfo
*si
= get_display_info(disp
, awesomeconf
->screen
, NULL
);
376 ScreenInfo
*screen_info
;
378 c
= p_new(Client
, 1);
381 c
->x
= c
->rw
= wa
->x
;
382 c
->y
= c
->ry
= wa
->y
;
383 c
->w
= c
->rw
= wa
->width
;
384 c
->h
= c
->rh
= wa
->height
;
385 c
->oldborder
= wa
->border_width
;
387 c
->phys_screen
= get_phys_screen(c
->display
, c
->screen
);
388 screen_info
= get_screen_info(c
->display
, c
->screen
, NULL
);
389 if(c
->w
== screen_info
[c
->screen
].width
&& c
->h
== screen_info
[c
->screen
].height
)
393 c
->border
= wa
->border_width
;
397 if(c
->x
+ c
->w
+ 2 * c
->border
> si
->x_org
+ si
->width
)
398 c
->x
= c
->rx
= si
->x_org
+ si
->width
- c
->w
- 2 * c
->border
;
399 if(c
->y
+ c
->h
+ 2 * c
->border
> si
->y_org
+ si
->height
)
400 c
->y
= c
->ry
= si
->y_org
+ si
->height
- c
->h
- 2 * c
->border
;
402 c
->x
= c
->rx
= si
->x_org
;
404 c
->y
= c
->ry
= si
->y_org
;
405 c
->border
= awesomeconf
->borderpx
;
408 wc
.border_width
= c
->border
;
409 XConfigureWindow(disp
, w
, CWBorderWidth
, &wc
);
410 XSetWindowBorder(disp
, w
, drawcontext
->norm
[ColBorder
]);
411 configure(c
); /* propagates border_width, if size doesn't change */
413 XSelectInput(disp
, w
, StructureNotifyMask
| PropertyChangeMask
| EnterWindowMask
);
414 if(awesomeconf
->have_shape
)
416 XShapeSelectInput(disp
, w
, ShapeNotifyMask
);
419 grabbuttons(c
, False
, awesomeconf
->modkey
, awesomeconf
->numlockmask
);
421 move_client_to_screen(c
, awesomeconf
, False
);
422 if((rettrans
= XGetTransientForHint(disp
, w
, &trans
) == Success
))
423 for(t
= clients
; t
&& t
->win
!= trans
; t
= t
->next
);
425 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
426 c
->tags
[i
] = t
->tags
[i
];
427 if(!loadprops(c
, awesomeconf
->ntags
))
428 applyrules(c
, awesomeconf
);
430 c
->isfloating
= (rettrans
== Success
) || c
->isfixed
;
431 saveprops(c
, awesomeconf
->ntags
);
434 XMoveResizeWindow(disp
, c
->win
, c
->x
, c
->y
, c
->w
, c
->h
); /* some windows require this */
436 arrange(disp
, drawcontext
, awesomeconf
);
440 resize(Client
*c
, int x
, int y
, int w
, int h
, awesome_config
*awesomeconf
, Bool sizehints
)
442 double dx
, dy
, max
, min
, ratio
;
448 if(c
->minay
> 0 && c
->maxay
> 0 && (h
- c
->baseh
) > 0 && (w
- c
->basew
) > 0)
450 dx
= (double) (w
- c
->basew
);
451 dy
= (double) (h
- c
->baseh
);
452 min
= (double) (c
->minax
) / (double) (c
->minay
);
453 max
= (double) (c
->maxax
) / (double) (c
->maxay
);
455 if(max
> 0 && min
> 0 && ratio
> 0)
459 dy
= (dx
* min
+ dy
) / (min
* min
+ 1);
461 w
= (int) dx
+ c
->basew
;
462 h
= (int) dy
+ c
->baseh
;
466 dy
= (dx
* min
+ dy
) / (max
* max
+ 1);
468 w
= (int) dx
+ c
->basew
;
469 h
= (int) dy
+ c
->baseh
;
473 if(c
->minw
&& w
< c
->minw
)
475 if(c
->minh
&& h
< c
->minh
)
477 if(c
->maxw
&& w
> c
->maxw
)
479 if(c
->maxh
&& h
> c
->maxh
)
482 w
-= (w
- c
->basew
) % c
->incw
;
484 h
-= (h
- c
->baseh
) % c
->inch
;
488 /* offscreen appearance fixes */
489 si
= get_display_info(c
->display
, c
->phys_screen
, NULL
);
491 x
= si
->width
- w
- 2 * c
->border
;
493 y
= si
->height
- h
- 2 * c
->border
;
495 if(x
+ w
+ 2 * c
->border
< 0)
497 if(y
+ h
+ 2 * c
->border
< 0)
499 if(c
->x
!= x
|| c
->y
!= y
|| c
->w
!= w
|| c
->h
!= h
)
504 c
->h
= wc
.height
= h
;
505 wc
.border_width
= c
->border
;
506 XConfigureWindow(c
->display
, c
->win
, CWX
| CWY
| CWWidth
| CWHeight
| CWBorderWidth
, &wc
);
508 XSync(c
->display
, False
);
509 if(XineramaIsActive(c
->display
))
511 int new_screen
= get_screen_bycoord(c
->display
, c
->x
, c
->y
);
512 if(c
->screen
!= new_screen
)
513 move_client_to_screen(c
, &awesomeconf
[new_screen
- awesomeconf
->screen
], False
);
519 saveprops(Client
* c
, int ntags
)
524 prop
= p_new(char, ntags
+ 2);
526 for(i
= 0; i
< ntags
; i
++)
527 prop
[i
] = c
->tags
[i
] ? '1' : '0';
530 prop
[i
] = c
->isfloating
? '1' : '0';
534 XChangeProperty(c
->display
, c
->win
, AWESOMEPROPS_ATOM(c
->display
), XA_STRING
, 8,
535 PropModeReplace
, (unsigned char *) prop
, i
);
543 XMapWindow(c
->display
, c
->win
);
544 setclientstate(c
, NormalState
);
550 unmanage(Client
* c
, DC
*drawcontext
, long state
, awesome_config
*awesomeconf
)
555 wc
.border_width
= c
->oldborder
;
556 /* The server grab construct avoids race conditions. */
557 XGrabServer(c
->display
);
558 XConfigureWindow(c
->display
, c
->win
, CWBorderWidth
, &wc
); /* restore border */
562 focus(c
->display
, drawcontext
, NULL
, True
, awesomeconf
);
563 XUngrabButton(c
->display
, AnyButton
, AnyModifier
, c
->win
);
564 setclientstate(c
, state
);
565 XSync(c
->display
, False
);
566 XSetErrorHandler(xerror
);
567 XUngrabServer(c
->display
);
568 if(state
!= NormalState
)
569 arrange(c
->display
, drawcontext
, awesomeconf
);
575 updatesizehints(Client
* c
)
580 if(!XGetWMNormalHints(c
->display
, c
->win
, &size
, &msize
) || !size
.flags
)
582 c
->flags
= size
.flags
;
583 if(c
->flags
& PBaseSize
)
585 c
->basew
= size
.base_width
;
586 c
->baseh
= size
.base_height
;
588 else if(c
->flags
& PMinSize
)
590 c
->basew
= size
.min_width
;
591 c
->baseh
= size
.min_height
;
594 c
->basew
= c
->baseh
= 0;
595 if(c
->flags
& PResizeInc
)
597 c
->incw
= size
.width_inc
;
598 c
->inch
= size
.height_inc
;
601 c
->incw
= c
->inch
= 0;
603 if(c
->flags
& PMaxSize
)
605 c
->maxw
= size
.max_width
;
606 c
->maxh
= size
.max_height
;
609 c
->maxw
= c
->maxh
= 0;
611 if(c
->flags
& PMinSize
)
613 c
->minw
= size
.min_width
;
614 c
->minh
= size
.min_height
;
616 else if(c
->flags
& PBaseSize
)
618 c
->minw
= size
.base_width
;
619 c
->minh
= size
.base_height
;
622 c
->minw
= c
->minh
= 0;
624 if(c
->flags
& PAspect
)
626 c
->minax
= size
.min_aspect
.x
;
627 c
->maxax
= size
.max_aspect
.x
;
628 c
->minay
= size
.min_aspect
.y
;
629 c
->maxay
= size
.max_aspect
.y
;
632 c
->minax
= c
->maxax
= c
->minay
= c
->maxay
= 0;
634 c
->isfixed
= (c
->maxw
&& c
->minw
&& c
->maxh
&& c
->minh
635 && c
->maxw
== c
->minw
&& c
->maxh
== c
->minh
);
642 int i
, b
; unsigned int u
; /* dummies */
643 /* Logic to decide if we have a shaped window cribbed from fvwm-2.5.10. */
644 if (XShapeQueryExtents(c
->display
, c
->win
, &bounding_shaped
, &i
, &i
,
645 &u
, &u
, &b
, &i
, &i
, &u
, &u
) && bounding_shaped
)
646 XShapeCombineShape(c
->display
, RootWindow(c
->display
, c
->screen
), ShapeBounding
, 0, 0, c
->win
, ShapeBounding
, ShapeSet
);
649 /** Set selected client transparency
650 * \param disp Display ref
651 * \param drawcontext Drawcontext ref
652 * \param awesomeconf awesome config
653 * \param arg unused arg
654 * \ingroup ui_callback
657 uicb_settrans(Display
*disp
__attribute__ ((unused
)),
658 DC
*drawcontext
__attribute__ ((unused
)),
659 awesome_config
*awesomeconf
__attribute__ ((unused
)),
662 double delta
= 100.0, current_opacity
= 0.0;
666 unsigned long n
, left
;
667 unsigned int current_opacity_raw
= 0;
673 XGetWindowProperty(sel
->display
, sel
->win
, XInternAtom(sel
->display
, "_NET_WM_WINDOW_OPACITY", False
),
674 0L, 1L, False
, XA_CARDINAL
, &actual
, &format
, &n
, &left
,
675 (unsigned char **) &data
);
678 memcpy(¤t_opacity_raw
, data
, sizeof(unsigned int));
680 current_opacity
= (current_opacity_raw
* 100.0) / 0xffffffff;
685 delta
= compute_new_value_from_arg(arg
, current_opacity
);
689 else if(delta
> 100.0)
695 if(delta
== 100.0 && !set_prop
)
696 setclienttrans(sel
, -1);
698 setclienttrans(sel
, delta
);
703 * \param disp Display ref
704 * \param drawcontext Drawcontext ref
705 * \param awesomeconf awesome config
706 * \param arg X, +X or -X
707 * \ingroup ui_callback
710 uicb_setborder(Display
*disp
__attribute__ ((unused
)),
711 DC
*drawcontext
__attribute__ ((unused
)),
712 awesome_config
*awesomeconf
,
718 if((awesomeconf
->borderpx
= (int) compute_new_value_from_arg(arg
, (double) awesomeconf
->borderpx
)) < 0)
719 awesomeconf
->borderpx
= 0;
723 uicb_swapnext(Display
*disp
,
725 awesome_config
*awesomeconf
,
726 const char *arg
__attribute__ ((unused
)))
733 for(next
= sel
->next
; next
&& !isvisible(next
, awesomeconf
->screen
, awesomeconf
->tags
, awesomeconf
->ntags
); next
= next
->next
);
736 client_swap(sel
, next
);
737 arrange(disp
, drawcontext
, awesomeconf
);
742 uicb_swapprev(Display
*disp
,
744 awesome_config
*awesomeconf
,
745 const char *arg
__attribute__ ((unused
)))
752 for(prev
= sel
->prev
; prev
&& !isvisible(prev
, awesomeconf
->screen
, awesomeconf
->tags
, awesomeconf
->ntags
); prev
= prev
->prev
);
755 client_swap(prev
, sel
);
756 arrange(disp
, drawcontext
, awesomeconf
);
761 uicb_moveresize(Display
*disp
__attribute__ ((unused
)),
762 DC
*drawcontext
__attribute__ ((unused
)),
763 awesome_config
*awesomeconf
,
766 int nx
, ny
, nw
, nh
, ox
, oy
, ow
, oh
;
767 char x
[8], y
[8], w
[8], h
[8];
768 int mx
, my
, dx
, dy
, nmx
, nmy
;
772 if(!IS_ARRANGE(layout_floating
))
773 if(!sel
|| !sel
->isfloating
|| sel
->isfixed
|| !arg
)
775 if(sscanf(arg
, "%s %s %s %s", x
, y
, w
, h
) != 4)
777 nx
= (int) compute_new_value_from_arg(x
, sel
->x
);
778 ny
= (int) compute_new_value_from_arg(y
, sel
->y
);
779 nw
= (int) compute_new_value_from_arg(w
, sel
->w
);
780 nh
= (int) compute_new_value_from_arg(h
, sel
->h
);
787 Bool xqp
= XQueryPointer(sel
->display
, RootWindow(sel
->display
, sel
->screen
), &dummy
, &dummy
, &mx
, &my
, &dx
, &dy
, &dui
);
788 resize(sel
, nx
, ny
, nw
, nh
, awesomeconf
, True
);
789 if (xqp
&& ox
<= mx
&& (ox
+ ow
) >= mx
&& oy
<= my
&& (oy
+ oh
) >= my
)
791 nmx
= mx
-ox
+sel
->w
-ow
-1 < 0 ? 0 : mx
-ox
+sel
->w
-ow
-1;
792 nmy
= my
-oy
+sel
->h
-oh
-1 < 0 ? 0 : my
-oy
+sel
->h
-oh
-1;
793 XWarpPointer(sel
->display
, None
, sel
->win
, 0, 0, 0, 0, nmx
, nmy
);
797 /** Kill selected client
798 * \param disp Display ref
799 * \param drawcontext Drawcontext ref
800 * \param awesomeconf awesome config
802 * \ingroup ui_callback
805 uicb_killclient(Display
*disp
__attribute__ ((unused
)),
806 DC
*drawcontext
__attribute__ ((unused
)),
807 awesome_config
*awesomeconf
__attribute__ ((unused
)),
808 const char *arg
__attribute__ ((unused
)))
816 ev
.type
= ClientMessage
;
817 ev
.xclient
.window
= sel
->win
;
818 ev
.xclient
.message_type
= XInternAtom(disp
, "WM_PROTOCOLS", False
);
819 ev
.xclient
.format
= 32;
820 ev
.xclient
.data
.l
[0] = XInternAtom(disp
, "WM_DELETE_WINDOW", False
);
821 ev
.xclient
.data
.l
[1] = CurrentTime
;
822 XSendEvent(sel
->display
, sel
->win
, False
, NoEventMask
, &ev
);
825 XKillClient(sel
->display
, sel
->win
);