1 /*
2 * Copyright (c) 2002,2003 Sasha Vasko <sasha@aftercode.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *
18 */
19
20 /**********************************************************************
21 *
22 * Add a new window, put the titlbar and other stuff around
23 * the window
24 *
25 **********************************************************************/
26 #define LOCAL_DEBUG
27
28 #include "../../configure.h"
29
30 #include "asinternals.h"
31 #include "../../libAfterStep/wmprops.h"
32
33 /* icon geometry relative to the root window : */
get_icon_root_geometry(ASWindow * asw,ASRectangle * geom)34 Bool get_icon_root_geometry (ASWindow * asw, ASRectangle * geom)
35 {
36 ASCanvas *canvas = NULL;
37 if (AS_ASSERT (asw) || AS_ASSERT (geom))
38 return False;
39
40 geom->height = 0;
41 if (asw->icon_canvas) {
42 canvas = asw->icon_canvas;
43 if (asw->icon_title_canvas && asw->icon_title_canvas != canvas)
44 geom->height = asw->icon_title_canvas->height;
45 } else if (asw->icon_title_canvas)
46 canvas = asw->icon_title_canvas;
47
48 if (canvas) {
49 geom->x = canvas->root_x;
50 geom->y = canvas->root_y;
51 geom->width = canvas->width + canvas->bw * 2;
52 geom->height += canvas->height + canvas->bw * 2;
53 return True;
54 }
55 return False;
56 }
57
check_canvas_offscreen(ASCanvas * pc)58 Bool check_canvas_offscreen (ASCanvas * pc)
59 {
60 if (!pc)
61 return True;
62 return (pc->root_x >= Scr.MyDisplayWidth
63 || pc->root_y >= Scr.MyDisplayHeight
64 || pc->root_x + (int)pc->width < 0
65 || pc->root_y + (int)pc->height < 0);
66 }
67
68
check_window_offscreen(ASWindow * asw)69 Bool check_window_offscreen (ASWindow * asw)
70 {
71 if (!ASWIN_GET_FLAGS (asw, AS_Sticky) &&
72 ASWIN_DESK (asw) != Scr.CurrentDesk)
73 return True;
74
75 return check_canvas_offscreen (asw->client_canvas);
76 }
77
check_frame_offscreen(ASWindow * asw)78 Bool check_frame_offscreen (ASWindow * asw)
79 {
80 if (!ASWIN_GET_FLAGS (asw, AS_Sticky) &&
81 ASWIN_DESK (asw) != Scr.CurrentDesk)
82 return True;
83
84 return check_canvas_offscreen (asw->frame_canvas);
85 }
86
check_frame_side_offscreen(ASWindow * asw,int side)87 Bool check_frame_side_offscreen (ASWindow * asw, int side)
88 {
89 if (!ASWIN_GET_FLAGS (asw, AS_Sticky) &&
90 ASWIN_DESK (asw) != Scr.CurrentDesk)
91 return True;
92
93 return check_canvas_offscreen (asw->frame_sides[side]);
94 }
95
96
97
98
99 /* this gets called when Root background changes : */
update_window_transparency(ASWindow * asw,Bool force)100 void update_window_transparency (ASWindow * asw, Bool force)
101 {
102 ASOrientation *od = get_orientation_data (asw);
103 int i;
104 ASCanvas *changed_canvases[6] = { NULL, NULL, NULL, NULL, NULL, NULL };
105
106 if (!ASWIN_GET_FLAGS (asw, AS_Iconic)) {
107 ASCanvas *fc;
108 for (i = 0; i < FRAME_PARTS; ++i)
109 if (asw->frame_bars[i]) {
110 fc = asw->frame_sides[od->tbar2canvas_xref[i]];
111 if (!check_canvas_offscreen (fc)) {
112 update_astbar_transparency (asw->frame_bars[i], fc, force);
113 if (DoesBarNeedsRendering (asw->frame_bars[i])) {
114 changed_canvases[od->tbar2canvas_xref[i]] = fc;
115 render_astbar (asw->frame_bars[i], fc);
116 }
117 }
118 }
119
120 if (asw->tbar) {
121 fc = asw->frame_sides[od->tbar_side];
122 if (!check_canvas_offscreen (fc)) {
123 update_astbar_transparency (asw->tbar, fc, force);
124 if (DoesBarNeedsRendering (asw->tbar)) {
125 changed_canvases[od->tbar_side] = fc;
126 render_astbar (asw->tbar, fc);
127 }
128 }
129 }
130 } else {
131 if (asw->icon_button) {
132 update_astbar_transparency (asw->icon_button, asw->icon_canvas,
133 force);
134 if (DoesBarNeedsRendering (asw->icon_button)) {
135 changed_canvases[4] = asw->icon_canvas;
136 render_astbar (asw->icon_button, asw->icon_canvas);
137 }
138 }
139 if (asw->icon_title) {
140 update_astbar_transparency (asw->icon_title,
141 asw->icon_title_canvas ? asw->
142 icon_title_canvas : asw->icon_canvas,
143 force);
144 if (DoesBarNeedsRendering (asw->icon_title)) {
145 if (asw->icon_title_canvas != NULL
146 && asw->icon_title_canvas != asw->icon_canvas)
147 changed_canvases[5] = asw->icon_title_canvas;
148 else
149 changed_canvases[4] = asw->icon_canvas;
150 render_astbar (asw->icon_title,
151 asw->icon_title_canvas ? asw->
152 icon_title_canvas : asw->icon_canvas);
153 }
154 }
155 }
156 for (i = 0; i < 6; ++i)
157 if (changed_canvases[i]) {
158 invalidate_canvas_save (changed_canvases[i]);
159 update_canvas_display (changed_canvases[i]);
160 }
161
162 }
163
164 #define GetNormalBarHeight(h,b,od) \
165 do{if((b)!=NULL){ *((od)->in_width)=(b)->width; *((od)->in_height)=(b)->height;(h) = *((od)->out_height);} \
166 else (h) = 0; \
167 }while(0)
168
169
make_corner_addon(ASOrientation * od,ASTBarData * longbar,ASTBarData * corner1,ASTBarData * corner2)170 static unsigned int make_corner_addon (ASOrientation * od,
171 ASTBarData * longbar,
172 ASTBarData * corner1,
173 ASTBarData * corner2)
174 {
175 unsigned int longbar_height = 0, c1_height = 0, c2_height = 0;
176 GetNormalBarHeight (longbar_height, longbar, od);
177 GetNormalBarHeight (c1_height, corner1, od);
178 GetNormalBarHeight (c2_height, corner2, od);
179 LOCAL_DEBUG_OUT ("longbar_height = %d, c1_height = %d, c2_height = %d",
180 longbar_height, c1_height, c2_height);
181 if (c1_height >= c2_height)
182 return (c1_height > longbar_height) ? c1_height - longbar_height : 0;
183 else
184 return (c2_height > longbar_height) ? c2_height - longbar_height : 0;
185 }
186
187 static void
resize_canvases(ASWindow * asw,ASOrientation * od,unsigned int normal_width,unsigned int normal_height,unsigned int * frame_sizes)188 resize_canvases (ASWindow * asw, ASOrientation * od,
189 unsigned int normal_width, unsigned int normal_height,
190 unsigned int *frame_sizes)
191 {
192 unsigned short tbar_size = frame_sizes[od->tbar_side];
193 unsigned short sbar_size = frame_sizes[od->sbar_side];
194 unsigned short tbar_addon, sbar_addon;
195
196 /* we need to determine if corners are bigger then frame bars on sbar and tbar : */
197 tbar_addon =
198 make_corner_addon (od, asw->frame_bars[od->tbar_side],
199 asw->frame_bars[od->tbar_mirror_corners[0]],
200 asw->frame_bars[od->tbar_mirror_corners[1]]);
201 sbar_addon =
202 make_corner_addon (od, asw->frame_bars[od->sbar_side],
203 asw->frame_bars[od->sbar_mirror_corners[0]],
204 asw->frame_bars[od->sbar_mirror_corners[1]]);
205 tbar_size += tbar_addon;
206 sbar_size += sbar_addon;
207 LOCAL_DEBUG_OUT
208 ("tbar_size = %d, addon = %d, sbar_size = %d, addon = %d, frame_sizes = {%d,%d}",
209 tbar_size, tbar_addon, sbar_size, sbar_addon,
210 frame_sizes[od->tbar_side], frame_sizes[od->sbar_side]);
211 *(od->in_width) = normal_width;
212 *(od->in_height) = tbar_size;
213 if (asw->frame_sides[od->tbar_side])
214 moveresize_canvas (asw->frame_sides[od->tbar_side], 0, 0,
215 *(od->out_width), *(od->out_height));
216
217 *(od->in_x) = 0;
218 *(od->in_y) = normal_height - sbar_size;
219 *(od->in_height) = sbar_size;
220 if (asw->frame_sides[od->sbar_side])
221 moveresize_canvas (asw->frame_sides[od->sbar_side], *(od->out_x),
222 *(od->out_y), *(od->out_width), *(od->out_height));
223
224 /* for left and right sides - somewhat twisted logic - we mirror sides over lt2rb diagonal in case of
225 * vertical title orientation. That allows us to apply simple x/y switching instead of complex
226 * calculations. Note that we only do that for placement purposes. Contexts and images are still taken
227 * from MyFrame parts as if it was rotated counterclockwise instead of mirrored.
228 */
229 *(od->in_x) = 0;
230 *(od->in_y) = tbar_size;
231 *(od->in_width) = frame_sizes[od->left_mirror_side];
232 *(od->in_height) = normal_height - (tbar_size + sbar_size);
233 if (asw->frame_sides[od->left_mirror_side])
234 moveresize_canvas (asw->frame_sides[od->left_mirror_side],
235 *(od->out_x), *(od->out_y), *(od->out_width),
236 *(od->out_height));
237
238 *(od->in_x) = normal_width - frame_sizes[od->right_mirror_side];
239 *(od->in_width) = frame_sizes[od->right_mirror_side];
240 if (asw->frame_sides[od->right_mirror_side])
241 moveresize_canvas (asw->frame_sides[od->right_mirror_side],
242 *(od->out_x), *(od->out_y), *(od->out_width),
243 *(od->out_height));
244 }
245
246 #if 0
247 static unsigned short frame_side_height (ASCanvas * c1, ASCanvas * c2)
248 {
249 unsigned short h = 0;
250 if (c1)
251 h += c1->height;
252 if (c2)
253 h += c2->height;
254 return h;
255 }
256
257 static unsigned short frame_side_width (ASCanvas * c1, ASCanvas * c2)
258 {
259 unsigned short w = 0;
260 if (c1)
261 w += c1->width;
262 if (c2)
263 w += c2->width;
264 return w;
265 }
266
267 static unsigned short
268 frame_corner_height (ASTBarData * c1, ASTBarData * c2)
269 {
270 unsigned short h = 0;
271 if (c1)
272 h += c1->height;
273 if (c2)
274 h += c2->height;
275 return h;
276 }
277
278 static unsigned short frame_corner_width (ASTBarData * c1, ASTBarData * c2)
279 {
280 unsigned short w = 0;
281 if (c1)
282 w += c1->width;
283 if (c2)
284 w += c2->width;
285 return w;
286 }
287 #endif
288
make_shade_animation_step(ASWindow * asw,ASOrientation * od)289 static int make_shade_animation_step (ASWindow * asw, ASOrientation * od)
290 {
291 int step_size = 0;
292 if (asw->tbar) {
293 int steps = asw->shading_steps;
294
295 if (steps > 0) {
296 int from_size, to_size;
297 *(od->in_width) = asw->frame_canvas->width;
298 *(od->in_height) = asw->frame_canvas->height;
299 from_size = *(od->out_height);
300 if (ASWIN_GET_FLAGS (asw, AS_Shaded)) {
301 *(od->in_width) = asw->tbar->width;
302 *(od->in_height) = asw->tbar->height;
303 } else {
304 *(od->in_width) = asw->status->width;
305 *(od->in_height) = asw->status->height;
306 }
307 to_size = *(od->out_height);
308
309 if (from_size != to_size) {
310 int step_delta = (from_size - to_size) / steps;
311 if (step_delta == 0)
312 step_delta = (from_size > to_size) ? 1 : -1;
313 LOCAL_DEBUG_OUT ("@@ANIM to(%d)->from(%d)->delta(%d)->step(%d)",
314 to_size, from_size, step_delta, steps);
315
316 step_size = from_size - step_delta;
317 --(asw->shading_steps);
318 }
319 } else if (!ASWIN_GET_FLAGS (asw, AS_Shaded)) {
320 /* when we shade the window - focus gets set to frame window -
321 we need to revert it back to the client : */
322 if (Scr.Windows->focused == asw) {
323 focus_window (asw, asw->w);
324 autoraise_window (asw);
325 }
326 if (!ASWIN_GET_FLAGS (asw, AS_Dead))
327 XRaiseWindow (dpy, asw->w);
328 return 0;
329 } else {
330 *(od->in_width) = asw->tbar->width;
331 *(od->in_height) = asw->tbar->height;
332 return *(od->out_height);
333 }
334 }
335 return step_size;
336 }
337
338 inline static Bool
move_resize_frame_bar(ASTBarData * tbar,ASCanvas * canvas,int normal_x,int normal_y,unsigned int normal_width,unsigned int normal_height,Bool force_render)339 move_resize_frame_bar (ASTBarData * tbar, ASCanvas * canvas, int normal_x,
340 int normal_y, unsigned int normal_width,
341 unsigned int normal_height, Bool force_render)
342 {
343 if (set_astbar_size (tbar, normal_width, normal_height))
344 force_render = True;
345 if (move_astbar (tbar, canvas, normal_x, normal_y))
346 force_render = True;
347 if (force_render)
348 render_astbar (tbar, canvas);
349 return force_render;
350 }
351
352 inline static Bool
move_resize_corner(ASTBarData * bar,ASCanvas * canvas,ASOrientation * od,int normal_y,unsigned int normal_width,unsigned int normal_height,Bool left,Bool force_render)353 move_resize_corner (ASTBarData * bar, ASCanvas * canvas,
354 ASOrientation * od, int normal_y,
355 unsigned int normal_width, unsigned int normal_height,
356 Bool left, Bool force_render)
357 {
358 unsigned int w = bar->width;
359 unsigned int h = bar->height;
360
361 *(od->in_y) = normal_y;
362
363 if (od == &VertOrientation)
364 w = normal_height - normal_y;
365 else
366 h = normal_height - normal_y;
367 LOCAL_DEBUG_OUT
368 (" w = %d, h = %d, bar->width = %d, bar->height = %d, n_w = %d, n_h = %d, n_y = %d",
369 w, h, bar->width, bar->height, normal_width, normal_height,
370 normal_y);
371 *(od->in_width) = w;
372 *(od->in_height) = h;
373 *(od->in_x) = left ? 0 : (normal_width - (*(od->out_width)));
374 return move_resize_frame_bar (bar, canvas, *(od->out_x), *(od->out_y), w,
375 h, force_render);
376 }
377
378 inline static Bool
move_resize_longbar(ASTBarData * bar,ASCanvas * canvas,ASOrientation * od,int normal_offset,unsigned int normal_length,unsigned int corner_size1,unsigned int corner_size2,Bool vertical,Bool force_render)379 move_resize_longbar (ASTBarData * bar, ASCanvas * canvas,
380 ASOrientation * od, int normal_offset,
381 unsigned int normal_length, unsigned int corner_size1,
382 unsigned int corner_size2, Bool vertical,
383 Bool force_render)
384 {
385 unsigned int w = bar->width;
386 unsigned int h = bar->height;
387 int bar_size;
388
389 LOCAL_DEBUG_OUT
390 ("normal_offset = %d, normal_length = %d, corner_sizes = %d,%d, vert = %d, force = %d",
391 normal_offset, normal_length, corner_size1, corner_size2, vertical,
392 force_render);
393 /* swapping bar height in case of vertical orientation of the etire window: */
394 *(od->in_width) = w;
395 *(od->in_height) = h;
396
397 if (vertical) { /*vertical bar - west or east */
398 bar_size = *(od->out_width);
399 *(od->in_width) = bar_size;
400 *(od->in_height) = normal_length;
401 *(od->in_x) = normal_offset;
402 *(od->in_y) = corner_size1;
403 } else {
404 bar_size = *(od->out_height);
405 *(od->in_height) = bar_size;
406 if (corner_size1 + corner_size2 > normal_length)
407 *(od->in_width) = 1;
408 else
409 *(od->in_width) = normal_length - (corner_size1 + corner_size2);
410 *(od->in_x) = corner_size1;
411 *(od->in_y) = normal_offset;
412 }
413
414 return move_resize_frame_bar (bar, canvas, *(od->out_x), *(od->out_y),
415 *(od->out_width), *(od->out_height),
416 force_render);
417 }
418
419 static unsigned int
condense_tbar(ASTBarData * tbar,unsigned int max_size,unsigned int * off1,unsigned int * off2,Bool vert,ASFlagType align)420 condense_tbar (ASTBarData * tbar, unsigned int max_size,
421 unsigned int *off1, unsigned int *off2, Bool vert,
422 ASFlagType align)
423 {
424 unsigned int condensed = max_size;
425 *off1 = 0;
426 *off2 = 0;
427
428 #ifdef SHAPE
429 if (get_flags (align, ALIGN_LEFT | ALIGN_RIGHT)) {
430 if (vert) {
431 condensed = calculate_astbar_height (tbar);
432 if (condensed < max_size) {
433 if (get_flags (align, ALIGN_LEFT)) {
434 *off1 = max_size - condensed;
435 if (get_flags (align, ALIGN_RIGHT)) {
436 *off1 /= 2;
437 *off2 = *off1;
438 }
439 } else
440 *off2 = max_size - condensed;
441 } else
442 condensed = max_size;
443 } else {
444 condensed = calculate_astbar_width (tbar);
445 if (condensed < max_size) {
446 if (get_flags (align, ALIGN_RIGHT)) {
447 *off1 = max_size - condensed;
448 if (get_flags (align, ALIGN_LEFT)) {
449 *off1 /= 2;
450 *off2 = *off1;
451 }
452 } else
453 *off2 = max_size - condensed;
454 } else
455 condensed = max_size;
456 }
457 }
458 #endif
459 return condensed;
460 }
461
462
463 static Bool
move_resize_frame_bars(ASWindow * asw,int side,ASOrientation * od,unsigned int normal_width,unsigned int normal_height,Bool force_render)464 move_resize_frame_bars (ASWindow * asw, int side, ASOrientation * od,
465 unsigned int normal_width,
466 unsigned int normal_height, Bool force_render)
467 {
468 int corner_size1 = 0, corner_size2 = 0;
469 Bool rendered = False;
470 int tbar_size = 0;
471 ASCanvas *canvas = asw->frame_sides[side];
472 ASTBarData *title = NULL, *corner1 = NULL, *longbar = NULL, *corner2 =
473 NULL;
474 Bool vertical = False;
475
476 LOCAL_DEBUG_CALLER_OUT ("%p,%d, %ux%u, %s", asw, side, normal_width,
477 normal_height,
478 force_render ? "force" : "don't force");
479 longbar = asw->frame_bars[side];
480 if (side == od->tbar_side) {
481 title = asw->tbar;
482 corner1 = asw->frame_bars[od->tbar_mirror_corners[0]];
483 corner2 = asw->frame_bars[od->tbar_mirror_corners[1]];
484 } else if (side == od->sbar_side) {
485 corner1 = asw->frame_bars[od->sbar_mirror_corners[0]];
486 corner2 = asw->frame_bars[od->sbar_mirror_corners[1]];
487 } else
488 vertical = True;
489
490 if (title) {
491 unsigned int tbar_offset1, tbar_offset2, tbar_width;
492
493 tbar_width =
494 condense_tbar (title, normal_width, &tbar_offset1, &tbar_offset2,
495 ASWIN_HFLAGS (asw, AS_VerticalTitle),
496 asw->frame_data->condense_titlebar);
497 if (tbar_offset1 > 0 || tbar_offset2 > 0 || tbar_width != normal_width)
498 set_flags (canvas->state, CANVAS_FORCE_MASK);
499
500 /* title always considered a "horizontal bar" */
501 if (move_resize_longbar
502 (title, canvas, od, 0, normal_width, tbar_offset1, tbar_offset2,
503 False, force_render))
504 rendered = True;
505 tbar_size = *(od->in_height);
506 }
507 /* mirror_corner 0 */
508 if (corner1) {
509 if (move_resize_corner
510 (corner1, canvas, od, tbar_size, normal_width, normal_height, True,
511 force_render))
512 rendered = True;
513 corner_size1 = *(od->out_width);
514 }
515 /* mirror_corner 1 */
516 if (corner2) {
517 if (move_resize_corner
518 (corner2, canvas, od, tbar_size, normal_width, normal_height,
519 False, force_render))
520 rendered = True;
521 corner_size2 = *(od->out_width);
522 }
523 /* side */
524 if (longbar) {
525 if (side != od->tbar_side && (corner_size1 > 0 || corner_size2 > 0)) { /* we are in the sbar */
526 *(od->in_width) = longbar->width;
527 *(od->in_height) = longbar->height;
528 tbar_size = normal_height - (int)(*(od->out_height));
529 if (tbar_size < 0)
530 tbar_size = 0;
531 }
532 if (move_resize_longbar (longbar, canvas, od,
533 tbar_size,
534 vertical ? normal_height : normal_width,
535 corner_size1, corner_size2, vertical,
536 force_render))
537 rendered = True;
538 }
539
540 return rendered;
541 }
542
543 static ASFlagType
resize_frame_subwindows(ASWindow * asw,ASOrientation * od,unsigned int frame_win_width,unsigned int frame_win_height)544 resize_frame_subwindows (ASWindow * asw, ASOrientation * od,
545 unsigned int frame_win_width,
546 unsigned int frame_win_height)
547 {
548 register unsigned int *frame_size = &(asw->status->frame_size[0]);
549 unsigned int normal_width, normal_height;
550 ASFlagType client_changes = 0;
551
552 if (od == NULL)
553 od = get_orientation_data (asw);
554
555 *(od->in_width) = asw->frame_canvas->width;
556 *(od->in_height) = asw->frame_canvas->height;
557 normal_width = *(od->out_width);
558 normal_height = *(od->out_height);
559
560 resize_canvases (asw, od, normal_width, normal_height, frame_size);
561 if (!ASWIN_GET_FLAGS (asw, AS_Shaded)) /* leave shaded client alone ! */
562 client_changes = moveresize_canvas (asw->client_canvas,
563 frame_size[FR_W], frame_size[FR_N],
564 (int)frame_win_width -
565 (int)(frame_size[FR_W] +
566 frame_size[FR_E]),
567 (int)frame_win_height -
568 (int)(frame_size[FR_N] +
569 frame_size[FR_S]));
570 return client_changes;
571 }
572
573
574
apply_window_status_size(register ASWindow * asw,ASOrientation * od)575 Bool apply_window_status_size (register ASWindow * asw, ASOrientation * od)
576 {
577 Bool moved = False;
578 Bool resized = False;
579 ASFlagType client_changes = 0;
580 /* note that icons are handled by iconbox */
581 if (!ASWIN_GET_FLAGS (asw, AS_Iconic)) {
582 int step_size = make_shade_animation_step (asw, od);
583 int new_width = asw->status->width;
584 int new_height = asw->status->height;
585 LOCAL_DEBUG_OUT
586 ("**CONFG Client(%lx(%s))->status(%ux%u%+d%+d,%s,%s(%d>-%d))",
587 asw->w, ASWIN_NAME (asw) ? ASWIN_NAME (asw) : "noname",
588 asw->status->width, asw->status->height, asw->status->x,
589 asw->status->y, ASWIN_HFLAGS (asw,
590 AS_VerticalTitle) ? "Vert" : "Horz",
591 step_size > 0 ? "Shaded" : "Unshaded", asw->shading_steps,
592 step_size);
593
594 if (step_size > 0) {
595 if (ASWIN_HFLAGS (asw, AS_VerticalTitle)) {
596 new_width = step_size;
597 } else {
598 new_height = step_size;
599 }
600 }
601 resized = (asw->frame_canvas->width != new_width ||
602 asw->frame_canvas->height != new_height);
603 moved = (asw->frame_canvas->root_x != asw->status->x ||
604 asw->frame_canvas->root_y != asw->status->y);
605
606 moveresize_canvas (asw->frame_canvas, asw->status->x, asw->status->y,
607 new_width, new_height);
608 /* when we resize the client - our frame should already be positioned correctly ! */
609 if (step_size <= 0)
610 client_changes =
611 resize_frame_subwindows (asw, od, new_width, new_height);
612 #if 0
613 fprintf (stderr, "client_changes = %X, moved = %d. Called from :\n",
614 client_changes, moved);
615 print_simple_backtrace ();
616 #endif
617 if (moved && client_changes == 0)
618 send_canvas_configure_notify (asw->frame_canvas, asw->client_canvas);
619 }
620 return moved || resized || client_changes != 0;
621 }
622
623 static void
on_frame_bars_moved(ASWindow * asw,unsigned int side,ASOrientation * od)624 on_frame_bars_moved (ASWindow * asw, unsigned int side, ASOrientation * od)
625 {
626 ASCanvas *canvas = asw->frame_sides[side];
627
628 update_astbar_transparency (asw->frame_bars[side], canvas, False);
629 if (side == od->tbar_side) {
630 update_astbar_transparency (asw->tbar, canvas, False);
631 update_astbar_transparency (asw->
632 frame_bars[od->tbar_mirror_corners[0]],
633 canvas, False);
634 update_astbar_transparency (asw->
635 frame_bars[od->tbar_mirror_corners[1]],
636 canvas, False);
637 } else if (side == od->sbar_side) {
638 update_astbar_transparency (asw->
639 frame_bars[od->sbar_mirror_corners[0]],
640 canvas, False);
641 update_astbar_transparency (asw->
642 frame_bars[od->sbar_mirror_corners[1]],
643 canvas, False);
644 }
645 }
646
update_window_frame_moved(ASWindow * asw,ASOrientation * od)647 void update_window_frame_moved (ASWindow * asw, ASOrientation * od)
648 {
649 int i;
650
651 if (ASWIN_GET_FLAGS (asw, AS_Dead | AS_MoveresizeInProgress))
652 return;
653
654 handle_canvas_config (asw->client_canvas);
655
656 if (!check_window_offscreen (asw))
657 if (asw->internal && asw->internal->on_moveresize)
658 asw->internal->on_moveresize (asw->internal, None);
659
660 if (!check_frame_offscreen (asw))
661 for (i = 0; i < FRAME_SIDES; ++i)
662 if (asw->frame_sides[i]) {
663 handle_canvas_config (asw->frame_sides[i]);
664 if (!check_frame_side_offscreen (asw, i)) { /* canvas has been resized - resize tbars!!! */
665 on_frame_bars_moved (asw, i, od);
666 }
667 }
668 }
669
update_window_frame_pos(ASWindow * asw)670 void update_window_frame_pos (ASWindow * asw)
671 {
672 if (ASWIN_GET_FLAGS (asw, AS_Dead | AS_MoveresizeInProgress))
673 return;
674
675 handle_canvas_config (asw->client_canvas);
676
677 /*
678 if (!check_window_offscreen( asw ))
679 if( asw->internal && asw->internal->on_moveresize )
680 asw->internal->on_moveresize( asw->internal, None );
681 */
682
683 if (!check_frame_offscreen (asw)) {
684 int i;
685 ASFlagType changes = 0;
686 for (i = 0; i < FRAME_SIDES; ++i)
687 if (asw->frame_sides[i])
688 changes |= handle_canvas_config (asw->frame_sides[i]);
689
690 if (changes != 0)
691 update_window_transparency (asw, False);
692 }
693 }
694
695
SendConfigureNotify(ASWindow * asw)696 void SendConfigureNotify (ASWindow * asw)
697 {
698 XEvent client_event;
699
700 if (ASWIN_GET_FLAGS (asw, AS_Dead | AS_MoveresizeInProgress))
701 return;
702
703 client_event.type = ConfigureNotify;
704 client_event.xconfigure.display = dpy;
705 client_event.xconfigure.event = asw->w;
706 client_event.xconfigure.window = asw->w;
707
708 client_event.xconfigure.x = asw->client_canvas->root_x;
709 client_event.xconfigure.y = asw->client_canvas->root_y;
710 client_event.xconfigure.width = asw->client_canvas->width;
711 client_event.xconfigure.height = asw->client_canvas->height;
712
713 client_event.xconfigure.border_width = asw->status->border_width;
714 /* Real ConfigureNotify events say we're above title window, so ... */
715 /* what if we don't have a title ????? */
716 client_event.xconfigure.above =
717 asw->frame_sides[FR_N] ? asw->frame_sides[FR_N]->w : asw->frame;
718 client_event.xconfigure.override_redirect = False;
719 XSendEvent (dpy, asw->w, False, StructureNotifyMask, &client_event);
720 }
721
722 static Bool
check_frame_side_config(ASWindow * asw,Window w,ASOrientation * od)723 check_frame_side_config (ASWindow * asw, Window w, ASOrientation * od)
724 {
725 Bool found = False;
726 int i;
727 unsigned int normal_width, normal_height;
728
729 for (i = 0; i < FRAME_SIDES; ++i)
730 if (asw->frame_sides[i] && asw->frame_sides[i]->w == w) { /* canvas has beer resized - resize tbars!!! */
731 Bool changes = handle_canvas_config (asw->frame_sides[i]);
732
733 /* we must resize using current window size instead of event's size */
734 *(od->in_width) = asw->frame_sides[i]->width;
735 *(od->in_height) = asw->frame_sides[i]->height;
736 normal_width = *(od->out_width);
737 normal_height = *(od->out_height);
738
739 /* don't redraw window decoration while in the middle of animation : */
740 if (asw->shading_steps <= 0) {
741 if (move_resize_frame_bars (asw, i, od, normal_width, normal_height, changes) || changes) { /* now we need to show them on screen !!!! */
742 update_canvas_display (asw->frame_sides[i]);
743 if (ASWIN_GET_FLAGS (asw, AS_Shaped | AS_ShapedDecor))
744 SetShape (asw, 0);
745 else if (get_flags
746 (asw->internal_flags, ASWF_PendingShapeRemoval))
747 ClearShape (asw);
748 }
749 }
750 found = True;
751 break;
752 }
753 return found;
754 }
755
756 static void
move_shading_frame(ASWindow * asw,ASOrientation * od,int step_size)757 move_shading_frame (ASWindow * asw, ASOrientation * od, int step_size)
758 {
759 if (asw->frame_sides[od->sbar_side]) {
760 XRaiseWindow (dpy, asw->frame_sides[od->sbar_side]->w);
761 if (ASWIN_HFLAGS (asw, AS_VerticalTitle))
762 move_canvas (asw->frame_sides[od->sbar_side],
763 step_size - asw->frame_sides[od->sbar_side]->width, 0);
764 else
765 move_canvas (asw->frame_sides[od->sbar_side], 0,
766 step_size - asw->frame_sides[od->sbar_side]->height);
767 }
768 if (asw->frame_sides[od->tbar_side])
769 XRaiseWindow (dpy, asw->frame_sides[od->tbar_side]->w);
770 }
771
772
773 /* this gets called when StructureNotify/SubstractureNotify arrives : */
on_window_moveresize(ASWindow * asw,Window w)774 void on_window_moveresize (ASWindow * asw, Window w)
775 {
776 int i;
777 ASOrientation *od;
778 unsigned int normal_width, normal_height;
779 Bool update_shape = False;
780
781 LOCAL_DEBUG_CALLER_OUT ("(%p,%lx,asw->w=%lx)", asw, w, asw->w);
782 if (AS_ASSERT (asw))
783 return;
784
785 od = get_orientation_data (asw);
786
787 if (w == asw->w) { /* simply update client's size and position */
788 ASFlagType changes;
789 if (ASWIN_GET_FLAGS (asw, AS_Dead))
790 return;
791 changes = handle_canvas_config (asw->client_canvas);
792 if (asw->internal && asw->internal->on_moveresize)
793 asw->internal->on_moveresize (asw->internal, w);
794
795 update_shape = (changes != 0);
796 if (XPending (dpy) > 0) {
797 XEvent tmp;
798 XNextEvent (dpy, &tmp);
799 if (tmp.type == ConfigureNotify
800 && tmp.xconfigure.window == asw->frame)
801 w = asw->frame;
802 else
803 XPutBackEvent (dpy, &tmp);
804 }
805
806 }
807
808 if (w == asw->frame) { /* resize canvases here : */
809 int changes = handle_canvas_config (asw->frame_canvas);
810 LOCAL_DEBUG_OUT ("changes=0x%X", changes);
811 /* we must resize using current window size instead of event's size */
812 *(od->in_width) = asw->frame_canvas->width;
813 *(od->in_height) = asw->frame_canvas->height;
814 normal_width = *(od->out_width);
815 normal_height = *(od->out_height);
816
817 if (get_flags (changes, CANVAS_RESIZED)) {
818 register unsigned int *frame_size = &(asw->status->frame_size[0]);
819 int step_size = make_shade_animation_step (asw, od);
820 LOCAL_DEBUG_OUT ("step_size = %d", step_size);
821 if (step_size <= 0) { /* don't moveresize client window while shading !!!! */
822 resize_frame_subwindows (asw, od, asw->frame_canvas->width,
823 asw->frame_canvas->height);
824 } else {
825 if (normal_height != step_size) {
826 *(od->in_width) = normal_width;
827 *(od->in_height) = step_size;
828
829 if (normal_height < step_size) {
830 /* we get smoother animation if we move decoration ahead of actually
831 * resizing frame window : */
832 move_shading_frame (asw, od, step_size);
833 ASSync (False);
834 sleep_a_millisec (10);
835 /*LOCAL_DEBUG_OUT( "**SHADE Client(%lx(%s))->(%d>-%d)", asw->w, ASWIN_NAME(asw)?ASWIN_NAME(asw):"noname", asw->shading_steps, step_size ); */
836 resize_canvas (asw->frame_canvas, *(od->out_width),
837 *(od->out_height));
838 ASSync (False);
839 } else {
840 sleep_a_millisec (10);
841 resize_canvas (asw->frame_canvas, *(od->out_width),
842 *(od->out_height));
843 ASSync (False);
844 move_shading_frame (asw, od, step_size);
845 ASSync (False);
846 }
847 } else { /* probably just the change of the look - titlebar may need to be resized */
848 resize_canvases (asw, od, normal_width, normal_height,
849 frame_size);
850 move_canvas (asw->client_canvas, frame_size[FR_W],
851 frame_size[FR_N]);
852 }
853
854 }
855 if (asw->shading_steps == 0) {
856 for (i = 0; i < FRAME_SIDES; ++i)
857 if (asw->frame_sides[i])
858 check_frame_side_config (asw, asw->frame_sides[i]->w, od);
859 }
860 update_shape = True;
861 } else if (get_flags (changes, CANVAS_MOVED)) {
862 LOCAL_DEBUG_OUT ("window is moved but not resized %s", "");
863 update_window_frame_moved (asw, od);
864 /* also sent synthetic ConfigureNotify : */
865 SendConfigureNotify (asw);
866 }
867
868 if (changes != 0) {
869 LOCAL_DEBUG_OUT ("resized = %X, shaped = %lX",
870 get_flags (changes, CANVAS_RESIZED),
871 ASWIN_GET_FLAGS (asw, AS_ShapedDecor | AS_Shaped));
872
873 if (!check_frame_offscreen (asw))
874 update_window_transparency (asw, False);
875
876 if (!ASWIN_GET_FLAGS (asw, AS_Dead | AS_MoveresizeInProgress))
877 broadcast_config (M_CONFIGURE_WINDOW, asw);
878 }
879 } else if (asw->icon_canvas && w == asw->icon_canvas->w) {
880 ASFlagType changes = handle_canvas_config (asw->icon_canvas);
881 LOCAL_DEBUG_OUT ("icon resized to %dx%d%+d%+d",
882 asw->icon_canvas->width, asw->icon_canvas->height,
883 asw->icon_canvas->root_x, asw->icon_canvas->root_y);
884 if (get_flags (changes, CANVAS_RESIZED)) {
885 unsigned short title_size = 0;
886 if (asw->icon_title
887 && (asw->icon_title_canvas == asw->icon_canvas
888 || asw->icon_title_canvas == NULL)) {
889 title_size = calculate_astbar_height (asw->icon_title);
890 move_astbar (asw->icon_title, asw->icon_canvas, 0,
891 asw->icon_canvas->height - title_size);
892 set_astbar_size (asw->icon_title, asw->icon_canvas->width,
893 title_size);
894 if (ASWIN_GET_FLAGS (asw, AS_Iconic)) {
895 render_astbar (asw->icon_title, asw->icon_canvas);
896 }
897 LOCAL_DEBUG_OUT ("title_size = %d", title_size);
898 }
899 set_astbar_size (asw->icon_button, asw->icon_canvas->width,
900 asw->icon_canvas->height - title_size);
901 if (ASWIN_GET_FLAGS (asw, AS_Iconic)) {
902 render_astbar (asw->icon_button, asw->icon_canvas);
903 update_canvas_display (asw->icon_canvas);
904 }
905 }
906 if (ASWIN_GET_FLAGS (asw, AS_Iconic))
907 broadcast_config (M_CONFIGURE_WINDOW, asw);
908 } else if (asw->icon_title_canvas && w == asw->icon_title_canvas->w) {
909 if (handle_canvas_config (asw->icon_title_canvas) && asw->icon_title) {
910 LOCAL_DEBUG_OUT ("icon_title resized to %dx%d%+d%+d",
911 asw->icon_title_canvas->width,
912 asw->icon_title_canvas->height,
913 asw->icon_title_canvas->root_x,
914 asw->icon_title_canvas->root_y);
915 set_astbar_size (asw->icon_title, asw->icon_title_canvas->width,
916 asw->icon_title->height);
917 if (ASWIN_GET_FLAGS (asw, AS_Iconic)) {
918 render_astbar (asw->icon_title, asw->icon_title_canvas);
919 update_canvas_display (asw->icon_title_canvas);
920 }
921 }
922 if (ASWIN_GET_FLAGS (asw, AS_Iconic))
923 broadcast_config (M_CONFIGURE_WINDOW, asw);
924 } else if (asw->shading_steps == 0) { /* one of the frame canvases : */
925 if (!check_frame_side_config (asw, w, od))
926 if (asw->internal && asw->internal->on_moveresize)
927 asw->internal->on_moveresize (asw->internal, w);
928 }
929
930 if (update_shape) {
931 if (ASWIN_GET_FLAGS (asw, AS_ShapedDecor | AS_Shaped))
932 SetShape (asw, 0);
933 else if (get_flags (asw->internal_flags, ASWF_PendingShapeRemoval))
934 ClearShape (asw);
935 }
936
937 ASSync (False);
938 }
939
940 int update_window_tbar_size (ASWindow * asw);
941
942
on_window_title_changed(ASWindow * asw,Bool update_display)943 void on_window_title_changed (ASWindow * asw, Bool update_display)
944 {
945 if (AS_ASSERT (asw))
946 return;
947 if (is_output_level_under_threshold (OUTPUT_LEVEL_HINTS))
948 print_clean_hints (NULL, NULL, asw->hints);
949 if (asw->tbar) {
950 ASCanvas *canvas =
951 ASWIN_HFLAGS (asw,
952 AS_VerticalTitle) ? asw->frame_sides[FR_W] : asw->
953 frame_sides[FR_N];
954 if (change_astbar_first_label
955 (asw->tbar, ASWIN_NAME (asw), ASWIN_NAME_ENCODING (asw)))
956 if (canvas && update_display) {
957 invalidate_canvas_save (canvas);
958
959 if (canvas->shape) {
960 XRectangle rect;
961 rect.x = asw->tbar->win_x;
962 rect.y = asw->tbar->win_y;
963 rect.width = asw->tbar->width;
964 rect.height = asw->tbar->height;
965 subtract_shape_rectangle (canvas->shape, &rect, 1, 0, 0,
966 canvas->width, canvas->height);
967 }
968 update_window_tbar_size (asw);
969 render_astbar (asw->tbar, canvas);
970 update_canvas_display (canvas);
971 //if( ASWIN_GET_FLAGS( asw, AS_ShapedDecor ) )
972 SetShape (asw, 0);
973 }
974 }
975 LOCAL_DEBUG_OUT ("icon_title = %p, icon_name = \"%s\"", asw->icon_title,
976 ASWIN_ICON_NAME (asw) ? ASWIN_ICON_NAME (asw) :
977 "(null)");
978 if (asw->icon_title) {
979 if (change_astbar_first_label
980 (asw->icon_title, ASWIN_ICON_NAME (asw),
981 ASWIN_ICON_NAME_ENC (asw)))
982 if (ASWIN_GET_FLAGS (asw, AS_Iconic))
983 on_icon_changed (asw);
984 }
985 }
986
987 Bool collect_aswindow_hints (ASWindow * asw, ASRawHints * raw_hints);
988
on_window_hints_changed(ASWindow * asw)989 void on_window_hints_changed (ASWindow * asw)
990 {
991 static ASRawHints raw_hints;
992 ASHints *hints = NULL, *old_hints = NULL;
993 Bool tie_changed = False;
994 ASStatusHints scratch_status; /* all we need from it is AS_Urgent state change */
995 Bool status_changed = False;
996
997
998 if (AS_ASSERT (asw))
999 return;
1000 if (ASWIN_GET_FLAGS (asw, AS_Dead))
1001 return;
1002 if (!collect_aswindow_hints (asw, &raw_hints))
1003 return;
1004
1005 memset (&scratch_status, 0x00, sizeof (scratch_status));
1006
1007 hints =
1008 merge_hints (&raw_hints, Database, &scratch_status,
1009 Scr.Look.supported_hints, HINT_ANY, NULL, asw->w);
1010
1011 destroy_raw_hints (&raw_hints, True);
1012 if (hints) {
1013 show_debug (__FILE__, __FUNCTION__, __LINE__,
1014 "Window management hints collected and merged for window %X",
1015 asw->w);
1016 if (is_output_level_under_threshold (OUTPUT_LEVEL_HINTS))
1017 print_clean_hints (NULL, NULL, hints);
1018 } else {
1019 show_warning ("Failed to merge window management hints for window %X",
1020 asw->w);
1021 return;
1022 }
1023
1024 old_hints = asw->hints;
1025 tie_changed = ((old_hints->transient_for != hints->transient_for) ||
1026 (old_hints->group_lead != hints->group_lead));
1027
1028 if (tie_changed)
1029 untie_aswindow (asw);
1030
1031 asw->hints = hints;
1032
1033 if (tie_changed)
1034 tie_aswindow (asw);
1035
1036 SelectDecor (asw);
1037
1038 LOCAL_DEBUG_OUT
1039 ("redecorating window %p(\"%s\") to update to new hints...", asw,
1040 hints->names[0] ? hints->names[0] : "none");
1041 /* we do not want to do a complete refresh of decorations -
1042 * we want to do only what is neccessary: */
1043
1044 if (get_flags (scratch_status.flags, AS_Urgent)) {
1045 if (!get_flags (asw->status->flags, AS_Urgent)) {
1046 set_flags (asw->status->flags, AS_Urgent);
1047 status_changed = True;
1048 }
1049 } else if (get_flags (asw->status->flags, AS_Urgent)) {
1050 ASFlagType extwm_state = 0;
1051
1052 if (!get_extwm_state_flags (asw->w, &extwm_state))
1053 extwm_state = 0; /* just in case */
1054 if (!get_flags (extwm_state, EXTWM_StateDemandsAttention)) {
1055 clear_flags (asw->status->flags, AS_Urgent);
1056 status_changed = True;
1057 }
1058 }
1059 if (hints2decorations (asw, old_hints))
1060 status_changed = True;
1061
1062 if (status_changed)
1063 on_window_status_changed (asw, True);
1064
1065 if (mystrcmp (old_hints->res_name, hints->res_name) != 0 ||
1066 mystrcmp (old_hints->res_class, hints->res_class) != 0)
1067 broadcast_res_names (asw);
1068 if (mystrcmp (old_hints->names[0], hints->names[0]) != 0) {
1069 broadcast_window_name (asw);
1070 set_flags (asw->internal_flags, ASWF_NameChanged);
1071 }
1072 if (mystrcmp (old_hints->icon_name, hints->icon_name) != 0)
1073 broadcast_icon_name (asw);
1074
1075 destroy_hints (old_hints, False);
1076 }
1077
on_window_opacity_changed(ASWindow * asw)1078 void on_window_opacity_changed (ASWindow * asw)
1079 {
1080 CARD32 new_opacity = NET_WM_WINDOW_OPACITY_OPAQUE;
1081 Bool set = False;
1082 ASDatabaseRecord db_rec;
1083
1084 if (AS_ASSERT (asw))
1085 return;
1086 if (ASWIN_GET_FLAGS (asw, AS_Dead))
1087 return;
1088 set =
1089 read_32bit_property (asw->w, _XA_NET_WM_WINDOW_OPACITY,
1090 &new_opacity);
1091 if (set && new_opacity == asw->hints->window_opacity
1092 && ASWIN_HFLAGS (asw, AS_WindowOpacity))
1093 return;
1094
1095 if (fill_asdb_record (Database, asw->hints->names, &db_rec, False)) {
1096 if (get_flags (db_rec.set_data_flags, STYLE_WINDOW_OPACITY)) {
1097 new_opacity =
1098 set_hints_window_opacity_percent (NULL, db_rec.window_opacity);
1099 set = True;
1100 }
1101 }
1102
1103 if (!set)
1104 XDeleteProperty (dpy, asw->frame, _XA_NET_WM_WINDOW_OPACITY);
1105 else if (new_opacity != asw->hints->window_opacity
1106 || !ASWIN_HFLAGS (asw, AS_WindowOpacity)) {
1107 set_flags (asw->hints->flags, AS_WindowOpacity);
1108 asw->hints->window_opacity = new_opacity;
1109 set_32bit_property (asw->frame, _XA_NET_WM_WINDOW_OPACITY, XA_CARDINAL,
1110 asw->hints->window_opacity);
1111 }
1112 }
1113
update_window_tbar_size(ASWindow * asw)1114 int update_window_tbar_size (ASWindow * asw)
1115 {
1116 int tbar_size = 0;
1117 if (asw->tbar) {
1118 unsigned int tbar_width = 0;
1119 unsigned int tbar_height = 0;
1120 int x_offset = 0, y_offset = 0;
1121 LOCAL_DEBUG_OUT ("IsVertical = %lX",
1122 ASWIN_HFLAGS (asw, AS_VerticalTitle));
1123
1124 if (ASWIN_HFLAGS (asw, AS_VerticalTitle)) {
1125 tbar_size = calculate_astbar_width (asw->tbar);
1126 tbar_width = tbar_size;
1127 tbar_height = asw->frame_canvas->height;
1128 #ifdef SHAPE
1129 if (get_flags
1130 (asw->frame_data->condense_titlebar, ALIGN_LEFT | ALIGN_RIGHT)) {
1131 int condensed = calculate_astbar_height (asw->tbar);
1132 if (condensed < tbar_height) {
1133 if (get_flags (asw->frame_data->condense_titlebar, ALIGN_LEFT)) {
1134 y_offset = tbar_height - condensed;
1135 if (get_flags
1136 (asw->frame_data->condense_titlebar, ALIGN_RIGHT))
1137 y_offset /= 2;
1138 }
1139 tbar_height = condensed;
1140 }
1141 }
1142 #endif
1143 } else {
1144 tbar_size = calculate_astbar_height (asw->tbar);
1145 tbar_width = asw->frame_canvas->width;
1146 tbar_height = tbar_size;
1147 #ifdef SHAPE
1148 if (get_flags
1149 (asw->frame_data->condense_titlebar, ALIGN_LEFT | ALIGN_RIGHT)) {
1150 int condensed = calculate_astbar_width (asw->tbar);
1151 if (condensed < tbar_width) {
1152 if (get_flags (asw->frame_data->condense_titlebar, ALIGN_RIGHT)) {
1153 x_offset = tbar_width - condensed;
1154 if (get_flags (asw->frame_data->condense_titlebar, ALIGN_LEFT))
1155 x_offset /= 2;
1156 }
1157 tbar_width = condensed;
1158 }
1159 }
1160 #endif
1161 }
1162 /* we need that to set up tbar size : */
1163 set_astbar_size (asw->tbar, tbar_width, tbar_height);
1164 /* does not matter if we use frame canvas, since part's
1165 * canvas resizes at frame canvas origin anyway */
1166 move_astbar (asw->tbar, asw->frame_canvas, x_offset, y_offset);
1167
1168 }
1169 return tbar_size;
1170 }
1171
1172
on_window_status_changed(ASWindow * asw,Bool reconfigured)1173 void on_window_status_changed (ASWindow * asw, Bool reconfigured)
1174 {
1175 char *unfocus_mystyle = NULL;
1176 char *frame_unfocus_mystyle = NULL;
1177 int i;
1178 Bool changed = False;
1179 ASOrientation *od = get_orientation_data (asw);
1180
1181 if (AS_ASSERT (asw))
1182 return;
1183
1184 /* get_extwm_state_flags (asw->w, &i); */
1185
1186 LOCAL_DEBUG_CALLER_OUT ("(%p,%s Reconfigured)", asw,
1187 reconfigured ? "" : "Not");
1188 LOCAL_DEBUG_OUT ("status geometry = %dx%d%+d%+d", asw->status->width,
1189 asw->status->height, asw->status->x, asw->status->y);
1190 if (ASWIN_GET_FLAGS (asw, AS_Iconic)) {
1191 unfocus_mystyle = ASWIN_GET_FLAGS (asw, AS_Sticky) ?
1192 AS_ICON_TITLE_STICKY_MYSTYLE : AS_ICON_TITLE_UNFOCUS_MYSTYLE;
1193 if (asw->icon_title)
1194 changed =
1195 set_astbar_style (asw->icon_title, BAR_STATE_UNFOCUSED,
1196 unfocus_mystyle);
1197 if (changed || reconfigured) /* now we need to update icon title size */
1198 on_icon_changed (asw);
1199 } else {
1200 Bool decor_shaped = False;
1201 MyFrame *frame_data = asw->frame_data;
1202 int back_type;
1203 ASFlagType *frame_bevel, title_bevel;
1204 int title_cm, title_hue = -1, title_sat = -1;
1205
1206 if (ASWIN_GET_FLAGS (asw, AS_Sticky)) {
1207 back_type = BACK_STICKY;
1208 frame_bevel = &(frame_data->part_sbevel[0]);
1209 title_bevel = frame_data->title_sbevel;
1210 title_cm = frame_data->title_scm;
1211 if (get_flags (frame_data->set_title_attr, MYFRAME_TitleSHueSet))
1212 title_hue = frame_data->title_shue;
1213 if (get_flags (frame_data->set_title_attr, MYFRAME_TitleSSatSet))
1214 title_sat = frame_data->title_ssat;
1215 } else {
1216 back_type = BACK_UNFOCUSED;
1217 frame_bevel = &(frame_data->part_ubevel[0]);
1218 title_bevel = frame_data->title_ubevel;
1219 title_cm = frame_data->title_ucm;
1220 if (get_flags (frame_data->set_title_attr, MYFRAME_TitleUHueSet))
1221 title_hue = frame_data->title_uhue;
1222 if (get_flags (frame_data->set_title_attr, MYFRAME_TitleUSatSet))
1223 title_sat = frame_data->title_usat;
1224 }
1225
1226 unfocus_mystyle = asw->hints->mystyle_names[back_type];
1227 if (frame_data->title_style_names[back_type])
1228 unfocus_mystyle = frame_data->title_style_names[back_type];
1229 if (unfocus_mystyle == NULL)
1230 unfocus_mystyle = Scr.Look.MSWindow[back_type]->name;
1231 if (unfocus_mystyle == NULL)
1232 unfocus_mystyle = Scr.Look.MSWindow[BACK_UNFOCUSED]->name;
1233
1234 frame_unfocus_mystyle =
1235 (frame_data->frame_style_names[back_type] ==
1236 NULL) ? unfocus_mystyle : frame_data->
1237 frame_style_names[back_type];
1238
1239 for (i = 0; i < FRAME_PARTS; ++i) {
1240 unsigned int real_part = od->frame_rotation[i];
1241 if (asw->frame_bars[real_part]) {
1242 if (set_astbar_style
1243 (asw->frame_bars[real_part], BAR_STATE_UNFOCUSED,
1244 frame_unfocus_mystyle))
1245 changed = True;
1246 if (set_astbar_hilite
1247 (asw->frame_bars[real_part], BAR_STATE_UNFOCUSED,
1248 frame_bevel[i]))
1249 changed = True;
1250 if (is_astbar_shaped (asw->frame_bars[real_part], -1))
1251 decor_shaped = True;
1252 }
1253 }
1254 if (asw->tbar) {
1255 if (set_astbar_style
1256 (asw->tbar, BAR_STATE_UNFOCUSED, unfocus_mystyle))
1257 changed = True;
1258 if (set_astbar_hilite (asw->tbar, BAR_STATE_UNFOCUSED, title_bevel))
1259 changed = True;
1260 if (set_astbar_composition_method
1261 (asw->tbar, BAR_STATE_UNFOCUSED, title_cm))
1262 changed = True;
1263 if (set_astbar_huesat
1264 (asw->tbar, BAR_STATE_UNFOCUSED, title_hue, title_sat))
1265 changed = True;
1266 if (get_flags
1267 (asw->frame_data->condense_titlebar, ALIGN_LEFT | ALIGN_RIGHT)
1268 || is_astbar_shaped (asw->tbar, -1)) {
1269 decor_shaped = True;
1270 }
1271 }
1272 if (decor_shaped)
1273 ASWIN_SET_FLAGS (asw, AS_ShapedDecor);
1274 else
1275 ASWIN_CLEAR_FLAGS (asw, AS_ShapedDecor);
1276
1277 LOCAL_DEBUG_OUT ("status geometry = %dx%d%+d%+d", asw->status->width,
1278 asw->status->height, asw->status->x, asw->status->y);
1279 if (changed || reconfigured) { /* now we need to update frame sizes in status */
1280 unsigned int *frame_size = &(asw->status->frame_size[0]);
1281 unsigned short tbar_size = 0;
1282 /* int bw = 0 ;
1283 if( asw->hints && get_flags(asw->hints->flags, AS_Border))
1284 bw = asw->hints->border_width ; */
1285 tbar_size = update_window_tbar_size (asw);
1286 for (i = 0; i < FRAME_SIDES; ++i) {
1287 if (asw->frame_bars[i])
1288 frame_size[i] = IsSideVertical (i) ? asw->frame_bars[i]->width :
1289 asw->frame_bars[i]->height;
1290 else
1291 frame_size[i] = 0;
1292 //frame_size[i] += bw ;
1293 }
1294 if (tbar_size > 0) {
1295 for (i = FRAME_SIDES; i < FRAME_PARTS; ++i) {
1296 if (get_flags
1297 (asw->internal_flags,
1298 ASWF_FirstCornerFollowsTbarSize << (i - FRAME_SIDES))) {
1299 unsigned int real_part = od->frame_rotation[i];
1300 if (asw->frame_bars[real_part]) {
1301 if (ASWIN_HFLAGS (asw, AS_VerticalTitle))
1302 set_astbar_size (asw->frame_bars[real_part],
1303 asw->frame_bars[real_part]->width,
1304 tbar_size);
1305 else
1306 set_astbar_size (asw->frame_bars[real_part], tbar_size,
1307 asw->frame_bars[real_part]->height);
1308 }
1309 }
1310 }
1311 }
1312
1313 frame_size[od->tbar_side] += tbar_size;
1314 LOCAL_DEBUG_OUT
1315 ("status geometry = %dx%d%+d%+d frame_size = %d,%d,%d,%d",
1316 asw->status->width, asw->status->height, asw->status->x,
1317 asw->status->y, frame_size[0], frame_size[1], frame_size[2],
1318 frame_size[3]);
1319 anchor2status (asw->status, asw->hints, &(asw->anchor));
1320 LOCAL_DEBUG_OUT ("status geometry = %dx%d%+d%+d", asw->status->width,
1321 asw->status->height, asw->status->x,
1322 asw->status->y);
1323 }
1324 }
1325
1326 /* now we need to move/resize our frame window */
1327 if (!apply_window_status_size (asw, od))
1328 changed = True;
1329 if (changed)
1330 broadcast_config (M_STATUS_CHANGE, asw); /* must enforce status change propagation */
1331 if (!ASWIN_GET_FLAGS (asw, AS_Dead))
1332 set_client_state (asw->w, asw->status);
1333 }
1334
on_window_anchor_changed(ASWindow * asw)1335 void on_window_anchor_changed (ASWindow * asw)
1336 {
1337 if (asw) {
1338 ASOrientation *od = get_orientation_data (asw);
1339 anchor2status (asw->status, asw->hints, &(asw->anchor));
1340 LOCAL_DEBUG_OUT ("status geometry = %dx%d%+d%+d", asw->status->width,
1341 asw->status->height, asw->status->x, asw->status->y);
1342
1343 /* now we need to move/resize our frame window */
1344 if (!apply_window_status_size (asw, od))
1345 broadcast_config (M_CONFIGURE_WINDOW, asw); /* must enforce status change propagation */
1346 if (!ASWIN_GET_FLAGS (asw, AS_Dead))
1347 set_client_state (asw->w, asw->status);
1348 }
1349 }
1350
1351 void
validate_window_anchor(ASWindow * asw,XRectangle * new_anchor,Bool initial_placement)1352 validate_window_anchor (ASWindow * asw, XRectangle * new_anchor,
1353 Bool initial_placement)
1354 {
1355 if (asw) {
1356 ASStatusHints status = *(asw->status);
1357 anchor2status (&status, asw->hints, new_anchor);
1358 LOCAL_DEBUG_OUT ("status geometry = %dx%d%+d%+d", status.width,
1359 status.height, status.x, status.y);
1360
1361 if (ASWIN_HFLAGS (asw, AS_AvoidCover | AS_ShortLived) != AS_AvoidCover) {
1362 obey_avoid_cover (asw, &status, new_anchor,
1363 initial_placement ? AS_LayerHighest :
1364 ASWIN_LAYER (asw));
1365 }
1366 }
1367 }
1368
on_window_hilite_changed(ASWindow * asw,Bool focused)1369 void on_window_hilite_changed (ASWindow * asw, Bool focused)
1370 {
1371 ASOrientation *od = get_orientation_data (asw);
1372 int i;
1373
1374 LOCAL_DEBUG_CALLER_OUT ("(%p,%s focused)", asw, focused ? "" : "not");
1375 if (AS_ASSERT (asw))
1376 return;
1377
1378 for (i = FRAME_SIDES; --i >= 0;) {
1379 ASCanvas *update_canvas = asw->frame_sides[i];
1380 int k;
1381 if (swap_save_canvas (update_canvas)) {
1382 LOCAL_DEBUG_OUT ("canvas save swapped for side %d", i);
1383 update_canvas = NULL;
1384 }
1385 if (i == od->tbar_side)
1386 set_astbar_focused (asw->tbar, update_canvas, focused);
1387
1388 for (k = 0; k < FRAME_PARTS; ++k)
1389 if (od->tbar2canvas_xref[k] == i)
1390 set_astbar_focused (asw->frame_bars[k], update_canvas, focused);
1391 }
1392 /* now posting all the changes on display : */
1393 for (i = FRAME_SIDES; --i >= 0;)
1394 if (is_canvas_dirty (asw->frame_sides[i]))
1395 update_canvas_display (asw->frame_sides[i]);
1396 if (asw->internal && asw->internal->on_hilite_changed)
1397 asw->internal->on_hilite_changed (asw->internal, NULL, focused);
1398 if (ASWIN_GET_FLAGS (asw, AS_ShapedDecor))
1399 SetShape (asw, 0);
1400 if (ASWIN_GET_FLAGS (asw, AS_Iconic)) {
1401 set_astbar_focused (asw->icon_button, asw->icon_canvas, focused);
1402 set_astbar_focused (asw->icon_title, asw->icon_title_canvas, focused);
1403 if (is_canvas_dirty (asw->icon_canvas))
1404 update_canvas_display (asw->icon_canvas);
1405 if (is_canvas_dirty (asw->icon_title_canvas))
1406 update_canvas_display (asw->icon_title_canvas);
1407 }
1408 }
1409
on_window_pressure_changed(ASWindow * asw,int pressed_context)1410 void on_window_pressure_changed (ASWindow * asw, int pressed_context)
1411 {
1412 ASOrientation *od = get_orientation_data (asw);
1413 LOCAL_DEBUG_CALLER_OUT ("(%p,%s)", asw, context2text (pressed_context));
1414
1415 if (AS_ASSERT (asw) || asw->status == NULL)
1416 return;
1417
1418 if (!ASWIN_GET_FLAGS (asw, AS_Iconic)) {
1419 register int i = FRAME_PARTS;
1420 /* Titlebar */
1421 set_astbar_btn_pressed (asw->tbar, pressed_context); /* must go before next call to properly redraw : */
1422 set_astbar_pressed (asw->tbar, asw->frame_sides[od->tbar_side],
1423 pressed_context & C_TITLE);
1424 /* frame decor : */
1425 for (i = FRAME_PARTS; --i >= 0;)
1426 set_astbar_pressed (asw->frame_bars[i],
1427 asw->frame_sides[od->tbar2canvas_xref[i]],
1428 pressed_context & (C_FrameN << i));
1429 /* now posting all the changes on display : */
1430 for (i = FRAME_SIDES; --i >= 0;)
1431 if (is_canvas_dirty (asw->frame_sides[i])) {
1432 update_canvas_display (asw->frame_sides[i]);
1433 }
1434 if (asw->internal && asw->internal->on_pressure_changed)
1435 asw->internal->on_pressure_changed (asw->internal,
1436 pressed_context & C_CLIENT);
1437 } else { /* Iconic !!! */
1438
1439 set_astbar_pressed (asw->icon_button, asw->icon_canvas,
1440 pressed_context & C_IconButton);
1441 set_astbar_pressed (asw->icon_title, asw->icon_title_canvas,
1442 pressed_context & C_IconTitle);
1443 if (is_canvas_dirty (asw->icon_canvas))
1444 update_canvas_display (asw->icon_canvas);
1445 if (is_canvas_dirty (asw->icon_title_canvas))
1446 update_canvas_display (asw->icon_title_canvas);
1447 }
1448 }
1449
1450 /********************************************************************/
1451 /* end of ASWindow frame decorations management */
1452
save_aswindow_anchor(ASWindow * asw,Bool hor,Bool vert)1453 void save_aswindow_anchor (ASWindow * asw, Bool hor, Bool vert)
1454 {
1455 if (hor && asw->saved_anchor.width == 0
1456 && asw->status->width < Scr.MyDisplayWidth) {
1457 asw->saved_anchor.x = asw->anchor.x;
1458 asw->saved_anchor.width = asw->anchor.width;
1459 }
1460 if (vert && asw->saved_anchor.height == 0
1461 && asw->status->height < Scr.MyDisplayHeight) {
1462 asw->saved_anchor.y = asw->anchor.y;
1463 asw->saved_anchor.height = asw->anchor.height;
1464 }
1465 }
1466
1467 void
moveresize_aswindow_wm(ASWindow * asw,int x,int y,unsigned int width,unsigned int height,Bool save_anchor)1468 moveresize_aswindow_wm (ASWindow * asw, int x, int y, unsigned int width,
1469 unsigned int height, Bool save_anchor)
1470 {
1471 LOCAL_DEBUG_CALLER_OUT ("asw(%p)->geom(%dx%d%+d%+d)->save_anchor(%d)",
1472 asw, width, height, x, y, save_anchor);
1473 if (!AS_ASSERT (asw)) {
1474 ASStatusHints scratch_status = *(asw->status);
1475 scratch_status.x = x;
1476 scratch_status.y = y;
1477 if (width > 0)
1478 scratch_status.width = width;
1479 if (height > 0)
1480 scratch_status.height = height;
1481
1482 if (ASWIN_GET_FLAGS (asw, AS_Shaded)) { /* tricky tricky */
1483 if (ASWIN_HFLAGS (asw, AS_VerticalTitle))
1484 scratch_status.width = asw->status->width;
1485 else
1486 scratch_status.height = asw->status->height;
1487 }
1488 if (save_anchor)
1489 save_aswindow_anchor (asw, True, True);
1490 /* need to apply two-way conversion in order to make sure that size restrains are applied : */
1491 status2anchor (&(asw->anchor), asw->hints, &scratch_status,
1492 Scr.VxMax + Scr.MyDisplayWidth,
1493 Scr.VyMax + Scr.MyDisplayHeight);
1494 anchor2status (asw->status, asw->hints, &(asw->anchor));
1495
1496 /* now lets actually resize the window : */
1497 apply_window_status_size (asw, get_orientation_data (asw));
1498 }
1499 }
1500
init_aswindow_status(ASWindow * t,ASStatusHints * status)1501 Bool init_aswindow_status (ASWindow * t, ASStatusHints * status)
1502 {
1503 Bool pending_placement = False;
1504
1505 if (t->status == NULL) {
1506 t->status = safecalloc (1, sizeof (ASStatusHints));
1507 *(t->status) = *status;
1508 }
1509 if (get_flags (status->flags, AS_StartDesktop)
1510 && status->desktop != Scr.CurrentDesk) {
1511 t->status->desktop = status->desktop;
1512 if (get_flags (AfterStepState, ASS_NormalOperation))
1513 ChangeDesks (status->desktop);
1514 } else
1515 t->status->desktop = Scr.CurrentDesk;
1516
1517 if (get_flags (status->flags, AS_StartViewportX)
1518 && get_flags (AfterStepState, ASS_NormalOperation)) {
1519 t->status->viewport_x = MIN (status->viewport_x, Scr.VxMax);
1520 t->status->x %= Scr.MyDisplayWidth;
1521 if (!get_flags (t->status->flags, AS_Sticky))
1522 t->status->x += t->status->viewport_x;
1523 } else if (!get_flags (t->status->flags, AS_Sticky)) {
1524 if (t->status->x < 0)
1525 t->status->viewport_x = 0;
1526 else
1527 t->status->viewport_x =
1528 (t->status->x / Scr.MyDisplayWidth) * Scr.MyDisplayWidth;
1529 if (!get_flags (AfterStepState, ASS_NormalOperation))
1530 set_flags (status->flags, AS_StartViewportX);
1531 } else
1532 t->status->x %= Scr.MyDisplayWidth;
1533
1534 if (get_flags (status->flags, AS_StartViewportY)
1535 && get_flags (AfterStepState, ASS_NormalOperation)) {
1536 t->status->viewport_y = MIN (status->viewport_y, Scr.VyMax);
1537 t->status->y %= Scr.MyDisplayWidth;
1538 if (!get_flags (t->status->flags, AS_Sticky))
1539 t->status->y += t->status->viewport_y;
1540 } else if (!get_flags (t->status->flags, AS_Sticky)) {
1541 if (t->status->y < 0)
1542 t->status->viewport_y = 0;
1543 else
1544 t->status->viewport_y =
1545 (t->status->y / Scr.MyDisplayHeight) * Scr.MyDisplayHeight;
1546 if (!get_flags (AfterStepState, ASS_NormalOperation))
1547 set_flags (status->flags, AS_StartViewportY);
1548 } else
1549 t->status->y %= Scr.MyDisplayHeight;
1550
1551 if (t->status->viewport_x != Scr.Vx || t->status->viewport_y != Scr.Vy) {
1552 int new_vx =
1553 get_flags (status->flags,
1554 AS_StartViewportX) ? t->status->viewport_x : Scr.Vx;
1555 int new_vy =
1556 get_flags (status->flags,
1557 AS_StartViewportY) ? t->status->viewport_y : Scr.Vy;
1558 MoveViewport (new_vx, new_vy, False);
1559 t->status->viewport_x = Scr.Vx;
1560 t->status->viewport_y = Scr.Vy;
1561 }
1562 if (!get_flags (t->status->flags, AS_Sticky)) {
1563 Bool absolute_origin = (!ASWIN_HFLAGS (t, AS_UseCurrentViewport));
1564
1565 if (absolute_origin && get_flags (t->hints->flags, AS_Transient) && get_flags (t->status->flags, AS_StartPositionUser)) { /* most likely stupid KDE or GNOME app that is abusing USPosition
1566 for no good reason - place it on current viewport */
1567 absolute_origin = (t->status->x >= Scr.MyDisplayWidth ||
1568 t->status->y >= Scr.MyDisplayHeight);
1569 }
1570 if (absolute_origin) {
1571 t->status->x -= t->status->viewport_x;
1572 t->status->y -= t->status->viewport_y;
1573 }
1574 }
1575 LOCAL_DEBUG_OUT ("status->pos = %+d%+d, Scr.Vpos = %+d%+d", t->status->x,
1576 t->status->y, Scr.Vx, Scr.Vy);
1577
1578 /* TODO: AS_Iconic */
1579 if (!ASWIN_GET_FLAGS (t, AS_StartLayer))
1580 ASWIN_LAYER (t) = AS_LayerNormal;
1581 else if (ASWIN_LAYER (t) < AS_LayerLowest)
1582 ASWIN_LAYER (t) = AS_LayerLowest;
1583 else if (ASWIN_LAYER (t) > AS_LayerHighest)
1584 ASWIN_LAYER (t) = AS_LayerHighest;
1585
1586 if (get_flags (t->status->flags, AS_Fullscreen)) {
1587 t->status->width = Scr.MyDisplayWidth;
1588 t->status->height = Scr.MyDisplayHeight;
1589 t->status->x = 0;
1590 t->status->y = 0;
1591 } else {
1592 if (get_flags (t->hints->flags, AS_MinSize)) {
1593 int width = t->status->width;
1594 int height = t->status->height;
1595 if ((!get_flags (t->status->flags, AS_StartSizeUser)
1596 && width < t->hints->min_width) || width == 1)
1597 width = min (t->hints->min_width, Scr.VxMax + Scr.MyDisplayWidth);
1598 if ((!get_flags (t->status->flags, AS_StartSizeUser)
1599 && height < t->hints->min_height) || height == 1)
1600 height =
1601 min (t->hints->min_height, Scr.VyMax + Scr.MyDisplayHeight);
1602 if (width != t->status->width || height != t->status->height) {
1603 int dx = 0, dy = 0;
1604 if (t->hints->gravity == EastGravity ||
1605 t->hints->gravity == SouthEastGravity ||
1606 t->hints->gravity == NorthEastGravity ||
1607 t->hints->gravity == CenterGravity)
1608 dx = (int)(t->status->width) - width;
1609 if (t->hints->gravity == SouthGravity ||
1610 t->hints->gravity == SouthEastGravity ||
1611 t->hints->gravity == SouthWestGravity ||
1612 t->hints->gravity == CenterGravity)
1613 dy = (int)(t->status->height) - height;
1614 if (t->hints->gravity == EastGravity
1615 || t->hints->gravity == CenterGravity)
1616 dx = dx / 2;
1617 if (t->hints->gravity == SouthGravity
1618 || t->hints->gravity == CenterGravity)
1619 dy = dy / 2;
1620 t->status->x += dx;
1621 t->status->y += dy;
1622 t->status->width = width;
1623 t->status->height = height;
1624 XResizeWindow (dpy, t->w, width, height);
1625 }
1626 }
1627 if (!get_flags (AfterStepState, ASS_NormalOperation)) {
1628 int min_x, min_y, max_x, max_y;
1629 int margin = Scr.MyDisplayWidth >> 5;
1630 if (!ASWIN_GET_FLAGS (t, AS_Sticky)) {
1631 min_x = -Scr.Vx;
1632 max_x = Scr.VxMax + Scr.MyDisplayWidth;
1633 min_y = -Scr.Vy;
1634 max_y = Scr.VyMax + Scr.MyDisplayHeight;
1635 } else {
1636 min_x = 0;
1637 max_x = Scr.MyDisplayWidth;
1638 min_y = 0;
1639 max_y = Scr.MyDisplayHeight;
1640 }
1641 /* we have to make sure that window is visible !!!! */
1642 LOCAL_DEBUG_OUT ("x_range(%d,%d), y_range(%d,%d), margin = %d",
1643 min_x, max_x, min_y, max_y, margin);
1644 if ((int)t->status->x + (int)t->status->width < min_x + margin)
1645 t->status->x = min_x + margin - (int)t->status->width;
1646 else if ((int)t->status->x > max_x - margin)
1647 t->status->x = max_x - margin;
1648 if ((int)t->status->y + (int)t->status->height < min_y + margin)
1649 t->status->y = min_y + margin - (int)t->status->height;
1650 else if ((int)t->status->y > max_y - margin)
1651 t->status->y = max_y - margin;
1652
1653 LOCAL_DEBUG_OUT ("status->pos = %+d%+d, Scr.Vpos = %+d%+d",
1654 t->status->x, t->status->y, Scr.Vx, Scr.Vy);
1655
1656 set_flags (t->status->flags, AS_Position);
1657
1658 } else if (get_flags (Scr.Feel.flags, NoPPosition)) {
1659
1660 if (!get_flags (t->hints->flags, AS_Transient) &&
1661 !get_flags (t->status->flags, AS_StartPositionUser))
1662 clear_flags (t->status->flags, AS_Position);
1663 }
1664 if (get_flags (status->flags, AS_MaximizedX | AS_MaximizedY))
1665 pending_placement = True;
1666 else if (!get_flags (t->status->flags, AS_Position)) {
1667 if (!get_flags (t->status->flags, AS_StartsIconic)) {
1668 int x = -1, y = -1;
1669 pending_placement = True;
1670 ASQueryPointerRootXY (&x, &y);
1671 if (get_flags (t->hints->flags, AS_Transient | AS_ShortLived)) {
1672 x -= (int)t->status->width / 2;
1673 y -= (int)t->status->height / 2;
1674 set_flags (t->status->flags, AS_Position);
1675 pending_placement = False;
1676 }
1677
1678 if (x + (int)t->status->width > (int)Scr.MyDisplayWidth)
1679 x = (int)Scr.MyDisplayWidth - (int)t->status->width;
1680 if (x < 0)
1681 x = 0;
1682
1683 if (y + (int)t->status->height > (int)Scr.MyDisplayHeight)
1684 y = Scr.MyDisplayHeight - (int)t->status->height;
1685 if (y < 0)
1686 y = 0;
1687
1688 t->status->x = x;
1689 t->status->y = y;
1690
1691 LOCAL_DEBUG_OUT ("status->pos = %+d%+d, Scr.Vpos = %+d%+d",
1692 t->status->x, t->status->y, Scr.Vx, Scr.Vy);
1693 }
1694 }
1695 }
1696
1697 if (is_output_level_under_threshold (OUTPUT_LEVEL_HINTS))
1698 print_status_hints (NULL, NULL, t->status);
1699
1700 /* by now we have a valid position for the window: */
1701 set_flags (t->status->flags, AS_Position);
1702
1703 status2anchor (&(t->anchor), t->hints, t->status,
1704 Scr.VxMax + Scr.MyDisplayWidth,
1705 Scr.VyMax + Scr.MyDisplayHeight);
1706 LOCAL_DEBUG_OUT
1707 ("status->geom=%dx%d%+d%+d,status->viewport=%+d%+d,anchor=%dx%d%+d%+d",
1708 t->status->width, t->status->height, t->status->x, t->status->y,
1709 t->status->viewport_x, t->status->viewport_y, t->anchor.width,
1710 t->anchor.height, t->anchor.x, t->anchor.y);
1711
1712 if (!pending_placement) {
1713 validate_window_anchor (t, &(t->anchor), True);
1714 anchor2status (t->status, t->hints, &(t->anchor));
1715 }
1716
1717 return pending_placement;
1718 }
1719
1720 /***************************************************************************************/
1721 /* iconify/deiconify code : */
1722 /***************************************************************************************/
complete_wm_state_transition(ASWindow * asw,int state)1723 void complete_wm_state_transition (ASWindow * asw, int state)
1724 {
1725 asw->wm_state_transition = ASWT_StableState;
1726 if (state == NormalState) {
1727 LOCAL_DEBUG_OUT
1728 ("mapping frame subwindows for client %lX, frame canvas = %p",
1729 asw->w, asw->frame_canvas);
1730 XMapSubwindows (dpy, asw->frame);
1731 map_canvas_window (asw->frame_canvas, False);
1732 restack_desktop_cover ();
1733 } else if (state == IconicState) {
1734 unmap_canvas_window (asw->frame_canvas);
1735 }
1736 if (!ASWIN_GET_FLAGS (asw, AS_Dead))
1737 set_multi32bit_property (asw->w, _XA_WM_STATE, _XA_WM_STATE, 2, state,
1738 (state ==
1739 IconicState) ? asw->status->
1740 icon_window : None);
1741 }
1742
1743 Bool
set_window_wm_state(ASWindow * asw,Bool iconify,Bool force_unmapped)1744 set_window_wm_state (ASWindow * asw, Bool iconify, Bool force_unmapped)
1745 {
1746 XWindowAttributes attr;
1747
1748 LOCAL_DEBUG_CALLER_OUT ("client = %p, iconify = %d", asw, iconify);
1749
1750 if (AS_ASSERT (asw))
1751 return False;
1752
1753 if (iconify) {
1754 asw->DeIconifyDesk = ASWIN_DESK (asw);
1755 if (asw->wm_state_transition == ASWT_StableState) {
1756 if (get_flags (asw->status->flags, AS_Iconic))
1757 return False;
1758
1759 asw->wm_state_transition = ASWT_Normal2Iconic;
1760 set_flags (asw->status->flags, AS_Iconic);
1761 if (get_flags (Scr.Feel.flags, StickyIcons)
1762 || ASWIN_DESK (asw) == Scr.CurrentDesk)
1763 quietly_reparent_aswindow (asw, Scr.Root, True);
1764 else
1765 quietly_reparent_aswindow (asw, Scr.ServiceWin, True);
1766 }
1767
1768 asw->status->icon_window =
1769 asw->icon_canvas ? asw->icon_canvas->w : None;
1770
1771 if (asw->icon_canvas)
1772 asw->status->icon_window = asw->icon_canvas->w;
1773 else if (asw->icon_title_canvas)
1774 asw->status->icon_window = asw->icon_title_canvas->w;
1775
1776 if (get_flags (Scr.Feel.flags, ClickToFocus)
1777 || get_flags (Scr.Feel.flags, SloppyFocus)) {
1778 if (asw == Scr.Windows->focused)
1779 focus_prev_aswindow (asw);
1780 }
1781
1782 LOCAL_DEBUG_OUT ("unmaping client window 0x%lX",
1783 (unsigned long)asw->w);
1784 if (!ASWIN_GET_FLAGS (asw, AS_Dead)) {
1785 if (!XGetWindowAttributes (dpy, asw->w, &attr))
1786 ASWIN_SET_FLAGS (asw, AS_Dead);
1787 else {
1788 if (attr.map_state != IsUnmapped)
1789 XUnmapWindow (dpy, asw->w);
1790 else {
1791 ASWIN_CLEAR_FLAGS (asw, AS_Mapped);
1792 complete_wm_state_transition (asw, IconicState);
1793 }
1794 }
1795 ASSync (False);
1796 }
1797
1798 LOCAL_DEBUG_OUT ("hilited == %p", Scr.Windows->hilited);
1799 if (Scr.Windows->hilited == asw)
1800 hide_hilite ();
1801
1802 /* finally mapping the icon windows : */
1803 add_iconbox_icon (asw);
1804 restack_window (asw, None, Below);
1805 map_canvas_window (asw->icon_canvas, True);
1806 if (asw->icon_canvas != asw->icon_title_canvas)
1807 map_canvas_window (asw->icon_title_canvas, True);
1808 on_window_status_changed (asw, True);
1809 LOCAL_DEBUG_OUT ("updating status to iconic for client %p(\"%s\")",
1810 asw, ASWIN_NAME (asw));
1811 } else { /* Performing transition IconicState->NormalState */
1812 if (asw->wm_state_transition == ASWT_StableState) {
1813 if (!get_flags (asw->status->flags, AS_Iconic))
1814 return False;
1815 asw->wm_state_transition = ASWT_Iconic2Normal;
1816 clear_flags (asw->status->flags, AS_Iconic);
1817 remove_iconbox_icon (asw);
1818 unmap_canvas_window (asw->icon_canvas);
1819 if (asw->icon_canvas != asw->icon_title_canvas)
1820 unmap_canvas_window (asw->icon_title_canvas);
1821
1822 change_aswindow_desktop (asw,
1823 get_flags (Scr.Feel.flags,
1824 StubbornIcons) ? asw->
1825 DeIconifyDesk : Scr.CurrentDesk, True);
1826 }
1827
1828 asw->status->icon_window = None;
1829
1830 if (!ASWIN_GET_FLAGS (asw, AS_Dead) && !force_unmapped) {
1831 if (!XGetWindowAttributes (dpy, asw->w, &attr))
1832 ASWIN_SET_FLAGS (asw, AS_Dead);
1833 }
1834 if (!ASWIN_GET_FLAGS (asw, AS_Dead)) {
1835 {
1836 /* TODO: make sure that the window is on this screen */
1837 if (attr.map_state == IsUnmapped || force_unmapped)
1838 XMapRaised (dpy, asw->w);
1839 else {
1840 complete_wm_state_transition (asw, NormalState);
1841 ASWIN_SET_FLAGS (asw, AS_Mapped);
1842 if (get_flags (Scr.Feel.flags, ClickToFocus))
1843 activate_aswindow (asw, True, False);
1844 }
1845 }
1846 }
1847 on_window_status_changed (asw, False);
1848 }
1849
1850 if (!get_flags (asw->wm_state_transition, ASWT_FROM_WITHDRAWN))
1851 broadcast_config (M_CONFIGURE_WINDOW, asw);
1852
1853 return True;
1854 }
1855
bring_aswindow_on_vscreen(ASWindow * asw)1856 Bool bring_aswindow_on_vscreen (ASWindow * asw)
1857 {
1858 int min_x, min_y, max_x, max_y;
1859 int margin_x = Scr.MyDisplayWidth >> 5, margin_y =
1860 Scr.MyDisplayHeight >> 5;
1861
1862 if (asw == NULL)
1863 return False;
1864
1865 if (!ASWIN_GET_FLAGS (asw, AS_Sticky)) {
1866 min_x = -Scr.Vx;
1867 max_x = Scr.VxMax + Scr.MyDisplayWidth - Scr.Vx;
1868 min_y = -Scr.Vy;
1869 max_y = Scr.VyMax + Scr.MyDisplayHeight - Scr.Vy;
1870 } else {
1871 min_x = 0;
1872 max_x = Scr.MyDisplayWidth;
1873 min_y = 0;
1874 max_y = Scr.MyDisplayHeight;
1875 }
1876 if (!ASWIN_GET_FLAGS (asw, AS_Iconic)) {
1877 int new_x = asw->status->x;
1878 int new_y = asw->status->y;
1879 int w = asw->status->width;
1880 int h = asw->status->height;
1881
1882 if (margin_x > w >> 2) {
1883 margin_x = w >> 2;
1884 if (margin_x == 0)
1885 margin_x = 1;
1886 }
1887 if (margin_y > h >> 2) {
1888 margin_y = h >> 2;
1889 if (margin_y == 0)
1890 margin_y = 1;
1891 }
1892
1893 if (new_x + w < min_x + margin_x)
1894 new_x = min_x + margin_x - w;
1895 else if (new_x > max_x - margin_x)
1896 new_x = max_x - margin_x;
1897
1898 if (new_y + h < min_y + margin_y)
1899 new_y = min_y + margin_y - h;
1900 else if (new_y > max_y - margin_y)
1901 new_y = max_y - margin_y;
1902 LOCAL_DEBUG_OUT
1903 ("min_pos = (%+d%+d), max_pos = (%+d%+d), new_pos = (%+d%+d)",
1904 min_x, min_y, max_x, max_y, new_x, new_y);
1905 if (new_x != asw->status->x || new_y != asw->status->y)
1906 moveresize_aswindow_wm (asw, new_x, new_y, asw->status->width,
1907 asw->status->height, False);
1908 }
1909 return True;
1910 }
1911
1912
make_aswindow_visible(ASWindow * asw,Bool deiconify)1913 Bool make_aswindow_visible (ASWindow * asw, Bool deiconify)
1914 {
1915 if (asw == NULL || !get_flags (AfterStepState, ASS_NormalOperation))
1916 return False;
1917
1918 if (ASWIN_GET_FLAGS (asw, AS_Iconic)) {
1919 if (deiconify) {
1920 set_window_wm_state (asw, False, False);
1921 }
1922 }
1923
1924 if (ASWIN_DESK (asw) != Scr.CurrentDesk) {
1925 ChangeDesks (ASWIN_DESK (asw));
1926 }
1927
1928 bring_aswindow_on_vscreen (asw);
1929
1930 #ifndef NO_VIRTUAL
1931 if (!ASWIN_GET_FLAGS (asw, AS_Sticky)) {
1932 int dx, dy;
1933 int cx = Scr.MyDisplayWidth / 2;
1934 int cy = Scr.MyDisplayHeight / 2;
1935
1936 if (ASWIN_GET_FLAGS (asw, AS_Iconic)) {
1937 if (asw->icon_canvas) {
1938 cx = asw->icon_canvas->root_x + asw->icon_canvas->width / 2;
1939 cy = asw->icon_canvas->root_y + asw->icon_canvas->height / 2;
1940 }
1941 } else if (asw->frame_canvas) {
1942 cx = asw->frame_canvas->root_x + asw->frame_canvas->width / 2;
1943 cy = asw->frame_canvas->root_y + asw->frame_canvas->height / 2;
1944 }
1945
1946 /* Put center of window on the visible screen */
1947 if (get_flags (Scr.Feel.flags, CenterOnCirculate)) {
1948 dx = cx - Scr.MyDisplayWidth / 2 + Scr.Vx;
1949 dy = cy - Scr.MyDisplayHeight / 2 + Scr.Vy;
1950 } else {
1951 dx = (cx + Scr.Vx) / Scr.MyDisplayWidth * Scr.MyDisplayWidth;
1952 dy = (cy + Scr.Vy) / Scr.MyDisplayHeight * Scr.MyDisplayHeight;
1953 }
1954 MoveViewport (dx, dy, True);
1955 }
1956 #endif
1957
1958 RaiseObscuredWindow (asw);
1959 if (!get_flags (Scr.Feel.flags, ClickToFocus)) {
1960 int x, y;
1961 /* need to to center on window */
1962 if (ASWIN_GET_FLAGS (asw, AS_Iconic)) {
1963 if (asw->icon_title_canvas
1964 && asw->icon_canvas != asw->icon_title_canvas)
1965 on_window_moveresize (asw, asw->icon_title_canvas->w);
1966 if (asw->icon_canvas) {
1967 on_window_moveresize (asw, asw->icon_canvas->w);
1968 x = asw->icon_canvas->root_x;
1969 y = asw->icon_canvas->root_y;
1970 } else if (asw->icon_title_canvas) {
1971 x = asw->icon_title_canvas->root_x;
1972 y = asw->icon_title_canvas->root_y;
1973 } else
1974 return False;
1975 } else {
1976 on_window_moveresize (asw, asw->frame);
1977 x = asw->client_canvas->root_x;
1978 y = asw->client_canvas->root_y;
1979 }
1980 LOCAL_DEBUG_OUT ("Warping pointer to : %+d%+d", x + Scr.Feel.Xzap,
1981 y + Scr.Feel.Yzap);
1982 XWarpPointer (dpy, None, Scr.Root, 0, 0, 0, 0, x + Scr.Feel.Xzap,
1983 y + Scr.Feel.Yzap);
1984 }
1985 return True;
1986 }
1987
change_aswindow_layer(ASWindow * asw,int layer)1988 void change_aswindow_layer (ASWindow * asw, int layer)
1989 {
1990 if (AS_ASSERT (asw))
1991 return;
1992 if (asw->transient_owner == NULL && ASWIN_LAYER (asw) != layer) {
1993 remove_aswindow_from_layer (asw, ASWIN_LAYER (asw));
1994 LOCAL_DEBUG_OUT ("changing window's layer to %d", layer);
1995 ASWIN_LAYER (asw) = layer;
1996 add_aswindow_to_layer (asw, layer);
1997 restack_window_list (ASWIN_DESK (asw));
1998 ASWIN_SET_FLAGS (asw, AS_Layer);
1999 set_client_state (asw->w, asw->status);
2000 }
2001 }
2002
2003 static void
do_change_aswindow_desktop(ASWindow * asw,int new_desk,Bool force)2004 do_change_aswindow_desktop (ASWindow * asw, int new_desk, Bool force)
2005 {
2006 int old_desk = ASWIN_DESK (asw);
2007
2008 if (!force && ASWIN_DESK (asw) == new_desk)
2009 return;
2010
2011 ASWIN_DESK (asw) = new_desk;
2012
2013 if (!ASWIN_GET_FLAGS (asw, AS_Dead)) {
2014 set_client_desktop (asw->w, as_desk2ext_desk_safe(new_desk));
2015
2016 /* desktop changing : */
2017 if (new_desk == Scr.CurrentDesk) {
2018 quietly_reparent_aswindow (asw, Scr.Root, True);
2019 } else if (old_desk == Scr.CurrentDesk)
2020 quietly_reparent_aswindow (asw, Scr.ServiceWin, True);
2021 broadcast_config (M_CONFIGURE_WINDOW, asw);
2022 }
2023 }
2024
2025 static void
change_aswindow_desktop_nontransient(ASWindow * asw,int new_desk,Bool force)2026 change_aswindow_desktop_nontransient (ASWindow * asw, int new_desk,
2027 Bool force)
2028 {
2029 ASWindow **sublist;
2030 int i;
2031
2032 if (ASWIN_GET_FLAGS (asw, AS_Sticky))
2033 new_desk = Scr.CurrentDesk;
2034
2035 do_change_aswindow_desktop (asw, new_desk, force);
2036 if (asw->transients) {
2037 sublist = PVECTOR_HEAD (ASWindow *, asw->transients);
2038 for (i = 0; i < PVECTOR_USED (asw->transients); ++i)
2039 do_change_aswindow_desktop (sublist[i], new_desk, force);
2040 }
2041 }
2042
2043 #if 0 /* TODO do we really need that ??? */
2044
2045 struct ChangeGroupDesktopAuxData {
2046 Window group_lead;
2047 ASWindow *initiator;
2048 int new_desk;
2049 Bool force;
2050
2051 };
2052
2053 static Bool
2054 change_aswindow_desktop_for_group_func (void *data, void *aux_data)
2055 {
2056 ASWindow *asw = (ASWindow *) data;
2057 struct ChangeGroupDesktopAuxData *ad =
2058 (struct ChangeGroupDesktopAuxData *)aux_data;
2059 LOCAL_DEBUG_OUT
2060 ("asw = %p(w = %lX), initiator = %p, to = %p, asw->gl = %lX, gl = %lX",
2061 asw, asw->w, ad->initiator, asw->transient_owner,
2062 asw->hints->group_lead, ad->group_lead);
2063 if (asw && asw != ad->initiator && asw->transient_owner == NULL
2064 && asw->hints->group_lead == ad->group_lead)
2065 change_aswindow_desktop_nontransient (asw, ad->new_desk, ad->force);
2066 return True;
2067 }
2068 #endif
2069
change_aswindow_desktop(ASWindow * asw,int new_desk,Bool force)2070 void change_aswindow_desktop (ASWindow * asw, int new_desk, Bool force)
2071 {
2072 ASWindow **sublist;
2073 int i;
2074
2075 if (AS_ASSERT (asw))
2076 return;
2077 if (asw->transient_owner)
2078 asw = asw->transient_owner;
2079
2080 change_aswindow_desktop_nontransient (asw, new_desk, force);
2081
2082 #if 0 /* TODO do we really need that ??? */
2083 LOCAL_DEBUG_OUT ("group_members = %p; group_lead = %lX",
2084 asw->group_members, asw->hints->group_lead);
2085 if (asw->group_members) {
2086 sublist = PVECTOR_HEAD (ASWindow *, asw->group_members);
2087 for (i = 0; i < PVECTOR_USED (asw->group_members); ++i)
2088 if (sublist[i]->transient_owner == NULL)
2089 do_change_aswindow_desktop (sublist[i], new_desk, force);
2090 } else if (asw->hints->group_lead != None) { /* sometimes group lead may be unmapped untracked window */
2091 struct ChangeGroupDesktopAuxData ad;
2092 ad.group_lead = asw->hints->group_lead;
2093 ad.initiator = asw;
2094 ad.new_desk = new_desk;
2095 ad.force = force;
2096 iterate_asbidirlist (Scr.Windows->clients,
2097 change_aswindow_desktop_for_group_func, &ad, NULL,
2098 False);
2099 }
2100 #endif
2101 }
2102
restore_anchor_x(ASWindow * asw)2103 static Bool restore_anchor_x (ASWindow * asw)
2104 {
2105 if (asw->saved_anchor.width > 0) {
2106 asw->anchor.x = asw->saved_anchor.x;
2107 asw->anchor.width = asw->saved_anchor.width;
2108 asw->saved_anchor.width = 0; /* invalidating saved anchor */
2109 return True;
2110 }
2111 return False;
2112 }
2113
restore_anchor_y(ASWindow * asw)2114 static Bool restore_anchor_y (ASWindow * asw)
2115 {
2116 if (asw->saved_anchor.height > 0) {
2117 asw->anchor.y = asw->saved_anchor.y;
2118 asw->anchor.height = asw->saved_anchor.height;
2119 asw->saved_anchor.height = 0; /* invalidating saved anchor */
2120 return True;
2121 }
2122 return False;
2123 }
2124
toggle_aswindow_status(ASWindow * asw,ASFlagType flags)2125 void toggle_aswindow_status (ASWindow * asw, ASFlagType flags)
2126 {
2127 ASFlagType on_flags, off_flags;
2128 Bool need_placement = False;
2129 Bool reconfigured = False;
2130
2131 if (AS_ASSERT (asw))
2132 return;
2133
2134 if (flags == 0)
2135 return;
2136
2137 if (get_flags (flags, AS_Fullscreen))
2138 clear_flags (flags, AS_MaximizedX | AS_MaximizedY);
2139
2140 on_flags = (~(asw->status->flags)) & flags;
2141 off_flags = (asw->status->flags) & (~flags);
2142 asw->status->flags = on_flags | off_flags;
2143 LOCAL_DEBUG_OUT ("flags = %lx, on_flags = %lx, off_flags = %lx", flags,
2144 on_flags, off_flags);
2145 if (get_flags (flags, AS_Shaded)) {
2146 if (get_flags (asw->status->flags, AS_Shaded)) {
2147 ASOrientation *od = get_orientation_data (asw);
2148 if (asw->frame_sides[od->tbar_side]) {
2149 Window ww[2];
2150 ww[0] = asw->w;
2151 ww[1] = asw->frame_sides[od->tbar_side]->w;
2152 XRestackWindows (dpy, &(ww[0]), 2);
2153 }
2154 }
2155 asw->shading_steps = Scr.Feel.ShadeAnimationSteps;
2156 }
2157 if (get_flags (flags, AS_Sticky)) { /* anchor of sticky window is always in real coordinates, while
2158 * for non-sticky its in virtual coordinates
2159 */
2160 if (ASWIN_GET_FLAGS (asw, AS_Sticky)) {
2161 asw->anchor.x -= asw->status->viewport_x;
2162 asw->anchor.y -= asw->status->viewport_y;
2163 } else {
2164 asw->anchor.x += asw->status->viewport_x;
2165 asw->anchor.y += asw->status->viewport_y;
2166 }
2167 }
2168
2169 if (get_flags (flags, AS_Fullscreen)) {
2170 if (!ASWIN_GET_FLAGS (asw, AS_Fullscreen)) { /* fullscreen->normal */
2171 if (!ASWIN_GET_FLAGS (asw, AS_MaximizedX))
2172 if (!restore_anchor_x (asw)) {
2173 asw->anchor.width = Scr.MyDisplayWidth / 3;
2174 asw->anchor.x = (Scr.MyDisplayWidth - asw->anchor.width) / 2;
2175 }
2176
2177 if (!ASWIN_GET_FLAGS (asw, AS_MaximizedY))
2178 if (!restore_anchor_y (asw)) {
2179 asw->anchor.height = Scr.MyDisplayHeight / 3;
2180 asw->anchor.y = (Scr.MyDisplayHeight - asw->anchor.height) / 2;
2181 }
2182
2183 reconfigured = True;
2184 if (ASWIN_GET_FLAGS (asw, AS_MaximizedY | AS_MaximizedX))
2185 need_placement = True;
2186 } else { /* normal->fullscreen */
2187 ASStatusHints scratch_status = *(asw->status);
2188 scratch_status.x = 0;
2189 scratch_status.y = 0;
2190 scratch_status.width = Scr.MyDisplayWidth;
2191 scratch_status.height = Scr.MyDisplayHeight;
2192
2193 save_aswindow_anchor (asw, True, True);
2194 status2anchor (&(asw->anchor), asw->hints, &scratch_status,
2195 Scr.VxMax + Scr.MyDisplayWidth,
2196 Scr.VyMax + Scr.MyDisplayHeight);
2197 reconfigured = True;
2198 }
2199 }
2200 if (get_flags (flags, AS_MaximizedX)) {
2201 if (!ASWIN_GET_FLAGS (asw, AS_MaximizedX)) {
2202 if (restore_anchor_x (asw))
2203 reconfigured = True;
2204 } else if (!ASWIN_GET_FLAGS (asw, AS_Fullscreen))
2205 need_placement = True;
2206 }
2207 if (get_flags (flags, AS_MaximizedY)) {
2208 if (!ASWIN_GET_FLAGS (asw, AS_MaximizedY)) {
2209 if (restore_anchor_y (asw))
2210 reconfigured = True;
2211 } else if (!ASWIN_GET_FLAGS (asw, AS_Fullscreen))
2212 need_placement = True;
2213 }
2214
2215 if (get_flags (flags, AS_Focused))
2216 activate_aswindow (asw, False, True);
2217
2218 if (need_placement)
2219 place_aswindow (asw);
2220
2221 on_window_status_changed (asw, reconfigured);
2222 if (get_flags (flags, AS_Sticky))
2223 update_window_transparency (asw, False);
2224 LOCAL_DEBUG_OUT ("Window is %sticky",
2225 ASWIN_GET_FLAGS (asw, AS_Sticky) ? "S" : "NotS");
2226 }
2227
activate_aswindow(ASWindow * asw,Bool force,Bool deiconify)2228 Bool activate_aswindow (ASWindow * asw, Bool force, Bool deiconify)
2229 {
2230 Bool res = False;
2231 LOCAL_DEBUG_CALLER_OUT ("%p, %d, %d", asw, force, deiconify);
2232 LOCAL_DEBUG_OUT ("current focused is %p, active is %p",
2233 Scr.Windows->focused, Scr.Windows->active);
2234 if (asw == NULL || asw->status == NULL || ASWIN_GET_FLAGS (asw, AS_Dead))
2235 return False;
2236
2237 if (force) {
2238 GrabEm (ASDefaultScr, Scr.Feel.cursors[ASCUR_Select]); /* to prevent Enter Notify events to
2239 be sent to us while shifting windows around */
2240 if ((res = make_aswindow_visible (asw, deiconify))) {
2241 LOCAL_DEBUG_OUT ("CHANGE Scr.Windows->active from %p to %p",
2242 Scr.Windows->active, asw);
2243 Scr.Windows->active = asw; /* must do that prior to UngrabEm, so that window gets focused */
2244 }
2245 UngrabEm ();
2246 } else {
2247 if (ASWIN_GET_FLAGS (asw, AS_Iconic)) {
2248 LOCAL_DEBUG_OUT ("Window is iconic - pending implementation%s", "");
2249 if (deiconify)
2250 set_window_wm_state (asw, False, False);
2251 else
2252 return False;
2253 }
2254 if (ASWIN_DESK (asw) != Scr.CurrentDesk) {
2255 LOCAL_DEBUG_OUT ("Window is on inactive desk - can't focus%s", "");
2256 return False;
2257 }
2258 if (asw->status->x + asw->status->width < 0
2259 || asw->status->x >= Scr.MyDisplayWidth
2260 || asw->status->y + asw->status->height < 0
2261 || asw->status->y >= Scr.MyDisplayHeight) {
2262 LOCAL_DEBUG_OUT ("Window is out of the screen - can't focus%s", "");
2263 return False; /* we are out of screen - can't focus */
2264 }
2265 LOCAL_DEBUG_OUT ("CHANGE Scr.Windows->active from %p to %p",
2266 Scr.Windows->active, asw);
2267 Scr.Windows->active = asw; /* must do that prior to UngrabEm, so that window gets focused */
2268 res = focus_active_window ();
2269 }
2270 return res;
2271 }
2272
2273
hilite_aswindow(ASWindow * asw)2274 void hilite_aswindow (ASWindow * asw)
2275 {
2276 if (Scr.Windows->hilited != asw) {
2277 if (Scr.Windows->hilited)
2278 on_window_hilite_changed (Scr.Windows->hilited, False);
2279 if (asw)
2280 on_window_hilite_changed (asw, True);
2281
2282 if (Scr.Windows->hilited)
2283 broadcast_focus_change (Scr.Windows->hilited, False);
2284 if (asw)
2285 broadcast_focus_change (asw, True);
2286
2287 Scr.Windows->hilited = asw;
2288 set_active_window_prop (Scr.wmprops, asw ? asw->w : None);
2289 }
2290 }
2291
hide_hilite()2292 void hide_hilite ()
2293 {
2294 if (Scr.Windows->hilited != NULL) {
2295 on_window_hilite_changed (Scr.Windows->hilited, False);
2296 broadcast_focus_change (Scr.Windows->hilited, False);
2297 Scr.Windows->hilited = NULL;
2298 }
2299 }
2300
press_aswindow(ASWindow * asw,int context)2301 void press_aswindow (ASWindow * asw, int context)
2302 {
2303 if (context == C_NO_CONTEXT) {
2304 if (Scr.Windows->pressed == asw)
2305 Scr.Windows->pressed = NULL;
2306 } else if (Scr.Windows->pressed != asw) {
2307 /* TODO :may need to do something to avoid recursion here */
2308 if (Scr.Windows->pressed != NULL)
2309 on_window_pressure_changed (Scr.Windows->pressed, C_NO_CONTEXT);
2310 Scr.Windows->pressed = asw;
2311 }
2312
2313 if (asw)
2314 on_window_pressure_changed (asw, context);
2315 }
2316
release_pressure()2317 void release_pressure ()
2318 {
2319 if (Scr.Windows->pressed != NULL) {
2320 on_window_pressure_changed (Scr.Windows->pressed, C_NO_CONTEXT);
2321 Scr.Windows->pressed = NULL;
2322 }
2323 }
2324
2325 /**********************************************************************/
2326 /* The End */
2327 /**********************************************************************/
2328