520.1.2
by Matthew Fuller
Bust functions related to iconifying/deiconifying windows out of |
1 |
/*
|
2 |
* Window de/iconification handling
|
|
3 |
*/
|
|
4 |
||
5 |
#include "ctwm.h" |
|
6 |
||
7 |
#include <stdlib.h> |
|
543
by Olaf 'Rhialto' Seibert
Add #include <sys/time.h> to get at struct timeval. This is necessary |
8 |
#include <sys/time.h> |
520.1.2
by Matthew Fuller
Bust functions related to iconifying/deiconifying windows out of |
9 |
|
10 |
#include <X11/extensions/shape.h> |
|
11 |
||
12 |
#include "events.h" |
|
13 |
#include "functions.h" |
|
14 |
#include "iconmgr.h" |
|
15 |
#include "icons.h" |
|
524.1.5
by Matthew Fuller
Pull list.h out of screen.h and #include it in the places that need |
16 |
#include "list.h" |
520.1.2
by Matthew Fuller
Bust functions related to iconifying/deiconifying windows out of |
17 |
#include "otp.h" |
18 |
#include "screen.h" |
|
19 |
#include "util.h" |
|
524.1.3
by Matthew Fuller
Pull vscreen.h out of screen.h and #include it directly in the files |
20 |
#include "vscreen.h" |
520.1.2
by Matthew Fuller
Bust functions related to iconifying/deiconifying windows out of |
21 |
#include "win_iconify.h" |
523.1.11
by Matthew Fuller
Inagurate win_ops.c by moving the focus functions from util.c into it. |
22 |
#include "win_ops.h" |
523.1.5
by Matthew Fuller
GetTwmWindow() is pretty obvious _utils fodder. |
23 |
#include "win_utils.h" |
520.1.2
by Matthew Fuller
Bust functions related to iconifying/deiconifying windows out of |
24 |
#include "workspace_manager.h" |
25 |
||
26 |
||
27 |
/* Animations */
|
|
28 |
static void MosaicFade(TwmWindow *tmp_win, Window blanket); |
|
29 |
static void ZoomInWindow(TwmWindow *tmp_win, Window blanket); |
|
30 |
static void ZoomOutWindow(TwmWindow *tmp_win, Window blanket); |
|
31 |
static void FadeWindow(TwmWindow *tmp_win, Window blanket); |
|
32 |
static void SweepWindow(TwmWindow *tmp_win, Window blanket); |
|
33 |
||
34 |
/* De/iconify utils */
|
|
520.1.4
by Matthew Fuller
Zoom() is only used in funcs now in win_iconify, so move it there and |
35 |
static void Zoom(Window wf, Window wt); |
520.1.2
by Matthew Fuller
Bust functions related to iconifying/deiconifying windows out of |
36 |
static void ReMapOne(TwmWindow *t, TwmWindow *leader); |
37 |
static void waitamoment(float timeout); |
|
38 |
||
39 |
||
40 |
||
41 |
/*
|
|
42 |
* The main routines for iconifying...
|
|
43 |
*/
|
|
44 |
void
|
|
45 |
Iconify(TwmWindow *tmp_win, int def_x, int def_y) |
|
46 |
{
|
|
47 |
TwmWindow *t; |
|
48 |
bool iconify; |
|
49 |
long eventMask; |
|
50 |
WList *wl; |
|
51 |
Window leader = (Window) - 1; |
|
52 |
Window blanket = (Window) - 1; |
|
53 |
||
54 |
iconify = (!tmp_win->iconify_by_unmapping); |
|
55 |
t = NULL; |
|
56 |
if(tmp_win->istransient) { |
|
57 |
leader = tmp_win->transientfor; |
|
58 |
t = GetTwmWindow(leader); |
|
59 |
}
|
|
60 |
else if((leader = tmp_win->group) != 0 && leader != tmp_win->w) { |
|
61 |
t = GetTwmWindow(leader); |
|
62 |
}
|
|
63 |
if(t && t->icon_on) { |
|
64 |
iconify = false; |
|
65 |
}
|
|
66 |
if(iconify) { |
|
67 |
if(!tmp_win->icon || !tmp_win->icon->w) { |
|
68 |
CreateIconWindow(tmp_win, def_x, def_y); |
|
69 |
}
|
|
70 |
else { |
|
71 |
IconUp(tmp_win); |
|
72 |
}
|
|
73 |
if(visible(tmp_win)) { |
|
604.1.2
by Matthew Fuller
Both sides of this conditional are identical, so why have it? |
74 |
OtpRaise(tmp_win, IconWin); |
75 |
XMapWindow(dpy, tmp_win->icon->w); |
|
520.1.2
by Matthew Fuller
Bust functions related to iconifying/deiconifying windows out of |
76 |
}
|
77 |
}
|
|
78 |
if(tmp_win->iconmanagerlist) { |
|
79 |
for(wl = tmp_win->iconmanagerlist; wl != NULL; wl = wl->nextv) { |
|
80 |
XMapWindow(dpy, wl->icon); |
|
81 |
}
|
|
82 |
}
|
|
83 |
||
84 |
/* Don't mask anything yet, just get the current for various uses */
|
|
85 |
eventMask = mask_out_event(tmp_win->w, 0); |
|
86 |
||
87 |
/* iconify transients and window group first */
|
|
88 |
UnmapTransients(tmp_win, iconify, eventMask); |
|
89 |
||
90 |
if(iconify) { |
|
91 |
Zoom(tmp_win->frame, tmp_win->icon->w); |
|
92 |
}
|
|
93 |
||
94 |
/*
|
|
95 |
* Prevent the receipt of an UnmapNotify, since that would
|
|
96 |
* cause a transition to the Withdrawn state.
|
|
97 |
*/
|
|
98 |
tmp_win->mapped = false; |
|
99 |
||
100 |
if((Scr->IconifyStyle != ICONIFY_NORMAL) && !Scr->WindowMask) { |
|
101 |
XWindowAttributes winattrs; |
|
102 |
XSetWindowAttributes attr; |
|
103 |
||
104 |
XGetWindowAttributes(dpy, tmp_win->frame, &winattrs); |
|
105 |
blanket = XCreateWindow(dpy, Scr->Root, winattrs.x, winattrs.y, |
|
106 |
winattrs.width, winattrs.height, 0, |
|
107 |
CopyFromParent, CopyFromParent, |
|
570.1.3
by Matthew Fuller
Setting SaveUnder=False on new windows is pointless, because that's |
108 |
CopyFromParent, None, &attr); |
520.1.2
by Matthew Fuller
Bust functions related to iconifying/deiconifying windows out of |
109 |
XMapWindow(dpy, blanket); |
110 |
}
|
|
111 |
||
112 |
mask_out_event_mask(tmp_win->w, StructureNotifyMask, eventMask); |
|
113 |
XUnmapWindow(dpy, tmp_win->w); |
|
114 |
XUnmapWindow(dpy, tmp_win->frame); |
|
115 |
restore_mask(tmp_win->w, eventMask); |
|
116 |
||
117 |
SetMapStateProp(tmp_win, IconicState); |
|
118 |
||
119 |
if((Scr->IconifyStyle != ICONIFY_NORMAL) && !Scr->WindowMask) { |
|
120 |
switch(Scr->IconifyStyle) { |
|
121 |
case ICONIFY_MOSAIC: |
|
122 |
MosaicFade(tmp_win, blanket); |
|
123 |
break; |
|
124 |
case ICONIFY_ZOOMIN: |
|
125 |
ZoomInWindow(tmp_win, blanket); |
|
126 |
break; |
|
127 |
case ICONIFY_ZOOMOUT: |
|
128 |
ZoomOutWindow(tmp_win, blanket); |
|
129 |
break; |
|
130 |
case ICONIFY_FADE: |
|
131 |
FadeWindow(tmp_win, blanket); |
|
132 |
break; |
|
133 |
case ICONIFY_SWEEP: |
|
134 |
SweepWindow(tmp_win, blanket); |
|
135 |
break; |
|
136 |
case ICONIFY_NORMAL: |
|
137 |
/* Placate insufficiently smart clang warning */
|
|
138 |
break; |
|
139 |
}
|
|
140 |
XDestroyWindow(dpy, blanket); |
|
141 |
}
|
|
142 |
if(tmp_win == Scr->Focus) { |
|
521.1.20
by Matthew Fuller
Rename lastTimestamp to EventTime to be more obvious about what time |
143 |
SetFocus(NULL, EventTime); |
520.1.2
by Matthew Fuller
Bust functions related to iconifying/deiconifying windows out of |
144 |
if(! Scr->ClickToFocus) { |
145 |
Scr->FocusRoot = true; |
|
146 |
}
|
|
147 |
}
|
|
148 |
tmp_win->isicon = true; |
|
149 |
tmp_win->icon_on = iconify; |
|
150 |
WMapIconify(tmp_win); |
|
151 |
if(! Scr->WindowMask && Scr->IconifyFunction.func != 0) { |
|
152 |
char *action; |
|
153 |
XEvent event; |
|
154 |
||
155 |
action = Scr->IconifyFunction.item ? Scr->IconifyFunction.item->action : NULL; |
|
156 |
ExecuteFunction(Scr->IconifyFunction.func, action, |
|
157 |
(Window) 0, tmp_win, &event, C_ROOT, false); |
|
158 |
}
|
|
159 |
XSync(dpy, 0); |
|
160 |
}
|
|
161 |
||
162 |
||
163 |
/*
|
|
164 |
* ... and its complement
|
|
165 |
*/
|
|
166 |
void
|
|
167 |
DeIconify(TwmWindow *tmp_win) |
|
168 |
{
|
|
169 |
TwmWindow *t = tmp_win; |
|
170 |
bool isicon = false; |
|
171 |
||
172 |
/* de-iconify the main window */
|
|
173 |
if(Scr->WindowMask) { |
|
174 |
XRaiseWindow(dpy, Scr->WindowMask); |
|
175 |
}
|
|
176 |
if(tmp_win->isicon) { |
|
177 |
isicon = true; |
|
178 |
if(tmp_win->icon_on && tmp_win->icon && tmp_win->icon->w) { |
|
179 |
Zoom(tmp_win->icon->w, tmp_win->frame); |
|
180 |
}
|
|
181 |
else if(tmp_win->group != (Window) 0) { |
|
685.1.25
by Matthew Fuller
Use a temp var to avoid the possible case of NULL-ing out this t, |
182 |
TwmWindow *tmpt = GetTwmWindow(tmp_win->group); |
183 |
if(tmpt) { |
|
184 |
t = tmpt; |
|
185 |
if(t->icon_on && t->icon && t->icon->w) { |
|
186 |
Zoom(t->icon->w, tmp_win->frame); |
|
187 |
}
|
|
520.1.2
by Matthew Fuller
Bust functions related to iconifying/deiconifying windows out of |
188 |
}
|
189 |
}
|
|
190 |
}
|
|
191 |
||
192 |
ReMapOne(tmp_win, t); |
|
193 |
||
194 |
if(isicon && |
|
195 |
(Scr->WarpCursor || |
|
563.1.4
by Matthew Fuller
Mechanically translate all these full_name references to name. |
196 |
LookInList(Scr->WarpCursorL, tmp_win->name, &tmp_win->class))) { |
520.1.2
by Matthew Fuller
Bust functions related to iconifying/deiconifying windows out of |
197 |
WarpToWindow(tmp_win, false); |
198 |
}
|
|
199 |
||
200 |
/* now de-iconify any window group transients */
|
|
201 |
ReMapTransients(tmp_win); |
|
202 |
||
203 |
if(! Scr->WindowMask && Scr->DeIconifyFunction.func != 0) { |
|
204 |
char *action; |
|
205 |
XEvent event; |
|
206 |
||
207 |
action = Scr->DeIconifyFunction.item ? |
|
208 |
Scr->DeIconifyFunction.item->action : NULL; |
|
209 |
ExecuteFunction(Scr->DeIconifyFunction.func, action, |
|
210 |
(Window) 0, tmp_win, &event, C_ROOT, false); |
|
211 |
}
|
|
212 |
XSync(dpy, 0); |
|
213 |
}
|
|
214 |
||
215 |
||
216 |
||
217 |
/*
|
|
218 |
* Animations for popping windows around.
|
|
219 |
*/
|
|
220 |
static void |
|
221 |
MosaicFade(TwmWindow *tmp_win, Window blanket) |
|
222 |
{
|
|
223 |
int srect; |
|
224 |
int i, j, nrects; |
|
225 |
Pixmap mask; |
|
226 |
GC gc; |
|
227 |
XGCValues gcv; |
|
228 |
XRectangle *rectangles; |
|
229 |
int width = tmp_win->frame_width; |
|
230 |
int height = tmp_win->frame_height; |
|
231 |
||
232 |
srect = (width < height) ? (width / 20) : (height / 20); |
|
233 |
mask = XCreatePixmap(dpy, blanket, width, height, 1); |
|
234 |
||
235 |
gcv.foreground = 1; |
|
236 |
gc = XCreateGC(dpy, mask, GCForeground, &gcv); |
|
237 |
XFillRectangle(dpy, mask, gc, 0, 0, width, height); |
|
238 |
gcv.function = GXclear; |
|
239 |
XChangeGC(dpy, gc, GCFunction, &gcv); |
|
240 |
||
241 |
nrects = ((width * height) / (srect * srect)) / 10; |
|
242 |
rectangles = calloc(nrects, sizeof(XRectangle)); |
|
243 |
for(j = 0; j < nrects; j++) { |
|
244 |
rectangles [j].width = srect; |
|
245 |
rectangles [j].height = srect; |
|
246 |
}
|
|
247 |
for(i = 0; i < 10; i++) { |
|
248 |
for(j = 0; j < nrects; j++) { |
|
249 |
rectangles [j].x = ((lrand48() % width) / srect) * srect; |
|
250 |
rectangles [j].y = ((lrand48() % height) / srect) * srect; |
|
251 |
}
|
|
252 |
XFillRectangles(dpy, mask, gc, rectangles, nrects); |
|
253 |
XShapeCombineMask(dpy, blanket, ShapeBounding, 0, 0, mask, ShapeSet); |
|
254 |
XFlush(dpy); |
|
255 |
waitamoment(0.020); |
|
256 |
}
|
|
257 |
XFreePixmap(dpy, mask); |
|
258 |
XFreeGC(dpy, gc); |
|
259 |
free(rectangles); |
|
260 |
}
|
|
261 |
||
262 |
||
263 |
static void |
|
264 |
ZoomInWindow(TwmWindow *tmp_win, Window blanket) |
|
265 |
{
|
|
266 |
Pixmap mask; |
|
267 |
GC gc, gcn; |
|
268 |
XGCValues gcv; |
|
269 |
||
270 |
int i, nsteps = 20; |
|
271 |
int w = tmp_win->frame_width; |
|
272 |
int h = tmp_win->frame_height; |
|
273 |
int step = (MAX(w, h)) / (2.0 * nsteps); |
|
274 |
||
275 |
mask = XCreatePixmap(dpy, blanket, w, h, 1); |
|
276 |
gcv.foreground = 1; |
|
277 |
gc = XCreateGC(dpy, mask, GCForeground, &gcv); |
|
278 |
gcv.function = GXclear; |
|
279 |
gcn = XCreateGC(dpy, mask, GCForeground | GCFunction, &gcv); |
|
280 |
||
281 |
for(i = 0; i < nsteps; i++) { |
|
282 |
XFillRectangle(dpy, mask, gcn, 0, 0, w, h); |
|
283 |
XFillArc(dpy, mask, gc, (w / 2) - ((nsteps - i) * step), |
|
284 |
(h / 2) - ((nsteps - i) * step), |
|
285 |
2 * (nsteps - i) * step, |
|
286 |
2 * (nsteps - i) * step, |
|
287 |
0, 360 * 64); |
|
288 |
XShapeCombineMask(dpy, blanket, ShapeBounding, 0, 0, mask, ShapeSet); |
|
289 |
XFlush(dpy); |
|
290 |
waitamoment(0.020); |
|
291 |
}
|
|
292 |
}
|
|
293 |
||
294 |
||
295 |
static void |
|
296 |
ZoomOutWindow(TwmWindow *tmp_win, Window blanket) |
|
297 |
{
|
|
298 |
Pixmap mask; |
|
299 |
GC gc; |
|
300 |
XGCValues gcv; |
|
301 |
||
302 |
int i, nsteps = 20; |
|
303 |
int w = tmp_win->frame_width; |
|
304 |
int h = tmp_win->frame_height; |
|
305 |
int step = (MAX(w, h)) / (2.0 * nsteps); |
|
306 |
||
307 |
mask = XCreatePixmap(dpy, blanket, w, h, 1); |
|
308 |
gcv.foreground = 1; |
|
309 |
gc = XCreateGC(dpy, mask, GCForeground, &gcv); |
|
310 |
XFillRectangle(dpy, mask, gc, 0, 0, w, h); |
|
311 |
gcv.function = GXclear; |
|
312 |
XChangeGC(dpy, gc, GCFunction, &gcv); |
|
313 |
||
314 |
for(i = 0; i < nsteps; i++) { |
|
315 |
XFillArc(dpy, mask, gc, (w / 2) - (i * step), |
|
316 |
(h / 2) - (i * step), |
|
317 |
2 * i * step, |
|
318 |
2 * i * step, |
|
319 |
0, 360 * 64); |
|
320 |
XShapeCombineMask(dpy, blanket, ShapeBounding, 0, 0, mask, ShapeSet); |
|
321 |
XFlush(dpy); |
|
322 |
waitamoment(0.020); |
|
323 |
}
|
|
324 |
}
|
|
325 |
||
326 |
||
327 |
void
|
|
328 |
FadeWindow(TwmWindow *tmp_win, Window blanket) |
|
329 |
{
|
|
330 |
Pixmap mask, stipple; |
|
331 |
GC gc; |
|
332 |
XGCValues gcv; |
|
333 |
static unsigned char stipple_bits[] = { 0x0F, 0x0F, |
|
334 |
0xF0, 0xF0, |
|
335 |
0x0F, 0x0F, |
|
336 |
0xF0, 0xF0, |
|
337 |
0x0F, 0x0F, |
|
338 |
0xF0, 0xF0, |
|
339 |
0x0F, 0x0F, |
|
340 |
0xF0, 0xF0, |
|
341 |
};
|
|
342 |
int w = tmp_win->frame_width; |
|
343 |
int h = tmp_win->frame_height; |
|
344 |
||
345 |
stipple = XCreateBitmapFromData(dpy, blanket, (char *)stipple_bits, 8, 8); |
|
346 |
mask = XCreatePixmap(dpy, blanket, w, h, 1); |
|
347 |
gcv.background = 0; |
|
348 |
gcv.foreground = 1; |
|
349 |
gcv.stipple = stipple; |
|
350 |
gcv.fill_style = FillOpaqueStippled; |
|
351 |
gc = XCreateGC(dpy, mask, GCBackground | GCForeground | GCFillStyle | GCStipple, |
|
352 |
&gcv); |
|
353 |
XFillRectangle(dpy, mask, gc, 0, 0, w, h); |
|
354 |
||
355 |
XShapeCombineMask(dpy, blanket, ShapeBounding, 0, 0, mask, ShapeSet); |
|
356 |
XFlush(dpy); |
|
357 |
waitamoment(0.10); |
|
358 |
XFreePixmap(dpy, stipple); |
|
359 |
XFlush(dpy); |
|
360 |
}
|
|
361 |
||
362 |
||
363 |
static void |
|
364 |
SweepWindow(TwmWindow *tmp_win, Window blanket) |
|
365 |
{
|
|
366 |
float step = 0.0; |
|
367 |
int i, nsteps = 20; |
|
368 |
int dir = 0, dist = tmp_win->frame_x, dist1; |
|
369 |
||
370 |
dist1 = tmp_win->frame_y; |
|
371 |
if(dist1 < dist) { |
|
372 |
dir = 1; |
|
373 |
dist = dist1; |
|
374 |
}
|
|
375 |
dist1 = tmp_win->vs->w - (tmp_win->frame_x + tmp_win->frame_width); |
|
376 |
if(dist1 < dist) { |
|
377 |
dir = 2; |
|
378 |
dist = dist1; |
|
379 |
}
|
|
380 |
dist1 = tmp_win->vs->h - (tmp_win->frame_y + tmp_win->frame_height); |
|
381 |
if(dist1 < dist) { |
|
382 |
dir = 3; |
|
383 |
dist = dist1; |
|
685.1.18
by Matthew Fuller
Mark a few known dead sture that we want to leave for cleanliness or |
384 |
ALLOW_DEAD_STORE(dist); |
520.1.2
by Matthew Fuller
Bust functions related to iconifying/deiconifying windows out of |
385 |
}
|
386 |
||
387 |
switch(dir) { |
|
388 |
case 0: |
|
389 |
step = tmp_win->frame_x + tmp_win->frame_width; |
|
390 |
break; |
|
391 |
case 1: |
|
392 |
step = tmp_win->frame_y + tmp_win->frame_height; |
|
393 |
break; |
|
394 |
case 2: |
|
395 |
step = tmp_win->vs->w - tmp_win->frame_x; |
|
396 |
break; |
|
397 |
case 3: |
|
398 |
step = tmp_win->vs->h - tmp_win->frame_y; |
|
399 |
break; |
|
400 |
}
|
|
401 |
step /= (float) nsteps; |
|
402 |
step /= (float) nsteps; |
|
403 |
for(i = 0; i < 20; i++) { |
|
404 |
int x = tmp_win->frame_x; |
|
405 |
int y = tmp_win->frame_y; |
|
406 |
switch(dir) { |
|
407 |
case 0: |
|
408 |
x -= i * i * step; |
|
409 |
break; |
|
410 |
case 1: |
|
411 |
y -= i * i * step; |
|
412 |
break; |
|
413 |
case 2: |
|
414 |
x += i * i * step; |
|
415 |
break; |
|
416 |
case 3: |
|
417 |
y += i * i * step; |
|
418 |
break; |
|
419 |
}
|
|
420 |
XMoveWindow(dpy, blanket, x, y); |
|
421 |
XFlush(dpy); |
|
422 |
waitamoment(0.020); |
|
423 |
}
|
|
424 |
}
|
|
425 |
||
426 |
||
427 |
||
428 |
/*
|
|
429 |
* Utils used by various bits above
|
|
430 |
*/
|
|
520.1.4
by Matthew Fuller
Zoom() is only used in funcs now in win_iconify, so move it there and |
431 |
|
432 |
/***********************************************************************
|
|
433 |
*
|
|
434 |
* Procedure:
|
|
435 |
* Zoom - zoom in or out of an icon
|
|
436 |
*
|
|
437 |
* Inputs:
|
|
438 |
* wf - window to zoom from
|
|
439 |
* wt - window to zoom to
|
|
440 |
*
|
|
441 |
***********************************************************************
|
|
442 |
*/
|
|
443 |
static void |
|
444 |
Zoom(Window wf, Window wt) |
|
445 |
{
|
|
446 |
int fx, fy, tx, ty; /* from, to */ |
|
447 |
unsigned int fw, fh, tw, th; /* from, to */ |
|
448 |
long dx, dy, dw, dh; |
|
449 |
long z; |
|
450 |
int j; |
|
451 |
||
452 |
if((Scr->IconifyStyle != ICONIFY_NORMAL) || !Scr->DoZoom |
|
453 |
|| Scr->ZoomCount < 1) { |
|
454 |
return; |
|
455 |
}
|
|
456 |
||
457 |
if(wf == None || wt == None) { |
|
458 |
return; |
|
459 |
}
|
|
460 |
||
461 |
XGetGeometry(dpy, wf, &JunkRoot, &fx, &fy, &fw, &fh, &JunkBW, &JunkDepth); |
|
462 |
XGetGeometry(dpy, wt, &JunkRoot, &tx, &ty, &tw, &th, &JunkBW, &JunkDepth); |
|
463 |
||
464 |
dx = (long) tx - (long) fx; /* going from -> to */ |
|
465 |
dy = (long) ty - (long) fy; /* going from -> to */ |
|
466 |
dw = (long) tw - (long) fw; /* going from -> to */ |
|
467 |
dh = (long) th - (long) fh; /* going from -> to */ |
|
468 |
z = (long)(Scr->ZoomCount + 1); |
|
469 |
||
470 |
for(j = 0; j < 2; j++) { |
|
471 |
long i; |
|
472 |
||
473 |
XDrawRectangle(dpy, Scr->Root, Scr->DrawGC, fx, fy, fw, fh); |
|
474 |
for(i = 1; i < z; i++) { |
|
475 |
int x = fx + (int)((dx * i) / z); |
|
476 |
int y = fy + (int)((dy * i) / z); |
|
477 |
unsigned width = (unsigned)(((long) fw) + (dw * i) / z); |
|
478 |
unsigned height = (unsigned)(((long) fh) + (dh * i) / z); |
|
479 |
||
480 |
XDrawRectangle(dpy, Scr->Root, Scr->DrawGC, |
|
481 |
x, y, width, height); |
|
482 |
}
|
|
483 |
XDrawRectangle(dpy, Scr->Root, Scr->DrawGC, tx, ty, tw, th); |
|
484 |
}
|
|
485 |
}
|
|
486 |
||
487 |
||
520.1.2
by Matthew Fuller
Bust functions related to iconifying/deiconifying windows out of |
488 |
static void |
489 |
ReMapOne(TwmWindow *t, TwmWindow *leader) |
|
490 |
{
|
|
491 |
if(t->icon_on) { |
|
492 |
Zoom(t->icon->w, t->frame); |
|
493 |
}
|
|
494 |
else if(leader->icon) { |
|
495 |
Zoom(leader->icon->w, t->frame); |
|
496 |
}
|
|
497 |
||
498 |
if(!t->squeezed) { |
|
499 |
XMapWindow(dpy, t->w); |
|
500 |
}
|
|
501 |
t->mapped = true; |
|
692.1.5
by Matthew Fuller
Add ifdef's around references to Screen and CLargs members that are |
502 |
#ifdef CAPTIVE
|
520.1.3
by Matthew Fuller
Use C99 bool for this inline literal. |
503 |
if(false && Scr->Root != Scr->CaptiveRoot) { /* XXX dubious test */ |
520.1.2
by Matthew Fuller
Bust functions related to iconifying/deiconifying windows out of |
504 |
ReparentWindow(dpy, t, WinWin, Scr->Root, t->frame_x, t->frame_y); |
505 |
}
|
|
692.1.5
by Matthew Fuller
Add ifdef's around references to Screen and CLargs members that are |
506 |
#endif
|
520.1.2
by Matthew Fuller
Bust functions related to iconifying/deiconifying windows out of |
507 |
if(!Scr->NoRaiseDeicon) { |
508 |
OtpRaise(t, WinWin); |
|
509 |
}
|
|
510 |
XMapWindow(dpy, t->frame); |
|
511 |
SetMapStateProp(t, NormalState); |
|
512 |
||
513 |
if(t->icon && t->icon->w) { |
|
514 |
XUnmapWindow(dpy, t->icon->w); |
|
515 |
IconDown(t); |
|
516 |
if(Scr->ShrinkIconTitles) { |
|
517 |
t->icon->title_shrunk = true; |
|
518 |
}
|
|
519 |
}
|
|
520 |
if(t->iconmanagerlist) { |
|
521 |
WList *wl; |
|
522 |
||
523 |
for(wl = t->iconmanagerlist; wl != NULL; wl = wl->nextv) { |
|
524 |
XUnmapWindow(dpy, wl->icon); |
|
525 |
}
|
|
526 |
}
|
|
527 |
t->isicon = false; |
|
528 |
t->icon_on = false; |
|
529 |
WMapDeIconify(t); |
|
530 |
}
|
|
531 |
||
532 |
||
533 |
/*
|
|
534 |
* Mostly internal util of iconification, but squeezing code needs it
|
|
535 |
* too.
|
|
536 |
*/
|
|
537 |
void
|
|
538 |
ReMapTransients(TwmWindow *tmp_win) |
|
539 |
{
|
|
540 |
TwmWindow *t; |
|
541 |
||
542 |
/* find t such that it is a transient or group member window */
|
|
543 |
for(t = Scr->FirstWindow; t != NULL; t = t->next) { |
|
544 |
if(t != tmp_win && |
|
545 |
((t->istransient && t->transientfor == tmp_win->w) || |
|
546 |
(t->group == tmp_win->w && t->isicon))) { |
|
547 |
ReMapOne(t, tmp_win); |
|
548 |
}
|
|
549 |
}
|
|
550 |
}
|
|
551 |
||
552 |
||
553 |
/*
|
|
554 |
* Ditto previous note about squeezing.
|
|
555 |
*/
|
|
556 |
void
|
|
557 |
UnmapTransients(TwmWindow *tmp_win, bool iconify, long eventMask) |
|
558 |
{
|
|
559 |
TwmWindow *t; |
|
560 |
||
561 |
for(t = Scr->FirstWindow; t != NULL; t = t->next) { |
|
562 |
if(t != tmp_win && |
|
563 |
((t->istransient && t->transientfor == tmp_win->w) || |
|
564 |
t->group == tmp_win->w)) { |
|
565 |
if(iconify) { |
|
566 |
if(t->icon_on) { |
|
567 |
Zoom(t->icon->w, tmp_win->icon->w); |
|
568 |
}
|
|
569 |
else if(tmp_win->icon) { |
|
570 |
Zoom(t->frame, tmp_win->icon->w); |
|
571 |
}
|
|
572 |
}
|
|
573 |
||
574 |
/*
|
|
575 |
* Prevent the receipt of an UnmapNotify, since that would
|
|
576 |
* cause a transition to the Withdrawn state.
|
|
577 |
*/
|
|
578 |
t->mapped = false; |
|
579 |
||
580 |
/*
|
|
581 |
* Note that here, we're setting masks relative to what we
|
|
582 |
* were passed, which is that of the window these are
|
|
583 |
* transient for, rather than relative to these windows'
|
|
584 |
* current masks. I believe in practice it's the same thing,
|
|
585 |
* and it saves getting attributes on each for masking.
|
|
586 |
* Still, a little odd...
|
|
587 |
*/
|
|
588 |
mask_out_event_mask(t->w, StructureNotifyMask, eventMask); |
|
589 |
XUnmapWindow(dpy, t->w); |
|
590 |
XUnmapWindow(dpy, t->frame); |
|
591 |
restore_mask(t->w, eventMask); |
|
592 |
||
593 |
if(t->icon && t->icon->w) { |
|
594 |
XUnmapWindow(dpy, t->icon->w); |
|
595 |
}
|
|
596 |
SetMapStateProp(t, IconicState); |
|
597 |
if(t == Scr->Focus) { |
|
521.1.20
by Matthew Fuller
Rename lastTimestamp to EventTime to be more obvious about what time |
598 |
SetFocus(NULL, EventTime); |
520.1.2
by Matthew Fuller
Bust functions related to iconifying/deiconifying windows out of |
599 |
if(! Scr->ClickToFocus) { |
600 |
Scr->FocusRoot = true; |
|
601 |
}
|
|
602 |
}
|
|
603 |
if(t->iconmanagerlist) { |
|
604 |
XMapWindow(dpy, t->iconmanagerlist->icon); |
|
605 |
}
|
|
606 |
t->isicon = true; |
|
607 |
t->icon_on = false; |
|
608 |
WMapIconify(t); |
|
609 |
}
|
|
610 |
}
|
|
611 |
}
|
|
612 |
||
613 |
||
614 |
static void |
|
615 |
waitamoment(float timeout) |
|
616 |
{
|
|
617 |
struct timeval timeoutstruct; |
|
618 |
int usec = timeout * 1000000; |
|
619 |
timeoutstruct.tv_usec = usec % (unsigned long) 1000000; |
|
620 |
timeoutstruct.tv_sec = usec / (unsigned long) 1000000; |
|
621 |
select(0, NULL, NULL, NULL, &timeoutstruct); |
|
622 |
}
|