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"
48 * include extern functions
52 #include "WmFunction.h"
55 #include "WmIconBox.h"
56 #include "WmKeyFocus.h"
58 #include "WmPanelP.h" /* for typedef in WmManage.h */
61 #include "WmProperty.h"
62 #include "WmWinInfo.h"
63 #include "WmWinList.h"
65 #include "WmWrkspace.h"
70 * Function Declarations:
73 #include "WmWinState.h"
75 static void SlideWindowOut (ClientData *pCD);
77 static void UnmapClients (ClientData *pCD, unsigned int event_mask);
78 static void SetupWindowStateWithEventMask (ClientData *pCD, int newState, Time setTime, unsigned int event_mask);
88 /******************************<->*************************************
90 * SetClientState (pCD, newState, setTime)
95 * This function is used to change the state of a client window (between
96 * withdrawn, normal, minimized, maximized).
101 * pCD = This is a pointer to the window data for the window that
102 * is to have its state changed. The fields that are used
103 * are clientState, ...
105 * newState = This is the state that the client window is to be changed to.
107 * setTime = timestamp for state setting operations
112 * pCD.clientState = new client state
114 ******************************<->***********************************/
116 void SetClientState (ClientData *pCD, int newState, Time setTime)
118 SetClientStateWithEventMask(pCD, newState, setTime, (unsigned int)0);
119 } /* END OF FUNCTION SetClientState */
121 void SetClientStateWithEventMask (ClientData *pCD, int newState, Time setTime, unsigned int event_mask)
123 ClientData *pcdLeader;
125 WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
127 Boolean notShowing = (newState & UNSEEN_STATE);
130 currentState = pCD->clientState;
131 if (currentState == newState)
133 /* no change in state */
139 * Undo the old state and setup the new state. If this is a transient
140 * window then insure that it is put in a state that is compatible
141 * with its transient leader (e.g., it cannot be minimized separately).
144 pcdLeader = (pCD->transientLeader) ? FindTransientTreeLeader (pCD) : pCD;
146 SetClientWsIndex (pCD);
149 if (pCD->transientLeader)
151 if ((pcdLeader->clientState == MINIMIZED_STATE) &&
152 (newState != WITHDRAWN_STATE))
154 newState = MINIMIZED_STATE;
158 newState |= UNSEEN_STATE;
162 else if ((newState == MINIMIZED_STATE) &&
163 (pcdLeader->clientState != MINIMIZED_STATE))
165 if (currentState == WITHDRAWN_STATE)
167 newState = NORMAL_STATE;
171 newState |= UNSEEN_STATE;
177 newState = currentState;
181 newState |= UNSEEN_STATE;
186 if (newState == currentState)
196 case UNSEEN_STATE | WITHDRAWN_STATE:
198 case WITHDRAWN_STATE:
202 * Free window manager resources (frame and icon). The
203 * WM_STATE property is set in WithdrawWindow.
206 UnManageWindow (pCD);
211 case MAXIMIZED_STATE:
213 SetupWindowStateWithEventMask (pCD, newState, setTime, event_mask);
215 XMapWindow (DISPLAY, pCD->client);
216 XMapWindow (DISPLAY, pCD->clientFrameWin);
217 #if defined(PANELIST)
218 WmStopWaiting(); /* in WmIPC.c */
219 #endif /* PANELIST */
224 case MINIMIZED_STATE:
226 Boolean clientHasFocus;
229 * Transient windows are minimized with the rest of the transient
230 * tree, including the transient leader.
233 if ((pCD->clientState == NORMAL_STATE) ||
234 (pCD->clientState == MAXIMIZED_STATE))
236 if ((wmGD.keyboardFocus == pCD) ||
237 (pCD->transientChildren && wmGD.keyboardFocus &&
238 (pCD == FindTransientTreeLeader (wmGD.keyboardFocus))))
240 clientHasFocus = True;
244 clientHasFocus = False;
247 if (clientHasFocus ||
248 ((wmGD.nextKeyboardFocus == pCD) ||
249 (pCD->transientChildren && wmGD.keyboardFocus &&
250 (pCD == FindTransientTreeLeader (wmGD.nextKeyboardFocus)))))
253 * Give up the keyboard focus when minimized (including
254 * the case in which an associated transient window has
255 * the focus). Immediately remove the focus indication
256 * from the window being minimized.
259 if (wmGD.autoKeyFocus &&
260 (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT))
262 AutoResetKeyFocus (pcdLeader, setTime);
266 Do_Focus_Key (NULL, setTime,
267 ALWAYS_SET_FOCUS | WORKSPACE_IF_NULL);
272 SetKeyboardFocus (NULL, 0);
276 /* unmap main client and all transients */
277 UnmapClients (pCD, event_mask);
281 * Display the icon for the minimized client.
284 if (ICON_FRAME_WIN(pCD))
287 if (pCD->clientState & UNSEEN_STATE)
291 XMapWindow (DISPLAY, pCD->iconWindow);
293 XMapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
296 ShowAllIconsForMinimizedClient (pCD);
298 ShowIconForMinimizedClient (pSD->pActiveWS, pCD);
302 SetClientWMState (pCD, IconicState, MINIMIZED_STATE);
304 if ((pSD->useIconBox) && P_ICON_BOX(pCD))
306 if ((pCD->clientFlags & ICON_BOX) && ACTIVE_ICON_TEXT_WIN)
309 * Hide active icon text window and reparent it to
312 HideActiveIconText((WmScreenData *)NULL);
313 pSD->activeLabelParent = ACTIVE_ROOT;
314 XReparentWindow(DISPLAY, ACTIVE_ICON_TEXT_WIN ,
317 if (ICON_FRAME_WIN(pCD))
320 * force icon appearance in icon box to change
322 IconExposureProc (pCD, True);
330 case UNSEEN_STATE | NORMAL_STATE:
331 case UNSEEN_STATE | MAXIMIZED_STATE:
332 case UNSEEN_STATE | MINIMIZED_STATE:
334 if (wmGD.keyboardFocus == pCD)
337 * Give up the keyboard focus
339 Do_Focus_Key ((ClientData *)NULL,
340 CurrentTime, ALWAYS_SET_FOCUS);
341 SetKeyboardFocus (NULL, 0);
344 if (!(pCD->clientState & UNSEEN_STATE) &&
345 (((pCD->clientState & ~UNSEEN_STATE) == NORMAL_STATE) ||
346 ((pCD->clientState & ~UNSEEN_STATE) == MAXIMIZED_STATE)))
348 /* unmap main client and all transients */
349 UnmapClients (pcdLeader, event_mask);
353 if (pCD->clientFrameWin)
355 if (!P_ICON_BOX(pCD))
357 if (ICON_FRAME_WIN(pCD))
359 XUnmapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
362 XUnmapWindow (DISPLAY, pCD->iconWindow);
366 switch (newState & ~UNSEEN_STATE)
368 case MINIMIZED_STATE:
369 SetClientWMState (pCD, IconicState, newState);
373 case MAXIMIZED_STATE:
375 SetClientWMState (pCD, NormalState, newState);
383 } /* END OF FUNCTION SetClientStateWithEventMask */
387 /*************************************<->*************************************
389 * SetupWindowStateWithEventMask (pCD, newState, setTime, event_mask)
394 * This function is used to setup a client window in the Normal or Maximized
400 * pCD = This is a pointer to the window data for the window that
401 * is to have its state changed.
403 * newState = This is the state that the client window is to be changed to.
405 * setTime = timestamp for state setting operations
407 * event_mask = what to grab to prevent stray events going somewhere
411 * pCD.clientState = new client state
413 *************************************<->***********************************/
415 static void SetupWindowStateWithEventMask (ClientData *pCD, int newState,
416 Time setTime, unsigned int event_mask)
421 WmWorkspaceData *pWS_i;
423 WmWorkspaceData *pWS = PSD_FOR_CLIENT(pCD)->pActiveWS;
425 WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
427 currentState = pCD->clientState;
430 * A transient window is not restored or maximized if the transient leader
434 if (newState == NORMAL_STATE)
436 if (pCD->maxConfig == True)
439 * The configuration function uses maxConfig to determine
440 * what the current configuration is (and then resets
441 * maxConfig) and uses the state paramenter to determine
442 * what the new configuration is.
445 ConfigureNewState (pCD);
448 else /* MAXIMIZED_STATE */
450 if (pCD->maxConfig == False)
452 ConfigureNewState (pCD);
456 if (currentState == MINIMIZED_STATE)
458 Boolean clearIconFocus;
461 * give up keyboard focus
464 if ((wmGD.keyboardFocus == pCD) ||
465 (wmGD.nextKeyboardFocus == pCD))
467 Do_Focus_Key (NULL, setTime, ALWAYS_SET_FOCUS | WORKSPACE_IF_NULL);
470 if (wmGD.keyboardFocus == pCD)
472 clearIconFocus = True;
476 clearIconFocus = False;
480 * The wm icon frame window and the client icon window
481 * (if it is being used) are mapped and the client window and
482 * client frame are unmapped.
485 if (ICON_FRAME_WIN(pCD))
487 if (pSD->useIconBox && P_ICON_BOX(pCD) &&
488 !(pCD->clientFlags & ICON_BOX))
490 ShowClientIconState(pCD, newState);
494 Boolean doGrab = False;
496 doGrab = (Success == XGrabPointer
497 (DISPLAY, DefaultRootWindow(DISPLAY),
498 False, event_mask, GrabModeAsync, GrabModeAsync,
499 None, None, CurrentTime));
500 XUnmapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
503 XUnmapWindow (DISPLAY, pCD->iconWindow);
505 if (event_mask && doGrab)
508 XMaskEvent(DISPLAY, event_mask, &event);
509 XUngrabPointer(DISPLAY,CurrentTime);
512 if (wmGD.iconAutoPlace)
514 for (wsI = 0; wsI < pCD->numInhabited; wsI++)
516 iplace = pCD->pWsList[wsI].iconPlace;
517 if (iplace != NO_ICON_PLACE)
519 pWS_i = GetWorkspaceData (pCD->pSD,
520 pCD->pWsList[wsI].wsID);
521 pWS_i->IPData.placeList[iplace].pCD =
527 if ((wmGD.iconAutoPlace) && (ICON_PLACE(pCD) != NO_ICON_PLACE))
529 pWS->IPData.placeList[ICON_PLACE(pCD)].pCD =
537 ClearFocusIndication (pCD, False /*no refresh*/);
538 wmGD.keyboardFocus = NULL;
542 if ((currentState != NORMAL_STATE) && (currentState != MAXIMIZED_STATE))
545 * Note that maximized state is considered a NormalState in
546 * the ICCC. SetClientWMState also sets the state in the
550 if (currentState == MINIMIZED_STATE)
553 * Raise the window(s) when they are deiconified.
556 pCD->clientState = newState;
558 wmGD.bSuspendSecondaryRestack = True;
560 F_Raise (NULL, pCD, NULL);
562 wmGD.bSuspendSecondaryRestack = False;
566 if ( (!(pCD->clientFlags & ICON_BOX)) ||
567 ((pCD->clientFlags & ICON_BOX) && (!(firstTime))) )
570 if ((currentState == WITHDRAWN_STATE) &&
571 (pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUBPANEL) &&
572 !(pCD->transientChildren))
574 if (pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUB_RESTORED)
576 pCD->dtwmBehaviors &= ~DtWM_BEHAVIOR_SUB_RESTORED;
577 pCD->dtwmBehaviors &= ~DtWM_BEHAVIOR_SUBPANEL;
578 XMapWindow (DISPLAY, pCD->client);
579 XMapWindow (DISPLAY, pCD->clientFrameWin);
583 SlideWindowOut (pCD);
587 #endif /* PANELIST */
588 MapClientWindows (pCD);
593 * Set the WM_STATE property of the window and any associated
594 * transients, along with the clientState value. The call
595 * is made with an indication of NORMAL_STATE to insure
596 * that transient window clientState values are setup
597 * correctly. The top-level window clientState is set later.
600 SetClientWMState (pCD, NormalState, NORMAL_STATE);
602 pCD->clientState = newState;
604 if ((wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT) &&
605 (currentState == MINIMIZED_STATE) && wmGD.deiconifyKeyFocus)
607 ClientData *pcdFocus;
609 pcdFocus = FindTransientFocus (pCD);
612 Do_Focus_Key (pcdFocus, setTime, ALWAYS_SET_FOCUS);
616 if ( pSD->useIconBox && P_ICON_BOX(pCD) &&
617 (!(pCD->clientFlags & ICON_BOX)) && (ICON_FRAME_WIN(pCD)))
620 * force icon appearance in icon box to change
623 IconExposureProc (pCD, True);
626 } /* END OF FUNCTION SetupWindowStateWithEventMask */
631 /*************************************<->*************************************
633 * ConfigureNewState (pcd)
638 * Configure the window to a new state
643 * pcd - pointer to client data
651 * o This is only good for going between NORMAL and MAXIMIZED state.
653 *************************************<->***********************************/
655 void ConfigureNewState (ClientData *pcd)
659 pcd->maxConfig = FALSE;
660 RegenerateClientFrame(pcd);
661 XResizeWindow (DISPLAY, pcd->client,
662 (unsigned int) pcd->clientWidth,
663 (unsigned int) pcd->clientHeight);
667 XResizeWindow (DISPLAY, pcd->client,
668 (unsigned int) pcd->maxWidth,
669 (unsigned int) pcd->maxHeight);
670 pcd->maxConfig = TRUE;
671 RegenerateClientFrame(pcd);
673 SendConfigureNotify (pcd);
676 * Force repaint if size doesn't change to update frame appearance.
679 if ((pcd->clientWidth == pcd->maxWidth) &&
680 (pcd->clientHeight == pcd->maxHeight))
682 FrameExposureProc (pcd);
685 } /* END OF FUNCTION ConfigureNewState */
689 /*************************************<->*************************************
691 * UnmapClients (pCD, event_mask)
696 * Unmap the window(s). The indicated client may be the head of a transient
697 * tree - if it is unmap all windows in the transient tree.
702 * pCD = pointer to client data of window(s) to be unmapped
703 * event_mask = what to grab to prevent stray events going somewhere. Our
704 * passive grab has just been activated -- but it is dropped when the
705 * window is unmapped and the ButtonRelease event can go to the window
706 * now exposed. Avoid this by grabbing the ButtonRelease before the unmap
708 * Also done for icon being unmapped.
710 *************************************<->***********************************/
712 static void UnmapClients (ClientData *pCD, unsigned int event_mask)
715 Boolean doGrab = False;
717 pNext = pCD->transientChildren;
720 /* unmap all children first */
721 if (pNext->transientChildren)
722 UnmapClients (pNext, (unsigned int) 0);
724 /* then unmap all siblings at this level */
725 XUnmapWindow (DISPLAY, pNext->clientFrameWin);
726 XUnmapWindow (DISPLAY, pNext->client);
727 pNext->wmUnmapCount++;
728 pNext = pNext->transientSiblings;
732 doGrab = (Success == XGrabPointer (DISPLAY, DefaultRootWindow(DISPLAY),
733 False, event_mask, GrabModeAsync, GrabModeAsync,
734 None, None, CurrentTime));
735 /* unmap this primary window */
736 XUnmapWindow (DISPLAY, pCD->clientFrameWin);
737 XUnmapWindow (DISPLAY, pCD->client);
738 if (event_mask && doGrab)
741 XMaskEvent(DISPLAY, event_mask, &event);
742 XUngrabPointer(DISPLAY,CurrentTime);
746 } /* END OF FUNCTION UnmapClients */
750 /*************************************<->*************************************
752 * SetClientWMState (pCD, wmState, mwmState)
757 * Set a new window manage state for a client window or a tree of transient
762 * pCD = pointer to client data
764 * wmState = new state for WM_STATE property
766 * mwmState = mwm client state
768 *************************************<->***********************************/
770 void SetClientWMState (ClientData *pCD, int wmState, int mwmState)
776 bToUnseen = (mwmState & UNSEEN_STATE) != 0;
777 mwmState &= ~UNSEEN_STATE;
781 SetClientWsIndex (pCD);
783 pNext = pCD->transientChildren;
786 if (pNext->transientChildren)
788 SetClientWMState (pNext, wmState, mwmState);
792 SetClientWsIndex (pNext);
794 SetWMState (pNext->client, wmState, ICON_FRAME_WIN(pNext));
795 if (pNext->maxConfig && mwmState == NORMAL_STATE)
797 pNext->clientState = MAXIMIZED_STATE;
800 else if (!pNext->maxConfig && mwmState == MAXIMIZED_STATE)
802 pNext->clientState = NORMAL_STATE;
807 pNext->clientState = mwmState;
811 pNext->clientState |= UNSEEN_STATE;
813 pNext = pNext->transientSiblings;
816 SetWMState (pCD->client, wmState, ICON_FRAME_WIN(pCD));
817 pCD->clientState = mwmState;
820 pCD->clientState |= UNSEEN_STATE;
823 } /* END OF FUNCTION SetClientWMState */
827 #define SLIDE_UP_PERCENTAGE 5
828 #define SLIDE_UP_DIVISOR (100/SLIDE_UP_PERCENTAGE)
829 #define SLIDE_UP_INTERVAL 15
831 /******************************<->*************************************
833 * void SlideOutTimerProc (client_data, id)
837 * An XtTimerCallbackProc to process slide up mapping of a panel
841 * client_data = pointer to a SlideOutRec
849 ******************************<->***********************************/
851 SlideOutTimerProc ( XtPointer client_data, XtIntervalId *id)
853 SlideOutRec *pSOR = (SlideOutRec *) client_data;
854 Boolean bDone = False;
859 * compute next increment;
861 switch (pSOR->direction)
866 pSOR->currY -= pSOR->incHeight;
867 pSOR->currHeight += pSOR->incHeight;
868 if ((pSOR->currY < pSOR->pCD->frameInfo.y) ||
869 (pSOR->currHeight > pSOR->pCD->frameInfo.height))
871 pSOR->currY = pSOR->pCD->frameInfo.y;
872 pSOR->currHeight = pSOR->pCD->frameInfo.height;
874 bDone = (pSOR->currY == pSOR->pCD->frameInfo.y);
878 pSOR->currY += pSOR->incHeight;
879 if (pSOR->incHeight >= pSOR->currHeight)
881 pSOR->currHeight = 0;
886 pSOR->currHeight -= pSOR->incHeight;
894 pSOR->currHeight += pSOR->incHeight;
895 if (pSOR->currHeight > pSOR->pCD->frameInfo.height)
897 pSOR->currHeight = pSOR->pCD->frameInfo.height;
900 (pSOR->currHeight == pSOR->pCD->frameInfo.height);
904 if (pSOR->incHeight >= pSOR->currHeight)
906 pSOR->currHeight = 0;
911 pSOR->currHeight -= pSOR->incHeight;
920 if (pSOR->currHeight > 0)
922 XMoveResizeWindow (DISPLAY, pSOR->coverWin,
923 pSOR->currX, pSOR->currY,
924 pSOR->currWidth, pSOR->currHeight);
926 XMoveResizeWindow (DISPLAY, pSOR->pCD->clientFrameWin,
927 pSOR->currX, pSOR->currY,
928 pSOR->currWidth, pSOR->currHeight);
932 * See if we need to continue
938 /* Time to really unmanage the slide-up */
939 XtUnmanageChild (pSOR->wSubpanel);
943 WmSubpanelPosted (DISPLAY1, pSOR->pCD->client);
944 SendConfigureNotify(pSOR->pCD);
948 XDestroyWindow (DISPLAY, pSOR->coverWin);
949 pSOR->pCD->pSOR = NULL;
950 XtFree ((char *)pSOR);
951 wmGD.iSlideUpsInProgress -= 1;
955 /* re-arm the timer */
956 XtAppAddTimeOut(wmGD.mwmAppContext, pSOR->interval,
957 SlideOutTimerProc, (XtPointer)pSOR);
958 XSync (DISPLAY, False);
962 } /* END OF FUNCTION SlideOutTimerProc */
966 /*************************************<->*************************************
968 * SlideWindowOut (pCD)
973 * Maps a window with a slide-out effect.
978 * pCD = pointer to client data
982 * Only supports slide-up or slide-down
984 *************************************<->***********************************/
987 SlideWindowOut (ClientData *pCD)
996 * Hmmm. We're already sliding this window.
997 * If we're supposed to go in the other direction,
998 * then turn it around.
1000 if (pSOR->mapping == True)
1003 * We're already mapping this guy, ignore this
1004 * and finish what we've already got going.
1011 * We're not mapping this guy. Reverse course!!
1013 pSOR->mapping = True;
1015 /* insure the client window is mapped */
1016 XMapWindow (DISPLAY, pCD->client);
1018 /* handle the rest on the next timeout */
1023 /* map the primary window */
1024 XMapWindow (DISPLAY, pCD->client);
1025 pSOR = (SlideOutRec *) XtMalloc (sizeof(SlideOutRec));
1029 * Compute this ahead of time so we can check against
1030 * the window size. If the window is short, we'll
1031 * just map it, avoiding a lot of processing.
1033 pSOR->incHeight = (Dimension) (DisplayHeight(DISPLAY,
1034 SCREEN_FOR_CLIENT(pCD))/SLIDE_UP_DIVISOR);
1037 if ((pCD->slideDirection != SLIDE_NOT) && pSOR &&
1038 (pSOR->incHeight < pCD->frameInfo.height))
1040 XSetWindowAttributes window_attribs;
1041 XWindowChanges window_changes;
1045 * Set up data for processing slide up
1048 pSOR->interval = SLIDE_UP_INTERVAL;
1049 pSOR->direction = pCD->slideDirection;
1050 pSOR->mapping = True;
1051 pSOR->wSubpanel = NULL;
1052 pSOR->pCD->pSOR = pSOR;
1054 switch (pSOR->direction)
1058 pSOR->currWidth = pCD->frameInfo.width;
1059 pSOR->currHeight = pSOR->incHeight;
1060 pSOR->currX = pCD->frameInfo.x;
1061 pSOR->currY = pCD->frameInfo.y +
1062 (pCD->frameInfo.height - pSOR->currHeight);
1067 pSOR->currWidth = pCD->frameInfo.width;
1068 pSOR->currHeight = pSOR->incHeight;
1069 pSOR->currX = pCD->frameInfo.x;
1070 pSOR->currY = pCD->frameInfo.y;
1075 * Create screening window to hide the slide-up from button
1076 * events until it is all the way up.
1078 mask = CWOverrideRedirect;
1079 window_attribs.override_redirect = True;
1080 pSOR->coverWin = XCreateWindow(DISPLAY,
1081 RootWindow (DISPLAY, SCREEN_FOR_CLIENT(pCD)),
1082 pSOR->currX, pSOR->currY,
1083 pSOR->currWidth, pSOR->currHeight, 0,
1084 CopyFromParent,InputOnly,CopyFromParent,
1085 mask, &window_attribs);
1088 * Put screen window above the slide-up client
1090 mask = CWStackMode | CWSibling;
1091 window_changes.stack_mode = Above;
1092 window_changes.sibling = pCD->clientFrameWin;
1093 XConfigureWindow (DISPLAY, pSOR->coverWin, mask, &window_changes);
1096 * Start slide-up processing
1098 XMoveResizeWindow (DISPLAY, pSOR->coverWin, pSOR->currX, pSOR->currY,
1099 pSOR->currWidth, pSOR->currHeight);
1100 XMoveResizeWindow (DISPLAY, pCD->clientFrameWin,
1101 pSOR->currX, pSOR->currY, pSOR->currWidth, pSOR->currHeight);
1102 XMapWindow (DISPLAY, pSOR->coverWin);
1103 XMapWindow (DISPLAY, pCD->clientFrameWin);
1104 XSync (DISPLAY, False);
1106 XtAppAddTimeOut(wmGD.mwmAppContext, pSOR->interval,
1107 SlideOutTimerProc, (XtPointer)pSOR);
1109 wmGD.iSlideUpsInProgress += 1;
1115 * Not sliding because no direction specified or our window
1116 * is just a little guy.
1118 XMapWindow (DISPLAY, pCD->clientFrameWin);
1121 XtFree ((char *) pSOR);
1126 } /* END OF FUNCTION SlideOutWindow */
1130 /*************************************<->*************************************
1132 * SlideSubpanelBackIn (pCD, wSubpanel)
1137 * Slides a subpanel back in
1142 * pCD = pointer to client data
1143 * wSubpanel = subpanel widget to unmanage
1148 *************************************<->***********************************/
1151 SlideSubpanelBackIn (ClientData *pCD, Widget wSubpanel)
1160 * Hmmm. We're already sliding this window.
1161 * If we're supposed to go in the other direction,
1162 * then turn it around.
1164 if (pSOR->mapping == False)
1167 * We're already unmapping this guy, ignore this
1168 * and finish what we've already got going.
1175 * We're mapping this guy. Reverse course!!
1177 pSOR->mapping = False;
1178 pSOR->wSubpanel = wSubpanel;
1180 /* handle the rest on the next timeout */
1185 pSOR = (SlideOutRec *) XtMalloc (sizeof(SlideOutRec));
1189 * Compute this ahead of time to check if our window
1190 * is short. If it is, we'll just unmap it, avoiding
1191 * a lot of extra work.
1193 pSOR->incHeight = (Dimension) (DisplayHeight(DISPLAY,
1194 SCREEN_FOR_CLIENT(pCD))/SLIDE_UP_DIVISOR);
1197 if ((pCD->slideDirection != SLIDE_NOT) && pSOR &&
1198 (pSOR->incHeight < pCD->frameInfo.height))
1200 XSetWindowAttributes window_attribs;
1201 XWindowChanges window_changes;
1205 * Set up data for processing slide up
1208 pSOR->interval = SLIDE_UP_INTERVAL;
1209 pSOR->direction = pCD->slideDirection;
1210 pSOR->mapping = False;
1211 pSOR->wSubpanel = wSubpanel;
1212 pSOR->pCD->pSOR = pSOR;
1215 pSOR->currWidth = pCD->frameInfo.width;
1216 pSOR->currHeight = pCD->frameInfo.height;
1217 pSOR->currX = pCD->frameInfo.x;
1218 pSOR->currY = pCD->frameInfo.y;
1220 switch (pSOR->direction)
1223 pSOR->currHeight -= pSOR->incHeight;
1224 pSOR->currY += pSOR->incHeight;
1228 pSOR->currHeight -= pSOR->incHeight;
1233 * Create screening window to hide the slide-up from button
1234 * events until it is all the way up.
1236 mask = CWOverrideRedirect;
1237 window_attribs.override_redirect = True;
1238 pSOR->coverWin = XCreateWindow(DISPLAY,
1239 RootWindow (DISPLAY, SCREEN_FOR_CLIENT(pCD)),
1240 pSOR->currX, pSOR->currY,
1241 pSOR->currWidth, pSOR->currHeight, 0,
1242 CopyFromParent,InputOnly,CopyFromParent,
1243 mask, &window_attribs);
1246 * Put screen window above the slide-up client
1248 mask = CWStackMode | CWSibling;
1249 window_changes.stack_mode = Above;
1250 window_changes.sibling = pCD->clientFrameWin;
1251 XConfigureWindow (DISPLAY, pSOR->coverWin, mask, &window_changes);
1254 * Start slide-up processing
1256 XMapWindow (DISPLAY, pSOR->coverWin);
1258 if (pSOR->currHeight > 0)
1260 XMoveResizeWindow (DISPLAY, pCD->clientFrameWin,
1261 pSOR->currX, pSOR->currY,
1262 pSOR->currWidth, pSOR->currHeight);
1264 XMoveResizeWindow (DISPLAY, pSOR->coverWin,
1265 pSOR->currX, pSOR->currY,
1266 pSOR->currWidth, pSOR->currHeight);
1268 XSync (DISPLAY, False);
1271 XtAppAddTimeOut(wmGD.mwmAppContext, pSOR->interval,
1272 SlideOutTimerProc, (XtPointer)pSOR);
1274 wmGD.iSlideUpsInProgress += 1;
1280 * Not sliding because no direction specified or our window
1281 * is just a little guy.
1283 /* Just unmanage the slide-up */
1284 XtUnmanageChild (wSubpanel);
1287 XtFree ((char *) pSOR);
1292 } /* END OF FUNCTION SlideOutWindow */
1293 #endif /* PANELIST */
1296 /*************************************<->*************************************
1298 * MapClientWindows (pCD)
1303 * Maps the window. If this is a transient tree then all the windows in
1304 * the transient tree are mapped.
1309 * pCD = pointer to client data
1311 *************************************<->***********************************/
1313 void MapClientWindows (ClientData *pCD)
1318 pNext = pCD->transientChildren;
1321 /* map all transient children first */
1322 if (pNext->transientChildren)
1324 MapClientWindows (pNext);
1327 /* then map all siblings at this level */
1328 XMapWindow (DISPLAY, pNext->client);
1329 XMapWindow (DISPLAY, pNext->clientFrameWin);
1331 pNext = pNext->transientSiblings;
1334 /* map the primary window */
1335 XMapWindow (DISPLAY, pCD->client);
1336 XMapWindow (DISPLAY, pCD->clientFrameWin);
1338 } /* END OF FUNCTION MapClientWindows */
1342 /*************************************<->*************************************
1344 * ShowIconForMinimizedClient (pWS, pCD)
1349 * This function shows the icon for the specified client. If the icon
1350 * is in an icon box then the "minimized" icon is displayed. If the icon
1351 * is on the root window it is mapped.
1356 * pWS = pointer to workspace data
1357 * pCD = pointer to client data
1359 *************************************<->***********************************/
1361 void ShowIconForMinimizedClient (WmWorkspaceData *pWS, ClientData *pCD)
1363 WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
1366 * Handle auto-placement for root icons (icons not in an icon
1369 if (wmGD.iconAutoPlace && !P_ICON_BOX(pCD))
1371 if ((ICON_PLACE(pCD) == NO_ICON_PLACE) ||
1372 ((pWS->IPData.placeList[ICON_PLACE(pCD)].pCD) &&
1373 (pWS->IPData.placeList[ICON_PLACE(pCD)].pCD != pCD)))
1376 * Icon place not defined or occupied by another client,
1377 * find a free place to put the icon.
1380 if ((ICON_PLACE(pCD) = GetNextIconPlace (&pWS->IPData))
1384 CvtIconPositionToPlace (&pWS->IPData,
1388 CvtIconPlaceToPosition (&pWS->IPData, ICON_PLACE(pCD),
1389 &ICON_X(pCD), &ICON_Y(pCD));
1392 XMoveWindow (DISPLAY, ICON_FRAME_WIN(pCD),
1393 ICON_X(pCD), ICON_Y(pCD));
1398 pWS->IPData.placeList[ICON_PLACE(pCD)].pCD = pCD;
1403 * If icon on root window and this workspace is active, the
1404 * make sure it's in the right place.
1406 if ((pWS == pSD->pActiveWS) && !P_ICON_BOX(pCD))
1408 XMoveWindow (DISPLAY, ICON_FRAME_WIN(pCD),
1409 ICON_X(pCD), ICON_Y(pCD));
1412 if (pCD->iconWindow)
1414 XMapWindow (DISPLAY, pCD->iconWindow);
1417 if ((pSD->useIconBox) && P_ICON_BOX(pCD))
1419 ShowClientIconState (pCD, MINIMIZED_STATE );
1423 XWindowChanges windowChanges;
1426 * Map the icon on the screen at the appropriate place in the
1430 if (wmGD.lowerOnIconify)
1432 if ((&pCD->iconEntry != pSD->lastClient) &&
1435 if (pSD->lastClient->type == MINIMIZED_STATE)
1437 windowChanges.sibling =
1438 ICON_FRAME_WIN(pSD->lastClient->pCD);
1442 windowChanges.sibling =
1443 pSD->lastClient->pCD->clientFrameWin;
1445 windowChanges.stack_mode = Below;
1446 XConfigureWindow (DISPLAY, ICON_FRAME_WIN(pCD),
1447 (CWSibling | CWStackMode), &windowChanges);
1448 MoveEntryInList (pWS, &pCD->iconEntry,
1449 False /*on bottom*/, NULL);
1454 windowChanges.sibling = pCD->clientFrameWin;
1455 windowChanges.stack_mode = Below;
1456 XConfigureWindow (DISPLAY, ICON_FRAME_WIN(pCD),
1457 (CWSibling | CWStackMode), &windowChanges);
1458 MoveEntryInList (pWS, &pCD->iconEntry, False /*below*/,
1463 if (pWS == pSD->pActiveWS)
1465 XMapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
1468 XMapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
1472 } /* END OF FUNCTION ShowIconForMinimizedClient */
1476 /*************************************<->*************************************
1478 * ShowAllIconsForMinimizedClient (pCD)
1483 * This function places icons in all the workspaces for the minimized
1484 * client. Since there is only one clientState per client (not per
1485 * workspace), this loops over all workspace in which the client
1486 * resides and places an icon in each.
1491 * pCD = pointer to client data
1495 * This operates by setting up the currentWsc index for each workspace
1496 * and calling ShowIconForMinimizedClient, which makes heavy use of
1497 * the macros that use the currentWsc index.
1499 *************************************<->***********************************/
1501 void ShowAllIconsForMinimizedClient (ClientData *pCD)
1503 int saveWsc = pCD->currentWsc;
1505 WmWorkspaceData *pWS;
1507 for (tmpWsc = 0; tmpWsc < pCD->numInhabited; tmpWsc++)
1509 pCD->currentWsc = tmpWsc;
1510 pWS = GetWorkspaceData (PSD_FOR_CLIENT(pCD),
1511 pCD->pWsList[tmpWsc].wsID);
1512 ShowIconForMinimizedClient(pWS, pCD);
1515 pCD->currentWsc = saveWsc;
1517 } /* END OF FUNCTION ShowAllIconsForMinimizedClient */