1 | /* |
---|
2 | * (c) Copyright 1989, 1990, 1991, 1992, 1993 OPEN SOFTWARE FOUNDATION, INC. |
---|
3 | * ALL RIGHTS RESERVED |
---|
4 | */ |
---|
5 | /* |
---|
6 | * Motif Release 1.2.3 |
---|
7 | */ |
---|
8 | #ifdef REV_INFO |
---|
9 | #ifndef lint |
---|
10 | static char rcsid[] = "$RCSfile: WmWinList.c,v $ $Revision: 1.1.1.1 $ $Date: 1997-03-25 09:12:27 $" |
---|
11 | #endif |
---|
12 | #endif |
---|
13 | /* |
---|
14 | * (c) Copyright 1987, 1988, 1989, 1990 HEWLETT-PACKARD COMPANY */ |
---|
15 | |
---|
16 | /* |
---|
17 | * Included Files: |
---|
18 | */ |
---|
19 | |
---|
20 | #include "WmGlobal.h" |
---|
21 | |
---|
22 | #define MWM_NEED_NOENTER16 |
---|
23 | #include "WmBitmap.h" |
---|
24 | |
---|
25 | |
---|
26 | /* |
---|
27 | * include extern functions |
---|
28 | */ |
---|
29 | #include "WmWinList.h" |
---|
30 | #include "WmCEvent.h" |
---|
31 | #include "WmFunction.h" |
---|
32 | #include "WmKeyFocus.h" |
---|
33 | #include "WmResource.h" |
---|
34 | #include "WmWinInfo.h" |
---|
35 | |
---|
36 | |
---|
37 | |
---|
38 | |
---|
39 | /* |
---|
40 | * Global Variables: |
---|
41 | */ |
---|
42 | |
---|
43 | |
---|
44 | /*************************************<->************************************* |
---|
45 | * |
---|
46 | * AddClientToList (pWS, pCD, onTop) |
---|
47 | * |
---|
48 | * |
---|
49 | * Description: |
---|
50 | * ----------- |
---|
51 | * This function adds a client window to the client window list. If it is |
---|
52 | * a transient window then it is added to the transient window tree that |
---|
53 | * contains its transient leader. The window stacking order is also |
---|
54 | * maintained for the cases where there is a system modal window active |
---|
55 | * or the window is a transient window. If a system modal window is being |
---|
56 | * added then the system modal "input screen" window is setup. |
---|
57 | * |
---|
58 | * |
---|
59 | * Inputs: |
---|
60 | * ------ |
---|
61 | * pCD = pointer to client data for the window to be added to the list |
---|
62 | * |
---|
63 | * pWS = pointer to workspace data |
---|
64 | * |
---|
65 | * onTop = if True then the window is displayed on top of the window |
---|
66 | * stack and is added to the beginning of the window list, otherwise |
---|
67 | * it is added to the end of the window list. |
---|
68 | * |
---|
69 | * |
---|
70 | * Outputs: |
---|
71 | * ------- |
---|
72 | * pWS = (clientList, lastClient) |
---|
73 | * |
---|
74 | *************************************<->***********************************/ |
---|
75 | |
---|
76 | #ifdef _NO_PROTO |
---|
77 | void AddClientToList (pWS, pCD, onTop) |
---|
78 | ClientData *pCD; |
---|
79 | WmWorkspaceData *pWS; |
---|
80 | Boolean onTop; |
---|
81 | |
---|
82 | #else /* _NO_PROTO */ |
---|
83 | void AddClientToList (WmWorkspaceData *pWS, ClientData *pCD, Boolean onTop) |
---|
84 | #endif /* _NO_PROTO */ |
---|
85 | { |
---|
86 | Boolean belowSystemModal = False; |
---|
87 | XWindowChanges windowChanges; |
---|
88 | WmScreenData *pSD = pWS->pSD; |
---|
89 | |
---|
90 | |
---|
91 | if (pCD->inputMode == MWM_INPUT_SYSTEM_MODAL) |
---|
92 | { |
---|
93 | /* |
---|
94 | * Set up the system modal input screen window just below the |
---|
95 | * system modal window. |
---|
96 | */ |
---|
97 | |
---|
98 | SetupSystemModalState (pCD); |
---|
99 | } |
---|
100 | else if (wmGD.systemModalActive && |
---|
101 | ((FindTransientTreeLeader (pCD))->inputMode != |
---|
102 | MWM_INPUT_SYSTEM_MODAL)) |
---|
103 | { |
---|
104 | /* |
---|
105 | * If a system modal window is active then place the window below |
---|
106 | * the system modal input screen window if the window is not a |
---|
107 | * descendant of the system modal window. |
---|
108 | */ |
---|
109 | |
---|
110 | windowChanges.sibling = pSD->inputScreenWindow; |
---|
111 | windowChanges.stack_mode = Below; |
---|
112 | XConfigureWindow (DISPLAY, pCD->clientFrameWin, |
---|
113 | CWSibling | CWStackMode, &windowChanges); |
---|
114 | belowSystemModal = True; |
---|
115 | } |
---|
116 | |
---|
117 | if (pCD->transientLeader) |
---|
118 | { |
---|
119 | AddTransient (pWS, pCD); |
---|
120 | } |
---|
121 | else |
---|
122 | { |
---|
123 | pCD->clientEntry.type = NORMAL_STATE; |
---|
124 | pCD->clientEntry.pCD = pCD; |
---|
125 | |
---|
126 | if (belowSystemModal && wmGD.systemModalClient) |
---|
127 | { |
---|
128 | AddEntryToList (pWS, &pCD->clientEntry, False /*below*/, |
---|
129 | pSD->clientList); |
---|
130 | } |
---|
131 | else if (onTop) |
---|
132 | { |
---|
133 | AddEntryToList (pWS, &pCD->clientEntry, True /*on top*/, NULL); |
---|
134 | } |
---|
135 | else |
---|
136 | { |
---|
137 | AddEntryToList (pWS, &pCD->clientEntry, False /*on bottom*/, NULL); |
---|
138 | } |
---|
139 | |
---|
140 | |
---|
141 | if (!pCD->pIconBox && pCD->iconFrameWin) |
---|
142 | { |
---|
143 | /* |
---|
144 | * Put the icon on the bottom of the stack. |
---|
145 | */ |
---|
146 | |
---|
147 | if (pSD->lastClient->type == MINIMIZED_STATE) |
---|
148 | { |
---|
149 | windowChanges.sibling = pSD->lastClient->pCD->iconFrameWin; |
---|
150 | } |
---|
151 | else |
---|
152 | { |
---|
153 | windowChanges.sibling = pSD->lastClient->pCD->clientFrameWin; |
---|
154 | } |
---|
155 | windowChanges.stack_mode = Below; |
---|
156 | XConfigureWindow (DISPLAY, pCD->iconFrameWin, |
---|
157 | CWSibling | CWStackMode, &windowChanges); |
---|
158 | |
---|
159 | pCD->iconEntry.type = MINIMIZED_STATE; |
---|
160 | pCD->iconEntry.pCD = pCD; |
---|
161 | pCD->iconEntry.nextSibling = NULL; |
---|
162 | pCD->iconEntry.prevSibling = pSD->lastClient; |
---|
163 | pSD->lastClient->nextSibling = &pCD->iconEntry; |
---|
164 | pSD->lastClient = &pCD->iconEntry; |
---|
165 | } |
---|
166 | } |
---|
167 | |
---|
168 | } /* END OF FUNCTION AddClientToList */ |
---|
169 | |
---|
170 | |
---|
171 | |
---|
172 | /*************************************<->************************************* |
---|
173 | * |
---|
174 | * AddEntryToList (pWS, pEntry, onTop, pStackEntry) |
---|
175 | * |
---|
176 | * |
---|
177 | * Description: |
---|
178 | * ----------- |
---|
179 | * This function adds a client list entry to the client window list. |
---|
180 | * This is usually done as part of the process of changing the ordering |
---|
181 | * of the window list. |
---|
182 | * |
---|
183 | * |
---|
184 | * Inputs: |
---|
185 | * ------ |
---|
186 | * pWS = pointer to workspace data |
---|
187 | * pEntry = pointer to a client list entry to be added to the client list |
---|
188 | * |
---|
189 | * onTop = if True then the client list entry is added on top of the |
---|
190 | * specified client list stack entry (if the stack entry is not |
---|
191 | * specified then the entry is added to the front of the list); |
---|
192 | * otherwise the entry is added after the specified stacking entry |
---|
193 | * (or to the end of the list if the stacking entry is not specified). |
---|
194 | * |
---|
195 | * pStackEntry = pointer to a client list entry to be used as a reference |
---|
196 | * in adding an entry to the client list. |
---|
197 | * |
---|
198 | * Outputs: |
---|
199 | * ------- |
---|
200 | * pWS = (clientList, lastClient) |
---|
201 | * |
---|
202 | *************************************<->***********************************/ |
---|
203 | |
---|
204 | #ifdef _NO_PROTO |
---|
205 | void AddEntryToList (pWS, pEntry, onTop, pStackEntry) |
---|
206 | WmWorkspaceData *pWS; |
---|
207 | ClientListEntry *pEntry; |
---|
208 | Boolean onTop; |
---|
209 | ClientListEntry *pStackEntry; |
---|
210 | |
---|
211 | #else /* _NO_PROTO */ |
---|
212 | void AddEntryToList (WmWorkspaceData *pWS, ClientListEntry *pEntry, Boolean onTop, ClientListEntry *pStackEntry) |
---|
213 | #endif /* _NO_PROTO */ |
---|
214 | { |
---|
215 | WmScreenData *pSD = pWS->pSD; |
---|
216 | |
---|
217 | if (onTop) |
---|
218 | { |
---|
219 | if (pStackEntry) |
---|
220 | { |
---|
221 | if (pEntry != pStackEntry) |
---|
222 | { |
---|
223 | pEntry->nextSibling = pStackEntry; |
---|
224 | pEntry->prevSibling = pStackEntry->prevSibling; |
---|
225 | pStackEntry->prevSibling = pEntry; |
---|
226 | if (pEntry->prevSibling) |
---|
227 | { |
---|
228 | pEntry->prevSibling->nextSibling = pEntry; |
---|
229 | } |
---|
230 | else |
---|
231 | { |
---|
232 | pSD->clientList = pEntry; |
---|
233 | } |
---|
234 | } |
---|
235 | } |
---|
236 | else |
---|
237 | { |
---|
238 | if (pSD->clientList != pEntry) |
---|
239 | { |
---|
240 | pEntry->nextSibling = pSD->clientList; |
---|
241 | pEntry->prevSibling = NULL; |
---|
242 | if (pSD->clientList) |
---|
243 | { |
---|
244 | pSD->clientList->prevSibling = pEntry; |
---|
245 | } |
---|
246 | else |
---|
247 | { |
---|
248 | pSD->lastClient = pEntry; |
---|
249 | } |
---|
250 | pSD->clientList = pEntry; |
---|
251 | } |
---|
252 | } |
---|
253 | } |
---|
254 | else |
---|
255 | { |
---|
256 | if (pStackEntry) |
---|
257 | { |
---|
258 | if (pEntry != pStackEntry) |
---|
259 | { |
---|
260 | pEntry->nextSibling = pStackEntry->nextSibling; |
---|
261 | pEntry->prevSibling = pStackEntry; |
---|
262 | pStackEntry->nextSibling = pEntry; |
---|
263 | if (pEntry->nextSibling) |
---|
264 | { |
---|
265 | pEntry->nextSibling->prevSibling = pEntry; |
---|
266 | } |
---|
267 | else |
---|
268 | { |
---|
269 | pSD->lastClient = pEntry; |
---|
270 | } |
---|
271 | } |
---|
272 | } |
---|
273 | else |
---|
274 | { |
---|
275 | if (pSD->lastClient != pEntry) |
---|
276 | { |
---|
277 | pEntry->nextSibling = NULL; |
---|
278 | pEntry->prevSibling = pSD->lastClient; |
---|
279 | if (pSD->clientList) |
---|
280 | { |
---|
281 | pSD->lastClient->nextSibling = pEntry; |
---|
282 | } |
---|
283 | else |
---|
284 | { |
---|
285 | pSD->clientList = pEntry; |
---|
286 | } |
---|
287 | pSD->lastClient = pEntry; |
---|
288 | } |
---|
289 | } |
---|
290 | } |
---|
291 | |
---|
292 | } /* END OF FUNCTION AddEntryToList */ |
---|
293 | |
---|
294 | |
---|
295 | |
---|
296 | /*************************************<->************************************* |
---|
297 | * |
---|
298 | * MoveEntryInList (pWS, pEntry, onTop, pStackEntry) |
---|
299 | * |
---|
300 | * |
---|
301 | * Description: |
---|
302 | * ----------- |
---|
303 | * This function moves a client list entry in the client window list. |
---|
304 | * |
---|
305 | * |
---|
306 | * Inputs: |
---|
307 | * ------ |
---|
308 | * pWS = pointer to workspace data |
---|
309 | * |
---|
310 | * pEntry = pointer to a client list entry to be moved in the client list |
---|
311 | * |
---|
312 | * onTop = if True then the client list entry is moved on top of the |
---|
313 | * specified client list stack entry (if the stack entry is not |
---|
314 | * specified then the entry is moved to the front of the list); |
---|
315 | * otherwise the entry is moved after the specified stacking entry |
---|
316 | * (or to the end of the list if the stacking entry is not specified). |
---|
317 | * |
---|
318 | * pStackEntry = pointer to a client list entry to be used as a reference |
---|
319 | * in moving an entry in the client list. |
---|
320 | * |
---|
321 | * Outputs: |
---|
322 | * ------- |
---|
323 | * pWS = (clientList, lastClient) |
---|
324 | * |
---|
325 | *************************************<->***********************************/ |
---|
326 | |
---|
327 | #ifdef _NO_PROTO |
---|
328 | void MoveEntryInList (pWS, pEntry, onTop, pStackEntry) |
---|
329 | WmWorkspaceData *pWS; |
---|
330 | ClientListEntry *pEntry; |
---|
331 | Boolean onTop; |
---|
332 | ClientListEntry *pStackEntry; |
---|
333 | |
---|
334 | #else /* _NO_PROTO */ |
---|
335 | void MoveEntryInList (WmWorkspaceData *pWS, ClientListEntry *pEntry, Boolean onTop, ClientListEntry *pStackEntry) |
---|
336 | #endif /* _NO_PROTO */ |
---|
337 | { |
---|
338 | DeleteEntryFromList (pWS, pEntry); |
---|
339 | AddEntryToList (pWS, pEntry, onTop, pStackEntry); |
---|
340 | |
---|
341 | } /* END OF FUNCTION MoveEntryInList */ |
---|
342 | |
---|
343 | |
---|
344 | |
---|
345 | /*************************************<->************************************* |
---|
346 | * |
---|
347 | * DeleteEntryFromList (pWS, pListEntry) |
---|
348 | * |
---|
349 | * |
---|
350 | * Description: |
---|
351 | * ----------- |
---|
352 | * This function deletes a client list entry from the client window list. |
---|
353 | * This is usually done as part of the process of changing the ordering |
---|
354 | * of the window list. |
---|
355 | * |
---|
356 | * |
---|
357 | * Inputs: |
---|
358 | * ------ |
---|
359 | * pWS = pointer to workspace data |
---|
360 | * listEntry = pointer to a client list entry |
---|
361 | * |
---|
362 | * Outputs: |
---|
363 | * ------- |
---|
364 | * pWS = (clientList, lastClient) |
---|
365 | * |
---|
366 | *************************************<->***********************************/ |
---|
367 | |
---|
368 | #ifdef _NO_PROTO |
---|
369 | void DeleteEntryFromList (pWS, pListEntry) |
---|
370 | WmWorkspaceData *pWS; |
---|
371 | ClientListEntry *pListEntry; |
---|
372 | |
---|
373 | #else /* _NO_PROTO */ |
---|
374 | void DeleteEntryFromList (WmWorkspaceData *pWS, ClientListEntry *pListEntry) |
---|
375 | #endif /* _NO_PROTO */ |
---|
376 | { |
---|
377 | |
---|
378 | if (pListEntry->prevSibling) |
---|
379 | { |
---|
380 | pListEntry->prevSibling->nextSibling = pListEntry->nextSibling; |
---|
381 | } |
---|
382 | else |
---|
383 | { |
---|
384 | pWS->pSD->clientList = pListEntry->nextSibling; |
---|
385 | } |
---|
386 | |
---|
387 | if (pListEntry->nextSibling) |
---|
388 | { |
---|
389 | pListEntry->nextSibling->prevSibling = pListEntry->prevSibling; |
---|
390 | } |
---|
391 | else |
---|
392 | { |
---|
393 | pWS->pSD->lastClient = pListEntry->prevSibling; |
---|
394 | } |
---|
395 | |
---|
396 | } /* END OF FUNCTION DeleteEntryFromList */ |
---|
397 | |
---|
398 | |
---|
399 | |
---|
400 | /*************************************<->************************************* |
---|
401 | * |
---|
402 | * DeleteClientFromList (pWS, pCD) |
---|
403 | * |
---|
404 | * |
---|
405 | * Description: |
---|
406 | * ----------- |
---|
407 | * This function deletes a client from the client window list. If this is |
---|
408 | * a transient window then it is deleted from its transient window tree. |
---|
409 | * If this is a system modal window then clean up the system modal state. |
---|
410 | * |
---|
411 | * |
---|
412 | * Inputs: |
---|
413 | * ------ |
---|
414 | * pCD = pointer to client data for the window to be added to the list |
---|
415 | * |
---|
416 | * Outputs: |
---|
417 | * ------- |
---|
418 | * pWS = (clientList, lastClient) |
---|
419 | * |
---|
420 | *************************************<->***********************************/ |
---|
421 | |
---|
422 | #ifdef _NO_PROTO |
---|
423 | void DeleteClientFromList (pWS, pCD) |
---|
424 | WmWorkspaceData *pWS; |
---|
425 | ClientData *pCD; |
---|
426 | |
---|
427 | #else /* _NO_PROTO */ |
---|
428 | void DeleteClientFromList (WmWorkspaceData *pWS, ClientData *pCD) |
---|
429 | #endif /* _NO_PROTO */ |
---|
430 | { |
---|
431 | WmScreenData *pSD = pWS->pSD; |
---|
432 | |
---|
433 | if (pCD->transientLeader) |
---|
434 | { |
---|
435 | DeleteTransient (pCD); |
---|
436 | } |
---|
437 | else |
---|
438 | { |
---|
439 | /* |
---|
440 | * If this is a system modal window then clean up the system modal |
---|
441 | * state. |
---|
442 | */ |
---|
443 | |
---|
444 | if (pCD->inputMode == MWM_INPUT_SYSTEM_MODAL) |
---|
445 | { |
---|
446 | UndoSystemModalState (); |
---|
447 | } |
---|
448 | |
---|
449 | /* |
---|
450 | * Remove the client and icon entries from the window list. |
---|
451 | */ |
---|
452 | |
---|
453 | if (!pCD->pIconBox && pCD->iconFrameWin) |
---|
454 | { |
---|
455 | if (pCD->iconEntry.prevSibling) |
---|
456 | { |
---|
457 | pCD->iconEntry.prevSibling->nextSibling = |
---|
458 | pCD->iconEntry.nextSibling; |
---|
459 | } |
---|
460 | else |
---|
461 | { |
---|
462 | pSD->clientList = pCD->iconEntry.nextSibling; |
---|
463 | } |
---|
464 | if (pCD->iconEntry.nextSibling) |
---|
465 | { |
---|
466 | pCD->iconEntry.nextSibling->prevSibling = |
---|
467 | pCD->iconEntry.prevSibling; |
---|
468 | } |
---|
469 | else |
---|
470 | { |
---|
471 | pSD->lastClient = pCD->iconEntry.prevSibling; |
---|
472 | } |
---|
473 | } |
---|
474 | |
---|
475 | if (pCD->clientEntry.prevSibling) |
---|
476 | { |
---|
477 | pCD->clientEntry.prevSibling->nextSibling = |
---|
478 | pCD->clientEntry.nextSibling; |
---|
479 | } |
---|
480 | else |
---|
481 | { |
---|
482 | pSD->clientList = pCD->clientEntry.nextSibling; |
---|
483 | } |
---|
484 | |
---|
485 | if (pCD->clientEntry.nextSibling) |
---|
486 | { |
---|
487 | pCD->clientEntry.nextSibling->prevSibling = |
---|
488 | pCD->clientEntry.prevSibling; |
---|
489 | } |
---|
490 | else |
---|
491 | { |
---|
492 | pSD->lastClient = pCD->clientEntry.prevSibling; |
---|
493 | } |
---|
494 | } |
---|
495 | |
---|
496 | } /* END OF FUNCTION DeleteClientFromList */ |
---|
497 | |
---|
498 | |
---|
499 | |
---|
500 | /*************************************<->************************************* |
---|
501 | * |
---|
502 | * AddTransient (pWS, pCD) |
---|
503 | * |
---|
504 | * |
---|
505 | * Description: |
---|
506 | * ----------- |
---|
507 | * This function adds the transient window to the lead window's list of |
---|
508 | * transients. |
---|
509 | * |
---|
510 | * |
---|
511 | * Inputs: |
---|
512 | * ------ |
---|
513 | * pWS = pointer to workspace data |
---|
514 | * pCD = pointer to client data of a transient window |
---|
515 | * |
---|
516 | * |
---|
517 | * Outputs: |
---|
518 | * ------- |
---|
519 | * pCD->transientLeader = (transientChildren, modalCount) |
---|
520 | * |
---|
521 | *************************************<->***********************************/ |
---|
522 | |
---|
523 | #ifdef _NO_PROTO |
---|
524 | void AddTransient (pWS, pCD) |
---|
525 | WmWorkspaceData *pWS; |
---|
526 | ClientData *pCD; |
---|
527 | |
---|
528 | #else /* _NO_PROTO */ |
---|
529 | void AddTransient (WmWorkspaceData *pWS, ClientData *pCD) |
---|
530 | #endif /* _NO_PROTO */ |
---|
531 | { |
---|
532 | ClientData *pcdLeader = pCD->transientLeader; |
---|
533 | ClientData *pcdTop = FindTransientTreeLeader (pCD); |
---|
534 | Boolean restackTransients; |
---|
535 | WmScreenData *pSD = pWS->pSD; |
---|
536 | |
---|
537 | |
---|
538 | pCD->transientSiblings = pcdLeader->transientChildren; |
---|
539 | pcdLeader->transientChildren = pCD; |
---|
540 | |
---|
541 | |
---|
542 | /* |
---|
543 | * Insure that the new transient window is on top of its siblings |
---|
544 | * and that the transient window tree is on top of the window |
---|
545 | * stack (this is the standard behavior for newly mapped and |
---|
546 | * managed windows). If there is a system modal window that the |
---|
547 | * transient window is not associated with then don't raise the |
---|
548 | * transient tree. |
---|
549 | */ |
---|
550 | |
---|
551 | restackTransients = PutTransientOnTop (pcdLeader); |
---|
552 | |
---|
553 | |
---|
554 | /* |
---|
555 | * Handle application modal transient windows |
---|
556 | */ |
---|
557 | |
---|
558 | if (pCD->inputMode == MWM_INPUT_PRIMARY_APPLICATION_MODAL) |
---|
559 | { |
---|
560 | /* |
---|
561 | * If this is a primary application modal window then increment |
---|
562 | * the modal count for transient leaders that are directly up |
---|
563 | * the transient tree. |
---|
564 | * |
---|
565 | * (This is the old MWM_INPUT_APPLICATION_MODAL behavior.) |
---|
566 | */ |
---|
567 | while (pcdLeader) |
---|
568 | { |
---|
569 | MarkModalTransient (pcdLeader, pCD); |
---|
570 | pcdLeader = pcdLeader->transientLeader; |
---|
571 | } |
---|
572 | } |
---|
573 | else if (pCD->inputMode == MWM_INPUT_FULL_APPLICATION_MODAL) |
---|
574 | { |
---|
575 | /* |
---|
576 | * If this is a full application modal window then increment |
---|
577 | * the modal count for the rest of the transient tree. |
---|
578 | */ |
---|
579 | |
---|
580 | MarkModalSubtree (pcdTop, pCD); |
---|
581 | } |
---|
582 | else if (pcdTop->fullModalCount) |
---|
583 | { |
---|
584 | /* |
---|
585 | * There is already a full application modal window in the tree |
---|
586 | */ |
---|
587 | pcdLeader = pCD->transientLeader; |
---|
588 | if ((pcdLeader->inputMode != MWM_INPUT_FULL_APPLICATION_MODAL) || |
---|
589 | (IS_APP_MODALIZED(pcdLeader))) |
---|
590 | { |
---|
591 | /* |
---|
592 | * The immediate parent of this transient is not the |
---|
593 | * current full application modal window. Set the full |
---|
594 | * modal count to the parent's so that they both become |
---|
595 | * unmodalized at the same time. This allows a full |
---|
596 | * app modal window to have active, non-modal transients. |
---|
597 | */ |
---|
598 | pCD->fullModalCount = pcdLeader->fullModalCount; |
---|
599 | } |
---|
600 | } |
---|
601 | |
---|
602 | |
---|
603 | /* |
---|
604 | * Do the actual restacking in the X window stack if necessary. |
---|
605 | */ |
---|
606 | |
---|
607 | if ((pSD->clientList != &pcdTop->clientEntry) && !wmGD.systemModalActive) |
---|
608 | { |
---|
609 | F_Raise (NULL, pCD, NULL); |
---|
610 | } |
---|
611 | else if (restackTransients) |
---|
612 | { |
---|
613 | RestackTransientsAtWindow (pCD); |
---|
614 | } |
---|
615 | else if (pCD != FindTransientOnTop (pcdTop)) |
---|
616 | { |
---|
617 | StackTransientWindow (pCD); |
---|
618 | } |
---|
619 | |
---|
620 | |
---|
621 | } /* END OF FUNCTION AddTransient */ |
---|
622 | |
---|
623 | |
---|
624 | |
---|
625 | /*************************************<->************************************* |
---|
626 | * |
---|
627 | * MarkModalSubtree (pcdTree, pcdAvoid) |
---|
628 | * |
---|
629 | * |
---|
630 | * Description: |
---|
631 | * ----------- |
---|
632 | * This function marks the transient tree with pcdTree as its leader. |
---|
633 | * If pcdAvoid is in the tree, it is not marked. |
---|
634 | * |
---|
635 | * Inputs: |
---|
636 | * ------ |
---|
637 | * pcdTree = pointer to client data of the tree to mark |
---|
638 | * pcdAvoid = pointer to client data to not mark if in tree |
---|
639 | * |
---|
640 | * |
---|
641 | *************************************<->***********************************/ |
---|
642 | |
---|
643 | #ifdef _NO_PROTO |
---|
644 | void MarkModalSubtree (pcdTree, pcdAvoid) |
---|
645 | ClientData *pcdTree, *pcdAvoid; |
---|
646 | |
---|
647 | #else /* _NO_PROTO */ |
---|
648 | void MarkModalSubtree (ClientData *pcdTree, ClientData *pcdAvoid) |
---|
649 | #endif /* _NO_PROTO */ |
---|
650 | { |
---|
651 | /* Mark children, if any */ |
---|
652 | |
---|
653 | if (pcdTree->transientChildren) |
---|
654 | MarkModalSubtree (pcdTree->transientChildren, pcdAvoid); |
---|
655 | |
---|
656 | /* Mark this node */ |
---|
657 | |
---|
658 | if (pcdTree != pcdAvoid) |
---|
659 | { |
---|
660 | MarkModalTransient (pcdTree, pcdAvoid); |
---|
661 | } |
---|
662 | |
---|
663 | /* Mark siblings */ |
---|
664 | |
---|
665 | if (pcdTree->transientSiblings) |
---|
666 | MarkModalSubtree (pcdTree->transientSiblings, pcdAvoid); |
---|
667 | |
---|
668 | } |
---|
669 | |
---|
670 | |
---|
671 | /*************************************<->************************************* |
---|
672 | * |
---|
673 | * MarkModalTransient (pcdLeader, pCD) |
---|
674 | * |
---|
675 | * |
---|
676 | * Description: |
---|
677 | * ----------- |
---|
678 | * This function marks a transient window for application modal processing. |
---|
679 | * Grabs are done to eat up pointer button events. |
---|
680 | * |
---|
681 | * Inputs: |
---|
682 | * ------ |
---|
683 | * pcdLeader = pointer to client data to mark |
---|
684 | * pCD = pointer to client data of new transient |
---|
685 | * |
---|
686 | * |
---|
687 | *************************************<->***********************************/ |
---|
688 | |
---|
689 | #ifdef _NO_PROTO |
---|
690 | void MarkModalTransient (pcdLeader, pCD) |
---|
691 | ClientData *pcdLeader, *pCD; |
---|
692 | |
---|
693 | #else /* _NO_PROTO */ |
---|
694 | void MarkModalTransient (ClientData *pcdLeader, ClientData *pCD) |
---|
695 | #endif /* _NO_PROTO */ |
---|
696 | { |
---|
697 | if (!IS_APP_MODALIZED(pcdLeader)) |
---|
698 | { |
---|
699 | /* |
---|
700 | * Eat pointer button events while application modal. |
---|
701 | */ |
---|
702 | XGrabButton (DISPLAY, AnyButton, AnyModifier, |
---|
703 | pcdLeader->clientBaseWin, True, |
---|
704 | ButtonPressMask | ButtonMotionMask, GrabModeAsync, |
---|
705 | GrabModeAsync, None, wmGD.workspaceCursor); |
---|
706 | } |
---|
707 | |
---|
708 | /* bump application modal count */ |
---|
709 | if (pCD->inputMode == MWM_INPUT_FULL_APPLICATION_MODAL) |
---|
710 | pcdLeader->fullModalCount++; |
---|
711 | else |
---|
712 | pcdLeader->primaryModalCount++; |
---|
713 | } |
---|
714 | |
---|
715 | |
---|
716 | /*************************************<->************************************* |
---|
717 | * |
---|
718 | * DeleteTransient (pCD) |
---|
719 | * |
---|
720 | * |
---|
721 | * Description: |
---|
722 | * ----------- |
---|
723 | * This function deletes the transient window from the lead window's list |
---|
724 | * of transients |
---|
725 | * |
---|
726 | * Much of the complication of this code arises from trying to handle |
---|
727 | * mixtures of both full- and primary-application modal transients. |
---|
728 | * It also tries to handle the case where a sequence of application |
---|
729 | * modal transients appear in different places in the transient tree |
---|
730 | * (i.e. not as descendents of a previously existing full app modal |
---|
731 | * transient). |
---|
732 | * |
---|
733 | * Inputs: |
---|
734 | * ------ |
---|
735 | * pCD = pointer to client data of transient. |
---|
736 | * |
---|
737 | *************************************<->***********************************/ |
---|
738 | |
---|
739 | #ifdef _NO_PROTO |
---|
740 | void DeleteTransient (pCD) |
---|
741 | ClientData *pCD; |
---|
742 | |
---|
743 | #else /* _NO_PROTO */ |
---|
744 | void DeleteTransient (ClientData *pCD) |
---|
745 | #endif /* _NO_PROTO */ |
---|
746 | { |
---|
747 | ClientData *pcdLeader; |
---|
748 | ClientData *pcdPrev; |
---|
749 | int modalCount; |
---|
750 | |
---|
751 | |
---|
752 | /* |
---|
753 | * Handle primary application modality. |
---|
754 | * Reset the modal window counts for the leader windows up through the |
---|
755 | * transient window tree. |
---|
756 | */ |
---|
757 | |
---|
758 | modalCount = pCD->primaryModalCount; |
---|
759 | if (pCD->inputMode == MWM_INPUT_PRIMARY_APPLICATION_MODAL) |
---|
760 | { |
---|
761 | modalCount += 1; |
---|
762 | } |
---|
763 | if (modalCount) |
---|
764 | { |
---|
765 | pcdLeader = pCD->transientLeader; |
---|
766 | while (pcdLeader) |
---|
767 | { |
---|
768 | if (modalCount) |
---|
769 | UnMarkModalTransient (pcdLeader, modalCount, pCD); |
---|
770 | |
---|
771 | pcdLeader = pcdLeader->transientLeader; |
---|
772 | } |
---|
773 | } |
---|
774 | |
---|
775 | /* |
---|
776 | * Handle full application modality. |
---|
777 | * Undo application modal windows in a depth first manner. |
---|
778 | */ |
---|
779 | |
---|
780 | pcdLeader = FindTransientTreeLeader (pCD); |
---|
781 | |
---|
782 | if (pCD->transientChildren) |
---|
783 | { |
---|
784 | DeleteFullAppModalChildren (pcdLeader, pCD->transientChildren); |
---|
785 | } |
---|
786 | if (pCD->inputMode == MWM_INPUT_FULL_APPLICATION_MODAL) |
---|
787 | |
---|
788 | { |
---|
789 | /* |
---|
790 | * If this is a full application modal window then decrement |
---|
791 | * the modal count for the rest of the transient tree. |
---|
792 | */ |
---|
793 | |
---|
794 | FixupFullAppModalCounts (pcdLeader, pCD); |
---|
795 | } |
---|
796 | |
---|
797 | |
---|
798 | /* |
---|
799 | * Delete this transient from its parent's list of transient windows. |
---|
800 | */ |
---|
801 | |
---|
802 | pcdPrev = pCD->transientLeader->transientChildren; |
---|
803 | if(pcdPrev) |
---|
804 | { |
---|
805 | if (pcdPrev == pCD) |
---|
806 | { |
---|
807 | pCD->transientLeader->transientChildren = pCD->transientSiblings; |
---|
808 | } |
---|
809 | else |
---|
810 | { |
---|
811 | while (pcdPrev && (pcdPrev->transientSiblings != pCD)) |
---|
812 | { |
---|
813 | pcdPrev = pcdPrev->transientSiblings; |
---|
814 | } |
---|
815 | if (pcdPrev) |
---|
816 | pcdPrev->transientSiblings = pCD->transientSiblings; |
---|
817 | } |
---|
818 | } |
---|
819 | |
---|
820 | } /* END OF FUNCTION DeleteTransient */ |
---|
821 | |
---|
822 | |
---|
823 | /*************************************<->************************************* |
---|
824 | * |
---|
825 | * DeleteFullAppModalChildren (pcdLeader, pCD) |
---|
826 | * |
---|
827 | * |
---|
828 | * Description: |
---|
829 | * ----------- |
---|
830 | * This function handles the clean-up of nested full application modal |
---|
831 | * windows. The deletion has to be handled carefully to keep a correct |
---|
832 | * fullModalCount on the transients that remain in the tree. |
---|
833 | * |
---|
834 | * The algorithm is to traverse the transient children depth first and |
---|
835 | * fix up the tree's fullModalCount for each full application modal |
---|
836 | * window that's found. |
---|
837 | * |
---|
838 | * Inputs: |
---|
839 | * ------ |
---|
840 | * pcdLeader = pointer to client data of transient tree root. |
---|
841 | * pCD = pointer to client data of transient subtree to delete. |
---|
842 | * |
---|
843 | *************************************<->***********************************/ |
---|
844 | |
---|
845 | #ifdef _NO_PROTO |
---|
846 | void DeleteFullAppModalChildren (pcdLeader, pCD) |
---|
847 | ClientData *pcdLeader, *pCD; |
---|
848 | |
---|
849 | #else /* _NO_PROTO */ |
---|
850 | void DeleteFullAppModalChildren (ClientData *pcdLeader, ClientData *pCD) |
---|
851 | #endif /* _NO_PROTO */ |
---|
852 | { |
---|
853 | |
---|
854 | /* recursively do children first */ |
---|
855 | if (pCD->transientChildren) |
---|
856 | DeleteFullAppModalChildren (pcdLeader, pCD->transientChildren); |
---|
857 | |
---|
858 | /* do fullAppModal fixup for this guy */ |
---|
859 | FixupFullAppModalCounts (pcdLeader, pCD); |
---|
860 | |
---|
861 | /* do siblings of passed transient */ |
---|
862 | if (pCD->transientSiblings) |
---|
863 | DeleteFullAppModalChildren (pcdLeader, pCD->transientSiblings); |
---|
864 | |
---|
865 | |
---|
866 | } /* END OF FUNCTION DeleteFullAppModalChildren */ |
---|
867 | |
---|
868 | |
---|
869 | /*************************************<->************************************* |
---|
870 | * |
---|
871 | * FixupFullAppModalCounts (pcdLeader, pcdDelete) |
---|
872 | * |
---|
873 | * |
---|
874 | * Description: |
---|
875 | * ----------- |
---|
876 | * This function traverses the entire transient tree (pointed to by |
---|
877 | * pcdLeader) and fixes up the fullModalCounts to reflect the removal |
---|
878 | * of pcdDelete. |
---|
879 | * |
---|
880 | * The fix-up consists of decrementing the count |
---|
881 | * of the remaining full app modal windows in the tree iff the remaining |
---|
882 | * window's fullModalCount is greater than the fullModalCount of the |
---|
883 | * transient being deleted. |
---|
884 | * |
---|
885 | * Inputs: |
---|
886 | * ------ |
---|
887 | * pcdLeader = pointer to client data for head of transient tree. |
---|
888 | * pcdDelet = pointer to client data of transient being deleted. |
---|
889 | * |
---|
890 | *************************************<->***********************************/ |
---|
891 | |
---|
892 | void |
---|
893 | #ifdef _NO_PROTO |
---|
894 | FixupFullAppModalCounts (pcdLeader, pcdDelete) |
---|
895 | ClientData *pcdLeader, *pcdDelete; |
---|
896 | #else /* _NO_PROTO */ |
---|
897 | FixupFullAppModalCounts (ClientData *pcdLeader, ClientData *pcdDelete) |
---|
898 | #endif /* _NO_PROTO */ |
---|
899 | |
---|
900 | { |
---|
901 | |
---|
902 | /* fixup children */ |
---|
903 | if (pcdLeader->transientChildren) |
---|
904 | { |
---|
905 | FixupFullAppModalCounts (pcdLeader->transientChildren, pcdDelete); |
---|
906 | } |
---|
907 | |
---|
908 | /* |
---|
909 | * fixup leader: decrement the count if it is greater than |
---|
910 | * the transient being deleted. |
---|
911 | * |
---|
912 | */ |
---|
913 | if (pcdLeader->fullModalCount > pcdDelete->fullModalCount) |
---|
914 | { |
---|
915 | UnMarkModalTransient (pcdLeader, 1, pcdDelete); |
---|
916 | } |
---|
917 | |
---|
918 | /* fixup siblings */ |
---|
919 | if (pcdLeader->transientSiblings) |
---|
920 | { |
---|
921 | FixupFullAppModalCounts (pcdLeader->transientSiblings, pcdDelete); |
---|
922 | } |
---|
923 | |
---|
924 | } /* END OF FUNCTION FixupFullAppModalCounts */ |
---|
925 | |
---|
926 | |
---|
927 | |
---|
928 | /*************************************<->************************************* |
---|
929 | * |
---|
930 | * UnMarkModalTransient (pcdModee, modalCount, pcdModal) |
---|
931 | * |
---|
932 | * |
---|
933 | * Description: |
---|
934 | * ----------- |
---|
935 | * This function unmarks a transient window for application modal processing. |
---|
936 | * Original grabs are restored. |
---|
937 | * |
---|
938 | * Inputs: |
---|
939 | * ------ |
---|
940 | * pcdModee = pointer to client data for transient to unmark |
---|
941 | * pcdModal = pointer to client data for modal transient |
---|
942 | * modalCount = amount to decrement the client's modal count by |
---|
943 | * |
---|
944 | * |
---|
945 | *************************************<->***********************************/ |
---|
946 | |
---|
947 | #ifdef _NO_PROTO |
---|
948 | void UnMarkModalTransient (pcdModee, modalCount, pcdModal) |
---|
949 | ClientData *pcdModee, *pcdModal; |
---|
950 | int modalCount; |
---|
951 | |
---|
952 | #else /* _NO_PROTO */ |
---|
953 | void UnMarkModalTransient (ClientData *pcdModee, int modalCount, ClientData *pcdModal) |
---|
954 | #endif /* _NO_PROTO */ |
---|
955 | { |
---|
956 | /* decrement application modal count */ |
---|
957 | if (pcdModal->inputMode == MWM_INPUT_FULL_APPLICATION_MODAL) |
---|
958 | pcdModee->fullModalCount -= modalCount; |
---|
959 | else if (pcdModal->inputMode == MWM_INPUT_PRIMARY_APPLICATION_MODAL) |
---|
960 | pcdModee->primaryModalCount -= modalCount; |
---|
961 | |
---|
962 | /* |
---|
963 | * Restore original button bindings/grabs if not modal anymore |
---|
964 | */ |
---|
965 | if (!IS_APP_MODALIZED(pcdModee)) |
---|
966 | { |
---|
967 | XUngrabButton (DISPLAY, AnyButton, AnyModifier, |
---|
968 | pcdModee->clientBaseWin); |
---|
969 | |
---|
970 | SetupCButtonBindings (pcdModee->clientBaseWin, BUTTON_SPECS(pcdModee)); |
---|
971 | |
---|
972 | if ((wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT) && |
---|
973 | (wmGD.keyboardFocus != pcdModee)) |
---|
974 | { |
---|
975 | DoExplicitSelectGrab (pcdModee->clientBaseWin); |
---|
976 | } |
---|
977 | } |
---|
978 | } |
---|
979 | |
---|
980 | |
---|
981 | /*************************************<->************************************* |
---|
982 | * |
---|
983 | * PutTransientOnTop (pcd) |
---|
984 | * |
---|
985 | * |
---|
986 | * Description: |
---|
987 | * ----------- |
---|
988 | * This function changes the transient window list to insure that the |
---|
989 | * specified transient window is on top of its siblings and its parent |
---|
990 | * is on top of its siblings, etc. The sibling list is ordered such |
---|
991 | * that the first window in the list is on top of second window in the |
---|
992 | * list, etc. |
---|
993 | * |
---|
994 | * |
---|
995 | * Inputs: |
---|
996 | * ------ |
---|
997 | * pcd = pointer to client data of a transient window |
---|
998 | * |
---|
999 | * |
---|
1000 | * Outputs: |
---|
1001 | * ------- |
---|
1002 | * pcdLeader = (transientSiblings) |
---|
1003 | * |
---|
1004 | * RETURN = True if the transient tree needs to be restacked |
---|
1005 | * |
---|
1006 | *************************************<->***********************************/ |
---|
1007 | |
---|
1008 | #ifdef _NO_PROTO |
---|
1009 | Boolean PutTransientOnTop (pcd) |
---|
1010 | ClientData *pcd; |
---|
1011 | |
---|
1012 | #else /* _NO_PROTO */ |
---|
1013 | Boolean PutTransientOnTop (ClientData *pcd) |
---|
1014 | #endif /* _NO_PROTO */ |
---|
1015 | { |
---|
1016 | ClientData *pcdLeader; |
---|
1017 | ClientData *pcdPrev; |
---|
1018 | Boolean restack = False; |
---|
1019 | |
---|
1020 | |
---|
1021 | pcdLeader = pcd->transientLeader; |
---|
1022 | if (pcdLeader != NULL) |
---|
1023 | { |
---|
1024 | pcdPrev = pcdLeader->transientChildren; |
---|
1025 | if (pcdPrev != pcd) |
---|
1026 | { |
---|
1027 | while (pcdPrev->transientSiblings != pcd) |
---|
1028 | { |
---|
1029 | pcdPrev = pcdPrev->transientSiblings; |
---|
1030 | } |
---|
1031 | pcdPrev->transientSiblings = pcd->transientSiblings; |
---|
1032 | pcd->transientSiblings = pcdLeader->transientChildren; |
---|
1033 | pcdLeader->transientChildren = pcd; |
---|
1034 | restack = True; |
---|
1035 | } |
---|
1036 | |
---|
1037 | if (PutTransientOnTop (pcdLeader)) |
---|
1038 | { |
---|
1039 | restack = True; |
---|
1040 | } |
---|
1041 | } |
---|
1042 | |
---|
1043 | return (restack); |
---|
1044 | |
---|
1045 | } /* END OF FUNCTION PutTransientOnTop */ |
---|
1046 | |
---|
1047 | |
---|
1048 | |
---|
1049 | /*************************************<->************************************* |
---|
1050 | * |
---|
1051 | * PutTransientBelowSiblings (pcd) |
---|
1052 | * |
---|
1053 | * |
---|
1054 | * Description: |
---|
1055 | * ----------- |
---|
1056 | * This function changes the transient window list to insure that the |
---|
1057 | * specified transient window is below its sibling windows. |
---|
1058 | * |
---|
1059 | * |
---|
1060 | * Inputs: |
---|
1061 | * ------ |
---|
1062 | * pcd = pointer to client data of a transient window |
---|
1063 | * |
---|
1064 | * |
---|
1065 | * Outputs: |
---|
1066 | * ------- |
---|
1067 | * pcdLeader = (transientSiblings) |
---|
1068 | * |
---|
1069 | * RETURN = True if restacking has been done in the transient window tree. |
---|
1070 | * |
---|
1071 | *************************************<->***********************************/ |
---|
1072 | |
---|
1073 | #ifdef _NO_PROTO |
---|
1074 | Boolean PutTransientBelowSiblings (pcd) |
---|
1075 | ClientData *pcd; |
---|
1076 | |
---|
1077 | #else /* _NO_PROTO */ |
---|
1078 | Boolean PutTransientBelowSiblings (ClientData *pcd) |
---|
1079 | #endif /* _NO_PROTO */ |
---|
1080 | { |
---|
1081 | ClientData *pcdLeader; |
---|
1082 | ClientData *pcdNext; |
---|
1083 | Boolean restack = False; |
---|
1084 | |
---|
1085 | |
---|
1086 | pcdLeader = pcd->transientLeader; |
---|
1087 | if (pcdLeader) |
---|
1088 | { |
---|
1089 | if (pcd->transientSiblings || (pcdLeader->transientChildren != pcd)) |
---|
1090 | { |
---|
1091 | restack = True; |
---|
1092 | if (pcdLeader->transientChildren == pcd) |
---|
1093 | { |
---|
1094 | pcdLeader->transientChildren = pcd->transientSiblings; |
---|
1095 | } |
---|
1096 | |
---|
1097 | pcdNext = pcdLeader->transientChildren; |
---|
1098 | while (pcdNext->transientSiblings) |
---|
1099 | { |
---|
1100 | if (pcdNext->transientSiblings == pcd) |
---|
1101 | { |
---|
1102 | pcdNext->transientSiblings = pcd->transientSiblings; |
---|
1103 | } |
---|
1104 | else |
---|
1105 | { |
---|
1106 | pcdNext = pcdNext->transientSiblings; |
---|
1107 | } |
---|
1108 | } |
---|
1109 | pcdNext->transientSiblings = pcd; |
---|
1110 | } |
---|
1111 | pcd->transientSiblings = NULL; |
---|
1112 | } |
---|
1113 | |
---|
1114 | return (restack); |
---|
1115 | |
---|
1116 | } /* END OF FUNCTION PutTransientBelowSiblings */ |
---|
1117 | |
---|
1118 | |
---|
1119 | |
---|
1120 | /*************************************<->************************************* |
---|
1121 | * |
---|
1122 | * RestackTransients (pcd, doTop) |
---|
1123 | * |
---|
1124 | * |
---|
1125 | * Description: |
---|
1126 | * ----------- |
---|
1127 | * This function restacks windows in a transient window tree. Secondary |
---|
1128 | * (transient) windows are stacked on top of their associated primary |
---|
1129 | * windows and the first secondary window in the transientSiblings list |
---|
1130 | * is stacked on top of the second window in the list, etc. |
---|
1131 | * |
---|
1132 | * |
---|
1133 | * Inputs: |
---|
1134 | * ------ |
---|
1135 | * pcd = pointer to client data of a window in a transient tree |
---|
1136 | * |
---|
1137 | * doTop = True, put transient on top before stacking |
---|
1138 | * |
---|
1139 | *************************************<->***********************************/ |
---|
1140 | |
---|
1141 | #ifdef _NO_PROTO |
---|
1142 | void RestackTransients (pcd, doTop) |
---|
1143 | ClientData *pcd; |
---|
1144 | Boolean doTop; |
---|
1145 | |
---|
1146 | #else /* _NO_PROTO */ |
---|
1147 | void RestackTransients (ClientData *pcd, Boolean doTop) |
---|
1148 | #endif /* _NO_PROTO */ |
---|
1149 | { |
---|
1150 | ClientData *pcdLeader; |
---|
1151 | int count; |
---|
1152 | static int size = 0; |
---|
1153 | static Window *windows = NULL; |
---|
1154 | Window *nextWindow; |
---|
1155 | |
---|
1156 | |
---|
1157 | /* |
---|
1158 | * Build a restacking list and do the restacking. |
---|
1159 | */ |
---|
1160 | |
---|
1161 | pcdLeader = FindTransientTreeLeader (pcd); |
---|
1162 | count = CountTransientChildren (pcdLeader); |
---|
1163 | |
---|
1164 | if (count > size) |
---|
1165 | { |
---|
1166 | /* |
---|
1167 | * Expand the (static) windows buffer that is used in restacking. |
---|
1168 | */ |
---|
1169 | |
---|
1170 | if (!(windows = |
---|
1171 | (Window *)WmMalloc ((char*)windows, (count + 5) * sizeof (Window)))) |
---|
1172 | { |
---|
1173 | /* cannot get memory space */ |
---|
1174 | size = 0; |
---|
1175 | return; |
---|
1176 | } |
---|
1177 | size = count + 5; |
---|
1178 | } |
---|
1179 | |
---|
1180 | nextWindow = MakeTransientWindowList (windows, pcdLeader); |
---|
1181 | *nextWindow = pcdLeader->clientFrameWin; |
---|
1182 | |
---|
1183 | if (doTop && (count > 1)) |
---|
1184 | { |
---|
1185 | XWindowChanges windowChanges; |
---|
1186 | |
---|
1187 | /* |
---|
1188 | * Force the transient we want on top to the top first |
---|
1189 | * before calling XRestackWindows to avoid spurious |
---|
1190 | * exposures and unnecessary repainting. |
---|
1191 | */ |
---|
1192 | |
---|
1193 | windowChanges.sibling = windows[1]; |
---|
1194 | windowChanges.stack_mode = Above; |
---|
1195 | XConfigureWindow (DISPLAY, windows[0], |
---|
1196 | CWSibling | CWStackMode, &windowChanges); |
---|
1197 | } |
---|
1198 | |
---|
1199 | XRestackWindows (DISPLAY, windows, count); |
---|
1200 | |
---|
1201 | |
---|
1202 | } /* END OF FUNCTION RestackTransients */ |
---|
1203 | |
---|
1204 | |
---|
1205 | |
---|
1206 | /*************************************<->************************************* |
---|
1207 | * |
---|
1208 | * RestackTransientsAtWindow (pcd) |
---|
1209 | * |
---|
1210 | * |
---|
1211 | * Description: |
---|
1212 | * ----------- |
---|
1213 | * This function restacks windows in a transient window tree. The |
---|
1214 | * "anchor point" in the stack for the transient window tree is the |
---|
1215 | * specified window. |
---|
1216 | * |
---|
1217 | * |
---|
1218 | * Inputs: |
---|
1219 | * ------ |
---|
1220 | * pcd = pointer to client data of a window in a transient tree |
---|
1221 | * |
---|
1222 | *************************************<->***********************************/ |
---|
1223 | |
---|
1224 | #ifdef _NO_PROTO |
---|
1225 | void RestackTransientsAtWindow (pcd) |
---|
1226 | ClientData *pcd; |
---|
1227 | |
---|
1228 | #else /* _NO_PROTO */ |
---|
1229 | void RestackTransientsAtWindow (ClientData *pcd) |
---|
1230 | #endif /* _NO_PROTO */ |
---|
1231 | { |
---|
1232 | ClientData *pcdTop; |
---|
1233 | XWindowChanges windowChanges; |
---|
1234 | |
---|
1235 | |
---|
1236 | if ((pcdTop = FindTransientOnTop (pcd)) != pcd) |
---|
1237 | { |
---|
1238 | windowChanges.sibling = pcd->clientFrameWin; |
---|
1239 | windowChanges.stack_mode = Above; |
---|
1240 | XConfigureWindow (DISPLAY, pcdTop->clientFrameWin, |
---|
1241 | CWSibling | CWStackMode, &windowChanges); |
---|
1242 | } |
---|
1243 | |
---|
1244 | RestackTransients (pcd, False); |
---|
1245 | |
---|
1246 | } /* END OF FUNCTION RestackTransientsAtWindow */ |
---|
1247 | |
---|
1248 | |
---|
1249 | |
---|
1250 | /*************************************<->************************************* |
---|
1251 | * |
---|
1252 | * FindTransientTreeLeader (pcd) |
---|
1253 | * |
---|
1254 | * |
---|
1255 | * Description: |
---|
1256 | * ----------- |
---|
1257 | * This function identifies the leader of the transient tree that |
---|
1258 | * contains the specified client. |
---|
1259 | * |
---|
1260 | * |
---|
1261 | * Inputs: |
---|
1262 | * ------ |
---|
1263 | * pcd = pointer to client data of a window in a transient tree. |
---|
1264 | * |
---|
1265 | * Outputs: |
---|
1266 | * ------- |
---|
1267 | * RETURN = pointer to the client data for the transient tree leader. |
---|
1268 | * |
---|
1269 | *************************************<->***********************************/ |
---|
1270 | |
---|
1271 | #ifdef _NO_PROTO |
---|
1272 | ClientData * FindTransientTreeLeader (pcd) |
---|
1273 | ClientData *pcd; |
---|
1274 | #else /* _NO_PROTO */ |
---|
1275 | ClientData * FindTransientTreeLeader (ClientData *pcd) |
---|
1276 | #endif /* _NO_PROTO */ |
---|
1277 | |
---|
1278 | { |
---|
1279 | |
---|
1280 | /* |
---|
1281 | * Find the head of the transient window tree. |
---|
1282 | */ |
---|
1283 | |
---|
1284 | while (pcd->transientLeader) |
---|
1285 | { |
---|
1286 | pcd = pcd->transientLeader; |
---|
1287 | } |
---|
1288 | |
---|
1289 | return (pcd); |
---|
1290 | |
---|
1291 | } /* END OF FUNCTION FindTransientTreeLeader */ |
---|
1292 | |
---|
1293 | |
---|
1294 | |
---|
1295 | /*************************************<->************************************* |
---|
1296 | * |
---|
1297 | * CountTransientChildren (pcd) |
---|
1298 | * |
---|
1299 | * |
---|
1300 | * Description: |
---|
1301 | * ----------- |
---|
1302 | * This function returns a count of the number of children in the |
---|
1303 | * transient window tree headed by the specified client window. |
---|
1304 | * |
---|
1305 | * |
---|
1306 | * Inputs: |
---|
1307 | * ------ |
---|
1308 | * pcd = pointer to client data of a window in a transient tree |
---|
1309 | * |
---|
1310 | * Outputs: |
---|
1311 | * ------- |
---|
1312 | * RETURN = count of transient windows in the transient window tree |
---|
1313 | * |
---|
1314 | *************************************<->***********************************/ |
---|
1315 | |
---|
1316 | #ifdef _NO_PROTO |
---|
1317 | int |
---|
1318 | CountTransientChildren (pcd) |
---|
1319 | ClientData *pcd; |
---|
1320 | #else /* _NO_PROTO */ |
---|
1321 | int |
---|
1322 | CountTransientChildren (ClientData *pcd) |
---|
1323 | #endif /* _NO_PROTO */ |
---|
1324 | |
---|
1325 | { |
---|
1326 | ClientData *pcdNext; |
---|
1327 | int count = 1; |
---|
1328 | |
---|
1329 | |
---|
1330 | pcdNext = pcd->transientChildren; |
---|
1331 | while (pcdNext) |
---|
1332 | { |
---|
1333 | if (pcdNext->transientChildren) |
---|
1334 | { |
---|
1335 | count += CountTransientChildren (pcdNext); |
---|
1336 | } |
---|
1337 | else |
---|
1338 | { |
---|
1339 | count++; |
---|
1340 | } |
---|
1341 | pcdNext = pcdNext->transientSiblings; |
---|
1342 | } |
---|
1343 | |
---|
1344 | return (count); |
---|
1345 | |
---|
1346 | } /* END OF FUNCTION CountTransientChildren */ |
---|
1347 | |
---|
1348 | |
---|
1349 | |
---|
1350 | /*************************************<->************************************* |
---|
1351 | * |
---|
1352 | * MakeTransientWindowList (windows, pcd) |
---|
1353 | * |
---|
1354 | * |
---|
1355 | * Description: |
---|
1356 | * ----------- |
---|
1357 | * This function makes a transient window list of windows in the |
---|
1358 | * transient window tree headed by the specified client. This list is |
---|
1359 | * to be passed to XRestackWindows. |
---|
1360 | * |
---|
1361 | * |
---|
1362 | * Inputs: |
---|
1363 | * ------ |
---|
1364 | * windows = pointer to the windows list to be filled out |
---|
1365 | * |
---|
1366 | * pcd = pointer to client data of a window in a transient tree |
---|
1367 | * |
---|
1368 | * Outputs: |
---|
1369 | * ------- |
---|
1370 | * RETURN = pointer to the next entry in the windows list |
---|
1371 | * |
---|
1372 | *************************************<->***********************************/ |
---|
1373 | |
---|
1374 | #ifdef _NO_PROTO |
---|
1375 | Window * MakeTransientWindowList (windows, pcd) |
---|
1376 | Window *windows; |
---|
1377 | ClientData *pcd; |
---|
1378 | #else /* _NO_PROTO */ |
---|
1379 | Window * MakeTransientWindowList (Window *windows, ClientData *pcd) |
---|
1380 | #endif /* _NO_PROTO */ |
---|
1381 | |
---|
1382 | { |
---|
1383 | ClientData *pcdNext; |
---|
1384 | |
---|
1385 | |
---|
1386 | pcdNext = pcd->transientChildren; |
---|
1387 | while (pcdNext) |
---|
1388 | { |
---|
1389 | if (pcdNext->transientChildren) |
---|
1390 | { |
---|
1391 | windows = MakeTransientWindowList (windows, pcdNext); |
---|
1392 | } |
---|
1393 | *windows = pcdNext->clientFrameWin; |
---|
1394 | windows++; |
---|
1395 | pcdNext = pcdNext->transientSiblings; |
---|
1396 | } |
---|
1397 | |
---|
1398 | return (windows); |
---|
1399 | |
---|
1400 | |
---|
1401 | } /* END OF FUNCTION MakeTransientWindowList */ |
---|
1402 | |
---|
1403 | |
---|
1404 | |
---|
1405 | /*************************************<->************************************* |
---|
1406 | * |
---|
1407 | * FindTransientFocus (pcd) |
---|
1408 | * |
---|
1409 | * |
---|
1410 | * Description: |
---|
1411 | * ----------- |
---|
1412 | * This function identifies a window in the transient tree that is headed |
---|
1413 | * by the specified client that can accept the keyboard input. The |
---|
1414 | * effect of application modal windows is taken into account. |
---|
1415 | * |
---|
1416 | * |
---|
1417 | * Inputs: |
---|
1418 | * ------ |
---|
1419 | * pcd = pointer to client data of a window in a transient tree. |
---|
1420 | * |
---|
1421 | * Outputs: |
---|
1422 | * ------- |
---|
1423 | * RETURN = pointer to the client data for a window that can accept the |
---|
1424 | * keyboard input focus. |
---|
1425 | * |
---|
1426 | *************************************<->***********************************/ |
---|
1427 | |
---|
1428 | #ifdef _NO_PROTO |
---|
1429 | ClientData * FindTransientFocus (pcd) |
---|
1430 | ClientData *pcd; |
---|
1431 | #else /* _NO_PROTO */ |
---|
1432 | ClientData * FindTransientFocus (ClientData *pcd) |
---|
1433 | #endif /* _NO_PROTO */ |
---|
1434 | |
---|
1435 | { |
---|
1436 | |
---|
1437 | ClientData *pcdFocus; |
---|
1438 | |
---|
1439 | /* |
---|
1440 | * Find a window that does not have an application modal subordinate. |
---|
1441 | * First, search descendents |
---|
1442 | */ |
---|
1443 | |
---|
1444 | pcdFocus = pcd; |
---|
1445 | while (pcdFocus->transientChildren && IS_APP_MODALIZED(pcdFocus)) |
---|
1446 | { |
---|
1447 | pcdFocus = pcdFocus->transientChildren; |
---|
1448 | } |
---|
1449 | |
---|
1450 | /* |
---|
1451 | * If (search of descendents FAILS) then search siblings. |
---|
1452 | */ |
---|
1453 | |
---|
1454 | if (IS_APP_MODALIZED(pcdFocus)) |
---|
1455 | { |
---|
1456 | ClientData *pcdSibling; |
---|
1457 | |
---|
1458 | pcdFocus = pcd; |
---|
1459 | while (pcdFocus && IS_APP_MODALIZED(pcdFocus)) |
---|
1460 | { |
---|
1461 | pcdSibling = pcdFocus; |
---|
1462 | while (pcdSibling->transientSiblings && IS_APP_MODALIZED(pcdFocus)) |
---|
1463 | { |
---|
1464 | pcdSibling = pcdSibling->transientSiblings; |
---|
1465 | } |
---|
1466 | if (IS_APP_MODALIZED(pcdSibling)) |
---|
1467 | { |
---|
1468 | pcdFocus = pcdFocus->transientChildren; |
---|
1469 | } |
---|
1470 | else |
---|
1471 | { |
---|
1472 | pcdFocus = pcdSibling; |
---|
1473 | break; |
---|
1474 | } |
---|
1475 | } |
---|
1476 | } |
---|
1477 | |
---|
1478 | return (pcdFocus ? pcdFocus : wmGD.keyboardFocus); |
---|
1479 | |
---|
1480 | } /* END OF FUNCTION FindTransientFocus */ |
---|
1481 | |
---|
1482 | |
---|
1483 | |
---|
1484 | /*************************************<->************************************* |
---|
1485 | * |
---|
1486 | * FindTransientOnTop (pcd) |
---|
1487 | * |
---|
1488 | * |
---|
1489 | * Description: |
---|
1490 | * ----------- |
---|
1491 | * This function identifies the top-most transient window in the |
---|
1492 | * transient window tree that contains the specified client. |
---|
1493 | * |
---|
1494 | * |
---|
1495 | * Inputs: |
---|
1496 | * ------ |
---|
1497 | * pcd = pointer to client data of a window in a transient tree. |
---|
1498 | * |
---|
1499 | * Outputs: |
---|
1500 | * ------- |
---|
1501 | * RETURN = pointer to the client data for the top-most transient window. |
---|
1502 | * |
---|
1503 | *************************************<->***********************************/ |
---|
1504 | |
---|
1505 | #ifdef _NO_PROTO |
---|
1506 | ClientData * FindTransientOnTop (pcd) |
---|
1507 | ClientData *pcd; |
---|
1508 | #else /* _NO_PROTO */ |
---|
1509 | ClientData * FindTransientOnTop (ClientData *pcd) |
---|
1510 | #endif /* _NO_PROTO */ |
---|
1511 | |
---|
1512 | { |
---|
1513 | |
---|
1514 | /* |
---|
1515 | * Find the head of the transient window tree. |
---|
1516 | */ |
---|
1517 | |
---|
1518 | pcd = FindTransientTreeLeader (pcd); |
---|
1519 | |
---|
1520 | |
---|
1521 | /* |
---|
1522 | * Find the top-most transient window (the window in the transient tree |
---|
1523 | * that is highest in the window stack). |
---|
1524 | */ |
---|
1525 | |
---|
1526 | while (pcd->transientChildren) |
---|
1527 | { |
---|
1528 | pcd = pcd->transientChildren; |
---|
1529 | } |
---|
1530 | |
---|
1531 | return (pcd); |
---|
1532 | |
---|
1533 | } /* END OF FUNCTION FindTransientOnTop */ |
---|
1534 | |
---|
1535 | |
---|
1536 | |
---|
1537 | /*************************************<->************************************* |
---|
1538 | * |
---|
1539 | * StackWindow (pWS, pEntry, onTop, pStackEntry) |
---|
1540 | * |
---|
1541 | * |
---|
1542 | * Description: |
---|
1543 | * ----------- |
---|
1544 | * This function stacks a window of a particular type (normal or icon) |
---|
1545 | * to the top or botton of the window stack on the screen. |
---|
1546 | * |
---|
1547 | * |
---|
1548 | * Inputs: |
---|
1549 | * ------ |
---|
1550 | * pWS = pointer to workspace data |
---|
1551 | * |
---|
1552 | * pEntry = pointer to the client list entry for the window to be restacked. |
---|
1553 | * |
---|
1554 | * onTop = if True then the window is to be restacked on top of the |
---|
1555 | * specified stack window (if the stack window is not specified then |
---|
1556 | * the entry is added to the top of the window stack) |
---|
1557 | * otherwise the window is stacked below the specified stack window |
---|
1558 | * (or at the bottom of the window stack if the stack window is not |
---|
1559 | * specified). |
---|
1560 | * |
---|
1561 | * pStackEntry = pointer to a client list entry for a window in the window |
---|
1562 | * stack that is to be used as a reference in restacking. |
---|
1563 | * |
---|
1564 | *************************************<->***********************************/ |
---|
1565 | |
---|
1566 | #ifdef _NO_PROTO |
---|
1567 | void StackWindow (pWS, pEntry, onTop, pStackEntry) |
---|
1568 | WmWorkspaceData *pWS; |
---|
1569 | ClientListEntry *pEntry; |
---|
1570 | Boolean onTop; |
---|
1571 | ClientListEntry *pStackEntry; |
---|
1572 | |
---|
1573 | #else /* _NO_PROTO */ |
---|
1574 | void StackWindow (WmWorkspaceData *pWS, ClientListEntry *pEntry, Boolean onTop, ClientListEntry *pStackEntry) |
---|
1575 | #endif /* _NO_PROTO */ |
---|
1576 | { |
---|
1577 | Window stackWindow; |
---|
1578 | Boolean stackTransientTreeWindows = False; |
---|
1579 | Window activeIconWindow; |
---|
1580 | Window window; |
---|
1581 | XWindowChanges changes; |
---|
1582 | WmScreenData *pSD = pWS->pSD; |
---|
1583 | |
---|
1584 | |
---|
1585 | if (pStackEntry) |
---|
1586 | { |
---|
1587 | if (pStackEntry->type == MINIMIZED_STATE) |
---|
1588 | { |
---|
1589 | stackWindow = ICON_FRAME_WIN(pStackEntry->pCD); |
---|
1590 | } |
---|
1591 | else |
---|
1592 | { |
---|
1593 | stackWindow = pStackEntry->pCD->clientFrameWin; |
---|
1594 | } |
---|
1595 | } |
---|
1596 | else |
---|
1597 | { |
---|
1598 | stackWindow = (Window)0; |
---|
1599 | } |
---|
1600 | |
---|
1601 | if (pEntry->type == MINIMIZED_STATE) |
---|
1602 | { |
---|
1603 | window = ICON_FRAME_WIN(pEntry->pCD); |
---|
1604 | } |
---|
1605 | else |
---|
1606 | { |
---|
1607 | /* |
---|
1608 | * Restack the transient tree if appropriate. |
---|
1609 | */ |
---|
1610 | |
---|
1611 | if (pEntry->pCD->transientLeader || pEntry->pCD->transientChildren) |
---|
1612 | { |
---|
1613 | stackTransientTreeWindows = True; |
---|
1614 | window = (FindTransientOnTop (pEntry->pCD))->clientFrameWin; |
---|
1615 | } |
---|
1616 | else |
---|
1617 | { |
---|
1618 | window = pEntry->pCD->clientFrameWin; |
---|
1619 | } |
---|
1620 | } |
---|
1621 | |
---|
1622 | |
---|
1623 | /* |
---|
1624 | * The active icon text label must be restacked along with the associated |
---|
1625 | * icon. |
---|
1626 | */ |
---|
1627 | |
---|
1628 | if ((pEntry->type == MINIMIZED_STATE) && |
---|
1629 | (pEntry->pCD == wmGD.keyboardFocus) && |
---|
1630 | (ICON_DECORATION(pEntry->pCD) & ICON_ACTIVE_LABEL_PART) && |
---|
1631 | (ACTIVE_ICON_TEXT_WIN)) |
---|
1632 | { |
---|
1633 | activeIconWindow = ACTIVE_ICON_TEXT_WIN; |
---|
1634 | } |
---|
1635 | else |
---|
1636 | { |
---|
1637 | activeIconWindow = (Window)0; |
---|
1638 | } |
---|
1639 | |
---|
1640 | if (onTop) |
---|
1641 | { |
---|
1642 | if ((stackWindow == 0) && (pSD->clientList)) |
---|
1643 | { |
---|
1644 | if (pSD->clientList->type == MINIMIZED_STATE) |
---|
1645 | { |
---|
1646 | stackWindow = ICON_FRAME_WIN(pSD->clientList->pCD); |
---|
1647 | } |
---|
1648 | else |
---|
1649 | { |
---|
1650 | if (pSD->clientList->pCD->transientChildren) |
---|
1651 | { |
---|
1652 | stackWindow = |
---|
1653 | (FindTransientOnTop(pSD->clientList->pCD))->clientFrameWin; |
---|
1654 | } |
---|
1655 | else |
---|
1656 | { |
---|
1657 | stackWindow = pSD->clientList->pCD->clientFrameWin; |
---|
1658 | } |
---|
1659 | } |
---|
1660 | } |
---|
1661 | |
---|
1662 | if (activeIconWindow) |
---|
1663 | { |
---|
1664 | changes.sibling = stackWindow; |
---|
1665 | changes.stack_mode = Above; |
---|
1666 | XConfigureWindow (DISPLAY, activeIconWindow, |
---|
1667 | (CWSibling | CWStackMode), &changes); |
---|
1668 | changes.sibling = activeIconWindow; |
---|
1669 | changes.stack_mode = Below; |
---|
1670 | XConfigureWindow (DISPLAY, window, (CWSibling | CWStackMode), |
---|
1671 | &changes); |
---|
1672 | } |
---|
1673 | else |
---|
1674 | { |
---|
1675 | changes.sibling = stackWindow; |
---|
1676 | changes.stack_mode = Above; |
---|
1677 | XConfigureWindow (DISPLAY, window, (CWSibling | CWStackMode), |
---|
1678 | &changes); |
---|
1679 | if (stackTransientTreeWindows) |
---|
1680 | { |
---|
1681 | RestackTransients (pEntry->pCD, False); |
---|
1682 | } |
---|
1683 | } |
---|
1684 | } |
---|
1685 | else |
---|
1686 | { |
---|
1687 | if (stackWindow == 0) |
---|
1688 | { |
---|
1689 | if (pSD->lastClient->type == MINIMIZED_STATE) |
---|
1690 | { |
---|
1691 | stackWindow = ICON_FRAME_WIN(pSD->lastClient->pCD); |
---|
1692 | } |
---|
1693 | else |
---|
1694 | { |
---|
1695 | stackWindow = pSD->lastClient->pCD->clientFrameWin; |
---|
1696 | } |
---|
1697 | } |
---|
1698 | |
---|
1699 | if (activeIconWindow) |
---|
1700 | { |
---|
1701 | changes.sibling = stackWindow; |
---|
1702 | changes.stack_mode = Below; |
---|
1703 | XConfigureWindow (DISPLAY, activeIconWindow, |
---|
1704 | (CWSibling | CWStackMode), &changes); |
---|
1705 | changes.sibling = activeIconWindow; |
---|
1706 | changes.stack_mode = Below; |
---|
1707 | XConfigureWindow (DISPLAY, window, (CWSibling | CWStackMode), |
---|
1708 | &changes); |
---|
1709 | } |
---|
1710 | else |
---|
1711 | { |
---|
1712 | changes.sibling = stackWindow; |
---|
1713 | changes.stack_mode = Below; |
---|
1714 | XConfigureWindow (DISPLAY, window, (CWSibling | CWStackMode), |
---|
1715 | &changes); |
---|
1716 | if (stackTransientTreeWindows) |
---|
1717 | { |
---|
1718 | RestackTransients (pEntry->pCD, False); |
---|
1719 | } |
---|
1720 | } |
---|
1721 | } |
---|
1722 | |
---|
1723 | } /* END OF FUNCTION StackWindow */ |
---|
1724 | |
---|
1725 | |
---|
1726 | |
---|
1727 | /*************************************<->************************************* |
---|
1728 | * |
---|
1729 | * StackTransientWindow (pcd) |
---|
1730 | * |
---|
1731 | * |
---|
1732 | * Description: |
---|
1733 | * ----------- |
---|
1734 | * This function stacks a transient window within its transient window |
---|
1735 | * tree on the screen. The transient window tree should indicate the |
---|
1736 | * intended stacking position. |
---|
1737 | * |
---|
1738 | * |
---|
1739 | * Inputs: |
---|
1740 | * ------ |
---|
1741 | * pcd = pointer to client data of a window in a transient tree |
---|
1742 | * |
---|
1743 | *************************************<->***********************************/ |
---|
1744 | |
---|
1745 | #ifdef _NO_PROTO |
---|
1746 | void StackTransientWindow (pcd) |
---|
1747 | ClientData *pcd; |
---|
1748 | |
---|
1749 | #else /* _NO_PROTO */ |
---|
1750 | void StackTransientWindow (ClientData *pcd) |
---|
1751 | #endif /* _NO_PROTO */ |
---|
1752 | { |
---|
1753 | XWindowChanges changes; |
---|
1754 | ClientData *pcdPrev; |
---|
1755 | |
---|
1756 | |
---|
1757 | if (pcd->transientLeader->transientChildren == pcd) |
---|
1758 | { |
---|
1759 | if (pcd->transientSiblings) |
---|
1760 | { |
---|
1761 | changes.sibling = pcd->transientSiblings->clientFrameWin; |
---|
1762 | } |
---|
1763 | else |
---|
1764 | { |
---|
1765 | changes.sibling = pcd->transientLeader->clientFrameWin; |
---|
1766 | } |
---|
1767 | changes.stack_mode = Above; |
---|
1768 | } |
---|
1769 | else |
---|
1770 | { |
---|
1771 | pcdPrev = pcd->transientLeader; |
---|
1772 | while (pcdPrev->transientSiblings != pcd) |
---|
1773 | { |
---|
1774 | pcdPrev = pcdPrev->transientSiblings; |
---|
1775 | } |
---|
1776 | changes.sibling = pcdPrev->clientFrameWin; |
---|
1777 | changes.stack_mode = Below; |
---|
1778 | } |
---|
1779 | |
---|
1780 | XConfigureWindow (DISPLAY, pcd->clientFrameWin, (CWSibling | CWStackMode), |
---|
1781 | &changes); |
---|
1782 | |
---|
1783 | |
---|
1784 | } /* END OF FUNCTION StackTransientWindow */ |
---|
1785 | |
---|
1786 | |
---|
1787 | |
---|
1788 | /*************************************<->************************************* |
---|
1789 | * |
---|
1790 | * CheckIfClientObscuring (pcdTop, pcd) |
---|
1791 | * |
---|
1792 | * |
---|
1793 | * Description: |
---|
1794 | * ----------- |
---|
1795 | * This function determines whether a window or a transient window tree |
---|
1796 | * is obscuring (at least partially) a window or a transient window tree |
---|
1797 | * that is below it in the window stack. |
---|
1798 | * |
---|
1799 | * |
---|
1800 | * Inputs: |
---|
1801 | * ------ |
---|
1802 | * pcdTop = pointer to client data for a window (it may be the leader of |
---|
1803 | * a transient tree; this window is the higher in the window stack |
---|
1804 | * than the window it is be checked against. |
---|
1805 | * |
---|
1806 | * pcd = pointer to client data for a window (it may be the leader of |
---|
1807 | * a transient tree. |
---|
1808 | * |
---|
1809 | * |
---|
1810 | * Outputs: |
---|
1811 | * ------- |
---|
1812 | * RETURN = True if the top window(s) overlap the lower window(s) |
---|
1813 | * |
---|
1814 | *************************************<->***********************************/ |
---|
1815 | |
---|
1816 | #ifdef _NO_PROTO |
---|
1817 | Boolean CheckIfClientObscuring (pcdTop, pcd) |
---|
1818 | ClientData *pcdTop; |
---|
1819 | ClientData *pcd; |
---|
1820 | |
---|
1821 | #else /* _NO_PROTO */ |
---|
1822 | Boolean CheckIfClientObscuring (ClientData *pcdTop, ClientData *pcd) |
---|
1823 | #endif /* _NO_PROTO */ |
---|
1824 | { |
---|
1825 | Boolean obscuring = False; |
---|
1826 | ClientData *pcdNext; |
---|
1827 | |
---|
1828 | |
---|
1829 | /* |
---|
1830 | * Check only if the top window is visible onscreen. |
---|
1831 | */ |
---|
1832 | |
---|
1833 | if (pcdTop->transientChildren && (pcdTop->clientState != MINIMIZED_STATE)) |
---|
1834 | { |
---|
1835 | pcdNext = pcdTop->transientChildren; |
---|
1836 | while (pcdNext && !obscuring) |
---|
1837 | { |
---|
1838 | obscuring = CheckIfClientObscuring (pcdNext, pcd); |
---|
1839 | pcdNext = pcdNext->transientSiblings; |
---|
1840 | } |
---|
1841 | } |
---|
1842 | |
---|
1843 | if (!obscuring && pcd->transientChildren && |
---|
1844 | (pcd->clientState != MINIMIZED_STATE)) |
---|
1845 | { |
---|
1846 | pcdNext = pcd->transientChildren; |
---|
1847 | while (pcdNext && !obscuring) |
---|
1848 | { |
---|
1849 | obscuring = CheckIfClientObscuring (pcdTop, pcdNext); |
---|
1850 | pcdNext = pcdNext->transientSiblings; |
---|
1851 | } |
---|
1852 | } |
---|
1853 | |
---|
1854 | if (!obscuring) |
---|
1855 | { |
---|
1856 | obscuring = CheckIfObscuring (pcdTop, pcd); |
---|
1857 | } |
---|
1858 | |
---|
1859 | return (obscuring); |
---|
1860 | |
---|
1861 | } /* END OF FUNCTION CheckIfClientObscuring */ |
---|
1862 | |
---|
1863 | |
---|
1864 | |
---|
1865 | /*************************************<->************************************* |
---|
1866 | * |
---|
1867 | * CheckIfObscuring (pcdA, pcdB) |
---|
1868 | * |
---|
1869 | * |
---|
1870 | * Description: |
---|
1871 | * ----------- |
---|
1872 | * This function determines whether a window (not a transient tree) |
---|
1873 | * is obscuring (at least partially) a window (not a transient tree) |
---|
1874 | * that is below it in the window stack. |
---|
1875 | * |
---|
1876 | * |
---|
1877 | * Inputs: |
---|
1878 | * ------ |
---|
1879 | * pcdA = pointer to client data for a window; this window is higher in |
---|
1880 | * the window stack than the window it is be checked against. |
---|
1881 | * |
---|
1882 | * pcdB = pointer to client data for a window. |
---|
1883 | * |
---|
1884 | * |
---|
1885 | * Outputs: |
---|
1886 | * ------- |
---|
1887 | * RETURN = True if the top window overlaps the lower window |
---|
1888 | * |
---|
1889 | *************************************<->***********************************/ |
---|
1890 | |
---|
1891 | #ifdef _NO_PROTO |
---|
1892 | Boolean CheckIfObscuring (pcdA, pcdB) |
---|
1893 | ClientData *pcdA; |
---|
1894 | ClientData *pcdB; |
---|
1895 | |
---|
1896 | #else /* _NO_PROTO */ |
---|
1897 | Boolean CheckIfObscuring (ClientData *pcdA, ClientData *pcdB) |
---|
1898 | #endif /* _NO_PROTO */ |
---|
1899 | { |
---|
1900 | Boolean obscuring = False; |
---|
1901 | int aX1; |
---|
1902 | int aX2; |
---|
1903 | int aY1; |
---|
1904 | int aY2; |
---|
1905 | int bX1; |
---|
1906 | int bX2; |
---|
1907 | int bY1; |
---|
1908 | int bY2; |
---|
1909 | |
---|
1910 | |
---|
1911 | if (pcdA->clientState == NORMAL_STATE) |
---|
1912 | { |
---|
1913 | aX1 = pcdA->clientX - pcdA->clientOffset.x; |
---|
1914 | aY1 = pcdA->clientY - pcdA->clientOffset.y; |
---|
1915 | aX2 = aX1 + pcdA->clientWidth + (2 * pcdA->clientOffset.x) - 1; |
---|
1916 | aY2 = aY1 + pcdA->clientHeight + pcdA->clientOffset.y + |
---|
1917 | pcdA->clientOffset.x - 1; |
---|
1918 | } |
---|
1919 | else if (pcdA->clientState == MINIMIZED_STATE) |
---|
1920 | { |
---|
1921 | aX1 = ICON_X(pcdA); |
---|
1922 | aY1 = ICON_Y(pcdA); |
---|
1923 | aX2 = aX1 + ICON_WIDTH(pcdA) - 1; |
---|
1924 | aY2 = aY1 + ICON_HEIGHT(pcdA) - 1; |
---|
1925 | } |
---|
1926 | else /* (pcdA->clientState == MAXIMIZED_STATE) */ |
---|
1927 | { |
---|
1928 | aX1 = pcdA->maxX - pcdA->clientOffset.x; |
---|
1929 | aY1 = pcdA->maxY - pcdA->clientOffset.y; |
---|
1930 | aX2 = aX1 + pcdA->maxWidth + (2 * pcdA->clientOffset.x) - 1; |
---|
1931 | aY2 = aY1 + pcdA->maxHeight + pcdA->clientOffset.y + |
---|
1932 | pcdA->clientOffset.x - 1; |
---|
1933 | } |
---|
1934 | |
---|
1935 | if (pcdB->clientState == NORMAL_STATE) |
---|
1936 | { |
---|
1937 | bX1 = pcdB->clientX - pcdB->clientOffset.x; |
---|
1938 | bY1 = pcdB->clientY - pcdB->clientOffset.y; |
---|
1939 | bX2 = bX1 + pcdB->clientWidth + (2 * pcdB->clientOffset.x) - 1; |
---|
1940 | bY2 = bY1 + pcdB->clientHeight + pcdB->clientOffset.y + |
---|
1941 | pcdB->clientOffset.x - 1; |
---|
1942 | } |
---|
1943 | else if (pcdB->clientState == MINIMIZED_STATE) |
---|
1944 | { |
---|
1945 | bX1 = ICON_X(pcdB); |
---|
1946 | bY1 = ICON_Y(pcdB); |
---|
1947 | bX2 = bX1 + ICON_WIDTH(pcdB) - 1; |
---|
1948 | bY2 = bY1 + ICON_HEIGHT(pcdB) - 1; |
---|
1949 | } |
---|
1950 | else /* (pcdB->clientState == MAXIMIZED_STATE) */ |
---|
1951 | { |
---|
1952 | bX1 = pcdB->maxX - pcdB->clientOffset.x; |
---|
1953 | bY1 = pcdB->maxY - pcdB->clientOffset.y; |
---|
1954 | bX2 = bX1 + pcdB->maxWidth + (2 * pcdB->clientOffset.x) - 1; |
---|
1955 | bY2 = bY1 + pcdB->maxHeight + pcdB->clientOffset.y + |
---|
1956 | pcdB->clientOffset.x - 1; |
---|
1957 | } |
---|
1958 | |
---|
1959 | /* |
---|
1960 | * Check if there is overlap in both dimensions. |
---|
1961 | */ |
---|
1962 | |
---|
1963 | if (((aX1 >= bX1) && (aX1 <= bX2)) || ((aX2 >= bX1) && (aX2 <= bX2)) || |
---|
1964 | ((bX1 >= aX1) && (bX1 <= aX2)) || ((bX2 >= aX1) && (bX2 <= aX2))) |
---|
1965 | { |
---|
1966 | if (((aY1 >= bY1) && (aY1 <= bY2)) || ((aY2 >= bY1) && (aY2 <= bY2)) || |
---|
1967 | ((bY1 >= aY1) && (bY1 <= aY2)) || ((bY2 >= aY1) && (bY2 <= aY2))) |
---|
1968 | { |
---|
1969 | obscuring = True; |
---|
1970 | } |
---|
1971 | } |
---|
1972 | |
---|
1973 | return (obscuring); |
---|
1974 | |
---|
1975 | |
---|
1976 | } /* END OF FUNCTION CheckIfObscuring */ |
---|
1977 | |
---|
1978 | |
---|
1979 | |
---|
1980 | /*************************************<->************************************* |
---|
1981 | * |
---|
1982 | * CheckIfClientObscuredByAny (pcd) |
---|
1983 | * |
---|
1984 | * |
---|
1985 | * Description: |
---|
1986 | * ----------- |
---|
1987 | * This function determines whether a window or a transient window tree |
---|
1988 | * is obscured (at least partially) by any other window. |
---|
1989 | * |
---|
1990 | * |
---|
1991 | * Inputs: |
---|
1992 | * ------ |
---|
1993 | * pcd = pointer to client data for a window (it may be the leader of |
---|
1994 | * a transient tree. |
---|
1995 | * |
---|
1996 | * |
---|
1997 | * Outputs: |
---|
1998 | * ------- |
---|
1999 | * RETURN = True if the window(s) are overlapped. |
---|
2000 | * |
---|
2001 | *************************************<->***********************************/ |
---|
2002 | |
---|
2003 | #ifdef _NO_PROTO |
---|
2004 | Boolean CheckIfClientObscuredByAny (pcd) |
---|
2005 | ClientData *pcd; |
---|
2006 | |
---|
2007 | #else /* _NO_PROTO */ |
---|
2008 | Boolean CheckIfClientObscuredByAny (ClientData *pcd) |
---|
2009 | #endif /* _NO_PROTO */ |
---|
2010 | { |
---|
2011 | Boolean obscured = False; |
---|
2012 | ClientListEntry *pListEntry; |
---|
2013 | |
---|
2014 | |
---|
2015 | pListEntry = ACTIVE_PSD->clientList; |
---|
2016 | while (pListEntry && !obscured) |
---|
2017 | { |
---|
2018 | if (pListEntry->pCD == pcd) |
---|
2019 | { |
---|
2020 | if (((pListEntry->type == MINIMIZED_STATE) && |
---|
2021 | (pListEntry->pCD->clientState == MINIMIZED_STATE)) || |
---|
2022 | ((pListEntry->type != MINIMIZED_STATE) && |
---|
2023 | (pListEntry->pCD->clientState != MINIMIZED_STATE))) |
---|
2024 | { |
---|
2025 | pListEntry = NULL; |
---|
2026 | } |
---|
2027 | } |
---|
2028 | else if (((pListEntry->type == MINIMIZED_STATE) && |
---|
2029 | (pListEntry->pCD->clientState == MINIMIZED_STATE)) || |
---|
2030 | ((pListEntry->type != MINIMIZED_STATE) && |
---|
2031 | (pListEntry->pCD->clientState != MINIMIZED_STATE))) |
---|
2032 | { |
---|
2033 | /* |
---|
2034 | * The window for the entry is visible on screen. See if it |
---|
2035 | * obscures the indicated window. |
---|
2036 | */ |
---|
2037 | |
---|
2038 | obscured = CheckIfClientObscuring (pListEntry->pCD, pcd); |
---|
2039 | } |
---|
2040 | |
---|
2041 | if (pListEntry) |
---|
2042 | { |
---|
2043 | pListEntry = pListEntry->nextSibling; |
---|
2044 | } |
---|
2045 | } |
---|
2046 | |
---|
2047 | return (obscured); |
---|
2048 | |
---|
2049 | } /* END OF FUNCTION CheckIfClientObscuredByAny */ |
---|
2050 | |
---|
2051 | |
---|
2052 | |
---|
2053 | /*************************************<->************************************* |
---|
2054 | * |
---|
2055 | * CheckIfClientObscuringAny (pcd) |
---|
2056 | * |
---|
2057 | * |
---|
2058 | * Description: |
---|
2059 | * ----------- |
---|
2060 | * This function determines whether a window or a transient window tree |
---|
2061 | * is obscuring another window. |
---|
2062 | * |
---|
2063 | * |
---|
2064 | * Inputs: |
---|
2065 | * ------ |
---|
2066 | * pcd = pointer to client data for a window (it may be the leader of |
---|
2067 | * a transient tree. |
---|
2068 | * |
---|
2069 | * |
---|
2070 | * Outputs: |
---|
2071 | * ------- |
---|
2072 | * RETURN = True if the window(s) overlaps anther window. |
---|
2073 | * |
---|
2074 | *************************************<->***********************************/ |
---|
2075 | |
---|
2076 | #ifdef _NO_PROTO |
---|
2077 | Boolean CheckIfClientObscuringAny (pcd) |
---|
2078 | ClientData *pcd; |
---|
2079 | |
---|
2080 | #else /* _NO_PROTO */ |
---|
2081 | Boolean CheckIfClientObscuringAny (ClientData *pcd) |
---|
2082 | #endif /* _NO_PROTO */ |
---|
2083 | { |
---|
2084 | Boolean obscuring = False; |
---|
2085 | ClientListEntry *pListEntry; |
---|
2086 | |
---|
2087 | |
---|
2088 | pListEntry = (pcd->clientState == MINIMIZED_STATE) ? |
---|
2089 | &pcd->iconEntry : &pcd->clientEntry; |
---|
2090 | while (pListEntry && !obscuring) |
---|
2091 | { |
---|
2092 | if ((pListEntry->pCD != pcd) && |
---|
2093 | (((pListEntry->type == MINIMIZED_STATE) && |
---|
2094 | (pListEntry->pCD->clientState == MINIMIZED_STATE)) || |
---|
2095 | ((pListEntry->type != MINIMIZED_STATE) && |
---|
2096 | (pListEntry->pCD->clientState != MINIMIZED_STATE)))) |
---|
2097 | { |
---|
2098 | obscuring = CheckIfClientObscuring (pcd, pListEntry->pCD); |
---|
2099 | } |
---|
2100 | |
---|
2101 | pListEntry = pListEntry->nextSibling; |
---|
2102 | } |
---|
2103 | |
---|
2104 | return (obscuring); |
---|
2105 | |
---|
2106 | } /* END OF FUNCTION CheckIfClientObscuringAny */ |
---|
2107 | |
---|
2108 | |
---|
2109 | |
---|
2110 | /*************************************<->************************************* |
---|
2111 | * |
---|
2112 | * SetupSystemModalState (pCD) |
---|
2113 | * |
---|
2114 | * |
---|
2115 | * Description: |
---|
2116 | * ----------- |
---|
2117 | * This function prepares for mapping a system modal window. An input |
---|
2118 | * screen window is mapped below the system modal window to prevent input |
---|
2119 | * to the windows not related to the system modal window. |
---|
2120 | * |
---|
2121 | * |
---|
2122 | * Inputs: |
---|
2123 | * ------ |
---|
2124 | * pCD = pointer to client data for the system modal window; if NULL the |
---|
2125 | * system modal window is a special window manager dialog box |
---|
2126 | * |
---|
2127 | * |
---|
2128 | * Outputs: |
---|
2129 | * ------- |
---|
2130 | * wmGD = changes to system modal state data |
---|
2131 | * |
---|
2132 | *************************************<->***********************************/ |
---|
2133 | |
---|
2134 | #ifdef _NO_PROTO |
---|
2135 | void SetupSystemModalState (pCD) |
---|
2136 | ClientData *pCD; |
---|
2137 | |
---|
2138 | #else /* _NO_PROTO */ |
---|
2139 | void SetupSystemModalState (ClientData *pCD) |
---|
2140 | #endif /* _NO_PROTO */ |
---|
2141 | { |
---|
2142 | XWindowChanges windowChanges; |
---|
2143 | unsigned int width, height; |
---|
2144 | unsigned int x_hot, y_hot; |
---|
2145 | unsigned char *bits; |
---|
2146 | unsigned char *mask_bits; |
---|
2147 | WmScreenData *pSD; |
---|
2148 | int scr; |
---|
2149 | |
---|
2150 | #ifdef LARGECURSORS |
---|
2151 | |
---|
2152 | if (wmGD.useLargeCursors) |
---|
2153 | { |
---|
2154 | width = noenter32_width; |
---|
2155 | height = noenter32_height; |
---|
2156 | x_hot = noenter32_x_hot; |
---|
2157 | y_hot = noenter32_y_hot; |
---|
2158 | bits = noenter32_bits; |
---|
2159 | mask_bits = noenter32m_bits; |
---|
2160 | } |
---|
2161 | else |
---|
2162 | |
---|
2163 | #endif /* LARGECURSORS */ |
---|
2164 | |
---|
2165 | { |
---|
2166 | width = noenter16_width; |
---|
2167 | height = noenter16_height; |
---|
2168 | x_hot = noenter16_x_hot; |
---|
2169 | y_hot = noenter16_y_hot; |
---|
2170 | bits = noenter16_bits; |
---|
2171 | mask_bits = noenter16m_bits; |
---|
2172 | } |
---|
2173 | |
---|
2174 | for (scr=0; scr<wmGD.numScreens; scr++) |
---|
2175 | { |
---|
2176 | pSD = &(wmGD.Screens[scr]); |
---|
2177 | |
---|
2178 | /* |
---|
2179 | * Make the system modal input screen window if necessary. |
---|
2180 | */ |
---|
2181 | |
---|
2182 | if (pSD->managed && pSD->inputScreenWindow == 0) |
---|
2183 | { |
---|
2184 | XSetWindowAttributes windowAttributes; |
---|
2185 | Pixmap pixmap; |
---|
2186 | Pixmap maskPixmap; |
---|
2187 | XColor xcolors[2]; |
---|
2188 | |
---|
2189 | windowAttributes.event_mask = ButtonPressMask; |
---|
2190 | if (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_POINTER) |
---|
2191 | { |
---|
2192 | windowAttributes.event_mask |= EnterWindowMask; |
---|
2193 | } |
---|
2194 | windowAttributes.override_redirect = True; |
---|
2195 | |
---|
2196 | pixmap = XCreateBitmapFromData (DISPLAY, pSD->rootWindow, |
---|
2197 | (char *)bits, width, height); |
---|
2198 | |
---|
2199 | maskPixmap = XCreateBitmapFromData (DISPLAY, pSD->rootWindow, |
---|
2200 | (char *)mask_bits, width, height); |
---|
2201 | |
---|
2202 | xcolors[0].pixel = BlackPixel (DISPLAY, pSD->screen); |
---|
2203 | xcolors[1].pixel = WhitePixel (DISPLAY, pSD->screen); |
---|
2204 | XQueryColors (DISPLAY, DefaultColormap (DISPLAY, pSD->screen), |
---|
2205 | xcolors, 2); |
---|
2206 | windowAttributes.cursor = |
---|
2207 | XCreatePixmapCursor (DISPLAY, pixmap, maskPixmap, |
---|
2208 | &(xcolors[0]), &(xcolors[1]), |
---|
2209 | x_hot, y_hot); |
---|
2210 | XFreePixmap (DISPLAY, pixmap); |
---|
2211 | XFreePixmap (DISPLAY, maskPixmap); |
---|
2212 | |
---|
2213 | pSD->inputScreenWindow = |
---|
2214 | XCreateWindow (DISPLAY, pSD->rootWindow, 0, 0, |
---|
2215 | DisplayWidth (DISPLAY, pSD->screen), |
---|
2216 | DisplayHeight (DISPLAY, pSD->screen), |
---|
2217 | 0, |
---|
2218 | 0, |
---|
2219 | InputOnly, |
---|
2220 | CopyFromParent, |
---|
2221 | CWEventMask | CWOverrideRedirect | CWCursor, |
---|
2222 | &windowAttributes); |
---|
2223 | } |
---|
2224 | if (pSD->managed && pSD != ACTIVE_PSD) |
---|
2225 | { |
---|
2226 | XMapRaised (DISPLAY, pSD->inputScreenWindow); |
---|
2227 | } |
---|
2228 | } |
---|
2229 | |
---|
2230 | if (pCD) |
---|
2231 | { |
---|
2232 | wmGD.systemModalWindow = pCD->clientFrameWin; |
---|
2233 | } |
---|
2234 | else |
---|
2235 | { |
---|
2236 | /* |
---|
2237 | * ELSE: the system modal window is a special window manager dialog |
---|
2238 | * box and wmGD.systemModalWindow is set prior to the call to |
---|
2239 | * SetupSystemModalState. Set the focus to the special window manager |
---|
2240 | * dialog box. |
---|
2241 | */ |
---|
2242 | |
---|
2243 | SetKeyboardFocus (NULL, REFRESH_LAST_FOCUS); |
---|
2244 | XSetInputFocus (DISPLAY, wmGD.systemModalWindow, RevertToPointerRoot, |
---|
2245 | CurrentTime); |
---|
2246 | } |
---|
2247 | |
---|
2248 | |
---|
2249 | /* |
---|
2250 | * Map the system modal input screen window below the system modal |
---|
2251 | * window. |
---|
2252 | */ |
---|
2253 | |
---|
2254 | windowChanges.sibling = wmGD.systemModalWindow; |
---|
2255 | windowChanges.stack_mode = Below; |
---|
2256 | XConfigureWindow (DISPLAY, ACTIVE_PSD->inputScreenWindow, |
---|
2257 | CWSibling | CWStackMode, &windowChanges); |
---|
2258 | |
---|
2259 | XMapWindow (DISPLAY, ACTIVE_PSD->inputScreenWindow); |
---|
2260 | |
---|
2261 | |
---|
2262 | /* |
---|
2263 | * Setup the system modal global data. |
---|
2264 | */ |
---|
2265 | |
---|
2266 | wmGD.systemModalActive = True; |
---|
2267 | wmGD.systemModalClient = pCD; |
---|
2268 | |
---|
2269 | |
---|
2270 | } /* END OF FUNCTION SetupSystemModalState */ |
---|
2271 | |
---|
2272 | |
---|
2273 | |
---|
2274 | /*************************************<->************************************* |
---|
2275 | * |
---|
2276 | * UndoSystemModalState () |
---|
2277 | * |
---|
2278 | * |
---|
2279 | * Description: |
---|
2280 | * ----------- |
---|
2281 | * This function cleans up after a system modal window goes away. |
---|
2282 | * |
---|
2283 | * |
---|
2284 | * Inputs: |
---|
2285 | * ------ |
---|
2286 | * wmGD = (system modal state data) |
---|
2287 | * |
---|
2288 | * |
---|
2289 | * Outputs: |
---|
2290 | * ------- |
---|
2291 | * wmGD = changes to system modal state data |
---|
2292 | * |
---|
2293 | *************************************<->***********************************/ |
---|
2294 | |
---|
2295 | #ifdef _NO_PROTO |
---|
2296 | void UndoSystemModalState () |
---|
2297 | |
---|
2298 | #else /* _NO_PROTO */ |
---|
2299 | void UndoSystemModalState (void) |
---|
2300 | #endif /* _NO_PROTO */ |
---|
2301 | { |
---|
2302 | int scr; |
---|
2303 | |
---|
2304 | /* |
---|
2305 | * Unmap the system modal input screen window. |
---|
2306 | */ |
---|
2307 | |
---|
2308 | for (scr = 0; scr < wmGD.numScreens; scr++) |
---|
2309 | { |
---|
2310 | if(wmGD.Screens[scr].managed) |
---|
2311 | { |
---|
2312 | XUnmapWindow (DISPLAY, wmGD.Screens[scr].inputScreenWindow); |
---|
2313 | } |
---|
2314 | } |
---|
2315 | |
---|
2316 | /* |
---|
2317 | * Reset the focus if a window manager system modal dialog box was |
---|
2318 | * being displayed. |
---|
2319 | */ |
---|
2320 | |
---|
2321 | if (!wmGD.systemModalClient) |
---|
2322 | { |
---|
2323 | AutoResetKeyFocus (NULL, CurrentTime); |
---|
2324 | } |
---|
2325 | |
---|
2326 | |
---|
2327 | /* |
---|
2328 | * Reset the system modal global data. |
---|
2329 | */ |
---|
2330 | |
---|
2331 | wmGD.systemModalActive = False; |
---|
2332 | wmGD.systemModalClient = NULL; |
---|
2333 | wmGD.systemModalWindow = 0; |
---|
2334 | |
---|
2335 | } /* END OF FUNCTION UndoSystemModalState */ |
---|
2336 | |
---|
2337 | |
---|
2338 | |
---|
2339 | /*************************************<->************************************* |
---|
2340 | * |
---|
2341 | * FindClientNameMatch (pStartingEntry, toNext, clientName, types) |
---|
2342 | * |
---|
2343 | * |
---|
2344 | * Description: |
---|
2345 | * ----------- |
---|
2346 | * This function searches for a client that has a particular name or class. |
---|
2347 | * A match will be indicated if the client with the name or class also |
---|
2348 | * is in a particular state. |
---|
2349 | * |
---|
2350 | * |
---|
2351 | * Inputs: |
---|
2352 | * ------ |
---|
2353 | * pEntry = pointer to the client list entry where the search is |
---|
2354 | * to begin. |
---|
2355 | * |
---|
2356 | * toNext = if True then search client list from first to last; otherwise |
---|
2357 | * search the client list last to first. |
---|
2358 | * |
---|
2359 | * clientName = string that indicates a client name or class. |
---|
2360 | * |
---|
2361 | * type = types of objects (icon, window, ...) that are to be matched. |
---|
2362 | * |
---|
2363 | * |
---|
2364 | * Outputs: |
---|
2365 | * ------- |
---|
2366 | * RETURN = pointer to client list entry for matched client. |
---|
2367 | * |
---|
2368 | *************************************<->***********************************/ |
---|
2369 | #ifdef _NO_PROTO |
---|
2370 | ClientListEntry * FindClientNameMatch (pEntry, toNext, clientName, types) |
---|
2371 | ClientListEntry *pEntry; |
---|
2372 | Boolean toNext; |
---|
2373 | String clientName; |
---|
2374 | unsigned long types; |
---|
2375 | #else /* _NO_PROTO */ |
---|
2376 | ClientListEntry * FindClientNameMatch (ClientListEntry *pEntry, |
---|
2377 | Boolean toNext, |
---|
2378 | String clientName, |
---|
2379 | unsigned long types) |
---|
2380 | #endif /* _NO_PROTO */ |
---|
2381 | |
---|
2382 | { |
---|
2383 | Boolean foundMatch = False; |
---|
2384 | Boolean checkEntry; |
---|
2385 | ClientData *pCD; |
---|
2386 | |
---|
2387 | |
---|
2388 | while (!foundMatch && pEntry) |
---|
2389 | { |
---|
2390 | checkEntry = False; |
---|
2391 | pCD = pEntry->pCD; |
---|
2392 | if (pEntry->type == MINIMIZED_STATE) |
---|
2393 | { |
---|
2394 | if ((pCD->clientState == MINIMIZED_STATE) && |
---|
2395 | (types & F_GROUP_ICON)) |
---|
2396 | { |
---|
2397 | checkEntry = True; |
---|
2398 | } |
---|
2399 | } |
---|
2400 | else |
---|
2401 | { |
---|
2402 | if ((pCD->clientState != MINIMIZED_STATE) && |
---|
2403 | (types & F_GROUP_WINDOW)) |
---|
2404 | { |
---|
2405 | checkEntry = True; |
---|
2406 | } |
---|
2407 | } |
---|
2408 | |
---|
2409 | if (checkEntry && |
---|
2410 | ((pCD->clientName && (strcmp (clientName,pCD->clientName) == 0)) || |
---|
2411 | (pCD->clientClass && (strcmp (clientName,pCD->clientClass) == 0)))) |
---|
2412 | { |
---|
2413 | foundMatch = True; |
---|
2414 | } |
---|
2415 | else |
---|
2416 | { |
---|
2417 | pEntry = (toNext) ? pEntry->nextSibling : pEntry->prevSibling; |
---|
2418 | } |
---|
2419 | } |
---|
2420 | |
---|
2421 | return (pEntry); |
---|
2422 | |
---|
2423 | } /* END OF FUNCTION FindClientNameMatch */ |
---|