Merge lp:~noskcaj/ubuntu/trusty/xfwm4/4.11 into lp:ubuntu/trusty/xfwm4

Proposed by Jackson Doak
Status: Needs review
Proposed branch: lp:~noskcaj/ubuntu/trusty/xfwm4/4.11
Merge into: lp:ubuntu/trusty/xfwm4
Diff against target: 99826 lines (+21489/-59611)
111 files modified
.pc/0004-Optimize-smart-placement-bug-5785.patch/src/placement.c (+0/-952)
.pc/8563.patch/src/client.c (+0/-3926)
.pc/applied-patches (+0/-2)
ChangeLog (+2037/-343)
INSTALL (+1/-1)
Makefile.in (+63/-26)
NEWS (+36/-12)
aclocal.m4 (+204/-106)
config.guess (+87/-64)
config.h.in (+3/-3)
config.sub (+14/-16)
configure (+532/-207)
configure.ac (+15/-6)
debian/changelog (+26/-0)
debian/control (+3/-3)
debian/patches/0004-Optimize-smart-placement-bug-5785.patch (+0/-217)
debian/patches/8563.patch (+7/-5)
debian/patches/series (+0/-2)
defaults/Makefile.in (+49/-17)
defaults/defaults (+1/-0)
depcomp (+2/-1)
helper-dialog/Makefile.in (+52/-19)
icons/22x22/Makefile.in (+49/-17)
icons/48x48/Makefile.in (+49/-17)
icons/Makefile.in (+55/-24)
icons/scalable/Makefile.in (+49/-17)
po/ar.po (+314/-1082)
po/ast.po (+106/-430)
po/az.po (+0/-1613)
po/be.po (+298/-407)
po/bg.po (+299/-584)
po/bn.po (+99/-410)
po/bn_IN.po (+0/-1606)
po/ca.po (+296/-1136)
po/cs.po (+296/-1124)
po/da.po (+297/-604)
po/de.po (+292/-1200)
po/dz.po (+0/-1732)
po/el.po (+304/-618)
po/en_AU.po (+752/-0)
po/en_GB.po (+300/-1066)
po/es.po (+298/-1143)
po/es_MX.po (+0/-1627)
po/eu.po (+298/-991)
po/fa.po (+0/-1614)
po/fi.po (+301/-586)
po/fr.po (+300/-619)
po/gl.po (+292/-611)
po/gu.po (+0/-1622)
po/he.po (+293/-303)
po/hi.po (+0/-1414)
po/hr.po (+291/-576)
po/hu.po (+299/-607)
po/id.po (+321/-1162)
po/is.po (+170/-448)
po/it.po (+299/-626)
po/ja.po (+98/-384)
po/ka.po (+0/-1018)
po/kk.po (+293/-598)
po/ko.po (+319/-591)
po/lt.po (+296/-577)
po/lv.po (+108/-993)
po/mk.po (+0/-1773)
po/mr.po (+0/-1621)
po/ms.po (+222/-1048)
po/nb.po (+102/-414)
po/nl.po (+298/-1077)
po/nn.po (+293/-577)
po/oc.po (+752/-0)
po/pl.po (+302/-1052)
po/pt.po (+297/-583)
po/pt_BR.po (+301/-1120)
po/ro.po (+294/-592)
po/ru.po (+152/-434)
po/sk.po (+301/-1078)
po/sq.po (+107/-922)
po/sr.po (+296/-573)
po/sv.po (+295/-1069)
po/ta.po (+0/-1570)
po/th.po (+752/-0)
po/tr.po (+295/-1070)
po/ug.po (+293/-562)
po/uk.po (+295/-605)
po/ur.po (+104/-598)
po/ur_PK.po (+104/-598)
po/zh_CN.po (+299/-579)
po/zh_HK.po (+755/-0)
po/zh_TW.po (+301/-592)
settings-dialogs/Makefile.in (+54/-19)
settings-dialogs/tweaks-settings.c (+14/-0)
settings-dialogs/xfwm4-dialog.glade (+412/-198)
settings-dialogs/xfwm4-dialog_ui.h (+688/-568)
settings-dialogs/xfwm4-settings.c (+149/-119)
settings-dialogs/xfwm4-tweaks-dialog.glade (+239/-92)
settings-dialogs/xfwm4-tweaks-dialog_ui.h (+627/-535)
settings-dialogs/xfwm4-workspace-dialog.glade (+14/-8)
settings-dialogs/xfwm4-workspace-dialog_ui.h (+78/-78)
src/Makefile.am (+2/-1)
src/Makefile.in (+54/-20)
src/client.c (+6/-10)
src/compositor.c (+386/-28)
src/compositor.h (+4/-0)
src/events.c (+12/-10)
src/screen.h (+17/-0)
src/settings.c (+8/-1)
src/settings.h (+1/-0)
themes/Makefile.in (+55/-24)
themes/daloa/Makefile.in (+49/-17)
themes/default/Makefile.in (+49/-17)
themes/kokodi/Makefile.in (+49/-17)
themes/moheli/Makefile.in (+49/-17)
To merge this branch: bzr merge lp:~noskcaj/ubuntu/trusty/xfwm4/4.11
Reviewer Review Type Date Requested Status
Daniel Holbach (community) Approve
Review via email: mp+202211@code.launchpad.net

Description of the change

Merge from debian experimental, needed for xubuntu

To post a comment you must log in.
Revision history for this message
Daniel Holbach (dholbach) wrote :

Thanks. Uploaded.

review: Approve

Unmerged revisions

69. By Jackson Doak

* Merge from Debian unstable. Remaining changes:
  - debian/control: demote xfwm4-themes from Recommends to Suggests, per
    the 'other-p-xubuntu-cleanthemes' spec.
  - Add patch from XFCE bugzilla to fix fullscreen behavior with Qt
    based apps

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== removed directory '.pc/0004-Optimize-smart-placement-bug-5785.patch'
2=== removed directory '.pc/0004-Optimize-smart-placement-bug-5785.patch/src'
3=== removed file '.pc/0004-Optimize-smart-placement-bug-5785.patch/src/placement.c'
4--- .pc/0004-Optimize-smart-placement-bug-5785.patch/src/placement.c 2013-05-21 23:37:03 +0000
5+++ .pc/0004-Optimize-smart-placement-bug-5785.patch/src/placement.c 1970-01-01 00:00:00 +0000
6@@ -1,952 +0,0 @@
7-/* $Id$
8-
9- This program is free software; you can redistribute it and/or modify
10- it under the terms of the GNU General Public License as published by
11- the Free Software Foundation; either version 2, or (at your option)
12- any later version.
13-
14- This program is distributed in the hope that it will be useful,
15- but WITHOUT ANY WARRANTY; without even the implied warranty of
16- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17- GNU General Public License for more details.
18-
19- You should have received a copy of the GNU General Public License
20- along with this program; if not, write to the Free Software
21- Foundation, Inc., Inc., 51 Franklin Street, Fifth Floor, Boston,
22- MA 02110-1301, USA.
23-
24-
25- xfwm4 - (c) 2002-2011 Olivier Fourdan
26-
27- */
28-
29-#ifdef HAVE_CONFIG_H
30-#include "config.h"
31-#endif
32-
33-#include <X11/Xlib.h>
34-#include <X11/Xutil.h>
35-#include <glib.h>
36-#include <libxfce4util/libxfce4util.h>
37-
38-#include "screen.h"
39-#include "misc.h"
40-#include "client.h"
41-#include "placement.h"
42-#include "transients.h"
43-#include "workspaces.h"
44-#include "frame.h"
45-#include "netwm.h"
46-
47-
48-/* Compute rectangle overlap area */
49-
50-static inline unsigned long
51-segment_overlap (int x0, int x1, int tx0, int tx1)
52-{
53- if (tx0 > x0)
54- {
55- x0 = tx0;
56- }
57- if (tx1 < x1)
58- {
59- x1 = tx1;
60- }
61- if (x1 <= x0)
62- {
63- return 0;
64- }
65- return (x1 - x0);
66-}
67-
68-static inline unsigned long
69-overlap (int x0, int y0, int x1, int y1, int tx0, int ty0, int tx1, int ty1)
70-{
71- /* Compute overlapping box */
72- return (segment_overlap (x0, x1, tx0, tx1)
73- * segment_overlap (y0, y1, ty0, ty1));
74-}
75-
76-static unsigned long
77-clientStrutAreaOverlap (int x, int y, int w, int h, Client * c)
78-{
79- unsigned long sigma = 0;
80-
81- if (FLAG_TEST (c->flags, CLIENT_FLAG_HAS_STRUT)
82- && FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE))
83- {
84- sigma = overlap (x, y, x + w, y + h,
85- 0, c->struts[STRUTS_LEFT_START_Y],
86- c->struts[STRUTS_LEFT],
87- c->struts[STRUTS_LEFT_END_Y])
88- + overlap (x, y, x + w, y + h,
89- c->screen_info->width - c->struts[STRUTS_RIGHT],
90- c->struts[STRUTS_RIGHT_START_Y],
91- c->screen_info->width, c->struts[STRUTS_RIGHT_END_Y])
92- + overlap (x, y, x + w, y + h,
93- c->struts[STRUTS_TOP_START_X], 0,
94- c->struts[STRUTS_TOP_END_X],
95- c->struts[STRUTS_TOP])
96- + overlap (x, y, x + w, y + h,
97- c->struts[STRUTS_BOTTOM_START_X],
98- c->screen_info->height - c->struts[STRUTS_BOTTOM],
99- c->struts[STRUTS_BOTTOM_END_X],
100- c->screen_info->height);
101- }
102- return sigma;
103-}
104-
105-void
106-clientMaxSpace (ScreenInfo *screen_info, int *x, int *y, int *w, int *h)
107-{
108- Client *c2;
109- guint i;
110- gint delta, screen_width, screen_height;
111-
112- g_return_if_fail (x != NULL);
113- g_return_if_fail (y != NULL);
114- g_return_if_fail (w != NULL);
115- g_return_if_fail (h != NULL);
116-
117- screen_width = 0;
118- screen_height = 0;
119- delta = 0;
120-
121- for (c2 = screen_info->clients, i = 0; i < screen_info->client_count; c2 = c2->next, i++)
122- {
123- if (FLAG_TEST (c2->flags, CLIENT_FLAG_HAS_STRUT)
124- && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE))
125- {
126- screen_width = c2->screen_info->width;
127- screen_height = c2->screen_info->height;
128-
129- /* Left */
130- if (overlap (*x, *y, *x + *w, *y + *h,
131- 0, c2->struts[STRUTS_LEFT_START_Y], c2->struts[STRUTS_LEFT], c2->struts[STRUTS_LEFT_END_Y]))
132- {
133- delta = c2->struts[STRUTS_LEFT] - *x;
134- *x = *x + delta;
135- *w = *w - delta;
136- }
137-
138- /* Right */
139- if (overlap (*x, *y, *x + *w, *y + *h,
140- screen_width - c2->struts[STRUTS_RIGHT], c2->struts[STRUTS_RIGHT_START_Y],
141- screen_width, c2->struts[STRUTS_RIGHT_END_Y]))
142- {
143- delta = (*x + *w) - screen_width + c2->struts[STRUTS_RIGHT];
144- *w = *w - delta;
145- }
146-
147- /* Top */
148- if (overlap (*x, *y, *x + *w, *y + *h,
149- c2->struts[STRUTS_TOP_START_X], 0, c2->struts[STRUTS_TOP_END_X], c2->struts[STRUTS_TOP]))
150- {
151- delta = c2->struts[STRUTS_TOP] - *y;
152- *y = *y + delta;
153- *h = *h - delta;
154- }
155-
156- /* Bottom */
157- if (overlap (*x, *y, *x + *w, *y + *h,
158- c2->struts[STRUTS_BOTTOM_START_X], screen_height - c2->struts[STRUTS_BOTTOM],
159- c2->struts[STRUTS_BOTTOM_END_X], screen_height))
160- {
161- delta = (*y + *h) - screen_height + c2->struts[STRUTS_BOTTOM];
162- *h = *h - delta;
163- }
164- }
165- }
166-}
167-
168-gboolean
169-clientCkeckTitle (Client * c)
170-{
171- Client *c2;
172- ScreenInfo *screen_info;
173- guint i;
174- gint frame_x, frame_y, frame_width, frame_top;
175-
176- frame_x = frameX (c);
177- frame_y = frameY (c);
178- frame_width = frameWidth (c);
179- frame_top = frameTop (c);
180-
181- /* Struts and other partial struts */
182- screen_info = c->screen_info;
183- for (c2 = screen_info->clients, i = 0; i < screen_info->client_count; c2 = c2->next, i++)
184- {
185- if ((c2 != c) && clientStrutAreaOverlap (frame_x, frame_y, frame_width, frame_top, c2))
186- {
187- return FALSE;
188- }
189- }
190- return TRUE;
191-}
192-
193-/* clientConstrainPos() is used when moving windows
194- to ensure that the window stays accessible to the user
195-
196- Returns the position in which the window was constrained.
197- CLIENT_CONSTRAINED_TOP = 1<<0
198- CLIENT_CONSTRAINED_BOTTOM = 1<<1
199- CLIENT_CONSTRAINED_LEFT = 1<<2
200- CLIENT_CONSTRAINED_RIGHT = 1<<3
201-
202- */
203-unsigned int
204-clientConstrainPos (Client * c, gboolean show_full)
205-{
206- Client *c2;
207- ScreenInfo *screen_info;
208- guint i;
209- gint cx, cy, disp_x, disp_y, disp_max_x, disp_max_y;
210- gint frame_height, frame_width, frame_top, frame_left;
211- gint frame_x, frame_y, frame_visible;
212- gint screen_width, screen_height;
213- guint ret;
214- GdkRectangle rect;
215- gint min_visible;
216-
217- g_return_val_if_fail (c != NULL, 0);
218- TRACE ("entering clientConstrainPos %s",
219- show_full ? "(with show full)" : "(w/out show full)");
220- TRACE ("client \"%s\" (0x%lx)", c->name, c->window);
221-
222- /* We use a bunch of local vars to reduce the overhead of calling other functions all the time */
223- frame_x = frameX (c);
224- frame_y = frameY (c);
225- frame_height = frameHeight (c);
226- frame_width = frameWidth (c);
227- frame_top = frameTop (c);
228- frame_left = frameLeft (c);
229- frame_visible = (frame_top ? frame_top : frame_height);
230- min_visible = MAX (frame_top, CLIENT_MIN_VISIBLE);
231- ret = 0;
232-
233- cx = frame_x + (frame_width / 2);
234- cy = frame_y + (frame_height / 2);
235-
236- screen_info = c->screen_info;
237- myScreenFindMonitorAtPoint (screen_info, cx, cy, &rect);
238-
239- screen_width = screen_info->width;
240- screen_height = screen_info->height;
241-
242- disp_x = rect.x;
243- disp_y = rect.y;
244- disp_max_x = rect.x + rect.width;
245- disp_max_y = rect.y + rect.height;
246-
247- if (FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
248- {
249- TRACE ("ignoring constrained for client \"%s\" (0x%lx)", c->name,
250- c->window);
251- return 0;
252- }
253- if (show_full)
254- {
255- /* Struts and other partial struts */
256-
257- for (c2 = screen_info->clients, i = 0; i < screen_info->client_count; c2 = c2->next, i++)
258- {
259- if (FLAG_TEST (c2->flags, CLIENT_FLAG_HAS_STRUT)
260- && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE)
261- && (c2 != c))
262- {
263- /* Right */
264- if (segment_overlap (frame_y, frame_y + frame_height,
265- c2->struts[STRUTS_RIGHT_START_Y], c2->struts[STRUTS_RIGHT_END_Y]))
266- {
267- if (segment_overlap (frame_x, frame_x + frame_width,
268- screen_width - c2->struts[STRUTS_RIGHT],
269- screen_width))
270- {
271- c->x = screen_width - c2->struts[STRUTS_RIGHT] - frame_width + frame_left;
272- frame_x = frameX (c);
273- ret |= CLIENT_CONSTRAINED_RIGHT;
274- }
275- }
276-
277- /* Bottom */
278- if (segment_overlap (frame_x, frame_x + frame_width,
279- c2->struts[STRUTS_BOTTOM_START_X], c2->struts[STRUTS_BOTTOM_END_X]))
280- {
281- if (segment_overlap (frame_y, frame_y + frame_height,
282- screen_height - c2->struts[STRUTS_BOTTOM],
283- screen_height))
284- {
285- c->y = screen_height - c2->struts[STRUTS_BOTTOM] - frame_height + frame_top;
286- frame_y = frameY (c);
287- ret |= CLIENT_CONSTRAINED_BOTTOM;
288-
289- }
290- }
291- }
292- }
293-
294- if (frame_x + frame_width >= disp_max_x)
295- {
296- c->x = disp_max_x - frame_width + frame_left;
297- frame_x = frameX (c);
298- ret |= CLIENT_CONSTRAINED_RIGHT;
299- }
300- if (frame_x <= disp_x)
301- {
302- c->x = disp_x + frame_left;
303- frame_x = frameX (c);
304- ret |= CLIENT_CONSTRAINED_LEFT;
305- }
306- if (frame_y + frame_height >= disp_max_y)
307- {
308- c->y = disp_max_y - frame_height + frame_top;
309- frame_y = frameY (c);
310- ret |= CLIENT_CONSTRAINED_BOTTOM;
311- }
312- if (frame_y <= disp_y)
313- {
314- c->y = disp_y + frame_top;
315- frame_y = frameY (c);
316- ret |= CLIENT_CONSTRAINED_TOP;
317- }
318-
319- for (c2 = screen_info->clients, i = 0; i < screen_info->client_count; c2 = c2->next, i++)
320- {
321- if (FLAG_TEST (c2->flags, CLIENT_FLAG_HAS_STRUT)
322- && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE)
323- && (c2 != c))
324- {
325- /* Left */
326- if (segment_overlap (frame_y, frame_y + frame_height,
327- c2->struts[STRUTS_LEFT_START_Y], c2->struts[STRUTS_LEFT_END_Y]))
328- {
329- if (segment_overlap (frame_x, frame_x + frame_width,
330- 0, c2->struts[STRUTS_LEFT]))
331- {
332- c->x = c2->struts[STRUTS_LEFT] + frame_left;
333- frame_x = frameX (c);
334- ret |= CLIENT_CONSTRAINED_LEFT;
335- }
336- }
337-
338- /* Top */
339- if (segment_overlap (frame_x,
340- frame_x + frame_width,
341- c2->struts[STRUTS_TOP_START_X],
342- c2->struts[STRUTS_TOP_END_X]))
343- {
344- if (segment_overlap (frame_y, frame_y + frame_height,
345- 0, c2->struts[STRUTS_TOP]))
346- {
347- c->y = c2->struts[STRUTS_TOP] + frame_top;
348- frame_y = frameY (c);
349- ret |= CLIENT_CONSTRAINED_TOP;
350- }
351- }
352- }
353- }
354- }
355- else
356- {
357- if (frame_x + frame_width <= disp_x + min_visible)
358- {
359- c->x = disp_x + min_visible - frame_width + frame_left;
360- frame_x = frameX (c);
361- ret |= CLIENT_CONSTRAINED_LEFT;
362- }
363- if (frame_x + min_visible >= disp_max_x)
364- {
365- c->x = disp_max_x - min_visible + frame_left;
366- frame_x = frameX (c);
367- ret |= CLIENT_CONSTRAINED_RIGHT;
368- }
369- if (frame_y + frame_height <= disp_y + min_visible)
370- {
371- c->y = disp_y + min_visible - frame_height + frame_top;
372- frame_y = frameY (c);
373- ret |= CLIENT_CONSTRAINED_TOP;
374- }
375- if (frame_y + min_visible >= disp_max_y)
376- {
377- c->y = disp_max_y - min_visible + frame_top;
378- frame_y = frameY (c);
379- ret |= CLIENT_CONSTRAINED_BOTTOM;
380- }
381- if ((frame_y <= disp_y) && (frame_y >= disp_y - frame_top))
382- {
383- c->y = disp_y + frame_top;
384- frame_y = frameY (c);
385- ret |= CLIENT_CONSTRAINED_TOP;
386- }
387- /* Struts and other partial struts */
388- for (c2 = screen_info->clients, i = 0; i < screen_info->client_count; c2 = c2->next, i++)
389- {
390- if (FLAG_TEST (c2->flags, CLIENT_FLAG_HAS_STRUT)
391- && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE)
392- && (c2 != c))
393- {
394- /* Right */
395- if (segment_overlap (frame_y, frame_y + frame_height,
396- c2->struts[STRUTS_RIGHT_START_Y], c2->struts[STRUTS_RIGHT_END_Y]))
397- {
398- if (frame_x >= screen_width - c2->struts[STRUTS_RIGHT] - min_visible)
399- {
400- c->x = screen_width - c2->struts[STRUTS_RIGHT] - min_visible + frame_left;
401- frame_x = frameX (c);
402- ret |= CLIENT_CONSTRAINED_RIGHT;
403- }
404- }
405-
406- /* Left */
407- if (segment_overlap (frame_y, frame_y + frame_height,
408- c2->struts[STRUTS_LEFT_START_Y], c2->struts[STRUTS_LEFT_END_Y]))
409- {
410- if (frame_x + frame_width <= c2->struts[STRUTS_LEFT] + min_visible)
411- {
412- c->x = c2->struts[STRUTS_LEFT] + min_visible - frame_width + frame_left;
413- frame_x = frameX (c);
414- ret |= CLIENT_CONSTRAINED_LEFT;
415- }
416- }
417-
418- /* Bottom */
419- if (segment_overlap (frame_x, frame_x + frame_width,
420- c2->struts[STRUTS_BOTTOM_START_X], c2->struts[STRUTS_BOTTOM_END_X]))
421- {
422- if (frame_y >= screen_height - c2->struts[STRUTS_BOTTOM] - min_visible)
423- {
424- c->y = screen_height - c2->struts[STRUTS_BOTTOM] - min_visible + frame_top;
425- frame_y = frameY (c);
426- ret |= CLIENT_CONSTRAINED_BOTTOM;
427- }
428- }
429-
430- /* Top */
431- if (segment_overlap (frame_x, frame_x + frame_width,
432- c2->struts[STRUTS_TOP_START_X], c2->struts[STRUTS_TOP_END_X]))
433- {
434- if (segment_overlap (frame_y, frame_y + frame_visible, 0, c2->struts[STRUTS_TOP]))
435- {
436- c->y = c2->struts[STRUTS_TOP] + frame_top;
437- frame_y = frameY (c);
438- ret |= CLIENT_CONSTRAINED_TOP;
439- }
440- if (frame_y + frame_height <= c2->struts[STRUTS_TOP] + min_visible)
441- {
442- c->y = c2->struts[STRUTS_TOP] + min_visible - frame_height + frame_top;
443- frame_y = frameY (c);
444- ret |= CLIENT_CONSTRAINED_TOP;
445- }
446- }
447- }
448- }
449- }
450- return ret;
451-}
452-
453-/* clientKeepVisible is used at initial mapping, to make sure
454- the window is visible on screen. It also does coordonate
455- translation in Xinerama to center window on physical screen
456- Not to be confused with clientConstrainPos()
457- */
458-static void
459-clientKeepVisible (Client * c, gint n_monitors, GdkRectangle *monitor_rect)
460-{
461- ScreenInfo *screen_info;
462- GdkRectangle rect;
463- gboolean centered;
464- int diff_x, diff_y;
465- int monitor_nbr;
466-
467- g_return_if_fail (c != NULL);
468- TRACE ("entering clientKeepVisible");
469- TRACE ("client \"%s\" (0x%lx)", c->name, c->window);
470-
471- screen_info = c->screen_info;
472-
473- centered = FALSE;
474- if ((c->size->x == 0) && (c->size->y == 0) && (c->type & (WINDOW_TYPE_DIALOG)))
475- {
476- /* Dialogs that place temselves in (0,0) will be centered */
477- centered = TRUE;
478- }
479- else if (n_monitors > 1)
480- {
481- /* First, check if the window is centered on the whole screen */
482- diff_x = abs (c->size->x - ((c->screen_info->width - c->size->width) / 2));
483- diff_y = abs (c->size->y - ((c->screen_info->height - c->size->height) / 2));
484-
485- monitor_nbr = 0;
486- centered = ((diff_x < 25) && (diff_y < 25));
487-
488- while ((!centered) && (monitor_nbr < n_monitors))
489- {
490- gdk_screen_get_monitor_geometry (screen_info->gscr, monitor_nbr, &rect);
491- diff_x = abs (c->size->x - ((rect.width - c->size->width) / 2));
492- diff_y = abs (c->size->y - ((rect.height - c->size->height) / 2));
493- centered = ((diff_x < 25) && (diff_y < 25));
494- monitor_nbr++;
495- }
496- }
497- if (centered)
498- {
499- /* We consider that the windows is centered on screen,
500- * Thus, will move it so its center on the current
501- * physical screen
502- */
503- c->x = monitor_rect->x + (monitor_rect->width - c->width) / 2;
504- c->y = monitor_rect->y + (monitor_rect->height - c->height) / 2;
505- }
506- clientConstrainPos (c, TRUE);
507-}
508-
509-static void
510-clientAutoMaximize (Client * c, int full_w, int full_h)
511-{
512- if (FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN) ||
513- !FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_BORDER))
514- {
515- /*
516- * Fullscreen or undecorated windows should not be
517- * automatically maximized...
518- */
519- return;
520- }
521-
522- if (!FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ) &&
523- (frameWidth (c) > full_w))
524- {
525- TRACE ("The application \"%s\" has requested a window width "
526- "(%u) larger than the actual width available in the workspace (%u), "
527- "the window will be maximized horizontally.", c->name, frameWidth (c), full_w);
528- FLAG_SET (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ);
529- }
530-
531- if (!FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_VERT) &&
532- (frameHeight (c) > full_h))
533- {
534- TRACE ("The application \"%s\" has requested a window height "
535- "(%u) larger than the actual height available in the workspace (%u), "
536- "the window will be maximized vertically.", c->name, frameHeight (c), full_h);
537- FLAG_SET (c->flags, CLIENT_FLAG_MAXIMIZED_VERT);
538- }
539-}
540-
541-static void
542-smartPlacement (Client * c, int full_x, int full_y, int full_w, int full_h)
543-{
544- Client *c2;
545- ScreenInfo *screen_info;
546- gfloat best_overlaps;
547- guint i;
548- gint test_x, test_y, xmax, ymax, best_x, best_y;
549- gint frame_height, frame_width, frame_left, frame_top;
550- gboolean first;
551- gint c2_x, c2_y;
552-
553- g_return_if_fail (c != NULL);
554- TRACE ("entering smartPlacement");
555-
556- screen_info = c->screen_info;
557- frame_height = frameHeight (c);
558- frame_width = frameWidth (c);
559- frame_left = frameLeft(c);
560- frame_top = frameTop (c);
561- test_x = 0;
562- test_y = 0;
563- best_overlaps = 0.0;
564- first = TRUE;
565-
566- xmax = full_x + full_w - c->width - frameRight (c);
567- ymax = full_y + full_h - c->height - frameBottom (c);
568- best_x = full_x + frameLeft (c);
569- best_y = full_y + frameTop (c);
570-
571- test_y = full_y + frameTop (c);
572- do
573- {
574- test_x = full_x + frameLeft (c);
575- do
576- {
577- gfloat count_overlaps = 0.0;
578- TRACE ("analyzing %i clients", screen_info->client_count);
579- for (c2 = screen_info->clients, i = 0; i < screen_info->client_count; c2 = c2->next, i++)
580- {
581- if ((c2 != c) && (c2->type != WINDOW_DESKTOP)
582- && (c->win_workspace == c2->win_workspace)
583- && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE))
584- {
585- c2_x = frameX (c2);
586- c2_y = frameY (c2);
587-
588- count_overlaps += overlap (test_x - frame_left,
589- test_y - frame_top,
590- test_x - frame_left + frame_width,
591- test_y - frame_top + frame_height,
592- c2_x,
593- c2_y,
594- c2_x + frameWidth (c2),
595- c2_y + frameHeight (c2));
596- }
597- }
598- if (count_overlaps < 0.1)
599- {
600- TRACE ("overlaps is 0 so it's the best we can get");
601- c->x = test_x;
602- c->y = test_y;
603-
604- return;
605- }
606- else if ((count_overlaps < best_overlaps) || (first))
607- {
608- best_x = test_x;
609- best_y = test_y;
610- best_overlaps = count_overlaps;
611- }
612- if (first)
613- {
614- first = FALSE;
615- }
616- test_x += 8;
617- }
618- while (test_x <= xmax);
619- test_y += 8;
620- }
621- while (test_y <= ymax);
622-
623- c->x = best_x;
624- c->y = best_y;
625-}
626-
627-static void
628-centerPlacement (Client * c, int full_x, int full_y, int full_w, int full_h)
629-{
630- g_return_if_fail (c != NULL);
631- TRACE ("entering centerPlacement");
632-
633- c->x = MAX (full_x + frameLeft(c) + (full_w - frameWidth(c)) / 2, full_x + frameLeft(c));
634- c->y = MAX (full_y + frameTop(c) + (full_h - frameHeight(c)) / 2, full_y + frameTop(c));
635-}
636-
637-static void
638-mousePlacement (Client * c, int full_x, int full_y, int full_w, int full_h, int mx, int my)
639-{
640- g_return_if_fail (c != NULL);
641- TRACE ("entering mousePlacement");
642-
643- c->x = mx + frameLeft(c) - frameWidth(c) / 2;
644- c->y = my + frameTop(c) - frameHeight(c) / 2;
645-
646- c->x = MIN (c->x, full_x + full_w - frameWidth(c) + frameLeft(c));
647- c->y = MIN (c->y, full_y + full_h - frameHeight(c) + frameTop(c));
648-
649- c->x = MAX (c->x, full_x + frameLeft(c));
650- c->y = MAX (c->y, full_y + frameTop(c));
651-}
652-
653-void
654-clientInitPosition (Client * c)
655-{
656- ScreenInfo *screen_info;
657- Client *c2;
658- GdkRectangle rect;
659- int full_x, full_y, full_w, full_h, msx, msy;
660- gint n_monitors;
661- gboolean place;
662- gboolean position;
663-
664- g_return_if_fail (c != NULL);
665- TRACE ("entering clientInitPosition");
666-
667- screen_info = c->screen_info;
668- msx = 0;
669- msy = 0;
670- position = (c->size->flags & (PPosition | USPosition));
671-
672- n_monitors = myScreenGetNumMonitors (c->screen_info);
673- if ((n_monitors > 1) || (screen_info->params->placement_mode == PLACE_MOUSE))
674- {
675- getMouseXY (screen_info, screen_info->xroot, &msx, &msy);
676- myScreenFindMonitorAtPoint (screen_info, msx, msy, &rect);
677- }
678- else
679- {
680- gdk_screen_get_monitor_geometry (screen_info->gscr, 0, &rect);
681- }
682- if (position || (c->type & (WINDOW_TYPE_DONT_PLACE | WINDOW_TYPE_DIALOG)) || clientIsTransient (c))
683- {
684- if (!position && clientIsTransient (c) && (c2 = clientGetTransient (c)))
685- {
686- /* Center transient relative to their parent window */
687- c->x = c2->x + (c2->width - c->width) / 2;
688- c->y = c2->y + (c2->height - c->height) / 2;
689-
690- if (n_monitors > 1)
691- {
692- msx = frameX (c) + (frameWidth (c) / 2);
693- msy = frameY (c) + (frameHeight (c) / 2);
694- myScreenFindMonitorAtPoint (screen_info, msx, msy, &rect);
695- }
696- }
697- if (CONSTRAINED_WINDOW (c))
698- {
699- clientKeepVisible (c, n_monitors, &rect);
700- }
701- place = FALSE;
702- }
703- else
704- {
705- place = TRUE;
706- }
707-
708- full_x = MAX (screen_info->params->xfwm_margins[STRUTS_LEFT], rect.x);
709- full_y = MAX (screen_info->params->xfwm_margins[STRUTS_TOP], rect.y);
710- full_w = MIN (screen_info->width - screen_info->params->xfwm_margins[STRUTS_RIGHT],
711- rect.x + rect.width) - full_x;
712- full_h = MIN (screen_info->height - screen_info->params->xfwm_margins[STRUTS_BOTTOM],
713- rect.y + rect.height) - full_y;
714-
715- /* Adjust size to the widest size available, not covering struts */
716- clientMaxSpace (screen_info, &full_x, &full_y, &full_w, &full_h);
717-
718- /*
719- If the windows is smaller than the given ratio of the available screen area,
720- or if the window is larger than the screen area or if the given ratio is higher
721- than 100% place the window at the center.
722- Otherwise, place the window "smartly", using the good old CPU consuming algorithm...
723- */
724- if (place)
725- {
726- if ((screen_info->params->placement_ratio >= 100) ||
727- (100 * frameWidth(c) * frameHeight(c)) < (screen_info->params->placement_ratio * full_w * full_h))
728- {
729- if (screen_info->params->placement_mode == PLACE_MOUSE)
730- {
731- mousePlacement (c, full_x, full_y, full_w, full_h, msx, msy);
732- }
733- else
734- {
735- centerPlacement (c, full_x, full_y, full_w, full_h);
736- }
737- }
738- else if ((frameWidth(c) >= full_w) && (frameHeight(c) >= full_h))
739- {
740- centerPlacement (c, full_x, full_y, full_w, full_h);
741- }
742- else
743- {
744- smartPlacement (c, full_x, full_y, full_w, full_h);
745- }
746- }
747-
748- if (c->type & WINDOW_REGULAR_FOCUSABLE)
749- {
750- clientAutoMaximize (c, full_w, full_h);
751- }
752-}
753-
754-
755-void
756-clientFill (Client * c, int fill_type)
757-{
758- ScreenInfo *screen_info;
759- Client *east_neighbour;
760- Client *west_neighbour;
761- Client *north_neighbour;
762- Client *south_neighbour;
763- Client *c2;
764- GdkRectangle rect;
765- XWindowChanges wc;
766- unsigned short mask;
767- guint i;
768- gint cx, cy, full_x, full_y, full_w, full_h;
769- gint tmp_x, tmp_y, tmp_w, tmp_h;
770-
771- g_return_if_fail (c != NULL);
772- TRACE ("entering clientFill");
773-
774- if (!CLIENT_CAN_FILL_WINDOW (c))
775- {
776- return;
777- }
778-
779- screen_info = c->screen_info;
780- mask = 0;
781- east_neighbour = NULL;
782- west_neighbour = NULL;
783- north_neighbour = NULL;
784- south_neighbour = NULL;
785-
786- for (c2 = screen_info->clients, i = 0; i < screen_info->client_count; c2 = c2->next, i++)
787- {
788-
789- /* Filter out all windows which are not visible, or not on the same layer
790- * as well as the client window itself
791- */
792- if ((c != c2) && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE) && (c2->win_layer == c->win_layer))
793- {
794- /* Fill horizontally */
795- if (fill_type & CLIENT_FILL_HORIZ)
796- {
797- /*
798- * check if the neigbour client (c2) is located
799- * east or west of our client.
800- */
801- if (segment_overlap (frameY(c), frameY(c) + frameHeight(c), frameY(c2), frameY(c2) + frameHeight(c2)))
802- {
803- if ((frameX(c2) + frameWidth(c2)) <= frameX(c))
804- {
805- if (west_neighbour)
806- {
807- /* Check if c2 is closer to the client
808- * then the west neighbour already found
809- */
810- if ((frameX(west_neighbour) + frameWidth(west_neighbour)) < (frameX(c2) + frameWidth(c2)))
811- {
812- west_neighbour = c2;
813- }
814- }
815- else
816- {
817- west_neighbour = c2;
818- }
819- }
820- if ((frameX(c) + frameWidth(c)) <= frameX(c2))
821- {
822- /* Check if c2 is closer to the client
823- * then the west neighbour already found
824- */
825- if (east_neighbour)
826- {
827- if (frameX(c2) < frameX(east_neighbour))
828- {
829- east_neighbour = c2;
830- }
831- }
832- else
833- {
834- east_neighbour = c2;
835- }
836- }
837- }
838- }
839-
840- /* Fill vertically */
841- if (fill_type & CLIENT_FILL_VERT)
842- {
843- /* check if the neigbour client (c2) is located
844- * north or south of our client.
845- */
846- if (segment_overlap (frameX(c), frameX(c) + frameWidth(c), frameX(c2), frameX(c2) + frameWidth(c2)))
847- {
848- if ((frameY(c2) + frameHeight(c2)) <= frameY(c))
849- {
850- if (north_neighbour)
851- {
852- /* Check if c2 is closer to the client
853- * then the north neighbour already found
854- */
855- if ((frameY(north_neighbour) + frameHeight(north_neighbour)) < (frameY(c2) + frameHeight(c2)))
856- {
857- north_neighbour = c2;
858- }
859- }
860- else
861- {
862- north_neighbour = c2;
863- }
864- }
865- if ((frameY(c) + frameHeight(c)) <= frameY(c2))
866- {
867- if (south_neighbour)
868- {
869- /* Check if c2 is closer to the client
870- * then the south neighbour already found
871- */
872- if (frameY(c2) < frameY(south_neighbour))
873- {
874- south_neighbour = c2;
875- }
876- }
877- else
878- {
879- south_neighbour = c2;
880- }
881- }
882- }
883- }
884- }
885- }
886-
887- /* Compute the largest size available, based on struts, margins and Xinerama layout */
888- tmp_x = frameX (c);
889- tmp_y = frameY (c);
890- tmp_h = frameHeight (c);
891- tmp_w = frameWidth (c);
892-
893- cx = tmp_x + (tmp_w / 2);
894- cy = tmp_y + (tmp_h / 2);
895-
896- myScreenFindMonitorAtPoint (screen_info, cx, cy, &rect);
897-
898- full_x = MAX (screen_info->params->xfwm_margins[STRUTS_LEFT], rect.x);
899- full_y = MAX (screen_info->params->xfwm_margins[STRUTS_TOP], rect.y);
900- full_w = MIN (screen_info->width - screen_info->params->xfwm_margins[STRUTS_RIGHT],
901- rect.x + rect.width) - full_x;
902- full_h = MIN (screen_info->height - screen_info->params->xfwm_margins[STRUTS_BOTTOM],
903- rect.y + rect.height) - full_y;
904-
905- if ((fill_type & CLIENT_FILL) == CLIENT_FILL)
906- {
907- mask = CWX | CWY | CWHeight | CWWidth;
908- /* Adjust size to the largest size available, not covering struts */
909- clientMaxSpace (screen_info, &full_x, &full_y, &full_w, &full_h);
910- }
911- else if (fill_type & CLIENT_FILL_VERT)
912- {
913- mask = CWY | CWHeight;
914- /* Adjust size to the tallest size available, for the current horizontal position/width */
915- clientMaxSpace (screen_info, &tmp_x, &full_y, &tmp_w, &full_h);
916- }
917- else if (fill_type & CLIENT_FILL_HORIZ)
918- {
919- mask = CWX | CWWidth;
920- /* Adjust size to the widest size available, for the current vertical position/height */
921- clientMaxSpace (screen_info, &full_x, &tmp_y, &full_w, &tmp_h);
922- }
923-
924- /* If there are neighbours, resize to their borders.
925- * If not, resize to the largest size available that you just have computed.
926- */
927-
928- wc.x = full_x + frameLeft(c);
929- if (west_neighbour)
930- {
931- wc.x += MAX (frameX(west_neighbour) + frameWidth(west_neighbour) - full_x, 0);
932- }
933-
934- wc.width = full_w - frameRight(c) - (wc.x - full_x);
935- if (east_neighbour)
936- {
937- wc.width -= MAX (full_w - (frameX(east_neighbour) - full_x), 0);
938- }
939-
940- wc.y = full_y + frameTop(c);
941- if (north_neighbour)
942- {
943- wc.y += MAX (frameY(north_neighbour) + frameHeight(north_neighbour) - full_y, 0);
944- }
945-
946- wc.height = full_h - frameBottom(c) - (wc.y - full_y);
947- if (south_neighbour)
948- {
949- wc.height -= MAX (full_h - (frameY(south_neighbour) - full_y), 0);
950- }
951-
952- TRACE ("Fill size request: (%d,%d) %dx%d", wc.x, wc.y, wc.width, wc.height);
953- if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MANAGED))
954- {
955- clientConfigure(c, &wc, mask, NO_CFG_FLAG);
956- }
957-}
958-
959
960=== removed directory '.pc/8563.patch'
961=== removed directory '.pc/8563.patch/src'
962=== removed file '.pc/8563.patch/src/client.c'
963--- .pc/8563.patch/src/client.c 2013-12-03 15:24:16 +0000
964+++ .pc/8563.patch/src/client.c 1970-01-01 00:00:00 +0000
965@@ -1,3926 +0,0 @@
966-/* $Id$
967-
968- This program is free software; you can redistribute it and/or modify
969- it under the terms of the GNU General Public License as published by
970- the Free Software Foundation; either version 2, or (at your option)
971- any later version.
972-
973- This program is distributed in the hope that it will be useful,
974- but WITHOUT ANY WARRANTY; without even the implied warranty of
975- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
976- GNU General Public License for more details.
977-
978- You should have received a copy of the GNU General Public License
979- along with this program; if not, write to the Free Software
980- Foundation, Inc., Inc., 51 Franklin Street, Fifth Floor, Boston,
981- MA 02110-1301, USA.
982-
983-
984- oroborus - (c) 2001 Ken Lynch
985- xfwm4 - (c) 2002-2011 Olivier Fourdan
986-
987- */
988-
989-#ifdef HAVE_CONFIG_H
990-#include "config.h"
991-#endif
992-
993-#include <sys/types.h>
994-#include <signal.h>
995-#include <unistd.h>
996-#include <errno.h>
997-
998-#include <X11/X.h>
999-#include <X11/Xlib.h>
1000-#include <X11/Xutil.h>
1001-#include <X11/Xatom.h>
1002-#include <X11/extensions/shape.h>
1003-
1004-#include <glib.h>
1005-#include <gdk/gdk.h>
1006-#include <gdk/gdkx.h>
1007-#include <gtk/gtk.h>
1008-#include <libxfce4util/libxfce4util.h>
1009-
1010-#include "client.h"
1011-#include "compositor.h"
1012-#include "focus.h"
1013-#include "frame.h"
1014-#include "hints.h"
1015-#include "icons.h"
1016-#include "misc.h"
1017-#include "moveresize.h"
1018-#include "mypixmap.h"
1019-#include "mywindow.h"
1020-#include "netwm.h"
1021-#include "placement.h"
1022-#include "screen.h"
1023-#include "session.h"
1024-#include "settings.h"
1025-#include "stacking.h"
1026-#include "startup_notification.h"
1027-#include "transients.h"
1028-#include "workspaces.h"
1029-#include "xsync.h"
1030-#include "event_filter.h"
1031-
1032-/* Event mask definition */
1033-
1034-#define POINTER_EVENT_MASK \
1035- ButtonPressMask|\
1036- ButtonReleaseMask
1037-
1038-#define FRAME_EVENT_MASK \
1039- SubstructureNotifyMask|\
1040- SubstructureRedirectMask|\
1041- PointerMotionMask|\
1042- ButtonMotionMask|\
1043- FocusChangeMask|\
1044- EnterWindowMask|\
1045- PropertyChangeMask
1046-
1047-#define CLIENT_EVENT_MASK \
1048- StructureNotifyMask|\
1049- FocusChangeMask|\
1050- PropertyChangeMask
1051-
1052-#define BUTTON_EVENT_MASK \
1053- EnterWindowMask|\
1054- LeaveWindowMask
1055-
1056-/* Useful macros */
1057-#define START_ICONIC(c) \
1058- ((c->wmhints) && \
1059- (c->wmhints->initial_state == IconicState) && \
1060- !clientIsTransientOrModal (c))
1061-
1062-#define OPACITY_SET_STEP (guint) 0x16000000
1063-#define OPACITY_SET_MIN (guint) 0x40000000
1064-
1065-typedef struct _ButtonPressData ButtonPressData;
1066-struct _ButtonPressData
1067-{
1068- int b;
1069- Client *c;
1070-};
1071-
1072-/* Forward decl */
1073-static void
1074-clientUpdateIconPix (Client *c);
1075-static gboolean
1076-clientNewMaxSize (Client *c, XWindowChanges *wc, GdkRectangle *, tilePositionType tile);
1077-
1078-Display *
1079-clientGetXDisplay (Client *c)
1080-{
1081- g_return_val_if_fail (c, NULL);
1082-
1083- return myScreenGetXDisplay (c->screen_info);
1084-}
1085-
1086-void
1087-clientInstallColormaps (Client *c)
1088-{
1089- XWindowAttributes attr;
1090- gboolean installed;
1091- int i;
1092-
1093- g_return_if_fail (c != NULL);
1094- TRACE ("entering clientInstallColormaps");
1095-
1096- installed = FALSE;
1097- if (c->ncmap)
1098- {
1099- for (i = c->ncmap - 1; i >= 0; i--)
1100- {
1101- XGetWindowAttributes (clientGetXDisplay (c), c->cmap_windows[i], &attr);
1102- XInstallColormap (clientGetXDisplay (c), attr.colormap);
1103- if (c->cmap_windows[i] == c->window)
1104- {
1105- installed = TRUE;
1106- }
1107- }
1108- }
1109- if ((!installed) && (c->cmap))
1110- {
1111- XInstallColormap (clientGetXDisplay (c), c->cmap);
1112- }
1113-}
1114-
1115-void
1116-clientUpdateColormaps (Client *c)
1117-{
1118- g_return_if_fail (c != NULL);
1119- TRACE ("entering clientUpdateColormaps");
1120-
1121- if (c->ncmap)
1122- {
1123- XFree (c->cmap_windows);
1124- c->ncmap = 0;
1125- }
1126- if (!XGetWMColormapWindows (clientGetXDisplay (c), c->window, &c->cmap_windows, &c->ncmap))
1127- {
1128- c->cmap_windows = NULL;
1129- c->ncmap = 0;
1130- }
1131-}
1132-
1133-static gchar*
1134-clientCreateTitleName (Client *c, gchar *name, gchar *hostname)
1135-{
1136- ScreenInfo *screen_info;
1137- DisplayInfo *display_info;
1138- gchar *title;
1139-
1140- g_return_val_if_fail (c != NULL, NULL);
1141- TRACE ("entering clientCreateTitleName");
1142-
1143- screen_info = c->screen_info;
1144- display_info = screen_info->display_info;
1145-
1146- if (strlen (hostname) && (display_info->hostname) && (g_ascii_strcasecmp (display_info->hostname, hostname)))
1147- {
1148- /* TRANSLATORS: "(on %s)" is like "running on" the name of the other host */
1149- title = g_strdup_printf (_("%s (on %s)"), name, hostname);
1150- }
1151- else
1152- {
1153- title = g_strdup (name);
1154- }
1155-
1156- return title;
1157-}
1158-
1159-void
1160-clientUpdateName (Client *c)
1161-{
1162- ScreenInfo *screen_info;
1163- DisplayInfo *display_info;
1164- gchar *hostname;
1165- gchar *wm_name;
1166- gchar *name;
1167- gboolean refresh;
1168-
1169- g_return_if_fail (c != NULL);
1170- TRACE ("entering clientUpdateName");
1171-
1172- screen_info = c->screen_info;
1173- display_info = screen_info->display_info;
1174-
1175- getWindowName (display_info, c->window, &wm_name);
1176- getWindowHostname (display_info, c->window, &hostname);
1177- refresh = FALSE;
1178-
1179- /* Update hostname too, as it's used when terminating a client */
1180- if (hostname)
1181- {
1182- if (c->hostname)
1183- {
1184- g_free (c->hostname);
1185- }
1186- c->hostname = hostname;
1187- }
1188-
1189- if (wm_name)
1190- {
1191- name = clientCreateTitleName (c, wm_name, hostname);
1192- g_free (wm_name);
1193- if (c->name)
1194- {
1195- if (strcmp (name, c->name))
1196- {
1197- refresh = TRUE;
1198- FLAG_SET (c->flags, CLIENT_FLAG_NAME_CHANGED);
1199- }
1200- g_free (c->name);
1201- }
1202- c->name = name;
1203- }
1204-
1205- if (refresh)
1206- {
1207- frameQueueDraw (c, TRUE);
1208- }
1209-}
1210-
1211-void
1212-clientUpdateAllFrames (ScreenInfo *screen_info, int mask)
1213-{
1214- Client *c;
1215- XWindowChanges wc;
1216- guint i;
1217-
1218- g_return_if_fail (screen_info != NULL);
1219-
1220- TRACE ("entering clientRedrawAllFrames");
1221- for (c = screen_info->clients, i = 0; i < screen_info->client_count; c = c->next, i++)
1222- {
1223- unsigned long configure_flags = 0L;
1224-
1225- if (mask & UPDATE_BUTTON_GRABS)
1226- {
1227- clientUngrabButtons (c);
1228- clientGrabButtons (c);
1229- clientGrabMouseButton (c);
1230- }
1231- if (mask & UPDATE_CACHE)
1232- {
1233- clientUpdateIconPix (c);
1234- }
1235- if (mask & UPDATE_GRAVITY)
1236- {
1237- clientCoordGravitate (c, c->gravity, REMOVE, &c->x, &c->y);
1238- clientCoordGravitate (c, c->gravity, APPLY, &c->x, &c->y);
1239- setNetFrameExtents (screen_info->display_info,
1240- c->window,
1241- frameTop (c),
1242- frameLeft (c),
1243- frameRight (c),
1244- frameBottom (c));
1245- configure_flags |= CFG_FORCE_REDRAW;
1246- mask &= ~UPDATE_FRAME;
1247- }
1248- if (mask & UPDATE_MAXIMIZE)
1249- {
1250- unsigned long maximization_flags = 0L;
1251-
1252- /* Recompute size and position of maximized windows */
1253- if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ | CLIENT_FLAG_MAXIMIZED_VERT))
1254- {
1255- maximization_flags = c->flags & CLIENT_FLAG_MAXIMIZED;
1256-
1257- /* Force an update by clearing the internal flags */
1258- FLAG_UNSET (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ | CLIENT_FLAG_MAXIMIZED_VERT);
1259- clientToggleMaximized (c, maximization_flags, FALSE);
1260-
1261- configure_flags |= CFG_FORCE_REDRAW;
1262- mask &= ~UPDATE_FRAME;
1263- }
1264- }
1265- if (configure_flags != 0L)
1266- {
1267- wc.x = c->x;
1268- wc.y = c->y;
1269- wc.width = c->width;
1270- wc.height = c->height;
1271- clientConfigure (c, &wc, CWX | CWY | CWWidth | CWHeight, configure_flags);
1272- }
1273- if (mask & UPDATE_FRAME)
1274- {
1275- frameQueueDraw (c, TRUE);
1276- }
1277-
1278- }
1279-}
1280-
1281-void
1282-clientGrabButtons (Client *c)
1283-{
1284- ScreenInfo *screen_info;
1285-
1286- g_return_if_fail (c != NULL);
1287- TRACE ("entering clientGrabButtons");
1288- TRACE ("grabbing buttons for client \"%s\" (0x%lx)", c->name, c->window);
1289-
1290- screen_info = c->screen_info;
1291- if (screen_info->params->easy_click)
1292- {
1293- grabButton(clientGetXDisplay (c), AnyButton, screen_info->params->easy_click, c->window);
1294- }
1295-}
1296-
1297-void
1298-clientUngrabButtons (Client *c)
1299-{
1300- g_return_if_fail (c != NULL);
1301- TRACE ("entering clientUngrabButtons");
1302- TRACE ("grabbing buttons for client \"%s\" (0x%lx)", c->name, c->window);
1303-
1304- XUngrabButton (clientGetXDisplay (c), AnyButton, AnyModifier, c->window);
1305-}
1306-
1307-static gboolean
1308-urgent_cb (gpointer data)
1309-{
1310- Client *c;
1311- ScreenInfo *screen_info;
1312-
1313- c = (Client *) data;
1314- g_return_val_if_fail (c != NULL, FALSE);
1315- TRACE ("entering urgent_cb, iteration %i", c->blink_iterations);
1316- screen_info = c->screen_info;
1317-
1318- if (c != clientGetFocus ())
1319- {
1320- /*
1321- * If we do not blink on urgency, check if the window was last
1322- * drawn focused and redraw it unfocused.
1323- * This is for th case when the tuser changes the settings
1324- * in between two redraws.
1325- */
1326- if (!screen_info->params->urgent_blink)
1327- {
1328- if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_SEEN_ACTIVE))
1329- {
1330- FLAG_TOGGLE (c->xfwm_flags, XFWM_FLAG_SEEN_ACTIVE);
1331- frameQueueDraw (c, FALSE);
1332- }
1333-
1334- if (c->blink_iterations)
1335- {
1336- c->blink_iterations = 0;
1337- }
1338- return TRUE;
1339- }
1340- /*
1341- * If we blink on urgency, check if we've not reach the number
1342- * of iterations and if not, simply change the status and redraw
1343- */
1344- if (c->blink_iterations < (2 * MAX_BLINK_ITERATIONS))
1345- {
1346- c->blink_iterations++;
1347- FLAG_TOGGLE (c->xfwm_flags, XFWM_FLAG_SEEN_ACTIVE);
1348- frameQueueDraw (c, FALSE);
1349- return TRUE;
1350- }
1351- /*
1352- * If we reached the max number of iterations, check if we
1353- * repeat. If repeat_urgent_blink is set, redraw the frame and
1354- * restart counting from 1
1355- */
1356- if (screen_info->params->repeat_urgent_blink)
1357- {
1358- FLAG_TOGGLE (c->xfwm_flags, XFWM_FLAG_SEEN_ACTIVE);
1359- frameQueueDraw (c, FALSE);
1360- c->blink_iterations = 1;
1361- return TRUE;
1362- }
1363- }
1364- else if (c->blink_iterations)
1365- {
1366- c->blink_iterations = 0;
1367- }
1368- return (TRUE);
1369-}
1370-
1371-void
1372-clientUpdateUrgency (Client *c)
1373-{
1374- g_return_if_fail (c != NULL);
1375-
1376- TRACE ("entering clientUpdateUrgency");
1377-
1378- FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_SEEN_ACTIVE);
1379- if (c->blink_timeout_id)
1380- {
1381- g_source_remove (c->blink_timeout_id);
1382- frameQueueDraw (c, FALSE);
1383- }
1384- FLAG_UNSET (c->wm_flags, WM_FLAG_URGENT);
1385-
1386- c->blink_timeout_id = 0;
1387- c->blink_iterations = 0;
1388- if ((c->wmhints) && (c->wmhints->flags & XUrgencyHint))
1389- {
1390- FLAG_SET (c->wm_flags, WM_FLAG_URGENT);
1391- if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE))
1392- {
1393- c->blink_timeout_id =
1394- g_timeout_add_full (G_PRIORITY_DEFAULT,
1395- CLIENT_BLINK_TIMEOUT,
1396- (GtkFunction) urgent_cb,
1397- (gpointer) c, NULL);
1398- }
1399- }
1400- if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_SEEN_ACTIVE)
1401- && !FLAG_TEST (c->wm_flags, WM_FLAG_URGENT)
1402- && (c != clientGetFocus ()))
1403- {
1404- FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_SEEN_ACTIVE);
1405- frameQueueDraw (c, FALSE);
1406- }
1407-}
1408-
1409-void
1410-clientCoordGravitate (Client *c, int gravity, int mode, int *x, int *y)
1411-{
1412- int dx, dy;
1413-
1414- g_return_if_fail (c != NULL);
1415- TRACE ("entering clientCoordGravitate");
1416-
1417- switch (gravity)
1418- {
1419- case CenterGravity:
1420- dx = (c->border_width * 2) - ((frameLeft (c) +
1421- frameRight (c)) / 2);
1422- dy = (c->border_width * 2) - ((frameTop (c) +
1423- frameBottom (c)) / 2);
1424- break;
1425- case NorthGravity:
1426- dx = (c->border_width * 2) - ((frameLeft (c) +
1427- frameRight (c)) / 2);
1428- dy = frameTop (c);
1429- break;
1430- case SouthGravity:
1431- dx = (c->border_width * 2) - ((frameLeft (c) +
1432- frameRight (c)) / 2);
1433- dy = (c->border_width * 2) - frameBottom (c);
1434- break;
1435- case EastGravity:
1436- dx = (c->border_width * 2) - frameRight (c);
1437- dy = (c->border_width * 2) - ((frameTop (c) +
1438- frameBottom (c)) / 2);
1439- break;
1440- case WestGravity:
1441- dx = frameLeft (c);
1442- dy = (c->border_width * 2) - ((frameTop (c) +
1443- frameBottom (c)) / 2);
1444- break;
1445- case NorthWestGravity:
1446- dx = frameLeft (c);
1447- dy = frameTop (c);
1448- break;
1449- case NorthEastGravity:
1450- dx = (c->border_width * 2) - frameRight (c);
1451- dy = frameTop (c);
1452- break;
1453- case SouthWestGravity:
1454- dx = frameLeft (c);
1455- dy = (c->border_width * 2) - frameBottom (c);
1456- break;
1457- case SouthEastGravity:
1458- dx = (c->border_width * 2) - frameRight (c);
1459- dy = (c->border_width * 2) - frameBottom (c);
1460- break;
1461- default:
1462- dx = 0;
1463- dy = 0;
1464- break;
1465- }
1466- *x = *x + (dx * mode);
1467- *y = *y + (dy * mode);
1468-}
1469-
1470-void
1471-clientAdjustCoordGravity (Client *c, int gravity, unsigned long *mask, XWindowChanges *wc)
1472-{
1473- int tx, ty, dw, dh;
1474-
1475- g_return_if_fail (c != NULL);
1476- TRACE ("entering clientAdjustCoordGravity");
1477-
1478- tx = wc->x;
1479- ty = wc->y;
1480- clientCoordGravitate (c, gravity, APPLY, &tx, &ty);
1481-
1482- switch (gravity)
1483- {
1484- case CenterGravity:
1485- dw = (c->width - wc->width) / 2;
1486- dh = (c->height - wc->height) / 2;
1487- break;
1488- case NorthGravity:
1489- dw = (c->width - wc->width) / 2;
1490- dh = 0;
1491- break;
1492- case SouthGravity:
1493- dw = (c->width - wc->width) / 2;
1494- dh = (c->height - wc->height);
1495- break;
1496- case EastGravity:
1497- dw = (c->width - wc->width);
1498- dh = (c->height - wc->height) / 2;
1499- break;
1500- case WestGravity:
1501- dw = 0;
1502- dh = (c->height - wc->height) / 2;
1503- break;
1504- case NorthWestGravity:
1505- dw = 0;
1506- dh = 0;
1507- break;
1508- case NorthEastGravity:
1509- dw = (c->width - wc->width);
1510- dh = 0;
1511- break;
1512- case SouthWestGravity:
1513- dw = 0;
1514- dh = (c->height - wc->height);
1515- break;
1516- case SouthEastGravity:
1517- dw = (c->width - wc->width);
1518- dh = (c->height - wc->height);
1519- break;
1520- default:
1521- dw = 0;
1522- dh = 0;
1523- break;
1524- }
1525-
1526- if (*mask & CWX)
1527- {
1528- wc->x = tx;
1529- }
1530- else if (*mask & CWWidth)
1531- {
1532- wc->x = c->x + dw;
1533- *mask |= CWX;
1534- }
1535-
1536- if (*mask & CWY)
1537- {
1538- wc->y = ty;
1539- }
1540- else if (*mask & CWHeight)
1541- {
1542- wc->y = c->y + dh;
1543- *mask |= CWY;
1544- }
1545-}
1546-
1547-#define WIN_MOVED (mask & (CWX | CWY))
1548-#define WIN_RESIZED (mask & (CWWidth | CWHeight))
1549-
1550-static void
1551-clientConfigureWindows (Client *c, XWindowChanges * wc, unsigned long mask, unsigned short flags)
1552-{
1553- unsigned long change_mask_frame, change_mask_client;
1554- XWindowChanges change_values;
1555- DisplayInfo *display_info;
1556- ScreenInfo *screen_info;
1557-
1558- screen_info = c->screen_info;
1559- display_info = screen_info->display_info;
1560-
1561- change_mask_frame = mask & (CWX | CWY | CWWidth | CWHeight);
1562- change_mask_client = mask & (CWWidth | CWHeight);
1563-
1564- if ((WIN_RESIZED) || (flags & CFG_FORCE_REDRAW))
1565- {
1566- frameDraw (c, (flags & CFG_FORCE_REDRAW));
1567- }
1568-
1569- if (flags & CFG_FORCE_REDRAW)
1570- {
1571- change_mask_client |= (CWX | CWY);
1572- }
1573-
1574- if (change_mask_frame & (CWX | CWY | CWWidth | CWHeight))
1575- {
1576- change_values.x = frameX (c);
1577- change_values.y = frameY (c);
1578- change_values.width = frameWidth (c);
1579- change_values.height = frameHeight (c);
1580- XConfigureWindow (display_info->dpy, c->frame, change_mask_frame, &change_values);
1581- }
1582-
1583- if (change_mask_client & (CWX | CWY | CWWidth | CWHeight))
1584- {
1585- change_values.x = frameLeft (c);
1586- change_values.y = frameTop (c);
1587- change_values.width = c->width;
1588- change_values.height = c->height;
1589- XConfigureWindow (display_info->dpy, c->window, change_mask_client, &change_values);
1590- }
1591- if (WIN_RESIZED)
1592- {
1593- compositorResizeWindow (display_info, c->frame, frameX (c), frameY (c), frameWidth (c), frameHeight (c));
1594- }
1595-}
1596-
1597-void
1598-clientConfigure (Client *c, XWindowChanges * wc, unsigned long mask, unsigned short flags)
1599-{
1600- XConfigureEvent ce;
1601- int px, py, pwidth, pheight;
1602-
1603- g_return_if_fail (c != NULL);
1604- g_return_if_fail (c->window != None);
1605-
1606- TRACE ("entering clientConfigure");
1607- TRACE ("configuring client \"%s\" (0x%lx) %s, type %u", c->name,
1608- c->window, flags & CFG_CONSTRAINED ? "constrained" : "not contrained", c->type);
1609-
1610- px = c->x;
1611- py = c->y;
1612- pwidth = c->width;
1613- pheight = c->height;
1614-
1615- if (mask & CWX)
1616- {
1617- if (!FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MOVING_RESIZING))
1618- {
1619- c->x = wc->x;
1620- }
1621- }
1622- if (mask & CWY)
1623- {
1624- if (!FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MOVING_RESIZING))
1625- {
1626- c->y = wc->y;
1627- }
1628- }
1629- if (mask & CWWidth)
1630- {
1631- clientSetWidth (c, wc->width, flags & CFG_REQUEST);
1632- }
1633- if (mask & CWHeight)
1634- {
1635- clientSetHeight (c, wc->height, flags & CFG_REQUEST);
1636- }
1637- if (mask & CWBorderWidth)
1638- {
1639- c->border_width = wc->border_width;
1640- }
1641- if (mask & CWStackMode)
1642- {
1643- switch (wc->stack_mode)
1644- {
1645- /*
1646- * Limitation: we don't support neither
1647- * TopIf, BottomIf nor Opposite ...
1648- */
1649- case Above:
1650- TRACE ("Above");
1651- if (mask & CWSibling)
1652- {
1653- clientRaise (c, wc->sibling);
1654- }
1655- else
1656- {
1657- clientRaise (c, None);
1658- }
1659- break;
1660- case Below:
1661- TRACE ("Below");
1662- if (mask & CWSibling)
1663- {
1664- clientLower (c, wc->sibling);
1665- }
1666- else
1667- {
1668- clientLower (c, None);
1669- }
1670-
1671- break;
1672- case Opposite:
1673- case TopIf:
1674- case BottomIf:
1675- default:
1676- break;
1677- }
1678- }
1679- mask &= ~(CWStackMode | CWSibling);
1680-
1681- /* Keep control over what the application does. */
1682- if (((flags & (CFG_CONSTRAINED | CFG_REQUEST)) == (CFG_CONSTRAINED | CFG_REQUEST))
1683- && CONSTRAINED_WINDOW (c))
1684- {
1685- clientConstrainPos (c, flags & CFG_KEEP_VISIBLE);
1686-
1687- if (c->x != px)
1688- {
1689- mask |= CWX;
1690- }
1691- else
1692- {
1693- mask &= ~CWX;
1694- }
1695-
1696- if (c->y != py)
1697- {
1698- mask |= CWY;
1699- }
1700- else
1701- {
1702- mask &= ~CWY;
1703- }
1704-
1705- if (c->width != pwidth)
1706- {
1707- mask |= CWWidth;
1708- }
1709- else
1710- {
1711- mask &= ~CWWidth;
1712- }
1713- if (c->height != pheight)
1714- {
1715- mask |= CWHeight;
1716- }
1717- else
1718- {
1719- mask &= ~CWHeight;
1720- }
1721- }
1722-
1723- clientConfigureWindows (c, wc, mask, flags);
1724- /*
1725-
1726- We reparent the client window. According to the ICCCM spec, the
1727- WM must send a senthetic event when the window is moved and not resized.
1728-
1729- But, since we reparent the window, we must also send a synthetic
1730- configure event when the window is moved and resized.
1731-
1732- See this thread for the rational:
1733- http://www.mail-archive.com/wm-spec-list@gnome.org/msg00379.html
1734-
1735- And specifically this post from Carsten Haitzler:
1736- http://www.mail-archive.com/wm-spec-list@gnome.org/msg00382.html
1737-
1738- */
1739- if ((WIN_MOVED) || (flags & CFG_NOTIFY) ||
1740- ((flags & CFG_REQUEST) && !(WIN_MOVED || WIN_RESIZED)))
1741- {
1742- DBG ("Sending ConfigureNotify");
1743- ce.type = ConfigureNotify;
1744- ce.display = clientGetXDisplay (c);
1745- ce.event = c->window;
1746- ce.window = c->window;
1747- ce.x = c->x;
1748- ce.y = c->y;
1749- ce.width = c->width;
1750- ce.height = c->height;
1751- ce.border_width = 0;
1752- ce.above = c->frame;
1753- ce.override_redirect = FALSE;
1754- XSendEvent (clientGetXDisplay (c), c->window, FALSE,
1755- StructureNotifyMask, (XEvent *) & ce);
1756- }
1757-#undef WIN_MOVED
1758-#undef WIN_RESIZED
1759-}
1760-
1761-void
1762-clientMoveResizeWindow (Client *c, XWindowChanges * wc, unsigned long mask)
1763-{
1764- ScreenInfo *screen_info;
1765- DisplayInfo *display_info;
1766- unsigned short flags;
1767-
1768- g_return_if_fail (c != NULL);
1769- TRACE ("entering clientMoveResizeWindow");
1770- TRACE ("client \"%s\" (0x%lx)", c->name, c->window);
1771-
1772- screen_info = c->screen_info;
1773- display_info = screen_info->display_info;
1774- if (c->type == WINDOW_DESKTOP)
1775- {
1776- /* Ignore stacking request for DESKTOP windows */
1777- mask &= ~(CWSibling | CWStackMode);
1778- }
1779- if (FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN)
1780- || (FLAG_TEST_ALL (c->flags, CLIENT_FLAG_MAXIMIZED)
1781- && (screen_info->params->borderless_maximize)))
1782- {
1783- /* Not allowed in fullscreen or maximzed mode */
1784- mask &= ~(CWX | CWY | CWWidth | CWHeight);
1785- }
1786- /*clean up buggy requests that set all flags */
1787- if ((mask & CWX) && (wc->x == c->x))
1788- {
1789- mask &= ~CWX;
1790- }
1791- if ((mask & CWY) && (wc->y == c->y))
1792- {
1793- mask &= ~CWY;
1794- }
1795- if ((mask & CWWidth) && (wc->width == c->width))
1796- {
1797- mask &= ~CWWidth;
1798- }
1799- if ((mask & CWHeight) && (wc->height == c->height))
1800- {
1801- mask &= ~CWHeight;
1802- }
1803-
1804- /* Still a move/resize after cleanup? */
1805- flags = CFG_REQUEST;
1806- if (mask & (CWX | CWY | CWWidth | CWHeight))
1807- {
1808- /* Clear any previously saved pos flag from screen resize */
1809- FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_SAVED_POS);
1810-
1811- if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED))
1812- {
1813- clientRemoveMaximizeFlag (c);
1814- }
1815-
1816- flags |= CFG_REQUEST | CFG_CONSTRAINED;
1817- }
1818- if ((mask & (CWWidth | CWHeight)) && !(mask & (CWX | CWY)))
1819- {
1820- /*
1821- * The client is resizing its window, but did not specify a
1822- * position, make sure the window remains fully visible in that
1823- *case so that the user does not have to relocate the window
1824- */
1825- flags |= CFG_KEEP_VISIBLE;
1826- }
1827- /*
1828- * Let's say that if the client performs a XRaiseWindow, we show the window if focus
1829- * stealing prevention is not activated, otherwise we just set the "demands attention"
1830- * flag...
1831- */
1832- if ((mask & CWStackMode) && (wc->stack_mode == Above) && (wc->sibling == None) && !(c->type & WINDOW_TYPE_DONT_FOCUS))
1833- {
1834- Client *last_raised;
1835-
1836- last_raised = clientGetLastRaise (screen_info);
1837- if (last_raised && (c != last_raised))
1838- {
1839- if ((screen_info->params->prevent_focus_stealing) && (screen_info->params->activate_action == ACTIVATE_ACTION_NONE))
1840- {
1841- mask &= ~(CWSibling | CWStackMode);
1842- TRACE ("Setting WM_STATE_DEMANDS_ATTENTION flag on \"%s\" (0x%lx)", c->name, c->window);
1843- FLAG_SET (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION);
1844- clientSetNetState (c);
1845- }
1846- else
1847- {
1848- clientActivate (c, getXServerTime (display_info), FALSE);
1849- }
1850- }
1851- }
1852- /* And finally, configure the window */
1853- clientConfigure (c, wc, mask, flags);
1854-}
1855-
1856-void
1857-clientGetMWMHints (Client *c, gboolean update)
1858-{
1859- ScreenInfo *screen_info;
1860- DisplayInfo *display_info;
1861- PropMwmHints *mwm_hints;
1862- XWindowChanges wc;
1863-
1864- g_return_if_fail (c != NULL);
1865- g_return_if_fail (c->window != None);
1866-
1867- TRACE ("entering clientGetMWMHints client \"%s\" (0x%lx)", c->name,
1868- c->window);
1869-
1870- screen_info = c->screen_info;
1871- display_info = screen_info->display_info;
1872-
1873- mwm_hints = getMotifHints (display_info, c->window);
1874- if (mwm_hints)
1875- {
1876- if ((mwm_hints->flags & MWM_HINTS_DECORATIONS))
1877- {
1878- if (!FLAG_TEST (c->flags, CLIENT_FLAG_HAS_SHAPE))
1879- {
1880- if (mwm_hints->decorations & MWM_DECOR_ALL)
1881- {
1882- FLAG_SET (c->xfwm_flags, XFWM_FLAG_HAS_BORDER | XFWM_FLAG_HAS_MENU);
1883- }
1884- else
1885- {
1886- FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_HAS_BORDER | XFWM_FLAG_HAS_MENU);
1887- FLAG_SET (c->xfwm_flags, (mwm_hints-> decorations & (MWM_DECOR_TITLE | MWM_DECOR_BORDER))
1888- ? XFWM_FLAG_HAS_BORDER : 0);
1889- FLAG_SET (c->xfwm_flags, (mwm_hints->decorations & (MWM_DECOR_MENU))
1890- ? XFWM_FLAG_HAS_MENU : 0);
1891- /*
1892- FLAG_UNSET(c->xfwm_flags, XFWM_FLAG_HAS_HIDE);
1893- FLAG_UNSET(c->xfwm_flags, XFWM_FLAG_HAS_MAXIMIZE);
1894- FLAG_SET(c->xfwm_flags, (mwm_hints->decorations & (MWM_DECOR_MINIMIZE)) ? XFWM_FLAG_HAS_HIDE : 0);
1895- FLAG_SET(c->xfwm_flags, (mwm_hints->decorations & (MWM_DECOR_MAXIMIZE)) ? XFWM_FLAG_HAS_MAXIMIZE : 0);
1896- */
1897- }
1898- }
1899- }
1900- /* The following is from Metacity : */
1901- if (mwm_hints->flags & MWM_HINTS_FUNCTIONS)
1902- {
1903- if (!(mwm_hints->functions & MWM_FUNC_ALL))
1904- {
1905- FLAG_UNSET (c->xfwm_flags,
1906- XFWM_FLAG_HAS_CLOSE | XFWM_FLAG_HAS_HIDE |
1907- XFWM_FLAG_HAS_MAXIMIZE | XFWM_FLAG_HAS_MOVE |
1908- XFWM_FLAG_HAS_RESIZE);
1909- }
1910- else
1911- {
1912- FLAG_SET (c->xfwm_flags,
1913- XFWM_FLAG_HAS_CLOSE | XFWM_FLAG_HAS_HIDE |
1914- XFWM_FLAG_HAS_MAXIMIZE | XFWM_FLAG_HAS_MOVE |
1915- XFWM_FLAG_HAS_RESIZE);
1916- }
1917-
1918- if (mwm_hints->functions & MWM_FUNC_CLOSE)
1919- {
1920- FLAG_TOGGLE (c->xfwm_flags, XFWM_FLAG_HAS_CLOSE);
1921- }
1922- if (mwm_hints->functions & MWM_FUNC_MINIMIZE)
1923- {
1924- FLAG_TOGGLE (c->xfwm_flags, XFWM_FLAG_HAS_HIDE);
1925- }
1926- if (mwm_hints->functions & MWM_FUNC_MAXIMIZE)
1927- {
1928- FLAG_TOGGLE (c->xfwm_flags, XFWM_FLAG_HAS_MAXIMIZE);
1929- }
1930- if (mwm_hints->functions & MWM_FUNC_RESIZE)
1931- {
1932- FLAG_TOGGLE (c->xfwm_flags, XFWM_FLAG_HAS_RESIZE);
1933- }
1934- if (mwm_hints->functions & MWM_FUNC_MOVE)
1935- {
1936- FLAG_TOGGLE (c->xfwm_flags, XFWM_FLAG_HAS_MOVE);
1937- }
1938- }
1939- g_free (mwm_hints);
1940- }
1941-
1942- if (update)
1943- {
1944- wc.x = c->x;
1945- wc.y = c->y;
1946- wc.width = c->width;
1947- wc.height = c->height;
1948-
1949- /* If client is maximized, we need to update its coordonates and size as well */
1950- if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED))
1951- {
1952- GdkRectangle rect;
1953- myScreenFindMonitorAtPoint (screen_info,
1954- frameX (c) + (frameWidth (c) / 2),
1955- frameY (c) + (frameHeight (c) / 2), &rect);
1956- clientNewMaxSize (c, &wc, &rect, TILE_NONE);
1957- }
1958-
1959- clientConfigure (c, &wc, CWX | CWY | CWWidth | CWHeight, CFG_FORCE_REDRAW);
1960-
1961- /* MWM hints can add or remove decorations, update NET_FRAME_EXTENTS accordingly */
1962- setNetFrameExtents (display_info,
1963- c->window,
1964- frameTop (c),
1965- frameLeft (c),
1966- frameRight (c),
1967- frameBottom (c));
1968- }
1969-}
1970-
1971-void
1972-clientGetWMNormalHints (Client *c, gboolean update)
1973-{
1974- XWindowChanges wc;
1975- unsigned long previous_value;
1976- long dummy;
1977-
1978- g_return_if_fail (c != NULL);
1979- g_return_if_fail (c->window != None);
1980-
1981- TRACE ("entering clientGetWMNormalHints client \"%s\" (0x%lx)", c->name,
1982- c->window);
1983-
1984- if (!c->size)
1985- {
1986- c->size = XAllocSizeHints ();
1987- }
1988- g_assert (c->size);
1989-
1990- dummy = 0;
1991- if (!XGetWMNormalHints (clientGetXDisplay (c), c->window, c->size, &dummy))
1992- {
1993- c->size->flags = 0;
1994- }
1995-
1996- /* Set/update gravity */
1997- c->gravity = c->size->flags & PWinGravity ? c->size->win_gravity : NorthWestGravity;
1998-
1999- previous_value = FLAG_TEST (c->xfwm_flags, XFWM_FLAG_IS_RESIZABLE);
2000- FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_IS_RESIZABLE);
2001-
2002- wc.x = c->x;
2003- wc.y = c->y;
2004- wc.width = c->width;
2005- wc.height = c->height;
2006-
2007- if (!(c->size->flags & PMaxSize))
2008- {
2009- c->size->max_width = G_MAXINT;
2010- c->size->max_height = G_MAXINT;
2011- c->size->flags |= PMaxSize;
2012- }
2013-
2014- if (!(c->size->flags & PBaseSize))
2015- {
2016- c->size->base_width = 0;
2017- c->size->base_height = 0;
2018- }
2019-
2020- if (!(c->size->flags & PMinSize))
2021- {
2022- if ((c->size->flags & PBaseSize))
2023- {
2024- c->size->min_width = c->size->base_width;
2025- c->size->min_height = c->size->base_height;
2026- }
2027- else
2028- {
2029- c->size->min_width = 1;
2030- c->size->min_height = 1;
2031- }
2032- c->size->flags |= PMinSize;
2033- }
2034-
2035- if (c->size->flags & PResizeInc)
2036- {
2037- if (c->size->width_inc < 1)
2038- {
2039- c->size->width_inc = 1;
2040- }
2041- if (c->size->height_inc < 1)
2042- {
2043- c->size->height_inc = 1;
2044- }
2045- }
2046- else
2047- {
2048- c->size->width_inc = 1;
2049- c->size->height_inc = 1;
2050- }
2051-
2052- if (c->size->flags & PAspect)
2053- {
2054- if (c->size->min_aspect.x < 1)
2055- {
2056- c->size->min_aspect.x = 1;
2057- }
2058- if (c->size->min_aspect.y < 1)
2059- {
2060- c->size->min_aspect.y = 1;
2061- }
2062- if (c->size->max_aspect.x < 1)
2063- {
2064- c->size->max_aspect.x = 1;
2065- }
2066- if (c->size->max_aspect.y < 1)
2067- {
2068- c->size->max_aspect.y = 1;
2069- }
2070- }
2071- else
2072- {
2073- c->size->min_aspect.x = 1;
2074- c->size->min_aspect.y = 1;
2075- c->size->max_aspect.x = G_MAXINT;
2076- c->size->max_aspect.y = G_MAXINT;
2077- }
2078-
2079- if (c->size->min_width < 1)
2080- {
2081- c->size->min_width = 1;
2082- }
2083- if (c->size->min_height < 1)
2084- {
2085- c->size->min_height = 1;
2086- }
2087- if (c->size->max_width < 1)
2088- {
2089- c->size->max_width = 1;
2090- }
2091- if (c->size->max_height < 1)
2092- {
2093- c->size->max_height = 1;
2094- }
2095- if (wc.width > c->size->max_width)
2096- {
2097- wc.width = c->size->max_width;
2098- }
2099- if (wc.height > c->size->max_height)
2100- {
2101- wc.height = c->size->max_height;
2102- }
2103- if (wc.width < c->size->min_width)
2104- {
2105- wc.width = c->size->min_width;
2106- }
2107- if (wc.height < c->size->min_height)
2108- {
2109- wc.height = c->size->min_height;
2110- }
2111-
2112- if ((c->size->min_width < c->size->max_width) ||
2113- (c->size->min_height < c->size->max_height))
2114- {
2115- FLAG_SET (c->xfwm_flags, XFWM_FLAG_IS_RESIZABLE);
2116- }
2117-
2118- if (update)
2119- {
2120- if ((c->width != wc.width) || (c->height != wc.height))
2121- {
2122- if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED))
2123- {
2124- clientRemoveMaximizeFlag (c);
2125- }
2126- clientConfigure (c, &wc, CWX | CWY | CWWidth | CWHeight, CFG_CONSTRAINED | CFG_FORCE_REDRAW);
2127- }
2128- else if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_IS_RESIZABLE) != previous_value)
2129- {
2130- frameQueueDraw (c, FALSE);
2131- }
2132- }
2133- else
2134- {
2135- c->width = wc.width;
2136- c->height = wc.height;
2137- }
2138-}
2139-
2140-void
2141-clientGetWMProtocols (Client *c)
2142-{
2143- ScreenInfo *screen_info;
2144- DisplayInfo *display_info;
2145- unsigned int wm_protocols_flags;
2146-
2147- g_return_if_fail (c != NULL);
2148- g_return_if_fail (c->window != None);
2149-
2150- TRACE ("entering clientGetWMProtocols client \"%s\" (0x%lx)", c->name,
2151- c->window);
2152-
2153- screen_info = c->screen_info;
2154- display_info = screen_info->display_info;
2155-
2156- wm_protocols_flags = getWMProtocols (display_info, c->window);
2157- FLAG_SET (c->wm_flags,
2158- (wm_protocols_flags & WM_PROTOCOLS_DELETE_WINDOW) ?
2159- WM_FLAG_DELETE : 0);
2160- FLAG_SET (c->wm_flags,
2161- (wm_protocols_flags & WM_PROTOCOLS_TAKE_FOCUS) ?
2162- WM_FLAG_TAKEFOCUS : 0);
2163- /* KDE extension */
2164- FLAG_SET (c->wm_flags,
2165- (wm_protocols_flags & WM_PROTOCOLS_CONTEXT_HELP) ?
2166- WM_FLAG_CONTEXT_HELP : 0);
2167- /* Ping */
2168- FLAG_SET (c->wm_flags,
2169- (wm_protocols_flags & WM_PROTOCOLS_PING) ?
2170- WM_FLAG_PING : 0);
2171-}
2172-
2173-static void
2174-clientFree (Client *c)
2175-{
2176- g_return_if_fail (c != NULL);
2177-
2178- TRACE ("entering clientFree");
2179- TRACE ("freeing client \"%s\" (0x%lx)", c->name, c->window);
2180-
2181- clientClearFocus (c);
2182- if (clientGetLastRaise (c->screen_info) == c)
2183- {
2184- clientClearLastRaise (c->screen_info);
2185- }
2186- if (clientGetDelayedFocus () == c)
2187- {
2188- clientClearDelayedFocus ();
2189- }
2190- if (c->blink_timeout_id)
2191- {
2192- g_source_remove (c->blink_timeout_id);
2193- }
2194- if (c->icon_timeout_id)
2195- {
2196- g_source_remove (c->icon_timeout_id);
2197- }
2198- if (c->frame_timeout_id)
2199- {
2200- g_source_remove (c->frame_timeout_id);
2201- }
2202- if (c->ping_timeout_id)
2203- {
2204- clientRemoveNetWMPing (c);
2205- }
2206- if (c->name)
2207- {
2208- g_free (c->name);
2209- }
2210- if (c->hostname)
2211- {
2212- g_free (c->hostname);
2213- }
2214-#ifdef HAVE_XSYNC
2215- if (c->xsync_alarm != None)
2216- {
2217- clientDestroyXSyncAlarm (c);
2218- }
2219- if (c->xsync_timeout_id)
2220- {
2221- g_source_remove (c->xsync_timeout_id);
2222- }
2223-#endif /* HAVE_XSYNC */
2224-#ifdef HAVE_LIBSTARTUP_NOTIFICATION
2225- if (c->startup_id)
2226- {
2227- g_free (c->startup_id);
2228- }
2229-#endif /* HAVE_LIBSTARTUP_NOTIFICATION */
2230- if (c->size)
2231- {
2232- XFree (c->size);
2233- }
2234- if (c->wmhints)
2235- {
2236- XFree (c->wmhints);
2237- }
2238- if ((c->ncmap > 0) && (c->cmap_windows))
2239- {
2240- XFree (c->cmap_windows);
2241- }
2242- if (c->class.res_name)
2243- {
2244- XFree (c->class.res_name);
2245- }
2246- if (c->class.res_class)
2247- {
2248- XFree (c->class.res_class);
2249- }
2250- if (c->dialog_pid)
2251- {
2252- kill (c->dialog_pid, SIGKILL);
2253- }
2254- if (c->dialog_fd >= 0)
2255- {
2256- close (c->dialog_fd);
2257- }
2258-
2259- g_free (c);
2260-}
2261-
2262-static void
2263-clientApplyInitialState (Client *c)
2264-{
2265- g_return_if_fail (c != NULL);
2266-
2267- TRACE ("entering clientApplyInitialState");
2268-
2269- /* We check that afterwards to make sure all states are now known */
2270- if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED))
2271- {
2272- if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_MAXIMIZE))
2273- {
2274- unsigned long mode = 0L;
2275-
2276- TRACE ("Applying client's initial state: maximized");
2277- mode = c->flags & CLIENT_FLAG_MAXIMIZED;
2278-
2279- /* Unset fullscreen mode so that clientToggleMaximized() really change the state */
2280- FLAG_UNSET (c->flags, CLIENT_FLAG_MAXIMIZED);
2281- clientToggleMaximized (c, mode, FALSE);
2282- }
2283- }
2284- if (FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
2285- {
2286- TRACE ("Applying client's initial state: fullscreen");
2287- clientUpdateFullscreenState (c);
2288- }
2289- if (FLAG_TEST_AND_NOT (c->flags, CLIENT_FLAG_ABOVE, CLIENT_FLAG_BELOW))
2290- {
2291- TRACE ("Applying client's initial state: above");
2292- clientUpdateLayerState (c);
2293- }
2294- if (FLAG_TEST_AND_NOT (c->flags, CLIENT_FLAG_BELOW, CLIENT_FLAG_ABOVE))
2295- {
2296- TRACE ("Applying client's initial state: below");
2297- clientUpdateLayerState (c);
2298- }
2299- if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY) &&
2300- FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_STICK))
2301- {
2302- TRACE ("Applying client's initial state: sticky");
2303- clientStick (c, TRUE);
2304- }
2305- if (FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
2306- {
2307- TRACE ("Applying client's initial state: shaded");
2308- clientShade (c);
2309- }
2310-}
2311-
2312-static gboolean
2313-clientCheckShape (Client *c)
2314-{
2315- ScreenInfo *screen_info;
2316- DisplayInfo *display_info;
2317- int xws, yws, xbs, ybs;
2318- unsigned wws, hws, wbs, hbs;
2319- int boundingShaped, clipShaped;
2320-
2321- g_return_val_if_fail (c != NULL, FALSE);
2322-
2323- screen_info = c->screen_info;
2324- display_info = screen_info->display_info;
2325-
2326- if (display_info->have_shape)
2327- {
2328- XShapeQueryExtents (display_info->dpy, c->window, &boundingShaped, &xws, &yws, &wws,
2329- &hws, &clipShaped, &xbs, &ybs, &wbs, &hbs);
2330- return (boundingShaped != 0);
2331- }
2332- return FALSE;
2333-}
2334-
2335-static void
2336-clientUpdateIconPix (Client *c)
2337-{
2338- ScreenInfo *screen_info;
2339- DisplayInfo *display_info;
2340- gint size;
2341- GdkPixbuf *icon;
2342- int i;
2343-
2344- g_return_if_fail (c != NULL);
2345- g_return_if_fail (c->window != None);
2346-
2347- TRACE ("entering clientUpdateIconPix for \"%s\" (0x%lx)", c->name, c->window);
2348-
2349- screen_info = c->screen_info;
2350- display_info = screen_info->display_info;
2351-
2352- for (i = 0; i < STATE_TOGGLED; i++)
2353- {
2354- xfwmPixmapFree (&c->appmenu[i]);
2355- }
2356-
2357- if (xfwmPixmapNone(&screen_info->buttons[MENU_BUTTON][ACTIVE]))
2358- {
2359- /* The current theme has no menu button */
2360- return;
2361- }
2362-
2363- for (i = 0; i < STATE_TOGGLED; i++)
2364- {
2365- if (!xfwmPixmapNone(&screen_info->buttons[MENU_BUTTON][i]))
2366- {
2367- xfwmPixmapDuplicate (&screen_info->buttons[MENU_BUTTON][i], &c->appmenu[i]);
2368- }
2369- }
2370- size = MIN (screen_info->buttons[MENU_BUTTON][ACTIVE].width,
2371- screen_info->buttons[MENU_BUTTON][ACTIVE].height);
2372-
2373- if (size > 1)
2374- {
2375- icon = getAppIcon (display_info, c->window, size, size);
2376-
2377- for (i = 0; i < STATE_TOGGLED; i++)
2378- {
2379- if (!xfwmPixmapNone(&c->appmenu[i]))
2380- {
2381- xfwmPixmapRenderGdkPixbuf (&c->appmenu[i], icon);
2382- }
2383- }
2384- g_object_unref (icon);
2385- }
2386-}
2387-
2388-static gboolean
2389-update_icon_idle_cb (gpointer data)
2390-{
2391- Client *c;
2392-
2393- TRACE ("entering update_icon_idle_cb");
2394-
2395- c = (Client *) data;
2396- g_return_val_if_fail (c, FALSE);
2397-
2398- clientUpdateIconPix (c);
2399- if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE))
2400- {
2401- frameQueueDraw (c, FALSE);
2402- }
2403- c->icon_timeout_id = 0;
2404-
2405- return (FALSE);
2406-}
2407-
2408-void
2409-clientUpdateIcon (Client *c)
2410-{
2411- g_return_if_fail (c);
2412-
2413- TRACE ("entering clientUpdateIcon for \"%s\" (0x%lx)", c->name, c->window);
2414-
2415- if (c->icon_timeout_id == 0)
2416- {
2417- c->icon_timeout_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2418- update_icon_idle_cb, c, NULL);
2419- }
2420-}
2421-
2422-void
2423-clientSaveSizePos (Client *c)
2424-{
2425- g_return_if_fail (c != NULL);
2426-
2427- if (!FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ))
2428- {
2429- c->old_x = c->x;
2430- c->old_width = c->width;
2431- }
2432-
2433- if (!FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_VERT))
2434- {
2435- c->old_y = c->y;
2436- c->old_height = c->height;
2437- }
2438-}
2439-
2440-Client *
2441-clientFrame (DisplayInfo *display_info, Window w, gboolean recapture)
2442-{
2443- ScreenInfo *screen_info;
2444- XWindowAttributes attr;
2445- XWindowChanges wc;
2446- XSetWindowAttributes attributes;
2447- Client *c = NULL;
2448- gboolean shaped;
2449- unsigned long valuemask;
2450- long pid;
2451- int i;
2452-
2453- g_return_val_if_fail (w != None, NULL);
2454- g_return_val_if_fail (display_info != NULL, NULL);
2455-
2456- TRACE ("entering clientFrame");
2457- TRACE ("framing client (0x%lx)", w);
2458-
2459- gdk_error_trap_push ();
2460- myDisplayGrabServer (display_info);
2461-
2462- if (!XGetWindowAttributes (display_info->dpy, w, &attr))
2463- {
2464- g_warning ("Cannot get window attributes for window (0x%lx)", w);
2465- myDisplayUngrabServer (display_info);
2466- gdk_error_trap_pop ();
2467- return NULL;
2468- }
2469-
2470- screen_info = myDisplayGetScreenFromRoot (display_info, attr.root);
2471- if (!screen_info)
2472- {
2473- g_warning ("Cannot determine screen info from window (0x%lx)", w);
2474- myDisplayUngrabServer (display_info);
2475- gdk_error_trap_pop ();
2476- return NULL;
2477- }
2478-
2479- if (w == screen_info->xfwm4_win)
2480- {
2481- TRACE ("Not managing our own event window");
2482- compositorAddWindow (display_info, w, NULL);
2483- myDisplayUngrabServer (display_info);
2484- gdk_error_trap_pop ();
2485- return NULL;
2486- }
2487-
2488-#ifdef ENABLE_KDE_SYSTRAY_PROXY
2489- if (checkKdeSystrayWindow (display_info, w))
2490- {
2491- TRACE ("Detected KDE systray windows");
2492- if (screen_info->systray != None)
2493- {
2494- sendSystrayReqDock (display_info, w, screen_info->systray);
2495- myDisplayUngrabServer (display_info);
2496- gdk_error_trap_pop ();
2497- return NULL;
2498- }
2499- TRACE ("No systray found for this screen");
2500- }
2501-#endif /* ENABLE_KDE_SYSTRAY_PROXY */
2502-
2503- if (attr.override_redirect)
2504- {
2505- TRACE ("Override redirect window 0x%lx", w);
2506- compositorAddWindow (display_info, w, NULL);
2507- myDisplayUngrabServer (display_info);
2508- gdk_error_trap_pop ();
2509- return NULL;
2510- }
2511-
2512- c = g_new0 (Client, 1);
2513- if (!c)
2514- {
2515- TRACE ("Cannot allocate memory for the window structure");
2516- myDisplayUngrabServer (display_info);
2517- gdk_error_trap_pop ();
2518- return NULL;
2519- }
2520-
2521- c->window = w;
2522- c->screen_info = screen_info;
2523- c->serial = screen_info->client_serial++;
2524-
2525- /* Termination dialog */
2526- c->dialog_pid = 0;
2527- c->dialog_fd = -1;
2528-
2529- getWindowName (display_info, c->window, &c->name);
2530- getWindowHostname (display_info, c->window, &c->hostname);
2531- getTransientFor (display_info, screen_info->xroot, c->window, &c->transient_for);
2532- XChangeSaveSet(display_info->dpy, c->window, SetModeInsert);
2533-
2534- /* Initialize structure */
2535- c->size = NULL;
2536- c->flags = 0L;
2537- c->wm_flags = 0L;
2538- c->xfwm_flags = XFWM_FLAG_INITIAL_VALUES;
2539- c->x = attr.x;
2540- c->y = attr.y;
2541- c->width = attr.width;
2542- c->height = attr.height;
2543-
2544-#ifdef HAVE_LIBSTARTUP_NOTIFICATION
2545- c->startup_id = NULL;
2546-#endif /* HAVE_LIBSTARTUP_NOTIFICATION */
2547-
2548-#ifdef HAVE_XSYNC
2549- c->xsync_waiting = FALSE;
2550- c->xsync_enabled = FALSE;
2551- c->xsync_counter = None;
2552- c->xsync_alarm = None;
2553- c->xsync_timeout_id = 0;
2554- if (display_info->have_xsync)
2555- {
2556- getXSyncCounter (display_info, c->window, &c->xsync_counter);
2557- if ((c->xsync_counter) && clientCreateXSyncAlarm (c))
2558- {
2559- c->xsync_enabled = TRUE;
2560- }
2561- }
2562-#endif /* HAVE_XSYNC */
2563-
2564- clientGetWMNormalHints (c, FALSE);
2565-
2566- c->size->x = c->x;
2567- c->size->y = c->y;
2568- c->size->width = c->width;
2569- c->size->height = c->height;
2570- c->previous_width = -1;
2571- c->previous_height = -1;
2572- c->border_width = attr.border_width;
2573- c->cmap = attr.colormap;
2574-
2575- shaped = clientCheckShape(c);
2576- if (shaped)
2577- {
2578- FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_HAS_BORDER);
2579- FLAG_SET (c->flags, CLIENT_FLAG_HAS_SHAPE);
2580- }
2581-
2582- if (((c->size->flags & (PMinSize | PMaxSize)) != (PMinSize | PMaxSize))
2583- || (((c->size->flags & (PMinSize | PMaxSize)) ==
2584- (PMinSize | PMaxSize))
2585- && ((c->size->min_width < c->size->max_width)
2586- || (c->size->min_height < c->size->max_height))))
2587- {
2588- FLAG_SET (c->xfwm_flags, XFWM_FLAG_IS_RESIZABLE);
2589- }
2590-
2591- for (i = 0; i < BUTTON_COUNT; i++)
2592- {
2593- c->button_status[i] = BUTTON_STATE_NORMAL;
2594- }
2595-
2596- if (!XGetWMColormapWindows (display_info->dpy, c->window, &c->cmap_windows, &c->ncmap))
2597- {
2598- c->ncmap = 0;
2599- }
2600-
2601- c->fullscreen_monitors[0] = 0;
2602- c->fullscreen_monitors[1] = 0;
2603- c->fullscreen_monitors[2] = 0;
2604- c->fullscreen_monitors[3] = 0;
2605-
2606- /* Opacity for compositing manager */
2607- c->opacity = NET_WM_OPAQUE;
2608- getOpacity (display_info, c->window, &c->opacity);
2609- c->opacity_applied = c->opacity;
2610- c->opacity_flags = 0;
2611-
2612- /* Keep count of blinking iterations */
2613- c->blink_iterations = 0;
2614-
2615- if (getOpacityLock (display_info, c->window))
2616- {
2617- FLAG_SET (c->xfwm_flags, XFWM_FLAG_OPACITY_LOCKED);
2618- }
2619-
2620- /* Timout for asynchronous icon update */
2621- c->icon_timeout_id = 0;
2622- /* Timout for asynchronous frame update */
2623- c->frame_timeout_id = 0;
2624- /* Timeout for blinking on urgency */
2625- c->blink_timeout_id = 0;
2626- /* Ping timeout */
2627- c->ping_timeout_id = 0;
2628- /* Ping timeout */
2629- c->ping_time = 0;
2630-
2631- c->class.res_name = NULL;
2632- c->class.res_class = NULL;
2633- XGetClassHint (display_info->dpy, w, &c->class);
2634- c->wmhints = XGetWMHints (display_info->dpy, c->window);
2635- c->group_leader = None;
2636- if (c->wmhints)
2637- {
2638- if (c->wmhints->flags & WindowGroupHint)
2639- {
2640- c->group_leader = c->wmhints->window_group;
2641- }
2642- }
2643- c->client_leader = getClientLeader (display_info, c->window);
2644-
2645- TRACE ("\"%s\" (0x%lx) initial map_state = %s",
2646- c->name, c->window,
2647- (attr.map_state == IsUnmapped) ?
2648- "IsUnmapped" :
2649- (attr.map_state == IsViewable) ?
2650- "IsViewable" :
2651- (attr.map_state == IsUnviewable) ?
2652- "IsUnviewable" :
2653- "(unknown)");
2654- if (attr.map_state != IsUnmapped)
2655- {
2656- /* Reparent will send us unmap/map events */
2657- FLAG_SET (c->xfwm_flags, XFWM_FLAG_MAP_PENDING);
2658- }
2659- c->ignore_unmap = 0;
2660- c->type = UNSET;
2661- c->type_atom = None;
2662-
2663- FLAG_SET (c->flags, START_ICONIC (c) ? CLIENT_FLAG_ICONIFIED : 0);
2664- FLAG_SET (c->wm_flags, HINTS_ACCEPT_INPUT (c->wmhints) ? WM_FLAG_INPUT : 0);
2665-
2666- clientGetWMProtocols (c);
2667- clientGetMWMHints (c, FALSE);
2668- c->win_layer = WIN_LAYER_NORMAL;
2669- c->fullscreen_old_layer = c->win_layer;
2670-
2671- /* net_wm_user_time standard */
2672- c->user_time = 0;
2673- c->user_time_win = getNetWMUserTimeWindow(display_info, c->window);
2674- clientAddUserTimeWin (c);
2675- clientGetUserTime (c);
2676-
2677- /*client PID */
2678- getHint (display_info, c->window, NET_WM_PID, (long *) &pid);
2679- c->pid = (GPid) pid;
2680- TRACE ("Client \"%s\" (0x%lx) PID = %i", c->name, c->window, c->pid);
2681-
2682- /* Apply startup notification properties if available */
2683- sn_client_startup_properties (c);
2684-
2685- /* Reload from session */
2686- if (sessionMatchWinToSM (c))
2687- {
2688- FLAG_SET (c->xfwm_flags, XFWM_FLAG_SESSION_MANAGED);
2689- }
2690-
2691- /* Beware, order of calls is important here ! */
2692- clientGetNetState (c);
2693- clientGetNetWmType (c);
2694- clientGetInitialNetWmDesktop (c);
2695- /* workarea will be updated when shown, no need to worry here */
2696- clientGetNetStruts (c);
2697-
2698- /* Once we know the type of window, we can initialize window position */
2699- if (!FLAG_TEST (c->xfwm_flags, XFWM_FLAG_SESSION_MANAGED))
2700- {
2701- clientCoordGravitate (c, c->gravity, APPLY, &c->x, &c->y);
2702- if ((attr.map_state == IsUnmapped))
2703- {
2704- clientInitPosition (c);
2705- }
2706- }
2707-
2708- /*
2709- Initialize "old" fields once the position is ensured, to avoid
2710- initially maximized or fullscreen windows being placed offscreen
2711- once de-maximized
2712- */
2713- c->old_x = c->x;
2714- c->old_y = c->y;
2715- c->old_width = c->width;
2716- c->old_height = c->height;
2717-
2718- c->fullscreen_old_x = c->x;
2719- c->fullscreen_old_y = c->y;
2720- c->fullscreen_old_width = c->width;
2721- c->fullscreen_old_height = c->height;
2722-
2723- /*
2724- We must call clientApplyInitialState() after having placed the
2725- window so that the inital position values are correctly set if the
2726- inital state is maximize or fullscreen
2727- */
2728- clientApplyInitialState (c);
2729-
2730- valuemask = CWEventMask|CWBitGravity|CWWinGravity;
2731- attributes.event_mask = (FRAME_EVENT_MASK | POINTER_EVENT_MASK);
2732- attributes.win_gravity = StaticGravity;
2733- attributes.bit_gravity = StaticGravity;
2734-
2735-#ifdef HAVE_RENDER
2736- if ((attr.depth == 32) && (display_info->have_render))
2737- {
2738- c->visual = attr.visual;
2739- c->depth = attr.depth;
2740-
2741- attributes.colormap = attr.colormap;
2742- attributes.background_pixmap = None;
2743- attributes.border_pixel = 0;
2744- attributes.background_pixel = 0;
2745-
2746- valuemask |= CWColormap|CWBackPixmap|CWBackPixel|CWBorderPixel;
2747- }
2748- else
2749- {
2750- /* Default depth/visual */
2751- c->visual = screen_info->visual;
2752- c->depth = screen_info->depth;
2753- }
2754-#else /* HAVE_RENDER */
2755- /* We don't support multiple depth/visual w/out render */
2756- c->visual = screen_info->visual;
2757- c->depth = screen_info->depth;
2758-#endif /* HAVE_RENDER */
2759-
2760- c->frame =
2761- XCreateWindow (display_info->dpy, screen_info->xroot, 0, 0, 1, 1, 0,
2762- c->depth, InputOutput, c->visual, valuemask, &attributes);
2763-
2764- XSelectInput (display_info->dpy, c->window, NoEventMask);
2765- XSetWindowBorderWidth (display_info->dpy, c->window, 0);
2766- if (FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
2767- {
2768- XUnmapWindow (display_info->dpy, c->window);
2769- }
2770- XReparentWindow (display_info->dpy, c->window, c->frame, frameLeft (c), frameTop (c));
2771- valuemask = CWEventMask;
2772- attributes.event_mask = (CLIENT_EVENT_MASK);
2773- XChangeWindowAttributes (display_info->dpy, c->window, valuemask, &attributes);
2774- if (display_info->have_shape)
2775- {
2776- XShapeSelectInput (display_info->dpy, c->window, ShapeNotifyMask);
2777- }
2778-
2779- clientAddToList (c);
2780- clientGrabButtons(c);
2781-
2782- /* Initialize per client menu button pixmap */
2783-
2784- for (i = 0; i < STATE_TOGGLED; i++)
2785- {
2786- xfwmPixmapInit (screen_info, &c->appmenu[i]);
2787- }
2788-
2789- for (i = 0; i < SIDE_TOP; i++) /* Keep SIDE_TOP for later */
2790- {
2791- xfwmWindowCreate (screen_info, c->visual, c->depth, c->frame,
2792- &c->sides[i], NoEventMask,
2793- myDisplayGetCursorResize(screen_info->display_info, CORNER_COUNT + i));
2794- }
2795-
2796- for (i = 0; i < CORNER_COUNT; i++)
2797- {
2798- xfwmWindowCreate (screen_info, c->visual, c->depth, c->frame,
2799- &c->corners[i], NoEventMask,
2800- myDisplayGetCursorResize(screen_info->display_info, i));
2801- }
2802-
2803- xfwmWindowCreate (screen_info, c->visual, c->depth, c->frame,
2804- &c->title, NoEventMask, None);
2805-
2806- /*create the top side window AFTER the title window since they overlap
2807- and the top side window should be on top */
2808-
2809- xfwmWindowCreate (screen_info, c->visual, c->depth, c->frame,
2810- &c->sides[SIDE_TOP], NoEventMask,
2811- myDisplayGetCursorResize(screen_info->display_info,
2812- CORNER_COUNT + SIDE_TOP));
2813-
2814- for (i = 0; i < BUTTON_COUNT; i++)
2815- {
2816- xfwmWindowCreate (screen_info, c->visual, c->depth, c->frame,
2817- &c->buttons[i], BUTTON_EVENT_MASK, None);
2818- }
2819- clientUpdateIconPix (c);
2820-
2821- /* Put the window on top to avoid XShape, that speeds up hw accelerated
2822- GL apps dramatically */
2823- XRaiseWindow (display_info->dpy, c->window);
2824-
2825- TRACE ("now calling configure for the new window \"%s\" (0x%lx)", c->name, c->window);
2826- wc.x = c->x;
2827- wc.y = c->y;
2828- wc.width = c->width;
2829- wc.height = c->height;
2830- clientConfigure (c, &wc, CWX | CWY | CWHeight | CWWidth, CFG_NOTIFY | CFG_FORCE_REDRAW);
2831-
2832- /* Notify the compositor about this new window */
2833- compositorAddWindow (display_info, c->frame, c);
2834-
2835- if (!FLAG_TEST (c->flags, CLIENT_FLAG_ICONIFIED))
2836- {
2837- if ((c->win_workspace == screen_info->current_ws) ||
2838- FLAG_TEST(c->flags, CLIENT_FLAG_STICKY))
2839- {
2840- if (recapture)
2841- {
2842- clientRaise (c, None);
2843- clientShow (c, TRUE);
2844- clientSortRing(c);
2845- }
2846- else
2847- {
2848- clientFocusNew(c);
2849- }
2850- }
2851- else
2852- {
2853- clientRaise (c, None);
2854- clientInitFocusFlag (c);
2855- clientSetNetActions (c);
2856- }
2857- }
2858- else
2859- {
2860- clientRaise (c, None);
2861- setWMState (display_info, c->window, IconicState);
2862- clientSetNetActions (c);
2863- }
2864- clientUpdateOpacity (c);
2865- clientGrabMouseButton (c);
2866- setNetFrameExtents (display_info, c->window, frameTop (c), frameLeft (c),
2867- frameRight (c), frameBottom (c));
2868- clientSetNetState (c);
2869-
2870- /* Window is reparented now, so we can safely release the grab
2871- * on the server
2872- */
2873- myDisplayUngrabServer (display_info);
2874- gdk_error_trap_pop ();
2875-
2876- DBG ("client \"%s\" (0x%lx) is now managed", c->name, c->window);
2877- DBG ("client_count=%d", screen_info->client_count);
2878-
2879- return c;
2880-}
2881-
2882-void
2883-clientUnframe (Client *c, gboolean remap)
2884-{
2885- ScreenInfo *screen_info;
2886- DisplayInfo *display_info;
2887- XEvent ev;
2888- int i;
2889- gboolean reparented;
2890-
2891- TRACE ("entering clientUnframe");
2892- TRACE ("unframing client \"%s\" (0x%lx) [%s]",
2893- c->name, c->window, remap ? "remap" : "no remap");
2894-
2895- g_return_if_fail (c != NULL);
2896-
2897- screen_info = c->screen_info;
2898- display_info = screen_info->display_info;
2899-
2900- clientRemoveFromList (c);
2901- compositorSetClient (display_info, c->frame, NULL);
2902-
2903- myDisplayGrabServer (display_info);
2904- gdk_error_trap_push ();
2905- clientRemoveUserTimeWin (c);
2906- clientUngrabButtons (c);
2907- XUnmapWindow (display_info->dpy, c->frame);
2908- clientCoordGravitate (c, c->gravity, REMOVE, &c->x, &c->y);
2909- XSelectInput (display_info->dpy, c->window, NoEventMask);
2910- XChangeSaveSet(display_info->dpy, c->window, SetModeDelete);
2911-
2912- reparented = XCheckTypedWindowEvent (display_info->dpy, c->window, ReparentNotify, &ev);
2913-
2914- if (remap || !reparented)
2915- {
2916- XReparentWindow (display_info->dpy, c->window, c->screen_info->xroot, c->x, c->y);
2917- XSetWindowBorderWidth (display_info->dpy, c->window, c->border_width);
2918- if (remap)
2919- {
2920- compositorAddWindow (display_info, c->window, NULL);
2921- XMapWindow (display_info->dpy, c->window);
2922- }
2923- else
2924- {
2925- XUnmapWindow (display_info->dpy, c->window);
2926- setWMState (display_info, c->window, WithdrawnState);
2927- }
2928- }
2929-
2930- if (!remap)
2931- {
2932- XDeleteProperty (display_info->dpy, c->window,
2933- display_info->atoms[NET_WM_STATE]);
2934- XDeleteProperty (display_info->dpy, c->window,
2935- display_info->atoms[NET_WM_DESKTOP]);
2936- XDeleteProperty (display_info->dpy, c->window,
2937- display_info->atoms[NET_WM_ALLOWED_ACTIONS]);
2938- }
2939-
2940- xfwmWindowDelete (&c->title);
2941-
2942- for (i = 0; i < SIDE_COUNT; i++)
2943- {
2944- xfwmWindowDelete (&c->sides[i]);
2945- }
2946- for (i = 0; i < CORNER_COUNT; i++)
2947- {
2948- xfwmWindowDelete (&c->corners[i]);
2949- }
2950- for (i = 0; i < STATE_TOGGLED; i++)
2951- {
2952- xfwmPixmapFree (&c->appmenu[i]);
2953- }
2954- for (i = 0; i < BUTTON_COUNT; i++)
2955- {
2956- xfwmWindowDelete (&c->buttons[i]);
2957- }
2958- if (FLAG_TEST (c->flags, CLIENT_FLAG_HAS_STRUT))
2959- {
2960- workspaceUpdateArea (c->screen_info);
2961- }
2962- XDestroyWindow (display_info->dpy, c->frame);
2963-
2964- myDisplayUngrabServer (display_info);
2965- gdk_error_trap_pop ();
2966- clientFree (c);
2967-}
2968-
2969-void
2970-clientFrameAll (ScreenInfo *screen_info)
2971-{
2972- DisplayInfo *display_info;
2973- XWindowAttributes attr;
2974- xfwmWindow shield;
2975- Window w1, w2, *wins;
2976- unsigned int count, i;
2977-
2978- TRACE ("entering clientFrameAll");
2979-
2980- display_info = screen_info->display_info;
2981- clientSetFocus (screen_info, NULL, myDisplayGetCurrentTime (display_info), NO_FOCUS_FLAG);
2982- xfwmWindowTemp (screen_info,
2983- NULL, 0,
2984- screen_info->xroot,
2985- &shield,
2986- 0, 0,
2987- screen_info->width,
2988- screen_info->height,
2989- EnterWindowMask,
2990- FALSE);
2991-
2992- XSync (display_info->dpy, FALSE);
2993- myDisplayGrabServer (display_info);
2994- XQueryTree (display_info->dpy, screen_info->xroot, &w1, &w2, &wins, &count);
2995- for (i = 0; i < count; i++)
2996- {
2997- XGetWindowAttributes (display_info->dpy, wins[i], &attr);
2998- if ((attr.map_state == IsViewable) && (attr.root == screen_info->xroot))
2999- {
3000- Client *c = clientFrame (display_info, wins[i], TRUE);
3001- if ((c) && ((screen_info->params->raise_on_click) || (screen_info->params->click_to_focus)))
3002- {
3003- clientGrabMouseButton (c);
3004- }
3005- }
3006- else
3007- {
3008- compositorAddWindow (display_info, wins[i], NULL);
3009- }
3010- }
3011- if (wins)
3012- {
3013- XFree (wins);
3014- }
3015- clientFocusTop (screen_info, WIN_LAYER_FULLSCREEN, myDisplayGetCurrentTime (display_info));
3016- xfwmWindowDelete (&shield);
3017- myDisplayUngrabServer (display_info);
3018- XSync (display_info->dpy, FALSE);
3019-}
3020-
3021-void
3022-clientUnframeAll (ScreenInfo *screen_info)
3023-{
3024- DisplayInfo *display_info;
3025- Client *c;
3026- Window w1, w2, *wins;
3027- unsigned int count, i;
3028-
3029- TRACE ("entering clientUnframeAll");
3030-
3031- display_info = screen_info->display_info;
3032- clientSetFocus (screen_info, NULL, myDisplayGetCurrentTime (display_info), FOCUS_IGNORE_MODAL);
3033- XSync (display_info->dpy, FALSE);
3034- myDisplayGrabServer (display_info);
3035- XQueryTree (display_info->dpy, screen_info->xroot, &w1, &w2, &wins, &count);
3036- for (i = 0; i < count; i++)
3037- {
3038- c = myScreenGetClientFromWindow (screen_info, wins[i], SEARCH_FRAME);
3039- if (c)
3040- {
3041- clientUnframe (c, TRUE);
3042- }
3043- }
3044- myDisplayUngrabServer (display_info);
3045- XSync(display_info->dpy, FALSE);
3046- if (wins)
3047- {
3048- XFree (wins);
3049- }
3050-}
3051-
3052-Client *
3053-clientGetFromWindow (Client *c, Window w, unsigned short mode)
3054-{
3055- int b;
3056-
3057- g_return_val_if_fail (w != None, NULL);
3058- g_return_val_if_fail (c != NULL, NULL);
3059- TRACE ("entering clientGetFromWindow");
3060-
3061- if (mode & SEARCH_WINDOW)
3062- {
3063- if (c->window == w)
3064- {
3065- TRACE ("found \"%s\" (mode WINDOW)", c->name);
3066- return (c);
3067- }
3068- }
3069-
3070- if (mode & SEARCH_FRAME)
3071- {
3072- if (c->frame == w)
3073- {
3074- TRACE ("found \"%s\" (mode FRAME)", c->name);
3075- return (c);
3076- }
3077- }
3078-
3079- if (mode & SEARCH_WIN_USER_TIME)
3080- {
3081- if (c->user_time_win == w)
3082- {
3083- TRACE ("found \"%s\" (mode WIN_USER_TIME)", c->name);
3084- return (c);
3085- }
3086- }
3087-
3088- if (mode & SEARCH_BUTTON)
3089- {
3090- for (b = 0; b < BUTTON_COUNT; b++)
3091- {
3092- if (MYWINDOW_XWINDOW(c->buttons[b]) == w)
3093- {
3094- TRACE ("found \"%s\" (mode BUTTON)", c->name);
3095- return (c);
3096- }
3097- }
3098- }
3099-
3100- TRACE ("no client found");
3101-
3102- return NULL;
3103-}
3104-
3105-static void
3106-clientSetWorkspaceSingle (Client *c, guint ws)
3107-{
3108- ScreenInfo *screen_info;
3109- DisplayInfo *display_info;
3110-
3111- g_return_if_fail (c != NULL);
3112-
3113- TRACE ("entering clientSetWorkspaceSingle");
3114-
3115- screen_info = c->screen_info;
3116- display_info = screen_info->display_info;
3117-
3118- if (ws > screen_info->workspace_count - 1)
3119- {
3120- ws = screen_info->workspace_count - 1;
3121- TRACE ("value off limits, using %i instead", ws);
3122- }
3123-
3124- if (c->win_workspace != ws)
3125- {
3126- TRACE ("setting client \"%s\" (0x%lx) to current_ws %d", c->name, c->window, ws);
3127- c->win_workspace = ws;
3128- if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
3129- {
3130- setHint (display_info, c->window, NET_WM_DESKTOP, (unsigned long) ALL_WORKSPACES);
3131- }
3132- else
3133- {
3134- setHint (display_info, c->window, NET_WM_DESKTOP, (unsigned long) ws);
3135- }
3136- }
3137- FLAG_SET (c->xfwm_flags, XFWM_FLAG_WORKSPACE_SET);
3138-}
3139-
3140-void
3141-clientSetWorkspace (Client *c, guint ws, gboolean manage_mapping)
3142-{
3143- Client *c2;
3144- GList *list_of_windows;
3145- GList *list;
3146- guint previous_ws;
3147-
3148- g_return_if_fail (c != NULL);
3149-
3150- TRACE ("entering clientSetWorkspace");
3151-
3152- if (ws > c->screen_info->workspace_count - 1)
3153- {
3154- g_warning ("Requested workspace %d does not exist", ws);
3155- return;
3156- }
3157-
3158- list_of_windows = clientListTransientOrModal (c);
3159- for (list = list_of_windows; list; list = g_list_next (list))
3160- {
3161- c2 = (Client *) list->data;
3162-
3163- if (c2->win_workspace != ws)
3164- {
3165- TRACE ("setting client \"%s\" (0x%lx) to current_ws %d", c->name, c->window, ws);
3166-
3167- previous_ws = c2->win_workspace;
3168- clientSetWorkspaceSingle (c2, ws);
3169-
3170- if (manage_mapping && !FLAG_TEST (c2->flags, CLIENT_FLAG_ICONIFIED))
3171- {
3172- if (previous_ws == c2->screen_info->current_ws)
3173- {
3174- clientWithdraw (c2, c2->screen_info->current_ws, FALSE);
3175- }
3176- if (FLAG_TEST (c2->flags, CLIENT_FLAG_STICKY) || (ws == c2->screen_info->current_ws))
3177- {
3178- clientShow (c2, FALSE);
3179- }
3180- }
3181- }
3182- }
3183- g_list_free (list_of_windows);
3184-}
3185-
3186-static void
3187-clientShowSingle (Client *c, gboolean deiconify)
3188-{
3189- ScreenInfo *screen_info;
3190- DisplayInfo *display_info;
3191-
3192- g_return_if_fail (c != NULL);
3193-
3194- if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE))
3195- {
3196- /* Should we map the window if it is visible? */
3197- return;
3198- }
3199-
3200- screen_info = c->screen_info;
3201- display_info = screen_info->display_info;
3202-
3203- if ((c->win_workspace == screen_info->current_ws) || FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
3204- {
3205- TRACE ("showing client \"%s\" (0x%lx)", c->name, c->window);
3206- FLAG_SET (c->xfwm_flags, XFWM_FLAG_VISIBLE);
3207- XMapWindow (display_info->dpy, c->frame);
3208- if (!FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
3209- {
3210- XMapWindow (display_info->dpy, c->window);
3211- }
3212- /* Adjust to urgency state as the window is visible */
3213- clientUpdateUrgency (c);
3214- }
3215- if (deiconify)
3216- {
3217- FLAG_UNSET (c->flags, CLIENT_FLAG_ICONIFIED);
3218- setWMState (display_info, c->window, NormalState);
3219- }
3220- clientSetNetActions (c);
3221- clientSetNetState (c);
3222-}
3223-
3224-void
3225-clientShow (Client *c, gboolean deiconify)
3226-{
3227- Client *c2;
3228- GList *list_of_windows;
3229- GList *list;
3230-
3231- g_return_if_fail (c != NULL);
3232- TRACE ("entering clientShow \"%s\" (0x%lx)", c->name, c->window);
3233-
3234- list_of_windows = clientListTransientOrModal (c);
3235- for (list = g_list_last (list_of_windows); list; list = g_list_previous (list))
3236- {
3237- c2 = (Client *) list->data;
3238- clientSetWorkspaceSingle (c2, c->win_workspace);
3239- /* Ignore request before if the window is not yet managed */
3240- if (!FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_MANAGED))
3241- {
3242- continue;
3243- }
3244- clientShowSingle (c2, deiconify);
3245- }
3246- g_list_free (list_of_windows);
3247-
3248- /* Update working area as windows have been shown */
3249- workspaceUpdateArea (c->screen_info);
3250-}
3251-
3252-static void
3253-clientWithdrawSingle (Client *c, GList *exclude_list, gboolean iconify)
3254-{
3255- ScreenInfo *screen_info;
3256- DisplayInfo *display_info;
3257-
3258- g_return_if_fail (c != NULL);
3259-
3260- screen_info = c->screen_info;
3261- display_info = screen_info->display_info;
3262-
3263- TRACE ("hiding client \"%s\" (0x%lx)", c->name, c->window);
3264- clientPassFocus(c->screen_info, c, exclude_list);
3265- if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE))
3266- {
3267- FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_VISIBLE);
3268- c->ignore_unmap++;
3269- /* Adjust to urgency state as the window is not visible */
3270- clientUpdateUrgency (c);
3271- }
3272- XUnmapWindow (display_info->dpy, c->window);
3273- XUnmapWindow (display_info->dpy, c->frame);
3274- if (iconify)
3275- {
3276- FLAG_SET (c->flags, CLIENT_FLAG_ICONIFIED);
3277- setWMState (display_info, c->window, IconicState);
3278- if (!screen_info->show_desktop)
3279- {
3280- clientSetLast (c);
3281- }
3282- }
3283- clientSetNetActions (c);
3284- clientSetNetState (c);
3285-}
3286-
3287-void
3288-clientWithdraw (Client *c, guint ws, gboolean iconify)
3289-{
3290- Client *c2;
3291- GList *list_of_windows;
3292- GList *list;
3293-
3294- g_return_if_fail (c != NULL);
3295- TRACE ("entering clientWithdraw \"%s\" (0x%lx)", c->name, c->window);
3296-
3297- list_of_windows = clientListTransientOrModal (c);
3298- for (list = list_of_windows; list; list = g_list_next (list))
3299- {
3300- c2 = (Client *) list->data;
3301-
3302- /* Ignore request before if the window is not yet managed */
3303- if (!FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_MANAGED))
3304- {
3305- continue;
3306- }
3307-
3308- if (FLAG_TEST (c2->flags, CLIENT_FLAG_STICKY) && !iconify)
3309- {
3310- continue;
3311- }
3312-
3313- if (clientIsTransientOrModalForGroup (c2))
3314- {
3315-
3316- if (clientTransientOrModalHasAncestor (c2, c2->win_workspace))
3317- {
3318- /* Other ancestors for that transient for group are still
3319- * visible on current workspace, so don't hide it...
3320- */
3321- continue;
3322- }
3323- if ((ws != c2->win_workspace) &&
3324- clientTransientOrModalHasAncestor (c2, ws))
3325- {
3326- /* ws is used when transitioning between desktops, to avoid
3327- hiding a transient for group that will be shown again on the new
3328- workspace (transient for groups can be transients for multiple
3329- ancesors splitted across workspaces...)
3330- */
3331- continue;
3332- }
3333- }
3334- clientWithdrawSingle (c2, list_of_windows, iconify);
3335- }
3336- g_list_free (list_of_windows);
3337-
3338- /* Update working area as windows have been hidden */
3339- workspaceUpdateArea (c->screen_info);
3340-}
3341-
3342-void
3343-clientWithdrawAll (Client *c, guint ws)
3344-{
3345- GList *list;
3346- Client *c2;
3347- ScreenInfo *screen_info;
3348-
3349- g_return_if_fail (c != NULL);
3350-
3351- TRACE ("entering clientWithdrawAll");
3352-
3353- screen_info = c->screen_info;
3354- for (list = screen_info->windows_stack; list; list = g_list_next (list))
3355- {
3356- c2 = (Client *) list->data;
3357-
3358- if ((c2 != c)
3359- && CLIENT_CAN_HIDE_WINDOW (c2)
3360- && !clientIsTransientOrModal (c2))
3361- {
3362- if (((!c) && (c2->win_workspace == ws))
3363- || ((c) && !clientIsTransientOrModalFor (c, c2)
3364- && (c2->win_workspace == c->win_workspace)))
3365- {
3366- clientWithdraw (c2, ws, TRUE);
3367- }
3368- }
3369- }
3370-}
3371-
3372-void
3373-clientClearAllShowDesktop (ScreenInfo *screen_info)
3374-{
3375- GList *list;
3376-
3377- TRACE ("entering clientClearShowDesktop");
3378-
3379- if (screen_info->show_desktop)
3380- {
3381- for (list = screen_info->windows_stack; list; list = g_list_next (list))
3382- {
3383- Client *c = (Client *) list->data;
3384- FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_WAS_SHOWN);
3385- }
3386- screen_info->show_desktop = FALSE;
3387- sendRootMessage (screen_info, NET_SHOWING_DESKTOP, screen_info->show_desktop,
3388- myDisplayGetCurrentTime (screen_info->display_info));
3389- }
3390-}
3391-
3392-void
3393-clientToggleShowDesktop (ScreenInfo *screen_info)
3394-{
3395- GList *list;
3396-
3397- TRACE ("entering clientToggleShowDesktop");
3398-
3399- clientSetFocus (screen_info, NULL,
3400- myDisplayGetCurrentTime (screen_info->display_info),
3401- FOCUS_IGNORE_MODAL);
3402- if (screen_info->show_desktop)
3403- {
3404- for (list = screen_info->windows_stack; list; list = g_list_next (list))
3405- {
3406- Client *c = (Client *) list->data;
3407- if ((c->type & WINDOW_REGULAR_FOCUSABLE)
3408- && !FLAG_TEST (c->flags, CLIENT_FLAG_ICONIFIED | CLIENT_FLAG_SKIP_TASKBAR))
3409- {
3410- FLAG_SET (c->xfwm_flags, XFWM_FLAG_WAS_SHOWN);
3411- clientWithdraw (c, c->win_workspace, TRUE);
3412- }
3413- }
3414- clientFocusTop (screen_info, WIN_LAYER_DESKTOP, myDisplayGetCurrentTime (screen_info->display_info));
3415- }
3416- else
3417- {
3418- for (list = g_list_last(screen_info->windows_stack); list; list = g_list_previous (list))
3419- {
3420- Client *c = (Client *) list->data;
3421- if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_WAS_SHOWN))
3422- {
3423- clientShow (c, TRUE);
3424- }
3425- FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_WAS_SHOWN);
3426- }
3427- clientFocusTop (screen_info, WIN_LAYER_FULLSCREEN, myDisplayGetCurrentTime (screen_info->display_info));
3428- }
3429-}
3430-
3431-void
3432-clientActivate (Client *c, guint32 timestamp, gboolean source_is_application)
3433-{
3434- ScreenInfo *screen_info;
3435- Client *focused;
3436- Client *sibling;
3437-
3438- g_return_if_fail (c != NULL);
3439- TRACE ("entering clientActivate \"%s\" (0x%lx)", c->name, c->window);
3440-
3441- screen_info = c->screen_info;
3442- sibling = clientGetTransientFor(c);
3443- focused = clientGetFocus ();
3444-
3445- if ((screen_info->current_ws == c->win_workspace) || (screen_info->params->activate_action != ACTIVATE_ACTION_NONE))
3446- {
3447- if ((focused) && (c != focused))
3448- {
3449- /* We might be able to avoid this if we are about to switch workspace */
3450- clientAdjustFullscreenLayer (focused, FALSE);
3451- }
3452- if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_WAS_SHOWN))
3453- {
3454- /* We are explicitely activating a window that was shown before show-desktop */
3455- clientClearAllShowDesktop (screen_info);
3456- }
3457- if (screen_info->current_ws != c->win_workspace)
3458- {
3459- if (screen_info->params->activate_action == ACTIVATE_ACTION_BRING)
3460- {
3461- clientSetWorkspace (c, screen_info->current_ws, TRUE);
3462- }
3463- else
3464- {
3465- workspaceSwitch (screen_info, c->win_workspace, NULL, FALSE, timestamp);
3466- }
3467- }
3468- clientRaise (sibling, None);
3469- clientShow (sibling, TRUE);
3470- if (source_is_application || screen_info->params->click_to_focus || (c->type & WINDOW_TYPE_DONT_FOCUS))
3471- {
3472- /*
3473- It's a bit tricky here, we want to honor the activate request only if:
3474-
3475- - The window use the _NET_ACTIVE_WINDOW protocol and identify itself as an application,
3476- - Or we use the click to focus model, in that case we focus the raised window anyway,
3477- - Or the request comes from an application that we would not focus by default,
3478- such as panels for example
3479- */
3480- clientSetFocus (screen_info, c, timestamp, NO_FOCUS_FLAG);
3481- }
3482- clientSetLastRaise (c);
3483- }
3484- else
3485- {
3486- TRACE ("Setting WM_STATE_DEMANDS_ATTENTION flag on \"%s\" (0x%lx)", c->name, c->window);
3487- FLAG_SET (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION);
3488- clientSetNetState (c);
3489- }
3490-}
3491-
3492-void
3493-clientClose (Client *c)
3494-{
3495- ScreenInfo *screen_info;
3496- DisplayInfo *display_info;
3497- guint32 timestamp;
3498-
3499- g_return_if_fail (c != NULL);
3500-
3501- TRACE ("entering clientClose");
3502- TRACE ("closing client \"%s\" (0x%lx)", c->name, c->window);
3503-
3504- screen_info = c->screen_info;
3505- display_info = screen_info->display_info;
3506- timestamp = myDisplayGetCurrentTime (display_info);
3507- timestamp = myDisplayGetTime (display_info, timestamp);
3508-
3509- if (FLAG_TEST (c->wm_flags, WM_FLAG_DELETE))
3510- {
3511- sendClientMessage (screen_info, c->window, WM_DELETE_WINDOW, timestamp);
3512- }
3513- else
3514- {
3515- clientKill (c);
3516- }
3517- if (FLAG_TEST (c->wm_flags, WM_FLAG_PING))
3518- {
3519- clientSendNetWMPing (c, timestamp);
3520- }
3521-}
3522-
3523-void
3524-clientKill (Client *c)
3525-{
3526- g_return_if_fail (c != NULL);
3527- TRACE ("entering clientKill");
3528- TRACE ("killing client \"%s\" (0x%lx)", c->name, c->window);
3529-
3530- XKillClient (clientGetXDisplay (c), c->window);
3531-}
3532-
3533-void
3534-clientTerminate (Client *c)
3535-{
3536- ScreenInfo *screen_info;
3537- DisplayInfo *display_info;
3538-
3539- g_return_if_fail (c != NULL);
3540- TRACE ("entering clientTerminate");
3541-
3542- screen_info = c->screen_info;
3543- display_info = screen_info->display_info;
3544-
3545- if ((c->hostname) && (c->pid > 0))
3546- {
3547- if (!strcmp (display_info->hostname, c->hostname))
3548- {
3549- TRACE ("Sending client %s (pid %i) signal SIGKILL\n", c->name, c->pid);
3550-
3551- if (kill (c->pid, SIGKILL) < 0)
3552- {
3553- g_warning ("Failed to kill client id %d: %s", c->pid, strerror (errno));
3554- }
3555- }
3556- }
3557-
3558- clientKill (c);
3559-}
3560-
3561-void
3562-clientEnterContextMenuState (Client *c)
3563-{
3564- ScreenInfo *screen_info;
3565- DisplayInfo *display_info;
3566-
3567- g_return_if_fail (c != NULL);
3568-
3569- TRACE ("entering clientEnterContextMenuState");
3570- TRACE ("Showing the what's this help for client \"%s\" (0x%lx)", c->name, c->window);
3571-
3572- screen_info = c->screen_info;
3573- display_info = screen_info->display_info;
3574-
3575- if (FLAG_TEST (c->wm_flags, WM_FLAG_CONTEXT_HELP))
3576- {
3577- sendClientMessage (c->screen_info, c->window, NET_WM_CONTEXT_HELP,
3578- myDisplayGetCurrentTime (display_info));
3579- }
3580-}
3581-
3582-void
3583-clientSetLayer (Client *c, guint l)
3584-{
3585- GList *list_of_windows = NULL;
3586- GList *list = NULL;
3587- Client *c2 = NULL;
3588-
3589- g_return_if_fail (c != NULL);
3590- TRACE ("entering clientSetLayer for \"%s\" (0x%lx) on layer %d", c->name, c->window, l);
3591-
3592- list_of_windows = clientListTransientOrModal (c);
3593- for (list = list_of_windows; list; list = g_list_next (list))
3594- {
3595- c2 = (Client *) list->data;
3596- if (c2->win_layer != l)
3597- {
3598- TRACE ("setting client \"%s\" (0x%lx) layer to %d", c2->name,
3599- c2->window, l);
3600- c2->win_layer = l;
3601- }
3602- }
3603- g_list_free (list_of_windows);
3604-
3605- if (clientGetLastRaise (c->screen_info) == c)
3606- {
3607- clientClearLastRaise (c->screen_info);
3608- }
3609-
3610- c2 = clientGetFocusOrPending ();
3611- if (c2 && (c2 != c) && (c2->win_layer == c->win_layer))
3612- {
3613- TRACE ("Placing %s under %s", c->name, c2->name);
3614- clientLower (c, c2->frame);
3615- }
3616- else
3617- {
3618- TRACE ("Placing %s on top of its layer %lu", c->name, c->win_layer);
3619- clientRaise (c, None);
3620- }
3621-}
3622-
3623-void
3624-clientShade (Client *c)
3625-{
3626- XWindowChanges wc;
3627- ScreenInfo *screen_info;
3628- DisplayInfo *display_info;
3629- unsigned long mask;
3630-
3631- g_return_if_fail (c != NULL);
3632- TRACE ("entering clientToggleShaded");
3633- TRACE ("shading client \"%s\" (0x%lx)", c->name, c->window);
3634-
3635- if (!FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_BORDER)
3636- || FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
3637- {
3638- TRACE ("cowardly refusing to shade \"%s\" (0x%lx) because it has no border", c->name, c->window);
3639- return;
3640- }
3641- else if (FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
3642- {
3643- TRACE ("\"%s\" (0x%lx) is already shaded", c->name, c->window);
3644- return;
3645- }
3646-
3647- screen_info = c->screen_info;
3648- display_info = screen_info->display_info;
3649-
3650- FLAG_SET (c->flags, CLIENT_FLAG_SHADED);
3651- if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MANAGED))
3652- {
3653- mask = (CWWidth | CWHeight);
3654- if (clientConstrainPos (c, FALSE))
3655- {
3656- wc.x = c->x;
3657- wc.y = c->y;
3658- mask |= (CWX | CWY);
3659- }
3660-
3661- if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE))
3662- {
3663- c->ignore_unmap++;
3664- }
3665- /*
3666- * Shading unmaps the client window. We therefore have to transfer focus to its frame
3667- * so that focus doesn't return to root. clientSetFocus() will take care of focusing
3668- * the window frame since the SHADED flag is now set.
3669- */
3670- if (c == clientGetFocus ())
3671- {
3672- clientSetFocus (screen_info, c, myDisplayGetCurrentTime (display_info), FOCUS_FORCE);
3673- }
3674- XUnmapWindow (display_info->dpy, c->window);
3675-
3676- wc.width = c->width;
3677- wc.height = c->height;
3678- clientConfigure (c, &wc, mask, CFG_FORCE_REDRAW);
3679- }
3680- clientSetNetState (c);
3681-}
3682-
3683-void
3684-clientUnshade (Client *c)
3685-{
3686- XWindowChanges wc;
3687- ScreenInfo *screen_info;
3688- DisplayInfo *display_info;
3689-
3690- g_return_if_fail (c != NULL);
3691- TRACE ("entering clientToggleShaded");
3692- TRACE ("shading/unshading client \"%s\" (0x%lx)", c->name, c->window);
3693-
3694- if (!FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
3695- {
3696- TRACE ("\"%s\" (0x%lx) is not shaded", c->name, c->window);
3697- return;
3698- }
3699-
3700- screen_info = c->screen_info;
3701- display_info = screen_info->display_info;
3702-
3703- FLAG_UNSET (c->flags, CLIENT_FLAG_SHADED);
3704- if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MANAGED))
3705- {
3706- if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE))
3707- {
3708- XMapWindow (display_info->dpy, c->window);
3709- }
3710- /*
3711- * Unshading will show the client window, so we need to focus it when unshading.
3712- */
3713- if (c == clientGetFocus ())
3714- {
3715- clientSetFocus (screen_info, c, myDisplayGetCurrentTime (display_info), FOCUS_FORCE);
3716- }
3717-
3718- wc.width = c->width;
3719- wc.height = c->height;
3720- clientConfigure (c, &wc, CWWidth | CWHeight, CFG_FORCE_REDRAW);
3721- }
3722- clientSetNetState (c);
3723-}
3724-
3725-void
3726-clientToggleShaded (Client *c)
3727-{
3728- if (FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
3729- {
3730- clientUnshade (c);
3731- }
3732- else
3733- {
3734- clientShade (c);
3735- }
3736-}
3737-
3738-void
3739-clientStick (Client *c, gboolean include_transients)
3740-{
3741- ScreenInfo *screen_info;
3742- DisplayInfo *display_info;
3743- Client *c2;
3744- GList *list_of_windows;
3745- GList *list;
3746-
3747- g_return_if_fail (c != NULL);
3748- TRACE ("entering clientStick");
3749-
3750- screen_info = c->screen_info;
3751- display_info = screen_info->display_info;
3752-
3753- if (include_transients)
3754- {
3755- list_of_windows = clientListTransientOrModal (c);
3756- for (list = list_of_windows; list; list = g_list_next (list))
3757- {
3758- c2 = (Client *) list->data;
3759- TRACE ("Sticking client \"%s\" (0x%lx)", c2->name, c2->window);
3760- FLAG_SET (c2->flags, CLIENT_FLAG_STICKY);
3761- setHint (display_info, c2->window, NET_WM_DESKTOP, (unsigned long) ALL_WORKSPACES);
3762- frameQueueDraw (c2, FALSE);
3763- }
3764- g_list_free (list_of_windows);
3765- }
3766- else
3767- {
3768- TRACE ("Sticking client \"%s\" (0x%lx)", c->name, c->window);
3769- FLAG_SET (c->flags, CLIENT_FLAG_STICKY);
3770- setHint (display_info, c->window, NET_WM_DESKTOP, (unsigned long) ALL_WORKSPACES);
3771- }
3772- clientSetWorkspace (c, screen_info->current_ws, TRUE);
3773- clientSetNetState (c);
3774-}
3775-
3776-void
3777-clientUnstick (Client *c, gboolean include_transients)
3778-{
3779- ScreenInfo *screen_info;
3780- DisplayInfo *display_info;
3781- Client *c2;
3782- GList *list_of_windows;
3783- GList *list;
3784-
3785- g_return_if_fail (c != NULL);
3786- TRACE ("entering clientUnstick");
3787-
3788- screen_info = c->screen_info;
3789- display_info = screen_info->display_info;
3790-
3791- if (include_transients)
3792- {
3793- list_of_windows = clientListTransientOrModal (c);
3794- for (list = list_of_windows; list; list = g_list_next (list))
3795- {
3796- c2 = (Client *) list->data;
3797- TRACE ("Unsticking client \"%s\" (0x%lx)", c2->name, c2->window);
3798- FLAG_UNSET (c2->flags, CLIENT_FLAG_STICKY);
3799- setHint (display_info, c2->window, NET_WM_DESKTOP, (unsigned long) screen_info->current_ws);
3800- frameQueueDraw (c2, FALSE);
3801- }
3802- g_list_free (list_of_windows);
3803- }
3804- else
3805- {
3806- TRACE ("Unsticking client \"%s\" (0x%lx)", c->name, c->window);
3807- FLAG_UNSET (c->flags, CLIENT_FLAG_STICKY);
3808- setHint (display_info, c->window, NET_WM_DESKTOP, (unsigned long) screen_info->current_ws);
3809- }
3810- clientSetWorkspace (c, screen_info->current_ws, TRUE);
3811- clientSetNetState (c);
3812-}
3813-
3814-void
3815-clientToggleSticky (Client *c, gboolean include_transients)
3816-{
3817- g_return_if_fail (c != NULL);
3818- TRACE ("entering clientToggleSticky");
3819- TRACE ("sticking/unsticking client \"%s\" (0x%lx)", c->name, c->window);
3820-
3821- if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
3822- {
3823- clientUnstick (c, include_transients);
3824- }
3825- else
3826- {
3827- clientStick (c, include_transients);
3828- }
3829-}
3830-
3831-void
3832-clientUpdateFullscreenSize (Client *c)
3833-{
3834- ScreenInfo *screen_info;
3835- XWindowChanges wc;
3836- GdkRectangle monitor, rect;
3837- int i;
3838-
3839- g_return_if_fail (c != NULL);
3840- TRACE ("entering clientUpdateFullscreenSize");
3841- TRACE ("Update fullscreen size for client \"%s\" (0x%lx)", c->name, c->window);
3842-
3843- screen_info = c->screen_info;
3844-
3845- if (FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
3846- {
3847- if (FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREN_MONITORS))
3848- {
3849- gdk_screen_get_monitor_geometry (screen_info->gscr, c->fullscreen_monitors[0], &rect);
3850- for (i = 1; i < 4; i++)
3851- {
3852- gdk_screen_get_monitor_geometry (screen_info->gscr, c->fullscreen_monitors[i], &monitor);
3853- gdk_rectangle_union (&rect, &monitor, &rect);
3854- }
3855- }
3856- else
3857- {
3858- int cx, cy;
3859-
3860- cx = frameX (c) + (frameWidth (c) / 2);
3861- cy = frameY (c) + (frameHeight (c) / 2);
3862-
3863- myScreenFindMonitorAtPoint (screen_info, cx, cy, &rect);
3864- }
3865-
3866- wc.x = rect.x;
3867- wc.y = rect.y;
3868- wc.width = rect.width;
3869- wc.height = rect.height;
3870- }
3871-
3872- else
3873- {
3874- wc.x = c->fullscreen_old_x;
3875- wc.y = c->fullscreen_old_y;
3876- wc.width = c->fullscreen_old_width;
3877- wc.height = c->fullscreen_old_height;
3878- }
3879-
3880- if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MANAGED))
3881- {
3882- clientConfigure (c, &wc, CWX | CWY | CWWidth | CWHeight, CFG_FORCE_REDRAW);
3883- }
3884- else
3885- {
3886- c->x = wc.x;
3887- c->y = wc.y;
3888- c->height = wc.height;
3889- c->width = wc.width;
3890- }
3891-}
3892-
3893-void clientToggleFullscreen (Client *c)
3894-{
3895- g_return_if_fail (c != NULL);
3896- TRACE ("entering clientToggleFullscreen");
3897- TRACE ("toggle fullscreen client \"%s\" (0x%lx)", c->name, c->window);
3898-
3899- /*can we switch to full screen, does it make any sense? */
3900- if (!FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN) && (c->size->flags & PMaxSize))
3901- {
3902- GdkRectangle rect;
3903- int cx, cy;
3904-
3905- cx = frameX (c) + (frameWidth (c) / 2);
3906- cy = frameY (c) + (frameHeight (c) / 2);
3907-
3908- myScreenFindMonitorAtPoint (c->screen_info, cx, cy, &rect);
3909-
3910- if ((c->size->max_width < rect.width) || (c->size->max_height < rect.height))
3911- {
3912- return;
3913- }
3914- }
3915-
3916- if (!clientIsTransientOrModal (c) && (c->type == WINDOW_NORMAL))
3917- {
3918- FLAG_TOGGLE (c->flags, CLIENT_FLAG_FULLSCREEN);
3919- clientUpdateFullscreenState (c);
3920- }
3921-}
3922-
3923-void clientSetFullscreenMonitor (Client *c, gint top, gint bottom, gint left, gint right)
3924-{
3925- ScreenInfo *screen_info;
3926- DisplayInfo *display_info;
3927- gint num_monitors;
3928-
3929- g_return_if_fail (c != NULL);
3930- TRACE ("entering clientSetFullscreenMonitor");
3931-
3932- screen_info = c->screen_info;
3933- display_info = screen_info->display_info;
3934-
3935- num_monitors = gdk_screen_get_n_monitors (screen_info->gscr);
3936- if ((top >= 0) && (top < num_monitors) &&
3937- (bottom >= 0) && (bottom < num_monitors) &&
3938- (left >= 0) && (left < num_monitors) &&
3939- (right >= 0) && (right < num_monitors))
3940- {
3941- c->fullscreen_monitors[0] = top;
3942- c->fullscreen_monitors[1] = bottom;
3943- c->fullscreen_monitors[2] = left;
3944- c->fullscreen_monitors[3] = right;
3945- FLAG_SET (c->flags, CLIENT_FLAG_FULLSCREN_MONITORS);
3946- }
3947- else
3948- {
3949- c->fullscreen_monitors[0] = 0;
3950- c->fullscreen_monitors[1] = 0;
3951- c->fullscreen_monitors[2] = 0;
3952- c->fullscreen_monitors[3] = 0;
3953- FLAG_UNSET (c->flags, CLIENT_FLAG_FULLSCREN_MONITORS);
3954- }
3955- if (FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
3956- {
3957- clientUpdateFullscreenSize (c);
3958- }
3959- if (FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREN_MONITORS))
3960- {
3961- setNetFullscreenMonitors (display_info, c->window, top, bottom, left, right);
3962- }
3963-}
3964-
3965-void clientToggleLayerAbove (Client *c)
3966-{
3967- g_return_if_fail (c != NULL);
3968- TRACE ("entering clientToggleAbove");
3969-
3970- if ((c->type & WINDOW_REGULAR_FOCUSABLE) &&
3971- !clientIsTransientOrModal (c) &&
3972- !FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
3973- {
3974- FLAG_UNSET (c->flags, CLIENT_FLAG_BELOW);
3975- FLAG_TOGGLE (c->flags, CLIENT_FLAG_ABOVE);
3976- clientUpdateLayerState (c);
3977- }
3978-}
3979-
3980-void clientToggleLayerBelow (Client *c)
3981-{
3982- g_return_if_fail (c != NULL);
3983- TRACE ("entering clientToggleBelow");
3984-
3985- if ((c->type & WINDOW_REGULAR_FOCUSABLE) &&
3986- !clientIsTransientOrModal (c) &&
3987- !FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
3988- {
3989- FLAG_UNSET (c->flags, CLIENT_FLAG_ABOVE);
3990- FLAG_TOGGLE (c->flags, CLIENT_FLAG_BELOW);
3991- clientUpdateLayerState (c);
3992- }
3993-}
3994-
3995-void clientSetLayerNormal (Client *c)
3996-{
3997- g_return_if_fail (c != NULL);
3998- TRACE ("entering clientSetLayerNormal");
3999-
4000- if (!FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
4001- {
4002- FLAG_UNSET (c->flags, CLIENT_FLAG_ABOVE | CLIENT_FLAG_BELOW);
4003- clientUpdateLayerState (c);
4004- }
4005-}
4006-
4007-void
4008-clientRemoveMaximizeFlag (Client *c)
4009-{
4010- g_return_if_fail (c != NULL);
4011- TRACE ("entering clientRemoveMaximizeFlag");
4012- TRACE ("Removing maximize flag on client \"%s\" (0x%lx)", c->name,
4013- c->window);
4014-
4015- FLAG_UNSET (c->flags, CLIENT_FLAG_MAXIMIZED);
4016- frameQueueDraw (c, FALSE);
4017- clientSetNetActions (c);
4018- clientSetNetState (c);
4019-}
4020-
4021-static void
4022-clientNewMaxState (Client *c, XWindowChanges *wc, int mode)
4023-{
4024- if (FLAG_TEST_ALL (mode, CLIENT_FLAG_MAXIMIZED))
4025- {
4026- /*
4027- * We need to test specifically for full de-maximization
4028- * otherwise it's too confusing when the window changes
4029- * from horiz to vertical maximization or vice-versa.
4030- */
4031- if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED))
4032- {
4033- FLAG_UNSET (c->flags, CLIENT_FLAG_MAXIMIZED);
4034- wc->x = c->old_x;
4035- wc->y = c->old_y;
4036- wc->width = c->old_width;
4037- wc->height = c->old_height;
4038-
4039- return;
4040- }
4041- }
4042-
4043- if (FLAG_TEST (mode, CLIENT_FLAG_MAXIMIZED_HORIZ))
4044- {
4045- if (!FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ))
4046- {
4047- FLAG_SET (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ);
4048- }
4049- else
4050- {
4051- FLAG_UNSET (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ);
4052- wc->x = c->old_x;
4053- wc->y = c->old_y;
4054- wc->width = c->old_width;
4055- wc->height = c->old_height;
4056- }
4057- }
4058-
4059- if (FLAG_TEST (mode, CLIENT_FLAG_MAXIMIZED_VERT))
4060- {
4061- if (!FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_VERT))
4062- {
4063- FLAG_SET (c->flags, CLIENT_FLAG_MAXIMIZED_VERT);
4064- }
4065- else
4066- {
4067- FLAG_UNSET (c->flags, CLIENT_FLAG_MAXIMIZED_VERT);
4068- wc->x = c->old_x;
4069- wc->y = c->old_y;
4070- wc->width = c->old_width;
4071- wc->height = c->old_height;
4072- }
4073- }
4074-}
4075-
4076-static gboolean
4077-clientNewMaxSize (Client *c, XWindowChanges *wc, GdkRectangle *rect, tilePositionType tile)
4078-{
4079- ScreenInfo *screen_info;
4080- int full_x, full_y, full_w, full_h;
4081- int tmp_x, tmp_y, tmp_w, tmp_h;
4082-
4083- tmp_x = frameX (c);
4084- tmp_y = frameY (c);
4085- tmp_h = frameHeight (c);
4086- tmp_w = frameWidth (c);
4087- screen_info = c->screen_info;
4088-
4089- full_x = MAX (screen_info->params->xfwm_margins[STRUTS_LEFT], rect->x);
4090- full_y = MAX (screen_info->params->xfwm_margins[STRUTS_TOP], rect->y);
4091- full_w = MIN (screen_info->width - screen_info->params->xfwm_margins[STRUTS_RIGHT],
4092- rect->x + rect->width) - full_x;
4093- full_h = MIN (screen_info->height - screen_info->params->xfwm_margins[STRUTS_BOTTOM],
4094- rect->y + rect->height) - full_y;
4095-
4096- if (FLAG_TEST_ALL (c->flags, CLIENT_FLAG_MAXIMIZED))
4097- {
4098- /* Adjust size to the largest size available, not covering struts */
4099- clientMaxSpace (screen_info, &full_x, &full_y, &full_w, &full_h);
4100- wc->x = full_x + frameLeft (c);
4101- wc->y = full_y + frameTop (c);
4102- wc->width = full_w - frameLeft (c) - frameRight (c);
4103- wc->height = full_h - frameTop (c) - frameBottom (c);
4104-
4105- return ((wc->width <= c->size->max_width) && (wc->height <= c->size->max_height));
4106- }
4107-
4108- if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ))
4109- {
4110- /* Adjust size to the widest size available, for the current vertical position/height */
4111- switch (tile)
4112- {
4113- case TILE_UP:
4114- tmp_h = full_h / 2;
4115- tmp_y = full_y;
4116- clientMaxSpace (screen_info, &full_x, &tmp_y, &full_w, &tmp_h);
4117- wc->y = tmp_y + frameTop (c);
4118- wc->height = tmp_h - frameTop (c) - frameBottom (c);
4119- break;
4120- case TILE_DOWN:
4121- tmp_h = full_h / 2;
4122- tmp_y = full_y + full_h / 2;
4123- clientMaxSpace (screen_info, &full_x, &tmp_y, &full_w, &tmp_h);
4124- wc->y = tmp_y + frameTop (c);
4125- wc->height = tmp_h - frameTop (c) - frameBottom (c);
4126- break;
4127- default:
4128- clientMaxSpace (screen_info, &full_x, &tmp_y, &full_w, &tmp_h);
4129- break;
4130- }
4131-
4132- wc->x = full_x + frameLeft (c);
4133- wc->width = full_w - frameLeft (c) - frameRight (c);
4134-
4135- return (wc->width <= c->size->max_width);
4136- }
4137-
4138- if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_VERT))
4139- {
4140- /* Adjust size to the tallest size available, for the current horizontal position/width */
4141- switch (tile)
4142- {
4143- case TILE_LEFT:
4144- tmp_x = full_x;
4145- tmp_w = full_w / 2;
4146- clientMaxSpace (screen_info, &tmp_x, &full_y, &tmp_w, &full_h);
4147- wc->x = tmp_x + frameLeft (c);
4148- wc->width = tmp_w - frameLeft (c) - frameRight (c);
4149- break;
4150- case TILE_RIGHT:
4151- tmp_x = full_x + full_w /2;
4152- tmp_w = full_w / 2;
4153- clientMaxSpace (screen_info, &tmp_x, &full_y, &tmp_w, &full_h);
4154- wc->x = tmp_x + frameLeft (c);
4155- wc->width = tmp_w - frameLeft (c) - frameRight (c);
4156- break;
4157- default:
4158- clientMaxSpace (screen_info, &tmp_x, &full_y, &tmp_w, &full_h);
4159- break;
4160- }
4161-
4162- wc->y = full_y + frameTop (c);
4163- wc->height = full_h - frameTop (c) - frameBottom (c);
4164-
4165- return (wc->height <= c->size->max_height);
4166- }
4167-
4168- return TRUE;
4169-}
4170-
4171-gboolean
4172-clientToggleMaximized (Client *c, int mode, gboolean restore_position)
4173-{
4174- DisplayInfo *display_info;
4175- ScreenInfo *screen_info;
4176- XWindowChanges wc;
4177- GdkRectangle rect;
4178- unsigned long old_flags;
4179-
4180- g_return_val_if_fail (c != NULL, FALSE);
4181-
4182- TRACE ("entering clientToggleMaximized");
4183- TRACE ("maximzing/unmaximizing client \"%s\" (0x%lx)", c->name, c->window);
4184-
4185- if (!CLIENT_CAN_MAXIMIZE_WINDOW (c))
4186- {
4187- return FALSE;
4188- }
4189-
4190- screen_info = c->screen_info;
4191- display_info = screen_info->display_info;
4192- myScreenFindMonitorAtPoint (screen_info,
4193- frameX (c) + (frameWidth (c) / 2),
4194- frameY (c) + (frameHeight (c) / 2), &rect);
4195-
4196- wc.x = c->x;
4197- wc.y = c->y;
4198- wc.width = c->width;
4199- wc.height = c->height;
4200-
4201- if (restore_position &&
4202- FLAG_TEST (mode, CLIENT_FLAG_MAXIMIZED) &&
4203- !FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED))
4204- {
4205- clientSaveSizePos (c);
4206- }
4207-
4208- old_flags = c->flags;
4209-
4210- /* 1) Compute the new state */
4211- clientNewMaxState (c, &wc, mode);
4212-
4213- /* 2) Compute the new size, based on the state */
4214- if (!clientNewMaxSize (c, &wc, &rect, TILE_NONE))
4215- {
4216- c->flags = old_flags;
4217- return FALSE;
4218- }
4219-
4220- /* 3) Update size and position fields */
4221- c->x = wc.x;
4222- c->y = wc.y;
4223- c->height = wc.height;
4224- c->width = wc.width;
4225-
4226- /* Maximizing may remove decoration on the side, update NET_FRAME_EXTENTS accordingly */
4227- setNetFrameExtents (display_info,
4228- c->window,
4229- frameTop (c),
4230- frameLeft (c),
4231- frameRight (c),
4232- frameBottom (c));
4233-
4234- /* Maximized windows w/out border cannot be resized, update allowed actions */
4235- clientSetNetActions (c);
4236- if (restore_position && FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MANAGED))
4237- {
4238- clientConfigure (c, &wc, CWWidth | CWHeight | CWX | CWY, CFG_FORCE_REDRAW);
4239- }
4240- clientSetNetState (c);
4241-
4242- return TRUE;
4243-}
4244-
4245-gboolean
4246-clientTile (Client *c, gint cx, gint cy, tilePositionType tile, gboolean send_configure)
4247-{
4248- DisplayInfo *display_info;
4249- ScreenInfo *screen_info;
4250- XWindowChanges wc;
4251- GdkRectangle rect;
4252- unsigned long old_flags;
4253- int mode;
4254-
4255- g_return_val_if_fail (c != NULL, FALSE);
4256-
4257- TRACE ("entering clientTile");
4258- TRACE ("Tiling client \"%s\" (0x%lx)", c->name, c->window);
4259-
4260- if (!CLIENT_CAN_TILE_WINDOW (c))
4261- {
4262- return FALSE;
4263- }
4264-
4265- screen_info = c->screen_info;
4266- display_info = screen_info->display_info;
4267- myScreenFindMonitorAtPoint (screen_info, cx, cy, &rect);
4268-
4269- wc.x = c->x;
4270- wc.y = c->y;
4271- wc.width = c->width;
4272- wc.height = c->height;
4273-
4274- switch (tile)
4275- {
4276- case TILE_LEFT:
4277- case TILE_RIGHT:
4278- mode = CLIENT_FLAG_MAXIMIZED_VERT;
4279- break;
4280- case TILE_UP:
4281- case TILE_DOWN:
4282- mode = CLIENT_FLAG_MAXIMIZED_HORIZ;
4283- break;
4284- default:
4285- return FALSE;
4286- break;
4287- }
4288-
4289- if (!FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED))
4290- {
4291- clientSaveSizePos (c);
4292- }
4293-
4294- old_flags = c->flags;
4295- FLAG_UNSET (c->flags, CLIENT_FLAG_MAXIMIZED);
4296- clientNewMaxState (c, &wc, mode);
4297- if (!clientNewMaxSize (c, &wc, &rect, tile))
4298- {
4299- c->flags = old_flags;
4300- return FALSE;
4301- }
4302-
4303- c->x = wc.x;
4304- c->y = wc.y;
4305- c->height = wc.height;
4306- c->width = wc.width;
4307-
4308- if (send_configure)
4309- {
4310- setNetFrameExtents (display_info,
4311- c->window,
4312- frameTop (c),
4313- frameLeft (c),
4314- frameRight (c),
4315- frameBottom (c));
4316-
4317- clientSetNetActions (c);
4318-
4319- clientConfigure (c, &wc, CWWidth | CWHeight | CWX | CWY, CFG_FORCE_REDRAW);
4320- }
4321- clientSetNetState (c);
4322-
4323- return TRUE;
4324-}
4325-
4326-void
4327-clientUpdateOpacity (Client *c)
4328-{
4329- ScreenInfo *screen_info;
4330- DisplayInfo *display_info;
4331- Client *focused;
4332- gboolean opaque;
4333-
4334- g_return_if_fail (c != NULL);
4335-
4336- screen_info = c->screen_info;
4337- display_info = screen_info->display_info;
4338- if (!compositorIsUsable (display_info))
4339- {
4340- return;
4341- }
4342-
4343- focused = clientGetFocus ();
4344- opaque = (FLAG_TEST(c->type, WINDOW_TYPE_DONT_PLACE | WINDOW_TYPE_DONT_FOCUS)
4345- || (focused == c));
4346-
4347- clientSetOpacity (c, c->opacity, OPACITY_INACTIVE, opaque ? 0 : OPACITY_INACTIVE);
4348-}
4349-
4350-void
4351-clientUpdateAllOpacity (ScreenInfo *screen_info)
4352-{
4353- DisplayInfo *display_info;
4354- Client *c;
4355- guint i;
4356-
4357- g_return_if_fail (screen_info != NULL);
4358-
4359- display_info = screen_info->display_info;
4360- if (!compositorIsUsable (display_info))
4361- {
4362- return;
4363- }
4364-
4365- for (c = screen_info->clients, i = 0; i < screen_info->client_count; c = c->next, ++i)
4366- {
4367- clientUpdateOpacity (c);
4368- }
4369-}
4370-
4371-void
4372-clientSetOpacity (Client *c, guint opacity, guint clear, guint xor)
4373-{
4374- ScreenInfo *screen_info;
4375- DisplayInfo *display_info;
4376- guint applied;
4377-
4378- screen_info = c->screen_info;
4379- display_info = screen_info->display_info;
4380-
4381- if (!compositorIsUsable (display_info))
4382- {
4383- return;
4384- }
4385-
4386- c->opacity_flags = (c->opacity_flags & ~clear) ^ xor;
4387-
4388- if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_OPACITY_LOCKED))
4389- {
4390- applied = c->opacity;
4391- }
4392- else
4393- {
4394- long long multiplier = 1, divisor = 1;
4395-
4396- c->opacity = applied = opacity;
4397-
4398- if (FLAG_TEST (c->opacity_flags, OPACITY_MOVE))
4399- {
4400- multiplier *= c->screen_info->params->move_opacity;
4401- divisor *= 100;
4402- }
4403- if (FLAG_TEST (c->opacity_flags, OPACITY_RESIZE))
4404- {
4405- multiplier *= c->screen_info->params->resize_opacity;
4406- divisor *= 100;
4407- }
4408- if (FLAG_TEST (c->opacity_flags, OPACITY_INACTIVE))
4409- {
4410- multiplier *= c->screen_info->params->inactive_opacity;
4411- divisor *= 100;
4412- }
4413-
4414- applied = (guint) ((long long) applied * multiplier / divisor);
4415- }
4416-
4417- if (applied != c->opacity_applied)
4418- {
4419- c->opacity_applied = applied;
4420- compositorWindowSetOpacity (display_info, c->frame, applied);
4421- }
4422-}
4423-
4424-void
4425-clientDecOpacity (Client *c)
4426-{
4427- ScreenInfo *screen_info;
4428- DisplayInfo *display_info;
4429-
4430- screen_info = c->screen_info;
4431- display_info = screen_info->display_info;
4432-
4433- if (!compositorIsUsable (display_info))
4434- {
4435- return;
4436- }
4437-
4438- if ((c->opacity > OPACITY_SET_MIN) && !(FLAG_TEST (c->xfwm_flags, XFWM_FLAG_OPACITY_LOCKED)))
4439- {
4440- clientSetOpacity (c, c->opacity - OPACITY_SET_STEP, 0, 0);
4441- }
4442-}
4443-
4444-void
4445-clientIncOpacity (Client *c)
4446-{
4447- ScreenInfo *screen_info;
4448- DisplayInfo *display_info;
4449-
4450- screen_info = c->screen_info;
4451- display_info = screen_info->display_info;
4452-
4453- if (!compositorIsUsable (display_info))
4454- {
4455- return;
4456- }
4457-
4458- if ((c->opacity < NET_WM_OPAQUE) && !(FLAG_TEST (c->xfwm_flags, XFWM_FLAG_OPACITY_LOCKED)))
4459- {
4460- guint opacity = c->opacity + OPACITY_SET_STEP;
4461-
4462- if (opacity < OPACITY_SET_MIN)
4463- {
4464- opacity = NET_WM_OPAQUE;
4465- }
4466- clientSetOpacity (c, opacity, 0, 0);
4467- }
4468-}
4469-
4470-/* Xrandr stuff: on screen size change, make sure all clients are still visible */
4471-void
4472-clientScreenResize(ScreenInfo *screen_info, gboolean fully_visible)
4473-{
4474- Client *c = NULL;
4475- GList *list, *list_of_windows;
4476- XWindowChanges wc;
4477- unsigned short configure_flags;
4478-
4479- list_of_windows = clientGetStackList (screen_info);
4480-
4481- if (!list_of_windows)
4482- {
4483- return;
4484- }
4485-
4486- /* Revalidate client struts */
4487- for (list = list_of_windows; list; list = g_list_next (list))
4488- {
4489- c = (Client *) list->data;
4490- if (FLAG_TEST (c->flags, CLIENT_FLAG_HAS_STRUT))
4491- {
4492- clientValidateNetStrut (c);
4493- }
4494- }
4495-
4496- for (list = list_of_windows; list; list = g_list_next (list))
4497- {
4498- unsigned long maximization_flags = 0L;
4499-
4500- c = (Client *) list->data;
4501- if (!CONSTRAINED_WINDOW (c))
4502- {
4503- continue;
4504- }
4505-
4506- /* Recompute size and position of maximized windows */
4507- if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED))
4508- {
4509- maximization_flags = c->flags & CLIENT_FLAG_MAXIMIZED;
4510-
4511- /* Force an update by clearing the internal flags */
4512- FLAG_UNSET (c->flags, CLIENT_FLAG_MAXIMIZED);
4513- clientToggleMaximized (c, maximization_flags, FALSE);
4514-
4515- wc.x = c->x;
4516- wc.y = c->y;
4517- wc.width = c->width;
4518- wc.height = c->height;
4519- clientConfigure (c, &wc, CWX | CWY | CWWidth | CWHeight, CFG_NOTIFY);
4520- }
4521- else if (FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
4522- {
4523- clientUpdateFullscreenSize (c);
4524- }
4525- else
4526- {
4527- configure_flags = CFG_CONSTRAINED | CFG_REQUEST;
4528- if (fully_visible)
4529- {
4530- configure_flags |= CFG_KEEP_VISIBLE;
4531- }
4532- if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_SAVED_POS))
4533- {
4534- wc.x = c->saved_x;
4535- wc.y = c->saved_y;
4536- }
4537- else
4538- {
4539- FLAG_SET (c->xfwm_flags, XFWM_FLAG_SAVED_POS);
4540-
4541- c->saved_x = c->x;
4542- c->saved_y = c->y;
4543-
4544- wc.x = c->x;
4545- wc.y = c->y;
4546- }
4547-
4548- clientConfigure (c, &wc, CWX | CWY, configure_flags);
4549- }
4550- }
4551-
4552- g_list_free (list_of_windows);
4553-}
4554-
4555-void
4556-clientUpdateCursor (Client *c)
4557-{
4558- ScreenInfo *screen_info;
4559- DisplayInfo *display_info;
4560- guint i;
4561-
4562- g_return_if_fail (c != NULL);
4563-
4564- screen_info = c->screen_info;
4565- display_info = screen_info->display_info;
4566-
4567- for (i = 0; i <= SIDE_TOP; i++)
4568- {
4569- xfwmWindowSetCursor (&c->sides[i],
4570- myDisplayGetCursorResize(display_info, CORNER_COUNT + i));
4571- }
4572-
4573- for (i = 0; i < CORNER_COUNT; i++)
4574- {
4575- xfwmWindowSetCursor (&c->corners[i],
4576- myDisplayGetCursorResize(display_info, i));
4577- }
4578-}
4579-
4580-void
4581-clientUpdateAllCursor (ScreenInfo *screen_info)
4582-{
4583- Client *c;
4584- guint i;
4585-
4586- g_return_if_fail (screen_info != NULL);
4587-
4588- for (c = screen_info->clients, i = 0; i < screen_info->client_count; c = c->next, ++i)
4589- {
4590- clientUpdateCursor (c);
4591- }
4592-}
4593-
4594-static eventFilterStatus
4595-clientButtonPressEventFilter (XEvent * xevent, gpointer data)
4596-{
4597- ScreenInfo *screen_info;
4598- DisplayInfo *display_info;
4599- Client *c;
4600- ButtonPressData *passdata;
4601- eventFilterStatus status;
4602- int b;
4603- gboolean pressed;
4604-
4605- passdata = (ButtonPressData *) data;
4606- c = passdata->c;
4607- b = passdata->b;
4608-
4609- screen_info = c->screen_info;
4610- display_info = screen_info->display_info;
4611-
4612- /* Update the display time */
4613- myDisplayUpdateCurrentTime (display_info, xevent);
4614-
4615- status = EVENT_FILTER_STOP;
4616- pressed = TRUE;
4617-
4618- switch (xevent->type)
4619- {
4620- case EnterNotify:
4621- if ((xevent->xcrossing.mode != NotifyGrab) && (xevent->xcrossing.mode != NotifyUngrab))
4622- {
4623- c->button_status[b] = BUTTON_STATE_PRESSED;
4624- frameQueueDraw (c, FALSE);
4625- }
4626- break;
4627- case LeaveNotify:
4628- if ((xevent->xcrossing.mode != NotifyGrab) && (xevent->xcrossing.mode != NotifyUngrab))
4629- {
4630- c->button_status[b] = BUTTON_STATE_NORMAL;
4631- frameQueueDraw (c, FALSE);
4632- }
4633- break;
4634- case ButtonRelease:
4635- pressed = FALSE;
4636- break;
4637- case UnmapNotify:
4638- if (xevent->xunmap.window == c->window)
4639- {
4640- pressed = FALSE;
4641- c->button_status[b] = BUTTON_STATE_NORMAL;
4642- }
4643- break;
4644- case KeyPress:
4645- case KeyRelease:
4646- break;
4647- default:
4648- status = EVENT_FILTER_CONTINUE;
4649- break;
4650- }
4651-
4652- if (!pressed)
4653- {
4654- TRACE ("event loop now finished");
4655- gtk_main_quit ();
4656- }
4657-
4658- return status;
4659-}
4660-
4661-void
4662-clientButtonPress (Client *c, Window w, XButtonEvent * bev)
4663-{
4664- ScreenInfo *screen_info;
4665- DisplayInfo *display_info;
4666- ButtonPressData passdata;
4667- int b, g1;
4668-
4669- g_return_if_fail (c != NULL);
4670- TRACE ("entering clientButtonPress");
4671-
4672- for (b = 0; b < BUTTON_COUNT; b++)
4673- {
4674- if (MYWINDOW_XWINDOW (c->buttons[b]) == w)
4675- {
4676- break;
4677- }
4678- }
4679-
4680- screen_info = c->screen_info;
4681- display_info = screen_info->display_info;
4682-
4683- g1 = XGrabPointer (display_info->dpy, w, FALSE,
4684- ButtonReleaseMask | EnterWindowMask | LeaveWindowMask,
4685- GrabModeAsync, GrabModeAsync,
4686- screen_info->xroot, None,
4687- myDisplayGetCurrentTime (display_info));
4688-
4689- if (g1 != GrabSuccess)
4690- {
4691- TRACE ("grab failed in clientButtonPress");
4692- gdk_beep ();
4693- if (g1 == GrabSuccess)
4694- {
4695- XUngrabKeyboard (display_info->dpy, myDisplayGetCurrentTime (display_info));
4696- }
4697- return;
4698- }
4699-
4700- passdata.c = c;
4701- passdata.b = b;
4702-
4703- c->button_status[b] = BUTTON_STATE_PRESSED;
4704- frameQueueDraw (c, FALSE);
4705-
4706- TRACE ("entering button press loop");
4707- eventFilterPush (display_info->xfilter, clientButtonPressEventFilter, &passdata);
4708- gtk_main ();
4709- eventFilterPop (display_info->xfilter);
4710- TRACE ("leaving button press loop");
4711-
4712- XUngrabPointer (display_info->dpy, myDisplayGetCurrentTime (display_info));
4713-
4714- if (c->button_status[b] == BUTTON_STATE_PRESSED)
4715- {
4716- /*
4717- * Button was pressed at the time, means the pointer was still within
4718- * the button, so return to prelight if available, normal otherwise.
4719- */
4720- if (!xfwmPixmapNone(clientGetButtonPixmap(c, b, PRELIGHT)))
4721- {
4722- c->button_status[b] = BUTTON_STATE_PRELIGHT;
4723- }
4724- else
4725- {
4726- c->button_status[b] = BUTTON_STATE_NORMAL;
4727- }
4728-
4729- switch (b)
4730- {
4731- case HIDE_BUTTON:
4732- if (CLIENT_CAN_HIDE_WINDOW (c))
4733- {
4734- clientWithdraw (c, c->win_workspace, TRUE);
4735- }
4736- break;
4737- case CLOSE_BUTTON:
4738- clientClose (c);
4739- break;
4740- case MAXIMIZE_BUTTON:
4741- if (CLIENT_CAN_MAXIMIZE_WINDOW (c))
4742- {
4743- if (bev->button == Button1)
4744- {
4745- clientToggleMaximized (c, CLIENT_FLAG_MAXIMIZED, TRUE);
4746- }
4747- else if (bev->button == Button2)
4748- {
4749- clientToggleMaximized (c, CLIENT_FLAG_MAXIMIZED_VERT, TRUE);
4750- }
4751- else if (bev->button == Button3)
4752- {
4753- clientToggleMaximized (c, CLIENT_FLAG_MAXIMIZED_HORIZ, TRUE);
4754- }
4755- }
4756- break;
4757- case SHADE_BUTTON:
4758- clientToggleShaded (c);
4759- break;
4760- case STICK_BUTTON:
4761- clientToggleSticky (c, TRUE);
4762- break;
4763- default:
4764- break;
4765- }
4766- frameQueueDraw (c, FALSE);
4767- }
4768-}
4769-
4770-xfwmPixmap *
4771-clientGetButtonPixmap (Client *c, int button, int state)
4772-{
4773- ScreenInfo *screen_info;
4774-
4775- TRACE ("entering clientGetButtonPixmap button=%i, state=%i", button, state);
4776- screen_info = c->screen_info;
4777- switch (button)
4778- {
4779- case MENU_BUTTON:
4780- if ((screen_info->params->show_app_icon)
4781- && (!xfwmPixmapNone(&c->appmenu[state])))
4782- {
4783- return &c->appmenu[state];
4784- }
4785- break;
4786- case SHADE_BUTTON:
4787- if (FLAG_TEST (c->flags, CLIENT_FLAG_SHADED)
4788- && (!xfwmPixmapNone(&screen_info->buttons[SHADE_BUTTON][state + STATE_TOGGLED])))
4789- {
4790- return &screen_info->buttons[SHADE_BUTTON][state + STATE_TOGGLED];
4791- }
4792- return &screen_info->buttons[SHADE_BUTTON][state];
4793- break;
4794- case STICK_BUTTON:
4795- if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY)
4796- && (!xfwmPixmapNone(&screen_info->buttons[STICK_BUTTON][state + STATE_TOGGLED])))
4797- {
4798- return &screen_info->buttons[STICK_BUTTON][state + STATE_TOGGLED];
4799- }
4800- return &screen_info->buttons[STICK_BUTTON][state];
4801- break;
4802- case MAXIMIZE_BUTTON:
4803- if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED)
4804- && (!xfwmPixmapNone(&screen_info->buttons[MAXIMIZE_BUTTON][state + STATE_TOGGLED])))
4805- {
4806- return &screen_info->buttons[MAXIMIZE_BUTTON][state + STATE_TOGGLED];
4807- }
4808- return &screen_info->buttons[MAXIMIZE_BUTTON][state];
4809- break;
4810- default:
4811- break;
4812- }
4813- return &screen_info->buttons[button][state];
4814-}
4815-
4816-int
4817-clientGetButtonState (Client *c, int button, int state)
4818-{
4819- if (state == INACTIVE)
4820- {
4821- return (state);
4822- }
4823-
4824- if ((c->button_status[button] == BUTTON_STATE_PRESSED) &&
4825- clientGetButtonPixmap (c, button, PRESSED))
4826- {
4827- return (PRESSED);
4828- }
4829-
4830- if ((c->button_status[button] == BUTTON_STATE_PRELIGHT) &&
4831- clientGetButtonPixmap (c, button, PRELIGHT))
4832- {
4833- return (PRELIGHT);
4834- }
4835-
4836- return (ACTIVE);
4837-}
4838-
4839-
4840-Client *
4841-clientGetLeader (Client *c)
4842-{
4843- TRACE ("entering clientGetLeader");
4844- g_return_val_if_fail (c != NULL, NULL);
4845-
4846- if (c->group_leader != None)
4847- {
4848- return myScreenGetClientFromWindow (c->screen_info, c->group_leader, SEARCH_WINDOW);
4849- }
4850- else if (c->client_leader != None)
4851- {
4852- return myScreenGetClientFromWindow (c->screen_info, c->client_leader, SEARCH_WINDOW);
4853- }
4854- return NULL;
4855-}
4856-
4857-#ifdef HAVE_LIBSTARTUP_NOTIFICATION
4858-char *
4859-clientGetStartupId (Client *c)
4860-{
4861- ScreenInfo *screen_info;
4862- DisplayInfo *display_info;
4863- gboolean got_startup_id;
4864-
4865- g_return_val_if_fail (c != NULL, NULL);
4866- g_return_val_if_fail (c->window != None, NULL);
4867-
4868- screen_info = c->screen_info;
4869- display_info = screen_info->display_info;
4870- got_startup_id = FALSE;
4871-
4872- if (c->startup_id)
4873- {
4874- return (c->startup_id);
4875- }
4876-
4877- got_startup_id = getWindowStartupId (display_info, c->window, &c->startup_id);
4878-
4879- if (!got_startup_id && (c->client_leader))
4880- {
4881- got_startup_id = getWindowStartupId (display_info, c->client_leader, &c->startup_id);
4882- }
4883-
4884- if (!got_startup_id && (c->group_leader))
4885- {
4886- got_startup_id = getWindowStartupId (display_info, c->group_leader, &c->startup_id);
4887- }
4888-
4889- return (c->startup_id);
4890-}
4891-#endif /* HAVE_LIBSTARTUP_NOTIFICATION */
4892
4893=== removed file '.pc/applied-patches'
4894--- .pc/applied-patches 2013-12-03 15:24:16 +0000
4895+++ .pc/applied-patches 1970-01-01 00:00:00 +0000
4896@@ -1,2 +0,0 @@
4897-0004-Optimize-smart-placement-bug-5785.patch
4898-8563.patch
4899
4900=== modified file 'ChangeLog'
4901--- ChangeLog 2013-08-08 22:00:03 +0000
4902+++ ChangeLog 2014-01-19 09:12:15 +0000
4903@@ -1,18 +1,1444 @@
4904-commit 3918e6b09eaeac51d23f2c4a4a08e52e06e60a1b
4905-Author: Nick Schermer <nick@xfce.org>
4906-Date: Sun May 5 17:58:40 2013 +0200
4907-
4908- Updates for release.
4909-
4910-commit 52e1ecd35ef750fbb86bd5b91b8030325a46bc9d
4911+commit 2b800f4f994e0e3951fc221933705051329b75bd
4912+Author: Nick Schermer <nick@xfce.org>
4913+Date: Thu Dec 26 22:41:16 2013 +0100
4914+
4915+ Updates for release.
4916+
4917+commit d8c3df328934e865c92e8b2deb74f74b19a724b4
4918+Author: Nick Schermer <nick@xfce.org>
4919+Date: Thu Dec 26 18:16:40 2013 +0100
4920+
4921+ Disable roll up feature by default (bug #10563).
4922+
4923+ Probably a confusing feature for new users, the previous commit
4924+ made it easy to enable this again.
4925+
4926+commit a99c18c19ce6f17150818d6c0af23556fac1d454
4927+Author: Nick Schermer <nick@xfce.org>
4928+Date: Thu Dec 26 18:13:27 2013 +0100
4929+
4930+ Add tweak setting to toggle roll up feature (bug #10563).
4931+
4932+commit 3dab5fb5d641606fd12fb710881af8a3d8858681
4933+Author: Nick Schermer <nick@xfce.org>
4934+Date: Thu Dec 26 18:02:37 2013 +0100
4935+
4936+ Fix ordering of items in dialog.
4937+
4938+commit 7b091d1fbcc4489d1235865eef0d4ba5ba18b1e2
4939+Author: Walter Cheuk <wwycheuk@gmail.com>
4940+Date: Sun Dec 15 12:32:22 2013 +0100
4941+
4942+ I18n: Add new translation zh_HK (100%).
4943+
4944+ 170 translated messages.
4945+
4946+ Transifex (https://www.transifex.com/projects/p/xfce/).
4947+
4948+commit 75275c39b90f74fa05697ba13569b5d0cf527d79
4949+Author: Sveinn í Felli <sv1@fellsnet.is>
4950+Date: Thu Dec 12 12:31:59 2013 +0100
4951+
4952+ I18n: Update translation is (97%).
4953+
4954+ 165 translated messages, 5 untranslated messages.
4955+
4956+ Transifex (https://www.transifex.com/projects/p/xfce/).
4957+
4958+commit ce5f008584302362f6374201432f91e3d950715d
4959+Author: Alistair Buxton <a.j.buxton@gmail.com>
4960+Date: Tue Dec 10 01:32:05 2013 +0000
4961+
4962+ Fix crash when compositor is compiled in but disabled.
4963+
4964+ If user attempts to zoom in when compositor is disabled,
4965+ don't do anything. Also handle possible divide by zero
4966+ if the refresh rate is reported as zero.
4967+
4968+commit 51a982b74c9b48b9ae20d712127187119dad7a05
4969+Author: Nick Schermer <nick@xfce.org>
4970+Date: Sat Dec 7 12:33:03 2013 +0100
4971+
4972+ Fix compiler warnings.
4973+
4974+commit e7da725aab39018f54383dc6e8a64eccd8793035
4975+Author: Alistair Buxton <a.j.buxton@gmail.com>
4976+Date: Sat Nov 16 16:25:35 2013 +0000
4977+
4978+ Implement zooming.
4979+
4980+ This implements zooming when the compositor is enabled. To zoom in,
4981+ hold the key used to grab and move windows (usually alt) and scroll
4982+ up with the mouse wheel. Scroll down to zoom out.
4983+
4984+ This works by transforming the offscreen buffer where windows are
4985+ composited when rendering it back to the screen.
4986+
4987+commit ab3de90429ae015e7f657f44f10f281120bbbe7a
4988+Author: Alistair Buxton <a.j.buxton@gmail.com>
4989+Date: Mon Nov 25 17:33:26 2013 +0000
4990+
4991+ Bring refresh_rate stuff outside of LIBDRM checks.
4992+
4993+ We want to know the refresh rate even if libdrm is not used.
4994+
4995+commit f7fcb87de1f90210258026592dab472b14e189c1
4996+Author: Alistair Buxton <a.j.buxton@gmail.com>
4997+Date: Wed Nov 27 19:55:12 2013 +0000
4998+
4999+ Ignore when root atoms are unset.
5000+
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: