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"
59 #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 "WmMultiHead.h"
74 #include "WmWinState.h"
75 static void SlideWindowOut (ClientData *pCD);
76 static void UnmapClients (ClientData *pCD, unsigned int event_mask);
77 static void SetupWindowStateWithEventMask (ClientData *pCD, int newState, Time setTime, unsigned int event_mask);
87 /******************************<->*************************************
89 * SetClientState (pCD, newState, setTime)
94 * This function is used to change the state of a client window (between
95 * withdrawn, normal, minimized, maximized).
100 * pCD = This is a pointer to the window data for the window that
101 * is to have its state changed. The fields that are used
102 * are clientState, ...
104 * newState = This is the state that the client window is to be changed to.
106 * setTime = timestamp for state setting operations
111 * pCD.clientState = new client state
113 ******************************<->***********************************/
115 void SetClientState (ClientData *pCD, int newState, Time setTime)
117 SetClientStateWithEventMask(pCD, newState, setTime, (unsigned int)0);
118 } /* END OF FUNCTION SetClientState */
120 void SetClientStateWithEventMask (ClientData *pCD, int newState, Time setTime, unsigned int event_mask)
122 ClientData *pcdLeader;
124 WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
126 Boolean notShowing = (newState & UNSEEN_STATE);
129 currentState = pCD->clientState;
130 if (currentState == newState)
132 /* no change in state */
138 * Undo the old state and setup the new state. If this is a transient
139 * window then insure that it is put in a state that is compatible
140 * with its transient leader (e.g., it cannot be minimized separately).
143 pcdLeader = (pCD->transientLeader) ? FindTransientTreeLeader (pCD) : pCD;
145 SetClientWsIndex (pCD);
148 if (pCD->transientLeader)
150 if ((pcdLeader->clientState == MINIMIZED_STATE) &&
151 (newState != WITHDRAWN_STATE))
153 newState = MINIMIZED_STATE;
157 newState |= UNSEEN_STATE;
161 else if ((newState == MINIMIZED_STATE) &&
162 (pcdLeader->clientState != MINIMIZED_STATE))
164 if (currentState == WITHDRAWN_STATE)
166 newState = NORMAL_STATE;
170 newState |= UNSEEN_STATE;
176 newState = currentState;
180 newState |= UNSEEN_STATE;
185 if (newState == currentState)
195 case UNSEEN_STATE | WITHDRAWN_STATE:
197 case WITHDRAWN_STATE:
201 * Free window manager resources (frame and icon). The
202 * WM_STATE property is set in WithdrawWindow.
205 UnManageWindow (pCD);
210 case MAXIMIZED_STATE:
212 SetupWindowStateWithEventMask (pCD, newState, setTime, event_mask);
214 XMapWindow (DISPLAY, pCD->client);
215 XMapWindow (DISPLAY, pCD->clientFrameWin);
216 WmStopWaiting(); /* in WmIPC.c */
221 case MINIMIZED_STATE:
223 Boolean clientHasFocus;
226 * Transient windows are minimized with the rest of the transient
227 * tree, including the transient leader.
230 if ((pCD->clientState == NORMAL_STATE) ||
231 (pCD->clientState == MAXIMIZED_STATE))
233 if ((wmGD.keyboardFocus == pCD) ||
234 (pCD->transientChildren && wmGD.keyboardFocus &&
235 (pCD == FindTransientTreeLeader (wmGD.keyboardFocus))))
237 clientHasFocus = True;
241 clientHasFocus = False;
244 if (clientHasFocus ||
245 ((wmGD.nextKeyboardFocus == pCD) ||
246 (pCD->transientChildren && wmGD.keyboardFocus &&
247 (pCD == FindTransientTreeLeader (wmGD.nextKeyboardFocus)))))
250 * Give up the keyboard focus when minimized (including
251 * the case in which an associated transient window has
252 * the focus). Immediately remove the focus indication
253 * from the window being minimized.
256 if (wmGD.autoKeyFocus &&
257 (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT))
259 AutoResetKeyFocus (pcdLeader, setTime);
263 Do_Focus_Key (NULL, setTime,
264 ALWAYS_SET_FOCUS | WORKSPACE_IF_NULL);
269 SetKeyboardFocus (NULL, 0);
273 /* unmap main client and all transients */
274 UnmapClients (pCD, event_mask);
278 * Display the icon for the minimized client.
281 if (ICON_FRAME_WIN(pCD))
284 if (pCD->clientState & UNSEEN_STATE)
288 XMapWindow (DISPLAY, pCD->iconWindow);
290 XMapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
293 ShowAllIconsForMinimizedClient (pCD);
295 ShowIconForMinimizedClient (pSD->pActiveWS, pCD);
299 SetClientWMState (pCD, IconicState, MINIMIZED_STATE);
301 if ((pSD->useIconBox) && P_ICON_BOX(pCD))
303 if ((pCD->clientFlags & ICON_BOX) && ACTIVE_ICON_TEXT_WIN)
306 * Hide active icon text window and reparent it to
309 HideActiveIconText((WmScreenData *)NULL);
310 pSD->activeLabelParent = ACTIVE_ROOT;
311 XReparentWindow(DISPLAY, ACTIVE_ICON_TEXT_WIN ,
314 if (ICON_FRAME_WIN(pCD))
317 * force icon appearance in icon box to change
319 IconExposureProc (pCD, True);
327 case UNSEEN_STATE | NORMAL_STATE:
328 case UNSEEN_STATE | MAXIMIZED_STATE:
329 case UNSEEN_STATE | MINIMIZED_STATE:
331 if (wmGD.keyboardFocus == pCD)
334 * Give up the keyboard focus
336 Do_Focus_Key ((ClientData *)NULL,
337 CurrentTime, ALWAYS_SET_FOCUS);
338 SetKeyboardFocus (NULL, 0);
341 if (!(pCD->clientState & UNSEEN_STATE) &&
342 (((pCD->clientState & ~UNSEEN_STATE) == NORMAL_STATE) ||
343 ((pCD->clientState & ~UNSEEN_STATE) == MAXIMIZED_STATE)))
345 /* unmap main client and all transients */
346 UnmapClients (pcdLeader, event_mask);
350 if (pCD->clientFrameWin)
352 if (!P_ICON_BOX(pCD))
354 if (ICON_FRAME_WIN(pCD))
356 XUnmapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
359 XUnmapWindow (DISPLAY, pCD->iconWindow);
363 switch (newState & ~UNSEEN_STATE)
365 case MINIMIZED_STATE:
366 SetClientWMState (pCD, IconicState, newState);
370 case MAXIMIZED_STATE:
372 SetClientWMState (pCD, NormalState, newState);
380 } /* END OF FUNCTION SetClientStateWithEventMask */
384 /*************************************<->*************************************
386 * SetupWindowStateWithEventMask (pCD, newState, setTime, event_mask)
391 * This function is used to setup a client window in the Normal or Maximized
397 * pCD = This is a pointer to the window data for the window that
398 * is to have its state changed.
400 * newState = This is the state that the client window is to be changed to.
402 * setTime = timestamp for state setting operations
404 * event_mask = what to grab to prevent stray events going somewhere
408 * pCD.clientState = new client state
410 *************************************<->***********************************/
412 static void SetupWindowStateWithEventMask (ClientData *pCD, int newState,
413 Time setTime, unsigned int event_mask)
418 WmWorkspaceData *pWS_i;
420 WmWorkspaceData *pWS = PSD_FOR_CLIENT(pCD)->pActiveWS;
422 WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
424 currentState = pCD->clientState;
427 * A transient window is not restored or maximized if the transient leader
431 if (newState == NORMAL_STATE)
433 if (pCD->maxConfig == True)
436 * The configuration function uses maxConfig to determine
437 * what the current configuration is (and then resets
438 * maxConfig) and uses the state paramenter to determine
439 * what the new configuration is.
442 ConfigureNewState (pCD);
445 else /* MAXIMIZED_STATE */
447 if (pCD->maxConfig == False)
449 ConfigureNewState (pCD);
453 if (currentState == MINIMIZED_STATE)
455 Boolean clearIconFocus;
458 * give up keyboard focus
461 if ((wmGD.keyboardFocus == pCD) ||
462 (wmGD.nextKeyboardFocus == pCD))
464 Do_Focus_Key (NULL, setTime, ALWAYS_SET_FOCUS | WORKSPACE_IF_NULL);
467 if (wmGD.keyboardFocus == pCD)
469 clearIconFocus = True;
473 clearIconFocus = False;
477 * The wm icon frame window and the client icon window
478 * (if it is being used) are mapped and the client window and
479 * client frame are unmapped.
482 if (ICON_FRAME_WIN(pCD))
484 if (pSD->useIconBox && P_ICON_BOX(pCD) &&
485 !(pCD->clientFlags & ICON_BOX))
487 ShowClientIconState(pCD, newState);
491 Boolean doGrab = False;
493 doGrab = (Success == XGrabPointer
494 (DISPLAY, DefaultRootWindow(DISPLAY),
495 False, event_mask, GrabModeAsync, GrabModeAsync,
496 None, None, CurrentTime));
497 XUnmapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
500 XUnmapWindow (DISPLAY, pCD->iconWindow);
502 if (event_mask && doGrab)
505 XMaskEvent(DISPLAY, event_mask, &event);
506 XUngrabPointer(DISPLAY,CurrentTime);
509 if (wmGD.iconAutoPlace)
511 for (wsI = 0; wsI < pCD->numInhabited; wsI++)
513 iplace = pCD->pWsList[wsI].iconPlace;
514 if (iplace != NO_ICON_PLACE)
516 pWS_i = GetWorkspaceData (pCD->pSD,
517 pCD->pWsList[wsI].wsID);
518 pWS_i->IPData.placeList[iplace].pCD =
524 if ((wmGD.iconAutoPlace) && (ICON_PLACE(pCD) != NO_ICON_PLACE))
526 pWS->IPData.placeList[ICON_PLACE(pCD)].pCD =
534 ClearFocusIndication (pCD, False /*no refresh*/);
535 wmGD.keyboardFocus = NULL;
539 if ((currentState != NORMAL_STATE) && (currentState != MAXIMIZED_STATE))
542 * Note that maximized state is considered a NormalState in
543 * the ICCC. SetClientWMState also sets the state in the
547 if (currentState == MINIMIZED_STATE)
550 * Raise the window(s) when they are deiconified.
553 pCD->clientState = newState;
555 wmGD.bSuspendSecondaryRestack = True;
557 F_Raise (NULL, pCD, NULL);
559 wmGD.bSuspendSecondaryRestack = False;
563 if ( (!(pCD->clientFlags & ICON_BOX)) ||
564 ((pCD->clientFlags & ICON_BOX) && (!(firstTime))) )
566 if ((currentState == WITHDRAWN_STATE) &&
567 (pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUBPANEL) &&
568 !(pCD->transientChildren))
570 if (pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUB_RESTORED)
572 pCD->dtwmBehaviors &= ~DtWM_BEHAVIOR_SUB_RESTORED;
573 pCD->dtwmBehaviors &= ~DtWM_BEHAVIOR_SUBPANEL;
574 XMapWindow (DISPLAY, pCD->client);
575 XMapWindow (DISPLAY, pCD->clientFrameWin);
579 SlideWindowOut (pCD);
583 MapClientWindows (pCD);
588 * Set the WM_STATE property of the window and any associated
589 * transients, along with the clientState value. The call
590 * is made with an indication of NORMAL_STATE to insure
591 * that transient window clientState values are setup
592 * correctly. The top-level window clientState is set later.
595 SetClientWMState (pCD, NormalState, NORMAL_STATE);
597 pCD->clientState = newState;
599 if ((wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT) &&
600 (currentState == MINIMIZED_STATE) && wmGD.deiconifyKeyFocus)
602 ClientData *pcdFocus;
604 pcdFocus = FindTransientFocus (pCD);
607 Do_Focus_Key (pcdFocus, setTime, ALWAYS_SET_FOCUS);
611 if ( pSD->useIconBox && P_ICON_BOX(pCD) &&
612 (!(pCD->clientFlags & ICON_BOX)) && (ICON_FRAME_WIN(pCD)))
615 * force icon appearance in icon box to change
618 IconExposureProc (pCD, True);
621 } /* END OF FUNCTION SetupWindowStateWithEventMask */
626 /*************************************<->*************************************
628 * ConfigureNewState (pcd)
633 * Configure the window to a new state
638 * pcd - pointer to client data
646 * o This is only good for going between NORMAL and MAXIMIZED state.
648 *************************************<->***********************************/
650 void ConfigureNewState (ClientData *pcd)
652 WmHeadInfo_t *WmHI = NULL;
656 pcd->maxConfig = FALSE;
657 RegenerateClientFrame(pcd);
658 XResizeWindow (DISPLAY, pcd->client,
659 (unsigned int) pcd->clientWidth,
660 (unsigned int) pcd->clientHeight);
665 * Update client config to reflect underlying head, if MultiHead is active
667 if (WmHI = GetHeadInfo(pcd)) {
668 FrameToClient(pcd, &WmHI->x_org, &WmHI->y_org,
669 &WmHI->width, &WmHI->height);
670 pcd->maxX = WmHI->x_org;
671 pcd->maxY = WmHI->y_org;
672 pcd->maxWidth = WmHI->width;
673 pcd->maxHeight = WmHI->height;
676 XResizeWindow (DISPLAY, pcd->client,
677 (unsigned int) pcd->maxWidth,
678 (unsigned int) pcd->maxHeight);
679 pcd->maxConfig = TRUE;
680 RegenerateClientFrame(pcd);
682 SendConfigureNotify (pcd);
685 * Force repaint if size doesn't change to update frame appearance.
688 if ((pcd->clientWidth == pcd->maxWidth) &&
689 (pcd->clientHeight == pcd->maxHeight))
691 FrameExposureProc (pcd);
694 } /* END OF FUNCTION ConfigureNewState */
698 /*************************************<->*************************************
700 * UnmapClients (pCD, event_mask)
705 * Unmap the window(s). The indicated client may be the head of a transient
706 * tree - if it is unmap all windows in the transient tree.
711 * pCD = pointer to client data of window(s) to be unmapped
712 * event_mask = what to grab to prevent stray events going somewhere. Our
713 * passive grab has just been activated -- but it is dropped when the
714 * window is unmapped and the ButtonRelease event can go to the window
715 * now exposed. Avoid this by grabbing the ButtonRelease before the unmap
717 * Also done for icon being unmapped.
719 *************************************<->***********************************/
721 static void UnmapClients (ClientData *pCD, unsigned int event_mask)
724 Boolean doGrab = False;
726 pNext = pCD->transientChildren;
729 /* unmap all children first */
730 if (pNext->transientChildren)
731 UnmapClients (pNext, (unsigned int) 0);
733 /* then unmap all siblings at this level */
734 XUnmapWindow (DISPLAY, pNext->clientFrameWin);
735 XUnmapWindow (DISPLAY, pNext->client);
736 pNext->wmUnmapCount++;
737 pNext = pNext->transientSiblings;
741 doGrab = (Success == XGrabPointer (DISPLAY, DefaultRootWindow(DISPLAY),
742 False, event_mask, GrabModeAsync, GrabModeAsync,
743 None, None, CurrentTime));
744 /* unmap this primary window */
745 XUnmapWindow (DISPLAY, pCD->clientFrameWin);
746 XUnmapWindow (DISPLAY, pCD->client);
747 if (event_mask && doGrab)
750 XMaskEvent(DISPLAY, event_mask, &event);
751 XUngrabPointer(DISPLAY,CurrentTime);
755 } /* END OF FUNCTION UnmapClients */
759 /*************************************<->*************************************
761 * SetClientWMState (pCD, wmState, mwmState)
766 * Set a new window manage state for a client window or a tree of transient
771 * pCD = pointer to client data
773 * wmState = new state for WM_STATE property
775 * mwmState = mwm client state
777 *************************************<->***********************************/
779 void SetClientWMState (ClientData *pCD, int wmState, int mwmState)
785 bToUnseen = (mwmState & UNSEEN_STATE) != 0;
786 mwmState &= ~UNSEEN_STATE;
790 SetClientWsIndex (pCD);
792 pNext = pCD->transientChildren;
795 if (pNext->transientChildren)
797 SetClientWMState (pNext, wmState, mwmState);
801 SetClientWsIndex (pNext);
803 SetWMState (pNext->client, wmState, ICON_FRAME_WIN(pNext));
804 if (pNext->maxConfig && mwmState == NORMAL_STATE)
806 pNext->clientState = MAXIMIZED_STATE;
809 else if (!pNext->maxConfig && mwmState == MAXIMIZED_STATE)
811 pNext->clientState = NORMAL_STATE;
816 pNext->clientState = mwmState;
820 pNext->clientState |= UNSEEN_STATE;
822 pNext = pNext->transientSiblings;
825 SetWMState (pCD->client, wmState, ICON_FRAME_WIN(pCD));
826 pCD->clientState = mwmState;
829 pCD->clientState |= UNSEEN_STATE;
832 } /* END OF FUNCTION SetClientWMState */
834 #define SLIDE_UP_PERCENTAGE 5
835 #define SLIDE_UP_DIVISOR (100/SLIDE_UP_PERCENTAGE)
836 #define SLIDE_UP_INTERVAL 15
838 /******************************<->*************************************
840 * void SlideOutTimerProc (client_data, id)
844 * An XtTimerCallbackProc to process slide up mapping of a panel
848 * client_data = pointer to a SlideOutRec
856 ******************************<->***********************************/
858 SlideOutTimerProc ( XtPointer client_data, XtIntervalId *id)
860 SlideOutRec *pSOR = (SlideOutRec *) client_data;
861 Boolean bDone = False;
866 * compute next increment;
868 switch (pSOR->direction)
873 pSOR->currY -= pSOR->incHeight;
874 pSOR->currHeight += pSOR->incHeight;
875 if ((pSOR->currY < pSOR->pCD->frameInfo.y) ||
876 (pSOR->currHeight > pSOR->pCD->frameInfo.height))
878 pSOR->currY = pSOR->pCD->frameInfo.y;
879 pSOR->currHeight = pSOR->pCD->frameInfo.height;
881 bDone = (pSOR->currY == pSOR->pCD->frameInfo.y);
885 pSOR->currY += pSOR->incHeight;
886 if (pSOR->incHeight >= pSOR->currHeight)
888 pSOR->currHeight = 0;
893 pSOR->currHeight -= pSOR->incHeight;
901 pSOR->currHeight += pSOR->incHeight;
902 if (pSOR->currHeight > pSOR->pCD->frameInfo.height)
904 pSOR->currHeight = pSOR->pCD->frameInfo.height;
907 (pSOR->currHeight == pSOR->pCD->frameInfo.height);
911 if (pSOR->incHeight >= pSOR->currHeight)
913 pSOR->currHeight = 0;
918 pSOR->currHeight -= pSOR->incHeight;
927 if (pSOR->currHeight > 0)
929 XMoveResizeWindow (DISPLAY, pSOR->coverWin,
930 pSOR->currX, pSOR->currY,
931 pSOR->currWidth, pSOR->currHeight);
933 XMoveResizeWindow (DISPLAY, pSOR->pCD->clientFrameWin,
934 pSOR->currX, pSOR->currY,
935 pSOR->currWidth, pSOR->currHeight);
939 * See if we need to continue
945 /* Time to really unmanage the slide-up */
946 XtUnmanageChild (pSOR->wSubpanel);
950 WmSubpanelPosted (DISPLAY1, pSOR->pCD->client);
951 SendConfigureNotify(pSOR->pCD);
955 XDestroyWindow (DISPLAY, pSOR->coverWin);
956 pSOR->pCD->pSOR = NULL;
957 XtFree ((char *)pSOR);
958 wmGD.iSlideUpsInProgress -= 1;
962 /* re-arm the timer */
963 XtAppAddTimeOut(wmGD.mwmAppContext, pSOR->interval,
964 SlideOutTimerProc, (XtPointer)pSOR);
965 XSync (DISPLAY, False);
969 } /* END OF FUNCTION SlideOutTimerProc */
973 /*************************************<->*************************************
975 * SlideWindowOut (pCD)
980 * Maps a window with a slide-out effect.
985 * pCD = pointer to client data
989 * Only supports slide-up or slide-down
991 *************************************<->***********************************/
994 SlideWindowOut (ClientData *pCD)
1003 * Hmmm. We're already sliding this window.
1004 * If we're supposed to go in the other direction,
1005 * then turn it around.
1007 if (pSOR->mapping == True)
1010 * We're already mapping this guy, ignore this
1011 * and finish what we've already got going.
1018 * We're not mapping this guy. Reverse course!!
1020 pSOR->mapping = True;
1022 /* insure the client window is mapped */
1023 XMapWindow (DISPLAY, pCD->client);
1025 /* handle the rest on the next timeout */
1030 /* map the primary window */
1031 XMapWindow (DISPLAY, pCD->client);
1032 pSOR = (SlideOutRec *) XtMalloc (sizeof(SlideOutRec));
1036 * Compute this ahead of time so we can check against
1037 * the window size. If the window is short, we'll
1038 * just map it, avoiding a lot of processing.
1040 pSOR->incHeight = (Dimension) (DisplayHeight(DISPLAY,
1041 SCREEN_FOR_CLIENT(pCD))/SLIDE_UP_DIVISOR);
1044 if ((pCD->slideDirection != SLIDE_NOT) && pSOR &&
1045 (pSOR->incHeight < pCD->frameInfo.height))
1047 XSetWindowAttributes window_attribs;
1048 XWindowChanges window_changes;
1052 * Set up data for processing slide up
1055 pSOR->interval = SLIDE_UP_INTERVAL;
1056 pSOR->direction = pCD->slideDirection;
1057 pSOR->mapping = True;
1058 pSOR->wSubpanel = NULL;
1059 pSOR->pCD->pSOR = pSOR;
1061 switch (pSOR->direction)
1065 pSOR->currWidth = pCD->frameInfo.width;
1066 pSOR->currHeight = pSOR->incHeight;
1067 pSOR->currX = pCD->frameInfo.x;
1068 pSOR->currY = pCD->frameInfo.y +
1069 (pCD->frameInfo.height - pSOR->currHeight);
1074 pSOR->currWidth = pCD->frameInfo.width;
1075 pSOR->currHeight = pSOR->incHeight;
1076 pSOR->currX = pCD->frameInfo.x;
1077 pSOR->currY = pCD->frameInfo.y;
1082 * Create screening window to hide the slide-up from button
1083 * events until it is all the way up.
1085 mask = CWOverrideRedirect;
1086 window_attribs.override_redirect = True;
1087 pSOR->coverWin = XCreateWindow(DISPLAY,
1088 RootWindow (DISPLAY, SCREEN_FOR_CLIENT(pCD)),
1089 pSOR->currX, pSOR->currY,
1090 pSOR->currWidth, pSOR->currHeight, 0,
1091 CopyFromParent,InputOnly,CopyFromParent,
1092 mask, &window_attribs);
1095 * Put screen window above the slide-up client
1097 mask = CWStackMode | CWSibling;
1098 window_changes.stack_mode = Above;
1099 window_changes.sibling = pCD->clientFrameWin;
1100 XConfigureWindow (DISPLAY, pSOR->coverWin, mask, &window_changes);
1103 * Start slide-up processing
1105 XMoveResizeWindow (DISPLAY, pSOR->coverWin, pSOR->currX, pSOR->currY,
1106 pSOR->currWidth, pSOR->currHeight);
1107 XMoveResizeWindow (DISPLAY, pCD->clientFrameWin,
1108 pSOR->currX, pSOR->currY, pSOR->currWidth, pSOR->currHeight);
1109 XMapWindow (DISPLAY, pSOR->coverWin);
1110 XMapWindow (DISPLAY, pCD->clientFrameWin);
1111 XSync (DISPLAY, False);
1113 XtAppAddTimeOut(wmGD.mwmAppContext, pSOR->interval,
1114 SlideOutTimerProc, (XtPointer)pSOR);
1116 wmGD.iSlideUpsInProgress += 1;
1122 * Not sliding because no direction specified or our window
1123 * is just a little guy.
1125 XMapWindow (DISPLAY, pCD->clientFrameWin);
1128 XtFree ((char *) pSOR);
1133 } /* END OF FUNCTION SlideOutWindow */
1137 /*************************************<->*************************************
1139 * SlideSubpanelBackIn (pCD, wSubpanel)
1144 * Slides a subpanel back in
1149 * pCD = pointer to client data
1150 * wSubpanel = subpanel widget to unmanage
1155 *************************************<->***********************************/
1158 SlideSubpanelBackIn (ClientData *pCD, Widget wSubpanel)
1167 * Hmmm. We're already sliding this window.
1168 * If we're supposed to go in the other direction,
1169 * then turn it around.
1171 if (pSOR->mapping == False)
1174 * We're already unmapping this guy, ignore this
1175 * and finish what we've already got going.
1182 * We're mapping this guy. Reverse course!!
1184 pSOR->mapping = False;
1185 pSOR->wSubpanel = wSubpanel;
1187 /* handle the rest on the next timeout */
1192 pSOR = (SlideOutRec *) XtMalloc (sizeof(SlideOutRec));
1196 * Compute this ahead of time to check if our window
1197 * is short. If it is, we'll just unmap it, avoiding
1198 * a lot of extra work.
1200 pSOR->incHeight = (Dimension) (DisplayHeight(DISPLAY,
1201 SCREEN_FOR_CLIENT(pCD))/SLIDE_UP_DIVISOR);
1204 if ((pCD->slideDirection != SLIDE_NOT) && pSOR &&
1205 (pSOR->incHeight < pCD->frameInfo.height))
1207 XSetWindowAttributes window_attribs;
1208 XWindowChanges window_changes;
1212 * Set up data for processing slide up
1215 pSOR->interval = SLIDE_UP_INTERVAL;
1216 pSOR->direction = pCD->slideDirection;
1217 pSOR->mapping = False;
1218 pSOR->wSubpanel = wSubpanel;
1219 pSOR->pCD->pSOR = pSOR;
1222 pSOR->currWidth = pCD->frameInfo.width;
1223 pSOR->currHeight = pCD->frameInfo.height;
1224 pSOR->currX = pCD->frameInfo.x;
1225 pSOR->currY = pCD->frameInfo.y;
1227 switch (pSOR->direction)
1230 pSOR->currHeight -= pSOR->incHeight;
1231 pSOR->currY += pSOR->incHeight;
1235 pSOR->currHeight -= pSOR->incHeight;
1240 * Create screening window to hide the slide-up from button
1241 * events until it is all the way up.
1243 mask = CWOverrideRedirect;
1244 window_attribs.override_redirect = True;
1245 pSOR->coverWin = XCreateWindow(DISPLAY,
1246 RootWindow (DISPLAY, SCREEN_FOR_CLIENT(pCD)),
1247 pSOR->currX, pSOR->currY,
1248 pSOR->currWidth, pSOR->currHeight, 0,
1249 CopyFromParent,InputOnly,CopyFromParent,
1250 mask, &window_attribs);
1253 * Put screen window above the slide-up client
1255 mask = CWStackMode | CWSibling;
1256 window_changes.stack_mode = Above;
1257 window_changes.sibling = pCD->clientFrameWin;
1258 XConfigureWindow (DISPLAY, pSOR->coverWin, mask, &window_changes);
1261 * Start slide-up processing
1263 XMapWindow (DISPLAY, pSOR->coverWin);
1265 if (pSOR->currHeight > 0)
1267 XMoveResizeWindow (DISPLAY, pCD->clientFrameWin,
1268 pSOR->currX, pSOR->currY,
1269 pSOR->currWidth, pSOR->currHeight);
1271 XMoveResizeWindow (DISPLAY, pSOR->coverWin,
1272 pSOR->currX, pSOR->currY,
1273 pSOR->currWidth, pSOR->currHeight);
1275 XSync (DISPLAY, False);
1278 XtAppAddTimeOut(wmGD.mwmAppContext, pSOR->interval,
1279 SlideOutTimerProc, (XtPointer)pSOR);
1281 wmGD.iSlideUpsInProgress += 1;
1287 * Not sliding because no direction specified or our window
1288 * is just a little guy.
1290 /* Just unmanage the slide-up */
1291 XtUnmanageChild (wSubpanel);
1294 XtFree ((char *) pSOR);
1299 } /* END OF FUNCTION SlideOutWindow */
1302 /*************************************<->*************************************
1304 * MapClientWindows (pCD)
1309 * Maps the window. If this is a transient tree then all the windows in
1310 * the transient tree are mapped.
1315 * pCD = pointer to client data
1317 *************************************<->***********************************/
1319 void MapClientWindows (ClientData *pCD)
1324 pNext = pCD->transientChildren;
1327 /* map all transient children first */
1328 if (pNext->transientChildren)
1330 MapClientWindows (pNext);
1333 /* then map all siblings at this level */
1334 XMapWindow (DISPLAY, pNext->client);
1335 XMapWindow (DISPLAY, pNext->clientFrameWin);
1337 pNext = pNext->transientSiblings;
1340 /* map the primary window */
1341 XMapWindow (DISPLAY, pCD->client);
1342 XMapWindow (DISPLAY, pCD->clientFrameWin);
1344 } /* END OF FUNCTION MapClientWindows */
1348 /*************************************<->*************************************
1350 * ShowIconForMinimizedClient (pWS, pCD)
1355 * This function shows the icon for the specified client. If the icon
1356 * is in an icon box then the "minimized" icon is displayed. If the icon
1357 * is on the root window it is mapped.
1362 * pWS = pointer to workspace data
1363 * pCD = pointer to client data
1365 *************************************<->***********************************/
1367 void ShowIconForMinimizedClient (WmWorkspaceData *pWS, ClientData *pCD)
1369 WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
1372 * Handle auto-placement for root icons (icons not in an icon
1375 if (wmGD.iconAutoPlace && !P_ICON_BOX(pCD))
1377 if ((ICON_PLACE(pCD) == NO_ICON_PLACE) ||
1378 ((pWS->IPData.placeList[ICON_PLACE(pCD)].pCD) &&
1379 (pWS->IPData.placeList[ICON_PLACE(pCD)].pCD != pCD)))
1382 * Icon place not defined or occupied by another client,
1383 * find a free place to put the icon.
1386 if ((ICON_PLACE(pCD) = GetNextIconPlace (&pWS->IPData))
1390 CvtIconPositionToPlace (&pWS->IPData,
1394 CvtIconPlaceToPosition (&pWS->IPData, ICON_PLACE(pCD),
1395 &ICON_X(pCD), &ICON_Y(pCD));
1398 XMoveWindow (DISPLAY, ICON_FRAME_WIN(pCD),
1399 ICON_X(pCD), ICON_Y(pCD));
1404 pWS->IPData.placeList[ICON_PLACE(pCD)].pCD = pCD;
1409 * If icon on root window and this workspace is active, the
1410 * make sure it's in the right place.
1412 if ((pWS == pSD->pActiveWS) && !P_ICON_BOX(pCD))
1414 XMoveWindow (DISPLAY, ICON_FRAME_WIN(pCD),
1415 ICON_X(pCD), ICON_Y(pCD));
1418 if (pCD->iconWindow)
1420 XMapWindow (DISPLAY, pCD->iconWindow);
1423 if ((pSD->useIconBox) && P_ICON_BOX(pCD))
1425 ShowClientIconState (pCD, MINIMIZED_STATE );
1429 XWindowChanges windowChanges;
1432 * Map the icon on the screen at the appropriate place in the
1436 if (wmGD.lowerOnIconify)
1438 if ((&pCD->iconEntry != pSD->lastClient) &&
1441 if (pSD->lastClient->type == MINIMIZED_STATE)
1443 windowChanges.sibling =
1444 ICON_FRAME_WIN(pSD->lastClient->pCD);
1448 windowChanges.sibling =
1449 pSD->lastClient->pCD->clientFrameWin;
1451 windowChanges.stack_mode = Below;
1452 XConfigureWindow (DISPLAY, ICON_FRAME_WIN(pCD),
1453 (CWSibling | CWStackMode), &windowChanges);
1454 MoveEntryInList (pWS, &pCD->iconEntry,
1455 False /*on bottom*/, NULL);
1460 windowChanges.sibling = pCD->clientFrameWin;
1461 windowChanges.stack_mode = Below;
1462 XConfigureWindow (DISPLAY, ICON_FRAME_WIN(pCD),
1463 (CWSibling | CWStackMode), &windowChanges);
1464 MoveEntryInList (pWS, &pCD->iconEntry, False /*below*/,
1469 if (pWS == pSD->pActiveWS)
1471 XMapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
1474 XMapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
1478 } /* END OF FUNCTION ShowIconForMinimizedClient */
1482 /*************************************<->*************************************
1484 * ShowAllIconsForMinimizedClient (pCD)
1489 * This function places icons in all the workspaces for the minimized
1490 * client. Since there is only one clientState per client (not per
1491 * workspace), this loops over all workspace in which the client
1492 * resides and places an icon in each.
1497 * pCD = pointer to client data
1501 * This operates by setting up the currentWsc index for each workspace
1502 * and calling ShowIconForMinimizedClient, which makes heavy use of
1503 * the macros that use the currentWsc index.
1505 *************************************<->***********************************/
1507 void ShowAllIconsForMinimizedClient (ClientData *pCD)
1509 int saveWsc = pCD->currentWsc;
1511 WmWorkspaceData *pWS;
1513 for (tmpWsc = 0; tmpWsc < pCD->numInhabited; tmpWsc++)
1515 pCD->currentWsc = tmpWsc;
1516 pWS = GetWorkspaceData (PSD_FOR_CLIENT(pCD),
1517 pCD->pWsList[tmpWsc].wsID);
1518 ShowIconForMinimizedClient(pWS, pCD);
1521 pCD->currentWsc = saveWsc;
1523 } /* END OF FUNCTION ShowAllIconsForMinimizedClient */