2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 * (c) Copyright 1989, 1990, 1991, 1992 OPEN SOFTWARE FOUNDATION, INC.
32 static char rcsid[] = "$XConsortium: WmWinState.c /main/6 1996/06/20 09:39:39 rswiston $"
36 * (c) Copyright 1987, 1988, 1989, 1990 HEWLETT-PACKARD COMPANY */
44 #include "WmProtocol.h"
49 * include extern functions
53 #include "WmFunction.h"
56 #include "WmIconBox.h"
57 #include "WmKeyFocus.h"
59 #include "WmPanelP.h" /* for typedef in WmManage.h */
62 #include "WmProperty.h"
63 #include "WmWinInfo.h"
64 #include "WmWinList.h"
66 #include "WmWrkspace.h"
71 * Function Declarations:
74 #include "WmWinState.h"
76 static void SlideWindowOut (ClientData *pCD);
78 static void UnmapClients (ClientData *pCD, unsigned int event_mask);
79 static void SetupWindowStateWithEventMask (ClientData *pCD, int newState, Time setTime, unsigned int event_mask);
89 /******************************<->*************************************
91 * SetClientState (pCD, newState, setTime)
96 * This function is used to change the state of a client window (between
97 * withdrawn, normal, minimized, maximized).
102 * pCD = This is a pointer to the window data for the window that
103 * is to have its state changed. The fields that are used
104 * are clientState, ...
106 * newState = This is the state that the client window is to be changed to.
108 * setTime = timestamp for state setting operations
113 * pCD.clientState = new client state
115 ******************************<->***********************************/
117 void SetClientState (ClientData *pCD, int newState, Time setTime)
119 SetClientStateWithEventMask(pCD, newState, setTime, (unsigned int)0);
120 } /* END OF FUNCTION SetClientState */
122 void SetClientStateWithEventMask (ClientData *pCD, int newState, Time setTime, unsigned int event_mask)
124 ClientData *pcdLeader;
126 WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
128 Boolean notShowing = (newState & UNSEEN_STATE);
131 currentState = pCD->clientState;
132 if (currentState == newState)
134 /* no change in state */
140 * Undo the old state and setup the new state. If this is a transient
141 * window then insure that it is put in a state that is compatible
142 * with its transient leader (e.g., it cannot be minimized separately).
145 pcdLeader = (pCD->transientLeader) ? FindTransientTreeLeader (pCD) : pCD;
147 SetClientWsIndex (pCD);
150 if (pCD->transientLeader)
152 if ((pcdLeader->clientState == MINIMIZED_STATE) &&
153 (newState != WITHDRAWN_STATE))
155 newState = MINIMIZED_STATE;
159 newState |= UNSEEN_STATE;
163 else if ((newState == MINIMIZED_STATE) &&
164 (pcdLeader->clientState != MINIMIZED_STATE))
166 if (currentState == WITHDRAWN_STATE)
168 newState = NORMAL_STATE;
172 newState |= UNSEEN_STATE;
178 newState = currentState;
182 newState |= UNSEEN_STATE;
187 if (newState == currentState)
197 case UNSEEN_STATE | WITHDRAWN_STATE:
199 case WITHDRAWN_STATE:
203 * Free window manager resources (frame and icon). The
204 * WM_STATE property is set in WithdrawWindow.
207 UnManageWindow (pCD);
212 case MAXIMIZED_STATE:
214 SetupWindowStateWithEventMask (pCD, newState, setTime, event_mask);
216 XMapWindow (DISPLAY, pCD->client);
217 XMapWindow (DISPLAY, pCD->clientFrameWin);
218 #if defined(PANELIST)
219 WmStopWaiting(); /* in WmIPC.c */
220 #endif /* PANELIST */
225 case MINIMIZED_STATE:
227 Boolean clientHasFocus;
230 * Transient windows are minimized with the rest of the transient
231 * tree, including the transient leader.
234 if ((pCD->clientState == NORMAL_STATE) ||
235 (pCD->clientState == MAXIMIZED_STATE))
237 if ((wmGD.keyboardFocus == pCD) ||
238 (pCD->transientChildren && wmGD.keyboardFocus &&
239 (pCD == FindTransientTreeLeader (wmGD.keyboardFocus))))
241 clientHasFocus = True;
245 clientHasFocus = False;
248 if (clientHasFocus ||
249 ((wmGD.nextKeyboardFocus == pCD) ||
250 (pCD->transientChildren && wmGD.keyboardFocus &&
251 (pCD == FindTransientTreeLeader (wmGD.nextKeyboardFocus)))))
254 * Give up the keyboard focus when minimized (including
255 * the case in which an associated transient window has
256 * the focus). Immediately remove the focus indication
257 * from the window being minimized.
260 if (wmGD.autoKeyFocus &&
261 (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT))
263 AutoResetKeyFocus (pcdLeader, setTime);
267 Do_Focus_Key (NULL, setTime,
268 ALWAYS_SET_FOCUS | WORKSPACE_IF_NULL);
273 SetKeyboardFocus (NULL, 0);
277 /* unmap main client and all transients */
278 UnmapClients (pCD, event_mask);
282 * Display the icon for the minimized client.
285 if (ICON_FRAME_WIN(pCD))
288 if (pCD->clientState & UNSEEN_STATE)
292 XMapWindow (DISPLAY, pCD->iconWindow);
294 XMapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
297 ShowAllIconsForMinimizedClient (pCD);
299 ShowIconForMinimizedClient (pSD->pActiveWS, pCD);
303 SetClientWMState (pCD, IconicState, MINIMIZED_STATE);
305 if ((pSD->useIconBox) && P_ICON_BOX(pCD))
307 if ((pCD->clientFlags & ICON_BOX) && ACTIVE_ICON_TEXT_WIN)
310 * Hide active icon text window and reparent it to
313 HideActiveIconText((WmScreenData *)NULL);
314 pSD->activeLabelParent = ACTIVE_ROOT;
315 XReparentWindow(DISPLAY, ACTIVE_ICON_TEXT_WIN ,
318 if (ICON_FRAME_WIN(pCD))
321 * force icon appearance in icon box to change
323 IconExposureProc (pCD, True);
331 case UNSEEN_STATE | NORMAL_STATE:
332 case UNSEEN_STATE | MAXIMIZED_STATE:
333 case UNSEEN_STATE | MINIMIZED_STATE:
335 if (wmGD.keyboardFocus == pCD)
338 * Give up the keyboard focus
340 Do_Focus_Key ((ClientData *)NULL,
341 CurrentTime, ALWAYS_SET_FOCUS);
342 SetKeyboardFocus (NULL, 0);
345 if (!(pCD->clientState & UNSEEN_STATE) &&
346 (((pCD->clientState & ~UNSEEN_STATE) == NORMAL_STATE) ||
347 ((pCD->clientState & ~UNSEEN_STATE) == MAXIMIZED_STATE)))
349 /* unmap main client and all transients */
350 UnmapClients (pcdLeader, event_mask);
354 if (pCD->clientFrameWin)
356 if (!P_ICON_BOX(pCD))
358 if (ICON_FRAME_WIN(pCD))
360 XUnmapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
363 XUnmapWindow (DISPLAY, pCD->iconWindow);
367 switch (newState & ~UNSEEN_STATE)
369 case MINIMIZED_STATE:
370 SetClientWMState (pCD, IconicState, newState);
374 case MAXIMIZED_STATE:
376 SetClientWMState (pCD, NormalState, newState);
384 } /* END OF FUNCTION SetClientStateWithEventMask */
388 /*************************************<->*************************************
390 * SetupWindowStateWithEventMask (pCD, newState, setTime, event_mask)
395 * This function is used to setup a client window in the Normal or Maximized
401 * pCD = This is a pointer to the window data for the window that
402 * is to have its state changed.
404 * newState = This is the state that the client window is to be changed to.
406 * setTime = timestamp for state setting operations
408 * event_mask = what to grab to prevent stray events going somewhere
412 * pCD.clientState = new client state
414 *************************************<->***********************************/
416 static void SetupWindowStateWithEventMask (ClientData *pCD, int newState,
417 Time setTime, unsigned int event_mask)
422 WmWorkspaceData *pWS_i;
424 WmWorkspaceData *pWS = PSD_FOR_CLIENT(pCD)->pActiveWS;
426 WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
428 currentState = pCD->clientState;
431 * A transient window is not restored or maximized if the transient leader
435 if (newState == NORMAL_STATE)
437 if (pCD->maxConfig == True)
440 * The configuration function uses maxConfig to determine
441 * what the current configuration is (and then resets
442 * maxConfig) and uses the state paramenter to determine
443 * what the new configuration is.
446 ConfigureNewState (pCD);
449 else /* MAXIMIZED_STATE */
451 if (pCD->maxConfig == False)
453 ConfigureNewState (pCD);
457 if (currentState == MINIMIZED_STATE)
459 Boolean clearIconFocus;
462 * give up keyboard focus
465 if ((wmGD.keyboardFocus == pCD) ||
466 (wmGD.nextKeyboardFocus == pCD))
468 Do_Focus_Key (NULL, setTime, ALWAYS_SET_FOCUS | WORKSPACE_IF_NULL);
471 if (wmGD.keyboardFocus == pCD)
473 clearIconFocus = True;
477 clearIconFocus = False;
481 * The wm icon frame window and the client icon window
482 * (if it is being used) are mapped and the client window and
483 * client frame are unmapped.
486 if (ICON_FRAME_WIN(pCD))
488 if (pSD->useIconBox && P_ICON_BOX(pCD) &&
489 !(pCD->clientFlags & ICON_BOX))
491 ShowClientIconState(pCD, newState);
495 Boolean doGrab = False;
497 doGrab = (Success == XGrabPointer
498 (DISPLAY, DefaultRootWindow(DISPLAY),
499 False, event_mask, GrabModeAsync, GrabModeAsync,
500 None, None, CurrentTime));
501 XUnmapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
504 XUnmapWindow (DISPLAY, pCD->iconWindow);
506 if (event_mask && doGrab)
509 XMaskEvent(DISPLAY, event_mask, &event);
510 XUngrabPointer(DISPLAY,CurrentTime);
513 if (wmGD.iconAutoPlace)
515 for (wsI = 0; wsI < pCD->numInhabited; wsI++)
517 iplace = pCD->pWsList[wsI].iconPlace;
518 if (iplace != NO_ICON_PLACE)
520 pWS_i = GetWorkspaceData (pCD->pSD,
521 pCD->pWsList[wsI].wsID);
522 pWS_i->IPData.placeList[iplace].pCD =
528 if ((wmGD.iconAutoPlace) && (ICON_PLACE(pCD) != NO_ICON_PLACE))
530 pWS->IPData.placeList[ICON_PLACE(pCD)].pCD =
538 ClearFocusIndication (pCD, False /*no refresh*/);
539 wmGD.keyboardFocus = NULL;
543 if ((currentState != NORMAL_STATE) && (currentState != MAXIMIZED_STATE))
546 * Note that maximized state is considered a NormalState in
547 * the ICCC. SetClientWMState also sets the state in the
551 if (currentState == MINIMIZED_STATE)
554 * Raise the window(s) when they are deiconified.
557 pCD->clientState = newState;
559 wmGD.bSuspendSecondaryRestack = True;
561 F_Raise (NULL, pCD, NULL);
563 wmGD.bSuspendSecondaryRestack = False;
567 if ( (!(pCD->clientFlags & ICON_BOX)) ||
568 ((pCD->clientFlags & ICON_BOX) && (!(firstTime))) )
571 if ((currentState == WITHDRAWN_STATE) &&
572 (pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUBPANEL) &&
573 !(pCD->transientChildren))
575 if (pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUB_RESTORED)
577 pCD->dtwmBehaviors &= ~DtWM_BEHAVIOR_SUB_RESTORED;
578 pCD->dtwmBehaviors &= ~DtWM_BEHAVIOR_SUBPANEL;
579 XMapWindow (DISPLAY, pCD->client);
580 XMapWindow (DISPLAY, pCD->clientFrameWin);
584 SlideWindowOut (pCD);
588 #endif /* PANELIST */
589 MapClientWindows (pCD);
594 * Set the WM_STATE property of the window and any associated
595 * transients, along with the clientState value. The call
596 * is made with an indication of NORMAL_STATE to insure
597 * that transient window clientState values are setup
598 * correctly. The top-level window clientState is set later.
601 SetClientWMState (pCD, NormalState, NORMAL_STATE);
603 pCD->clientState = newState;
605 if ((wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT) &&
606 (currentState == MINIMIZED_STATE) && wmGD.deiconifyKeyFocus)
608 ClientData *pcdFocus;
610 pcdFocus = FindTransientFocus (pCD);
613 Do_Focus_Key (pcdFocus, setTime, ALWAYS_SET_FOCUS);
617 if ( pSD->useIconBox && P_ICON_BOX(pCD) &&
618 (!(pCD->clientFlags & ICON_BOX)) && (ICON_FRAME_WIN(pCD)))
621 * force icon appearance in icon box to change
624 IconExposureProc (pCD, True);
627 } /* END OF FUNCTION SetupWindowStateWithEventMask */
632 /*************************************<->*************************************
634 * ConfigureNewState (pcd)
639 * Configure the window to a new state
644 * pcd - pointer to client data
652 * o This is only good for going between NORMAL and MAXIMIZED state.
654 *************************************<->***********************************/
656 void ConfigureNewState (ClientData *pcd)
660 pcd->maxConfig = FALSE;
661 RegenerateClientFrame(pcd);
662 XResizeWindow (DISPLAY, pcd->client,
663 (unsigned int) pcd->clientWidth,
664 (unsigned int) pcd->clientHeight);
668 XResizeWindow (DISPLAY, pcd->client,
669 (unsigned int) pcd->maxWidth,
670 (unsigned int) pcd->maxHeight);
671 pcd->maxConfig = TRUE;
672 RegenerateClientFrame(pcd);
674 SendConfigureNotify (pcd);
677 * Force repaint if size doesn't change to update frame appearance.
680 if ((pcd->clientWidth == pcd->maxWidth) &&
681 (pcd->clientHeight == pcd->maxHeight))
683 FrameExposureProc (pcd);
686 } /* END OF FUNCTION ConfigureNewState */
690 /*************************************<->*************************************
692 * UnmapClients (pCD, event_mask)
697 * Unmap the window(s). The indicated client may be the head of a transient
698 * tree - if it is unmap all windows in the transient tree.
703 * pCD = pointer to client data of window(s) to be unmapped
704 * event_mask = what to grab to prevent stray events going somewhere. Our
705 * passive grab has just been activated -- but it is dropped when the
706 * window is unmapped and the ButtonRelease event can go to the window
707 * now exposed. Avoid this by grabbing the ButtonRelease before the unmap
709 * Also done for icon being unmapped.
711 *************************************<->***********************************/
713 static void UnmapClients (ClientData *pCD, unsigned int event_mask)
716 Boolean doGrab = False;
718 pNext = pCD->transientChildren;
721 /* unmap all children first */
722 if (pNext->transientChildren)
723 UnmapClients (pNext, (unsigned int) 0);
725 /* then unmap all siblings at this level */
726 XUnmapWindow (DISPLAY, pNext->clientFrameWin);
727 XUnmapWindow (DISPLAY, pNext->client);
728 pNext->wmUnmapCount++;
729 pNext = pNext->transientSiblings;
733 doGrab = (Success == XGrabPointer (DISPLAY, DefaultRootWindow(DISPLAY),
734 False, event_mask, GrabModeAsync, GrabModeAsync,
735 None, None, CurrentTime));
736 /* unmap this primary window */
737 XUnmapWindow (DISPLAY, pCD->clientFrameWin);
738 XUnmapWindow (DISPLAY, pCD->client);
739 if (event_mask && doGrab)
742 XMaskEvent(DISPLAY, event_mask, &event);
743 XUngrabPointer(DISPLAY,CurrentTime);
747 } /* END OF FUNCTION UnmapClients */
751 /*************************************<->*************************************
753 * SetClientWMState (pCD, wmState, mwmState)
758 * Set a new window manage state for a client window or a tree of transient
763 * pCD = pointer to client data
765 * wmState = new state for WM_STATE property
767 * mwmState = mwm client state
769 *************************************<->***********************************/
771 void SetClientWMState (ClientData *pCD, int wmState, int mwmState)
777 bToUnseen = (mwmState & UNSEEN_STATE) != 0;
778 mwmState &= ~UNSEEN_STATE;
782 SetClientWsIndex (pCD);
784 pNext = pCD->transientChildren;
787 if (pNext->transientChildren)
789 SetClientWMState (pNext, wmState, mwmState);
793 SetClientWsIndex (pNext);
795 SetWMState (pNext->client, wmState, ICON_FRAME_WIN(pNext));
796 if (pNext->maxConfig && mwmState == NORMAL_STATE)
798 pNext->clientState = MAXIMIZED_STATE;
801 else if (!pNext->maxConfig && mwmState == MAXIMIZED_STATE)
803 pNext->clientState = NORMAL_STATE;
808 pNext->clientState = mwmState;
812 pNext->clientState |= UNSEEN_STATE;
814 pNext = pNext->transientSiblings;
817 SetWMState (pCD->client, wmState, ICON_FRAME_WIN(pCD));
818 pCD->clientState = mwmState;
821 pCD->clientState |= UNSEEN_STATE;
824 } /* END OF FUNCTION SetClientWMState */
828 #define SLIDE_UP_PERCENTAGE 5
829 #define SLIDE_UP_DIVISOR (100/SLIDE_UP_PERCENTAGE)
830 #define SLIDE_UP_INTERVAL 15
832 /******************************<->*************************************
834 * void SlideOutTimerProc (client_data, id)
838 * An XtTimerCallbackProc to process slide up mapping of a panel
842 * client_data = pointer to a SlideOutRec
850 ******************************<->***********************************/
852 SlideOutTimerProc ( XtPointer client_data, XtIntervalId *id)
854 SlideOutRec *pSOR = (SlideOutRec *) client_data;
855 Boolean bDone = False;
860 * compute next increment;
862 switch (pSOR->direction)
867 pSOR->currY -= pSOR->incHeight;
868 pSOR->currHeight += pSOR->incHeight;
869 if ((pSOR->currY < pSOR->pCD->frameInfo.y) ||
870 (pSOR->currHeight > pSOR->pCD->frameInfo.height))
872 pSOR->currY = pSOR->pCD->frameInfo.y;
873 pSOR->currHeight = pSOR->pCD->frameInfo.height;
875 bDone = (pSOR->currY == pSOR->pCD->frameInfo.y);
879 pSOR->currY += pSOR->incHeight;
880 if (pSOR->incHeight >= pSOR->currHeight)
882 pSOR->currHeight = 0;
887 pSOR->currHeight -= pSOR->incHeight;
895 pSOR->currHeight += pSOR->incHeight;
896 if (pSOR->currHeight > pSOR->pCD->frameInfo.height)
898 pSOR->currHeight = pSOR->pCD->frameInfo.height;
901 (pSOR->currHeight == pSOR->pCD->frameInfo.height);
905 if (pSOR->incHeight >= pSOR->currHeight)
907 pSOR->currHeight = 0;
912 pSOR->currHeight -= pSOR->incHeight;
921 if (pSOR->currHeight > 0)
923 XMoveResizeWindow (DISPLAY, pSOR->coverWin,
924 pSOR->currX, pSOR->currY,
925 pSOR->currWidth, pSOR->currHeight);
927 XMoveResizeWindow (DISPLAY, pSOR->pCD->clientFrameWin,
928 pSOR->currX, pSOR->currY,
929 pSOR->currWidth, pSOR->currHeight);
933 * See if we need to continue
939 /* Time to really unmanage the slide-up */
940 XtUnmanageChild (pSOR->wSubpanel);
944 WmSubpanelPosted (DISPLAY1, pSOR->pCD->client);
945 SendConfigureNotify(pSOR->pCD);
949 XDestroyWindow (DISPLAY, pSOR->coverWin);
950 pSOR->pCD->pSOR = NULL;
951 XtFree ((char *)pSOR);
952 wmGD.iSlideUpsInProgress -= 1;
956 /* re-arm the timer */
957 XtAppAddTimeOut(wmGD.mwmAppContext, pSOR->interval,
958 SlideOutTimerProc, (XtPointer)pSOR);
959 XSync (DISPLAY, False);
963 } /* END OF FUNCTION SlideOutTimerProc */
967 /*************************************<->*************************************
969 * SlideWindowOut (pCD)
974 * Maps a window with a slide-out effect.
979 * pCD = pointer to client data
983 * Only supports slide-up or slide-down
985 *************************************<->***********************************/
988 SlideWindowOut (ClientData *pCD)
997 * Hmmm. We're already sliding this window.
998 * If we're supposed to go in the other direction,
999 * then turn it around.
1001 if (pSOR->mapping == True)
1004 * We're already mapping this guy, ignore this
1005 * and finish what we've already got going.
1012 * We're not mapping this guy. Reverse course!!
1014 pSOR->mapping = True;
1016 /* insure the client window is mapped */
1017 XMapWindow (DISPLAY, pCD->client);
1019 /* handle the rest on the next timeout */
1024 /* map the primary window */
1025 XMapWindow (DISPLAY, pCD->client);
1026 pSOR = (SlideOutRec *) XtMalloc (sizeof(SlideOutRec));
1030 * Compute this ahead of time so we can check against
1031 * the window size. If the window is short, we'll
1032 * just map it, avoiding a lot of processing.
1034 pSOR->incHeight = (Dimension) (DisplayHeight(DISPLAY,
1035 SCREEN_FOR_CLIENT(pCD))/SLIDE_UP_DIVISOR);
1038 if ((pCD->slideDirection != SLIDE_NOT) && pSOR &&
1039 (pSOR->incHeight < pCD->frameInfo.height))
1041 XSetWindowAttributes window_attribs;
1042 XWindowChanges window_changes;
1046 * Set up data for processing slide up
1049 pSOR->interval = SLIDE_UP_INTERVAL;
1050 pSOR->direction = pCD->slideDirection;
1051 pSOR->mapping = True;
1052 pSOR->wSubpanel = NULL;
1053 pSOR->pCD->pSOR = pSOR;
1055 switch (pSOR->direction)
1059 pSOR->currWidth = pCD->frameInfo.width;
1060 pSOR->currHeight = pSOR->incHeight;
1061 pSOR->currX = pCD->frameInfo.x;
1062 pSOR->currY = pCD->frameInfo.y +
1063 (pCD->frameInfo.height - pSOR->currHeight);
1068 pSOR->currWidth = pCD->frameInfo.width;
1069 pSOR->currHeight = pSOR->incHeight;
1070 pSOR->currX = pCD->frameInfo.x;
1071 pSOR->currY = pCD->frameInfo.y;
1076 * Create screening window to hide the slide-up from button
1077 * events until it is all the way up.
1079 mask = CWOverrideRedirect;
1080 window_attribs.override_redirect = True;
1081 pSOR->coverWin = XCreateWindow(DISPLAY,
1082 RootWindow (DISPLAY, SCREEN_FOR_CLIENT(pCD)),
1083 pSOR->currX, pSOR->currY,
1084 pSOR->currWidth, pSOR->currHeight, 0,
1085 CopyFromParent,InputOnly,CopyFromParent,
1086 mask, &window_attribs);
1089 * Put screen window above the slide-up client
1091 mask = CWStackMode | CWSibling;
1092 window_changes.stack_mode = Above;
1093 window_changes.sibling = pCD->clientFrameWin;
1094 XConfigureWindow (DISPLAY, pSOR->coverWin, mask, &window_changes);
1097 * Start slide-up processing
1099 XMoveResizeWindow (DISPLAY, pSOR->coverWin, pSOR->currX, pSOR->currY,
1100 pSOR->currWidth, pSOR->currHeight);
1101 XMoveResizeWindow (DISPLAY, pCD->clientFrameWin,
1102 pSOR->currX, pSOR->currY, pSOR->currWidth, pSOR->currHeight);
1103 XMapWindow (DISPLAY, pSOR->coverWin);
1104 XMapWindow (DISPLAY, pCD->clientFrameWin);
1105 XSync (DISPLAY, False);
1107 XtAppAddTimeOut(wmGD.mwmAppContext, pSOR->interval,
1108 SlideOutTimerProc, (XtPointer)pSOR);
1110 wmGD.iSlideUpsInProgress += 1;
1116 * Not sliding because no direction specified or our window
1117 * is just a little guy.
1119 XMapWindow (DISPLAY, pCD->clientFrameWin);
1122 XtFree ((char *) pSOR);
1127 } /* END OF FUNCTION SlideOutWindow */
1131 /*************************************<->*************************************
1133 * SlideSubpanelBackIn (pCD, wSubpanel)
1138 * Slides a subpanel back in
1143 * pCD = pointer to client data
1144 * wSubpanel = subpanel widget to unmanage
1149 *************************************<->***********************************/
1152 SlideSubpanelBackIn (ClientData *pCD, Widget wSubpanel)
1161 * Hmmm. We're already sliding this window.
1162 * If we're supposed to go in the other direction,
1163 * then turn it around.
1165 if (pSOR->mapping == False)
1168 * We're already unmapping this guy, ignore this
1169 * and finish what we've already got going.
1176 * We're mapping this guy. Reverse course!!
1178 pSOR->mapping = False;
1179 pSOR->wSubpanel = wSubpanel;
1181 /* handle the rest on the next timeout */
1186 pSOR = (SlideOutRec *) XtMalloc (sizeof(SlideOutRec));
1190 * Compute this ahead of time to check if our window
1191 * is short. If it is, we'll just unmap it, avoiding
1192 * a lot of extra work.
1194 pSOR->incHeight = (Dimension) (DisplayHeight(DISPLAY,
1195 SCREEN_FOR_CLIENT(pCD))/SLIDE_UP_DIVISOR);
1198 if ((pCD->slideDirection != SLIDE_NOT) && pSOR &&
1199 (pSOR->incHeight < pCD->frameInfo.height))
1201 XSetWindowAttributes window_attribs;
1202 XWindowChanges window_changes;
1206 * Set up data for processing slide up
1209 pSOR->interval = SLIDE_UP_INTERVAL;
1210 pSOR->direction = pCD->slideDirection;
1211 pSOR->mapping = False;
1212 pSOR->wSubpanel = wSubpanel;
1213 pSOR->pCD->pSOR = pSOR;
1216 pSOR->currWidth = pCD->frameInfo.width;
1217 pSOR->currHeight = pCD->frameInfo.height;
1218 pSOR->currX = pCD->frameInfo.x;
1219 pSOR->currY = pCD->frameInfo.y;
1221 switch (pSOR->direction)
1224 pSOR->currHeight -= pSOR->incHeight;
1225 pSOR->currY += pSOR->incHeight;
1229 pSOR->currHeight -= pSOR->incHeight;
1234 * Create screening window to hide the slide-up from button
1235 * events until it is all the way up.
1237 mask = CWOverrideRedirect;
1238 window_attribs.override_redirect = True;
1239 pSOR->coverWin = XCreateWindow(DISPLAY,
1240 RootWindow (DISPLAY, SCREEN_FOR_CLIENT(pCD)),
1241 pSOR->currX, pSOR->currY,
1242 pSOR->currWidth, pSOR->currHeight, 0,
1243 CopyFromParent,InputOnly,CopyFromParent,
1244 mask, &window_attribs);
1247 * Put screen window above the slide-up client
1249 mask = CWStackMode | CWSibling;
1250 window_changes.stack_mode = Above;
1251 window_changes.sibling = pCD->clientFrameWin;
1252 XConfigureWindow (DISPLAY, pSOR->coverWin, mask, &window_changes);
1255 * Start slide-up processing
1257 XMapWindow (DISPLAY, pSOR->coverWin);
1259 if (pSOR->currHeight > 0)
1261 XMoveResizeWindow (DISPLAY, pCD->clientFrameWin,
1262 pSOR->currX, pSOR->currY,
1263 pSOR->currWidth, pSOR->currHeight);
1265 XMoveResizeWindow (DISPLAY, pSOR->coverWin,
1266 pSOR->currX, pSOR->currY,
1267 pSOR->currWidth, pSOR->currHeight);
1269 XSync (DISPLAY, False);
1272 XtAppAddTimeOut(wmGD.mwmAppContext, pSOR->interval,
1273 SlideOutTimerProc, (XtPointer)pSOR);
1275 wmGD.iSlideUpsInProgress += 1;
1281 * Not sliding because no direction specified or our window
1282 * is just a little guy.
1284 /* Just unmanage the slide-up */
1285 XtUnmanageChild (wSubpanel);
1288 XtFree ((char *) pSOR);
1293 } /* END OF FUNCTION SlideOutWindow */
1294 #endif /* PANELIST */
1297 /*************************************<->*************************************
1299 * MapClientWindows (pCD)
1304 * Maps the window. If this is a transient tree then all the windows in
1305 * the transient tree are mapped.
1310 * pCD = pointer to client data
1312 *************************************<->***********************************/
1314 void MapClientWindows (ClientData *pCD)
1319 pNext = pCD->transientChildren;
1322 /* map all transient children first */
1323 if (pNext->transientChildren)
1325 MapClientWindows (pNext);
1328 /* then map all siblings at this level */
1329 XMapWindow (DISPLAY, pNext->client);
1330 XMapWindow (DISPLAY, pNext->clientFrameWin);
1332 pNext = pNext->transientSiblings;
1335 /* map the primary window */
1336 XMapWindow (DISPLAY, pCD->client);
1337 XMapWindow (DISPLAY, pCD->clientFrameWin);
1339 } /* END OF FUNCTION MapClientWindows */
1343 /*************************************<->*************************************
1345 * ShowIconForMinimizedClient (pWS, pCD)
1350 * This function shows the icon for the specified client. If the icon
1351 * is in an icon box then the "minimized" icon is displayed. If the icon
1352 * is on the root window it is mapped.
1357 * pWS = pointer to workspace data
1358 * pCD = pointer to client data
1360 *************************************<->***********************************/
1362 void ShowIconForMinimizedClient (WmWorkspaceData *pWS, ClientData *pCD)
1364 WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
1367 * Handle auto-placement for root icons (icons not in an icon
1370 if (wmGD.iconAutoPlace && !P_ICON_BOX(pCD))
1372 if ((ICON_PLACE(pCD) == NO_ICON_PLACE) ||
1373 ((pWS->IPData.placeList[ICON_PLACE(pCD)].pCD) &&
1374 (pWS->IPData.placeList[ICON_PLACE(pCD)].pCD != pCD)))
1377 * Icon place not defined or occupied by another client,
1378 * find a free place to put the icon.
1381 if ((ICON_PLACE(pCD) = GetNextIconPlace (&pWS->IPData))
1385 CvtIconPositionToPlace (&pWS->IPData,
1389 CvtIconPlaceToPosition (&pWS->IPData, ICON_PLACE(pCD),
1390 &ICON_X(pCD), &ICON_Y(pCD));
1393 XMoveWindow (DISPLAY, ICON_FRAME_WIN(pCD),
1394 ICON_X(pCD), ICON_Y(pCD));
1399 pWS->IPData.placeList[ICON_PLACE(pCD)].pCD = pCD;
1404 * If icon on root window and this workspace is active, the
1405 * make sure it's in the right place.
1407 if ((pWS == pSD->pActiveWS) && !P_ICON_BOX(pCD))
1409 XMoveWindow (DISPLAY, ICON_FRAME_WIN(pCD),
1410 ICON_X(pCD), ICON_Y(pCD));
1413 if (pCD->iconWindow)
1415 XMapWindow (DISPLAY, pCD->iconWindow);
1418 if ((pSD->useIconBox) && P_ICON_BOX(pCD))
1420 ShowClientIconState (pCD, MINIMIZED_STATE );
1424 XWindowChanges windowChanges;
1427 * Map the icon on the screen at the appropriate place in the
1431 if (wmGD.lowerOnIconify)
1433 if ((&pCD->iconEntry != pSD->lastClient) &&
1436 if (pSD->lastClient->type == MINIMIZED_STATE)
1438 windowChanges.sibling =
1439 ICON_FRAME_WIN(pSD->lastClient->pCD);
1443 windowChanges.sibling =
1444 pSD->lastClient->pCD->clientFrameWin;
1446 windowChanges.stack_mode = Below;
1447 XConfigureWindow (DISPLAY, ICON_FRAME_WIN(pCD),
1448 (CWSibling | CWStackMode), &windowChanges);
1449 MoveEntryInList (pWS, &pCD->iconEntry,
1450 False /*on bottom*/, NULL);
1455 windowChanges.sibling = pCD->clientFrameWin;
1456 windowChanges.stack_mode = Below;
1457 XConfigureWindow (DISPLAY, ICON_FRAME_WIN(pCD),
1458 (CWSibling | CWStackMode), &windowChanges);
1459 MoveEntryInList (pWS, &pCD->iconEntry, False /*below*/,
1464 if (pWS == pSD->pActiveWS)
1466 XMapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
1469 XMapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
1473 } /* END OF FUNCTION ShowIconForMinimizedClient */
1477 /*************************************<->*************************************
1479 * ShowAllIconsForMinimizedClient (pCD)
1484 * This function places icons in all the workspaces for the minimized
1485 * client. Since there is only one clientState per client (not per
1486 * workspace), this loops over all workspace in which the client
1487 * resides and places an icon in each.
1492 * pCD = pointer to client data
1496 * This operates by setting up the currentWsc index for each workspace
1497 * and calling ShowIconForMinimizedClient, which makes heavy use of
1498 * the macros that use the currentWsc index.
1500 *************************************<->***********************************/
1502 void ShowAllIconsForMinimizedClient (ClientData *pCD)
1504 int saveWsc = pCD->currentWsc;
1506 WmWorkspaceData *pWS;
1508 for (tmpWsc = 0; tmpWsc < pCD->numInhabited; tmpWsc++)
1510 pCD->currentWsc = tmpWsc;
1511 pWS = GetWorkspaceData (PSD_FOR_CLIENT(pCD),
1512 pCD->pWsList[tmpWsc].wsID);
1513 ShowIconForMinimizedClient(pWS, pCD);
1516 pCD->currentWsc = saveWsc;
1518 } /* END OF FUNCTION ShowAllIconsForMinimizedClient */