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 libraries 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
54 #include "WmFunction.h"
57 #include "WmIconBox.h"
58 #include "WmKeyFocus.h"
60 #include "WmPanelP.h" /* for typedef in WmManage.h */
63 #include "WmProperty.h"
64 #include "WmWinInfo.h"
65 #include "WmWinList.h"
67 #include "WmWrkspace.h"
72 * Function Declarations:
75 #include "WmMultiHead.h"
76 #include "WmWinState.h"
78 static void SlideWindowOut (ClientData *pCD);
80 static void UnmapClients (ClientData *pCD, unsigned int event_mask);
81 static void SetupWindowStateWithEventMask (ClientData *pCD, int newState, Time setTime, unsigned int event_mask);
91 /******************************<->*************************************
93 * SetClientState (pCD, newState, setTime)
98 * This function is used to change the state of a client window (between
99 * withdrawn, normal, minimized, maximized).
104 * pCD = This is a pointer to the window data for the window that
105 * is to have its state changed. The fields that are used
106 * are clientState, ...
108 * newState = This is the state that the client window is to be changed to.
110 * setTime = timestamp for state setting operations
115 * pCD.clientState = new client state
117 ******************************<->***********************************/
119 void SetClientState (ClientData *pCD, int newState, Time setTime)
121 SetClientStateWithEventMask(pCD, newState, setTime, (unsigned int)0);
122 } /* END OF FUNCTION SetClientState */
124 void SetClientStateWithEventMask (ClientData *pCD, int newState, Time setTime, unsigned int event_mask)
126 ClientData *pcdLeader;
128 WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
130 Boolean notShowing = (newState & UNSEEN_STATE);
133 currentState = pCD->clientState;
134 if (currentState == newState)
136 /* no change in state */
142 * Undo the old state and setup the new state. If this is a transient
143 * window then insure that it is put in a state that is compatible
144 * with its transient leader (e.g., it cannot be minimized separately).
147 pcdLeader = (pCD->transientLeader) ? FindTransientTreeLeader (pCD) : pCD;
149 SetClientWsIndex (pCD);
152 if (pCD->transientLeader)
154 if ((pcdLeader->clientState == MINIMIZED_STATE) &&
155 (newState != WITHDRAWN_STATE))
157 newState = MINIMIZED_STATE;
161 newState |= UNSEEN_STATE;
165 else if ((newState == MINIMIZED_STATE) &&
166 (pcdLeader->clientState != MINIMIZED_STATE))
168 if (currentState == WITHDRAWN_STATE)
170 newState = NORMAL_STATE;
174 newState |= UNSEEN_STATE;
180 newState = currentState;
184 newState |= UNSEEN_STATE;
189 if (newState == currentState)
199 case UNSEEN_STATE | WITHDRAWN_STATE:
201 case WITHDRAWN_STATE:
205 * Free window manager resources (frame and icon). The
206 * WM_STATE property is set in WithdrawWindow.
209 UnManageWindow (pCD);
214 case MAXIMIZED_STATE:
216 SetupWindowStateWithEventMask (pCD, newState, setTime, event_mask);
218 XMapWindow (DISPLAY, pCD->client);
219 XMapWindow (DISPLAY, pCD->clientFrameWin);
220 #if defined(PANELIST)
221 WmStopWaiting(); /* in WmIPC.c */
222 #endif /* PANELIST */
227 case MINIMIZED_STATE:
229 Boolean clientHasFocus;
232 * Transient windows are minimized with the rest of the transient
233 * tree, including the transient leader.
236 if ((pCD->clientState == NORMAL_STATE) ||
237 (pCD->clientState == MAXIMIZED_STATE))
239 if ((wmGD.keyboardFocus == pCD) ||
240 (pCD->transientChildren && wmGD.keyboardFocus &&
241 (pCD == FindTransientTreeLeader (wmGD.keyboardFocus))))
243 clientHasFocus = True;
247 clientHasFocus = False;
250 if (clientHasFocus ||
251 ((wmGD.nextKeyboardFocus == pCD) ||
252 (pCD->transientChildren && wmGD.keyboardFocus &&
253 (pCD == FindTransientTreeLeader (wmGD.nextKeyboardFocus)))))
256 * Give up the keyboard focus when minimized (including
257 * the case in which an associated transient window has
258 * the focus). Immediately remove the focus indication
259 * from the window being minimized.
262 if (wmGD.autoKeyFocus &&
263 (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT))
265 AutoResetKeyFocus (pcdLeader, setTime);
269 Do_Focus_Key (NULL, setTime,
270 ALWAYS_SET_FOCUS | WORKSPACE_IF_NULL);
275 SetKeyboardFocus (NULL, 0);
279 /* unmap main client and all transients */
280 UnmapClients (pCD, event_mask);
284 * Display the icon for the minimized client.
287 if (ICON_FRAME_WIN(pCD))
290 if (pCD->clientState & UNSEEN_STATE)
294 XMapWindow (DISPLAY, pCD->iconWindow);
296 XMapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
299 ShowAllIconsForMinimizedClient (pCD);
301 ShowIconForMinimizedClient (pSD->pActiveWS, pCD);
305 SetClientWMState (pCD, IconicState, MINIMIZED_STATE);
307 if ((pSD->useIconBox) && P_ICON_BOX(pCD))
309 if ((pCD->clientFlags & ICON_BOX) && ACTIVE_ICON_TEXT_WIN)
312 * Hide active icon text window and reparent it to
315 HideActiveIconText((WmScreenData *)NULL);
316 pSD->activeLabelParent = ACTIVE_ROOT;
317 XReparentWindow(DISPLAY, ACTIVE_ICON_TEXT_WIN ,
320 if (ICON_FRAME_WIN(pCD))
323 * force icon appearance in icon box to change
325 IconExposureProc (pCD, True);
333 case UNSEEN_STATE | NORMAL_STATE:
334 case UNSEEN_STATE | MAXIMIZED_STATE:
335 case UNSEEN_STATE | MINIMIZED_STATE:
337 if (wmGD.keyboardFocus == pCD)
340 * Give up the keyboard focus
342 Do_Focus_Key ((ClientData *)NULL,
343 CurrentTime, ALWAYS_SET_FOCUS);
344 SetKeyboardFocus (NULL, 0);
347 if (!(pCD->clientState & UNSEEN_STATE) &&
348 (((pCD->clientState & ~UNSEEN_STATE) == NORMAL_STATE) ||
349 ((pCD->clientState & ~UNSEEN_STATE) == MAXIMIZED_STATE)))
351 /* unmap main client and all transients */
352 UnmapClients (pcdLeader, event_mask);
356 if (pCD->clientFrameWin)
358 if (!P_ICON_BOX(pCD))
360 if (ICON_FRAME_WIN(pCD))
362 XUnmapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
365 XUnmapWindow (DISPLAY, pCD->iconWindow);
369 switch (newState & ~UNSEEN_STATE)
371 case MINIMIZED_STATE:
372 SetClientWMState (pCD, IconicState, newState);
376 case MAXIMIZED_STATE:
378 SetClientWMState (pCD, NormalState, newState);
386 } /* END OF FUNCTION SetClientStateWithEventMask */
390 /*************************************<->*************************************
392 * SetupWindowStateWithEventMask (pCD, newState, setTime, event_mask)
397 * This function is used to setup a client window in the Normal or Maximized
403 * pCD = This is a pointer to the window data for the window that
404 * is to have its state changed.
406 * newState = This is the state that the client window is to be changed to.
408 * setTime = timestamp for state setting operations
410 * event_mask = what to grab to prevent stray events going somewhere
414 * pCD.clientState = new client state
416 *************************************<->***********************************/
418 static void SetupWindowStateWithEventMask (ClientData *pCD, int newState,
419 Time setTime, unsigned int event_mask)
424 WmWorkspaceData *pWS_i;
426 WmWorkspaceData *pWS = PSD_FOR_CLIENT(pCD)->pActiveWS;
428 WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
430 currentState = pCD->clientState;
433 * A transient window is not restored or maximized if the transient leader
437 if (newState == NORMAL_STATE)
439 if (pCD->maxConfig == True)
442 * The configuration function uses maxConfig to determine
443 * what the current configuration is (and then resets
444 * maxConfig) and uses the state paramenter to determine
445 * what the new configuration is.
448 ConfigureNewState (pCD);
451 else /* MAXIMIZED_STATE */
453 if (pCD->maxConfig == False)
455 ConfigureNewState (pCD);
459 if (currentState == MINIMIZED_STATE)
461 Boolean clearIconFocus;
464 * give up keyboard focus
467 if ((wmGD.keyboardFocus == pCD) ||
468 (wmGD.nextKeyboardFocus == pCD))
470 Do_Focus_Key (NULL, setTime, ALWAYS_SET_FOCUS | WORKSPACE_IF_NULL);
473 if (wmGD.keyboardFocus == pCD)
475 clearIconFocus = True;
479 clearIconFocus = False;
483 * The wm icon frame window and the client icon window
484 * (if it is being used) are mapped and the client window and
485 * client frame are unmapped.
488 if (ICON_FRAME_WIN(pCD))
490 if (pSD->useIconBox && P_ICON_BOX(pCD) &&
491 !(pCD->clientFlags & ICON_BOX))
493 ShowClientIconState(pCD, newState);
497 Boolean doGrab = False;
499 doGrab = (Success == XGrabPointer
500 (DISPLAY, DefaultRootWindow(DISPLAY),
501 False, event_mask, GrabModeAsync, GrabModeAsync,
502 None, None, CurrentTime));
503 XUnmapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
506 XUnmapWindow (DISPLAY, pCD->iconWindow);
508 if (event_mask && doGrab)
511 XMaskEvent(DISPLAY, event_mask, &event);
512 XUngrabPointer(DISPLAY,CurrentTime);
515 if (wmGD.iconAutoPlace)
517 for (wsI = 0; wsI < pCD->numInhabited; wsI++)
519 iplace = pCD->pWsList[wsI].iconPlace;
520 if (iplace != NO_ICON_PLACE)
522 pWS_i = GetWorkspaceData (pCD->pSD,
523 pCD->pWsList[wsI].wsID);
524 pWS_i->IPData.placeList[iplace].pCD =
530 if ((wmGD.iconAutoPlace) && (ICON_PLACE(pCD) != NO_ICON_PLACE))
532 pWS->IPData.placeList[ICON_PLACE(pCD)].pCD =
540 ClearFocusIndication (pCD, False /*no refresh*/);
541 wmGD.keyboardFocus = NULL;
545 if ((currentState != NORMAL_STATE) && (currentState != MAXIMIZED_STATE))
548 * Note that maximized state is considered a NormalState in
549 * the ICCC. SetClientWMState also sets the state in the
553 if (currentState == MINIMIZED_STATE)
556 * Raise the window(s) when they are deiconified.
559 pCD->clientState = newState;
561 wmGD.bSuspendSecondaryRestack = True;
563 F_Raise (NULL, pCD, NULL);
565 wmGD.bSuspendSecondaryRestack = False;
569 if ( (!(pCD->clientFlags & ICON_BOX)) ||
570 ((pCD->clientFlags & ICON_BOX) && (!(firstTime))) )
573 if ((currentState == WITHDRAWN_STATE) &&
574 (pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUBPANEL) &&
575 !(pCD->transientChildren))
577 if (pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUB_RESTORED)
579 pCD->dtwmBehaviors &= ~DtWM_BEHAVIOR_SUB_RESTORED;
580 pCD->dtwmBehaviors &= ~DtWM_BEHAVIOR_SUBPANEL;
581 XMapWindow (DISPLAY, pCD->client);
582 XMapWindow (DISPLAY, pCD->clientFrameWin);
586 SlideWindowOut (pCD);
590 #endif /* PANELIST */
591 MapClientWindows (pCD);
596 * Set the WM_STATE property of the window and any associated
597 * transients, along with the clientState value. The call
598 * is made with an indication of NORMAL_STATE to insure
599 * that transient window clientState values are setup
600 * correctly. The top-level window clientState is set later.
603 SetClientWMState (pCD, NormalState, NORMAL_STATE);
605 pCD->clientState = newState;
607 if ((wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT) &&
608 (currentState == MINIMIZED_STATE) && wmGD.deiconifyKeyFocus)
610 ClientData *pcdFocus;
612 pcdFocus = FindTransientFocus (pCD);
615 Do_Focus_Key (pcdFocus, setTime, ALWAYS_SET_FOCUS);
619 if ( pSD->useIconBox && P_ICON_BOX(pCD) &&
620 (!(pCD->clientFlags & ICON_BOX)) && (ICON_FRAME_WIN(pCD)))
623 * force icon appearance in icon box to change
626 IconExposureProc (pCD, True);
629 } /* END OF FUNCTION SetupWindowStateWithEventMask */
634 /*************************************<->*************************************
636 * ConfigureNewState (pcd)
641 * Configure the window to a new state
646 * pcd - pointer to client data
654 * o This is only good for going between NORMAL and MAXIMIZED state.
656 *************************************<->***********************************/
658 void ConfigureNewState (ClientData *pcd)
660 WmHeadInfo_t *WmHI = NULL;
664 pcd->maxConfig = FALSE;
665 RegenerateClientFrame(pcd);
666 XResizeWindow (DISPLAY, pcd->client,
667 (unsigned int) pcd->clientWidth,
668 (unsigned int) pcd->clientHeight);
673 * Update client config to reflect underlying head, if MultiHead is active
675 if (WmHI = GetHeadInfo(pcd)) {
676 FrameToClient(pcd, &WmHI->x_org, &WmHI->y_org,
677 &WmHI->width, &WmHI->height);
678 pcd->maxX = WmHI->x_org;
679 pcd->maxY = WmHI->y_org;
680 pcd->maxWidth = WmHI->width;
681 pcd->maxHeight = WmHI->height;
684 XResizeWindow (DISPLAY, pcd->client,
685 (unsigned int) pcd->maxWidth,
686 (unsigned int) pcd->maxHeight);
687 pcd->maxConfig = TRUE;
688 RegenerateClientFrame(pcd);
690 SendConfigureNotify (pcd);
693 * Force repaint if size doesn't change to update frame appearance.
696 if ((pcd->clientWidth == pcd->maxWidth) &&
697 (pcd->clientHeight == pcd->maxHeight))
699 FrameExposureProc (pcd);
702 } /* END OF FUNCTION ConfigureNewState */
706 /*************************************<->*************************************
708 * UnmapClients (pCD, event_mask)
713 * Unmap the window(s). The indicated client may be the head of a transient
714 * tree - if it is unmap all windows in the transient tree.
719 * pCD = pointer to client data of window(s) to be unmapped
720 * event_mask = what to grab to prevent stray events going somewhere. Our
721 * passive grab has just been activated -- but it is dropped when the
722 * window is unmapped and the ButtonRelease event can go to the window
723 * now exposed. Avoid this by grabbing the ButtonRelease before the unmap
725 * Also done for icon being unmapped.
727 *************************************<->***********************************/
729 static void UnmapClients (ClientData *pCD, unsigned int event_mask)
732 Boolean doGrab = False;
734 pNext = pCD->transientChildren;
737 /* unmap all children first */
738 if (pNext->transientChildren)
739 UnmapClients (pNext, (unsigned int) 0);
741 /* then unmap all siblings at this level */
742 XUnmapWindow (DISPLAY, pNext->clientFrameWin);
743 XUnmapWindow (DISPLAY, pNext->client);
744 pNext->wmUnmapCount++;
745 pNext = pNext->transientSiblings;
749 doGrab = (Success == XGrabPointer (DISPLAY, DefaultRootWindow(DISPLAY),
750 False, event_mask, GrabModeAsync, GrabModeAsync,
751 None, None, CurrentTime));
752 /* unmap this primary window */
753 XUnmapWindow (DISPLAY, pCD->clientFrameWin);
754 XUnmapWindow (DISPLAY, pCD->client);
755 if (event_mask && doGrab)
758 XMaskEvent(DISPLAY, event_mask, &event);
759 XUngrabPointer(DISPLAY,CurrentTime);
763 } /* END OF FUNCTION UnmapClients */
767 /*************************************<->*************************************
769 * SetClientWMState (pCD, wmState, mwmState)
774 * Set a new window manage state for a client window or a tree of transient
779 * pCD = pointer to client data
781 * wmState = new state for WM_STATE property
783 * mwmState = mwm client state
785 *************************************<->***********************************/
787 void SetClientWMState (ClientData *pCD, int wmState, int mwmState)
793 bToUnseen = (mwmState & UNSEEN_STATE) != 0;
794 mwmState &= ~UNSEEN_STATE;
798 SetClientWsIndex (pCD);
800 pNext = pCD->transientChildren;
803 if (pNext->transientChildren)
805 SetClientWMState (pNext, wmState, mwmState);
809 SetClientWsIndex (pNext);
811 SetWMState (pNext->client, wmState, ICON_FRAME_WIN(pNext));
812 if (pNext->maxConfig && mwmState == NORMAL_STATE)
814 pNext->clientState = MAXIMIZED_STATE;
817 else if (!pNext->maxConfig && mwmState == MAXIMIZED_STATE)
819 pNext->clientState = NORMAL_STATE;
824 pNext->clientState = mwmState;
828 pNext->clientState |= UNSEEN_STATE;
830 pNext = pNext->transientSiblings;
833 SetWMState (pCD->client, wmState, ICON_FRAME_WIN(pCD));
834 pCD->clientState = mwmState;
837 pCD->clientState |= UNSEEN_STATE;
840 } /* END OF FUNCTION SetClientWMState */
844 #define SLIDE_UP_PERCENTAGE 5
845 #define SLIDE_UP_DIVISOR (100/SLIDE_UP_PERCENTAGE)
846 #define SLIDE_UP_INTERVAL 15
848 /******************************<->*************************************
850 * void SlideOutTimerProc (client_data, id)
854 * An XtTimerCallbackProc to process slide up mapping of a panel
858 * client_data = pointer to a SlideOutRec
866 ******************************<->***********************************/
868 SlideOutTimerProc ( XtPointer client_data, XtIntervalId *id)
870 SlideOutRec *pSOR = (SlideOutRec *) client_data;
871 Boolean bDone = False;
876 * compute next increment;
878 switch (pSOR->direction)
883 pSOR->currY -= pSOR->incHeight;
884 pSOR->currHeight += pSOR->incHeight;
885 if ((pSOR->currY < pSOR->pCD->frameInfo.y) ||
886 (pSOR->currHeight > pSOR->pCD->frameInfo.height))
888 pSOR->currY = pSOR->pCD->frameInfo.y;
889 pSOR->currHeight = pSOR->pCD->frameInfo.height;
891 bDone = (pSOR->currY == pSOR->pCD->frameInfo.y);
895 pSOR->currY += pSOR->incHeight;
896 if (pSOR->incHeight >= pSOR->currHeight)
898 pSOR->currHeight = 0;
903 pSOR->currHeight -= pSOR->incHeight;
911 pSOR->currHeight += pSOR->incHeight;
912 if (pSOR->currHeight > pSOR->pCD->frameInfo.height)
914 pSOR->currHeight = pSOR->pCD->frameInfo.height;
917 (pSOR->currHeight == pSOR->pCD->frameInfo.height);
921 if (pSOR->incHeight >= pSOR->currHeight)
923 pSOR->currHeight = 0;
928 pSOR->currHeight -= pSOR->incHeight;
937 if (pSOR->currHeight > 0)
939 XMoveResizeWindow (DISPLAY, pSOR->coverWin,
940 pSOR->currX, pSOR->currY,
941 pSOR->currWidth, pSOR->currHeight);
943 XMoveResizeWindow (DISPLAY, pSOR->pCD->clientFrameWin,
944 pSOR->currX, pSOR->currY,
945 pSOR->currWidth, pSOR->currHeight);
949 * See if we need to continue
955 /* Time to really unmanage the slide-up */
956 XtUnmanageChild (pSOR->wSubpanel);
960 WmSubpanelPosted (DISPLAY1, pSOR->pCD->client);
961 SendConfigureNotify(pSOR->pCD);
965 XDestroyWindow (DISPLAY, pSOR->coverWin);
966 pSOR->pCD->pSOR = NULL;
967 XtFree ((char *)pSOR);
968 wmGD.iSlideUpsInProgress -= 1;
972 /* re-arm the timer */
973 XtAppAddTimeOut(wmGD.mwmAppContext, pSOR->interval,
974 SlideOutTimerProc, (XtPointer)pSOR);
975 XSync (DISPLAY, False);
979 } /* END OF FUNCTION SlideOutTimerProc */
983 /*************************************<->*************************************
985 * SlideWindowOut (pCD)
990 * Maps a window with a slide-out effect.
995 * pCD = pointer to client data
999 * Only supports slide-up or slide-down
1001 *************************************<->***********************************/
1004 SlideWindowOut (ClientData *pCD)
1013 * Hmmm. We're already sliding this window.
1014 * If we're supposed to go in the other direction,
1015 * then turn it around.
1017 if (pSOR->mapping == True)
1020 * We're already mapping this guy, ignore this
1021 * and finish what we've already got going.
1028 * We're not mapping this guy. Reverse course!!
1030 pSOR->mapping = True;
1032 /* insure the client window is mapped */
1033 XMapWindow (DISPLAY, pCD->client);
1035 /* handle the rest on the next timeout */
1040 /* map the primary window */
1041 XMapWindow (DISPLAY, pCD->client);
1042 pSOR = (SlideOutRec *) XtMalloc (sizeof(SlideOutRec));
1046 * Compute this ahead of time so we can check against
1047 * the window size. If the window is short, we'll
1048 * just map it, avoiding a lot of processing.
1050 pSOR->incHeight = (Dimension) (DisplayHeight(DISPLAY,
1051 SCREEN_FOR_CLIENT(pCD))/SLIDE_UP_DIVISOR);
1054 if ((pCD->slideDirection != SLIDE_NOT) && pSOR &&
1055 (pSOR->incHeight < pCD->frameInfo.height))
1057 XSetWindowAttributes window_attribs;
1058 XWindowChanges window_changes;
1062 * Set up data for processing slide up
1065 pSOR->interval = SLIDE_UP_INTERVAL;
1066 pSOR->direction = pCD->slideDirection;
1067 pSOR->mapping = True;
1068 pSOR->wSubpanel = NULL;
1069 pSOR->pCD->pSOR = pSOR;
1071 switch (pSOR->direction)
1075 pSOR->currWidth = pCD->frameInfo.width;
1076 pSOR->currHeight = pSOR->incHeight;
1077 pSOR->currX = pCD->frameInfo.x;
1078 pSOR->currY = pCD->frameInfo.y +
1079 (pCD->frameInfo.height - pSOR->currHeight);
1084 pSOR->currWidth = pCD->frameInfo.width;
1085 pSOR->currHeight = pSOR->incHeight;
1086 pSOR->currX = pCD->frameInfo.x;
1087 pSOR->currY = pCD->frameInfo.y;
1092 * Create screening window to hide the slide-up from button
1093 * events until it is all the way up.
1095 mask = CWOverrideRedirect;
1096 window_attribs.override_redirect = True;
1097 pSOR->coverWin = XCreateWindow(DISPLAY,
1098 RootWindow (DISPLAY, SCREEN_FOR_CLIENT(pCD)),
1099 pSOR->currX, pSOR->currY,
1100 pSOR->currWidth, pSOR->currHeight, 0,
1101 CopyFromParent,InputOnly,CopyFromParent,
1102 mask, &window_attribs);
1105 * Put screen window above the slide-up client
1107 mask = CWStackMode | CWSibling;
1108 window_changes.stack_mode = Above;
1109 window_changes.sibling = pCD->clientFrameWin;
1110 XConfigureWindow (DISPLAY, pSOR->coverWin, mask, &window_changes);
1113 * Start slide-up processing
1115 XMoveResizeWindow (DISPLAY, pSOR->coverWin, pSOR->currX, pSOR->currY,
1116 pSOR->currWidth, pSOR->currHeight);
1117 XMoveResizeWindow (DISPLAY, pCD->clientFrameWin,
1118 pSOR->currX, pSOR->currY, pSOR->currWidth, pSOR->currHeight);
1119 XMapWindow (DISPLAY, pSOR->coverWin);
1120 XMapWindow (DISPLAY, pCD->clientFrameWin);
1121 XSync (DISPLAY, False);
1123 XtAppAddTimeOut(wmGD.mwmAppContext, pSOR->interval,
1124 SlideOutTimerProc, (XtPointer)pSOR);
1126 wmGD.iSlideUpsInProgress += 1;
1132 * Not sliding because no direction specified or our window
1133 * is just a little guy.
1135 XMapWindow (DISPLAY, pCD->clientFrameWin);
1138 XtFree ((char *) pSOR);
1143 } /* END OF FUNCTION SlideOutWindow */
1147 /*************************************<->*************************************
1149 * SlideSubpanelBackIn (pCD, wSubpanel)
1154 * Slides a subpanel back in
1159 * pCD = pointer to client data
1160 * wSubpanel = subpanel widget to unmanage
1165 *************************************<->***********************************/
1168 SlideSubpanelBackIn (ClientData *pCD, Widget wSubpanel)
1177 * Hmmm. We're already sliding this window.
1178 * If we're supposed to go in the other direction,
1179 * then turn it around.
1181 if (pSOR->mapping == False)
1184 * We're already unmapping this guy, ignore this
1185 * and finish what we've already got going.
1192 * We're mapping this guy. Reverse course!!
1194 pSOR->mapping = False;
1195 pSOR->wSubpanel = wSubpanel;
1197 /* handle the rest on the next timeout */
1202 pSOR = (SlideOutRec *) XtMalloc (sizeof(SlideOutRec));
1206 * Compute this ahead of time to check if our window
1207 * is short. If it is, we'll just unmap it, avoiding
1208 * a lot of extra work.
1210 pSOR->incHeight = (Dimension) (DisplayHeight(DISPLAY,
1211 SCREEN_FOR_CLIENT(pCD))/SLIDE_UP_DIVISOR);
1214 if ((pCD->slideDirection != SLIDE_NOT) && pSOR &&
1215 (pSOR->incHeight < pCD->frameInfo.height))
1217 XSetWindowAttributes window_attribs;
1218 XWindowChanges window_changes;
1222 * Set up data for processing slide up
1225 pSOR->interval = SLIDE_UP_INTERVAL;
1226 pSOR->direction = pCD->slideDirection;
1227 pSOR->mapping = False;
1228 pSOR->wSubpanel = wSubpanel;
1229 pSOR->pCD->pSOR = pSOR;
1232 pSOR->currWidth = pCD->frameInfo.width;
1233 pSOR->currHeight = pCD->frameInfo.height;
1234 pSOR->currX = pCD->frameInfo.x;
1235 pSOR->currY = pCD->frameInfo.y;
1237 switch (pSOR->direction)
1240 pSOR->currHeight -= pSOR->incHeight;
1241 pSOR->currY += pSOR->incHeight;
1245 pSOR->currHeight -= pSOR->incHeight;
1250 * Create screening window to hide the slide-up from button
1251 * events until it is all the way up.
1253 mask = CWOverrideRedirect;
1254 window_attribs.override_redirect = True;
1255 pSOR->coverWin = XCreateWindow(DISPLAY,
1256 RootWindow (DISPLAY, SCREEN_FOR_CLIENT(pCD)),
1257 pSOR->currX, pSOR->currY,
1258 pSOR->currWidth, pSOR->currHeight, 0,
1259 CopyFromParent,InputOnly,CopyFromParent,
1260 mask, &window_attribs);
1263 * Put screen window above the slide-up client
1265 mask = CWStackMode | CWSibling;
1266 window_changes.stack_mode = Above;
1267 window_changes.sibling = pCD->clientFrameWin;
1268 XConfigureWindow (DISPLAY, pSOR->coverWin, mask, &window_changes);
1271 * Start slide-up processing
1273 XMapWindow (DISPLAY, pSOR->coverWin);
1275 if (pSOR->currHeight > 0)
1277 XMoveResizeWindow (DISPLAY, pCD->clientFrameWin,
1278 pSOR->currX, pSOR->currY,
1279 pSOR->currWidth, pSOR->currHeight);
1281 XMoveResizeWindow (DISPLAY, pSOR->coverWin,
1282 pSOR->currX, pSOR->currY,
1283 pSOR->currWidth, pSOR->currHeight);
1285 XSync (DISPLAY, False);
1288 XtAppAddTimeOut(wmGD.mwmAppContext, pSOR->interval,
1289 SlideOutTimerProc, (XtPointer)pSOR);
1291 wmGD.iSlideUpsInProgress += 1;
1297 * Not sliding because no direction specified or our window
1298 * is just a little guy.
1300 /* Just unmanage the slide-up */
1301 XtUnmanageChild (wSubpanel);
1304 XtFree ((char *) pSOR);
1309 } /* END OF FUNCTION SlideOutWindow */
1310 #endif /* PANELIST */
1313 /*************************************<->*************************************
1315 * MapClientWindows (pCD)
1320 * Maps the window. If this is a transient tree then all the windows in
1321 * the transient tree are mapped.
1326 * pCD = pointer to client data
1328 *************************************<->***********************************/
1330 void MapClientWindows (ClientData *pCD)
1335 pNext = pCD->transientChildren;
1338 /* map all transient children first */
1339 if (pNext->transientChildren)
1341 MapClientWindows (pNext);
1344 /* then map all siblings at this level */
1345 XMapWindow (DISPLAY, pNext->client);
1346 XMapWindow (DISPLAY, pNext->clientFrameWin);
1348 pNext = pNext->transientSiblings;
1351 /* map the primary window */
1352 XMapWindow (DISPLAY, pCD->client);
1353 XMapWindow (DISPLAY, pCD->clientFrameWin);
1355 } /* END OF FUNCTION MapClientWindows */
1359 /*************************************<->*************************************
1361 * ShowIconForMinimizedClient (pWS, pCD)
1366 * This function shows the icon for the specified client. If the icon
1367 * is in an icon box then the "minimized" icon is displayed. If the icon
1368 * is on the root window it is mapped.
1373 * pWS = pointer to workspace data
1374 * pCD = pointer to client data
1376 *************************************<->***********************************/
1378 void ShowIconForMinimizedClient (WmWorkspaceData *pWS, ClientData *pCD)
1380 WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
1383 * Handle auto-placement for root icons (icons not in an icon
1386 if (wmGD.iconAutoPlace && !P_ICON_BOX(pCD))
1388 if ((ICON_PLACE(pCD) == NO_ICON_PLACE) ||
1389 ((pWS->IPData.placeList[ICON_PLACE(pCD)].pCD) &&
1390 (pWS->IPData.placeList[ICON_PLACE(pCD)].pCD != pCD)))
1393 * Icon place not defined or occupied by another client,
1394 * find a free place to put the icon.
1397 if ((ICON_PLACE(pCD) = GetNextIconPlace (&pWS->IPData))
1401 CvtIconPositionToPlace (&pWS->IPData,
1405 CvtIconPlaceToPosition (&pWS->IPData, ICON_PLACE(pCD),
1406 &ICON_X(pCD), &ICON_Y(pCD));
1409 XMoveWindow (DISPLAY, ICON_FRAME_WIN(pCD),
1410 ICON_X(pCD), ICON_Y(pCD));
1415 pWS->IPData.placeList[ICON_PLACE(pCD)].pCD = pCD;
1420 * If icon on root window and this workspace is active, the
1421 * make sure it's in the right place.
1423 if ((pWS == pSD->pActiveWS) && !P_ICON_BOX(pCD))
1425 XMoveWindow (DISPLAY, ICON_FRAME_WIN(pCD),
1426 ICON_X(pCD), ICON_Y(pCD));
1429 if (pCD->iconWindow)
1431 XMapWindow (DISPLAY, pCD->iconWindow);
1434 if ((pSD->useIconBox) && P_ICON_BOX(pCD))
1436 ShowClientIconState (pCD, MINIMIZED_STATE );
1440 XWindowChanges windowChanges;
1443 * Map the icon on the screen at the appropriate place in the
1447 if (wmGD.lowerOnIconify)
1449 if ((&pCD->iconEntry != pSD->lastClient) &&
1452 if (pSD->lastClient->type == MINIMIZED_STATE)
1454 windowChanges.sibling =
1455 ICON_FRAME_WIN(pSD->lastClient->pCD);
1459 windowChanges.sibling =
1460 pSD->lastClient->pCD->clientFrameWin;
1462 windowChanges.stack_mode = Below;
1463 XConfigureWindow (DISPLAY, ICON_FRAME_WIN(pCD),
1464 (CWSibling | CWStackMode), &windowChanges);
1465 MoveEntryInList (pWS, &pCD->iconEntry,
1466 False /*on bottom*/, NULL);
1471 windowChanges.sibling = pCD->clientFrameWin;
1472 windowChanges.stack_mode = Below;
1473 XConfigureWindow (DISPLAY, ICON_FRAME_WIN(pCD),
1474 (CWSibling | CWStackMode), &windowChanges);
1475 MoveEntryInList (pWS, &pCD->iconEntry, False /*below*/,
1480 if (pWS == pSD->pActiveWS)
1482 XMapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
1485 XMapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
1489 } /* END OF FUNCTION ShowIconForMinimizedClient */
1493 /*************************************<->*************************************
1495 * ShowAllIconsForMinimizedClient (pCD)
1500 * This function places icons in all the workspaces for the minimized
1501 * client. Since there is only one clientState per client (not per
1502 * workspace), this loops over all workspace in which the client
1503 * resides and places an icon in each.
1508 * pCD = pointer to client data
1512 * This operates by setting up the currentWsc index for each workspace
1513 * and calling ShowIconForMinimizedClient, which makes heavy use of
1514 * the macros that use the currentWsc index.
1516 *************************************<->***********************************/
1518 void ShowAllIconsForMinimizedClient (ClientData *pCD)
1520 int saveWsc = pCD->currentWsc;
1522 WmWorkspaceData *pWS;
1524 for (tmpWsc = 0; tmpWsc < pCD->numInhabited; tmpWsc++)
1526 pCD->currentWsc = tmpWsc;
1527 pWS = GetWorkspaceData (PSD_FOR_CLIENT(pCD),
1528 pCD->pWsList[tmpWsc].wsID);
1529 ShowIconForMinimizedClient(pWS, pCD);
1532 pCD->currentWsc = saveWsc;
1534 } /* END OF FUNCTION ShowAllIconsForMinimizedClient */