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.
31 * (c) Copyright 1987, 1988, 1989, 1990 HEWLETT-PACKARD COMPANY */
39 #include "WmProtocol.h"
44 * include extern functions
49 #include "WmFunction.h"
52 #include "WmIconBox.h"
53 #include "WmKeyFocus.h"
54 #include "WmPanelP.h" /* for typedef in WmManage.h */
56 #include "WmProperty.h"
57 #include "WmWinInfo.h"
58 #include "WmWinList.h"
59 #include "WmWrkspace.h"
63 * Function Declarations:
66 #include "WmMultiHead.h"
67 #include "WmWinState.h"
68 static void SlideWindowOut (ClientData *pCD);
69 static void UnmapClients (ClientData *pCD, unsigned int event_mask);
70 static void SetupWindowStateWithEventMask (ClientData *pCD, int newState, Time setTime, unsigned int event_mask);
80 /******************************<->*************************************
82 * SetClientState (pCD, newState, setTime)
87 * This function is used to change the state of a client window (between
88 * withdrawn, normal, minimized, maximized).
93 * pCD = This is a pointer to the window data for the window that
94 * is to have its state changed. The fields that are used
95 * are clientState, ...
97 * newState = This is the state that the client window is to be changed to.
99 * setTime = timestamp for state setting operations
104 * pCD.clientState = new client state
106 ******************************<->***********************************/
108 void SetClientState (ClientData *pCD, int newState, Time setTime)
110 SetClientStateWithEventMask(pCD, newState, setTime, (unsigned int)0);
111 } /* END OF FUNCTION SetClientState */
113 void SetClientStateWithEventMask (ClientData *pCD, int newState, Time setTime, unsigned int event_mask)
115 ClientData *pcdLeader;
117 WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
118 Boolean notShowing = (newState & UNSEEN_STATE);
120 currentState = pCD->clientState;
121 if (currentState == newState)
123 /* no change in state */
129 * Undo the old state and setup the new state. If this is a transient
130 * window then insure that it is put in a state that is compatible
131 * with its transient leader (e.g., it cannot be minimized separately).
134 pcdLeader = (pCD->transientLeader) ? FindTransientTreeLeader (pCD) : pCD;
135 SetClientWsIndex (pCD);
137 if (pCD->transientLeader)
139 if ((pcdLeader->clientState == MINIMIZED_STATE) &&
140 (newState != WITHDRAWN_STATE))
142 newState = MINIMIZED_STATE;
145 newState |= UNSEEN_STATE;
148 else if ((newState == MINIMIZED_STATE) &&
149 (pcdLeader->clientState != MINIMIZED_STATE))
151 if (currentState == WITHDRAWN_STATE)
153 newState = NORMAL_STATE;
156 newState |= UNSEEN_STATE;
161 newState = currentState;
164 newState |= UNSEEN_STATE;
168 if (newState == currentState)
177 case UNSEEN_STATE | WITHDRAWN_STATE:
180 * Free window manager resources (frame and icon). The
181 * WM_STATE property is set in WithdrawWindow.
184 UnManageWindow (pCD);
189 case MAXIMIZED_STATE:
191 SetupWindowStateWithEventMask (pCD, newState, setTime, event_mask);
192 XMapWindow (DISPLAY, pCD->client);
193 XMapWindow (DISPLAY, pCD->clientFrameWin);
194 WmStopWaiting(); /* in WmIPC.c */
198 case MINIMIZED_STATE:
200 Boolean clientHasFocus;
203 * Transient windows are minimized with the rest of the transient
204 * tree, including the transient leader.
207 if ((pCD->clientState == NORMAL_STATE) ||
208 (pCD->clientState == MAXIMIZED_STATE))
210 if ((wmGD.keyboardFocus == pCD) ||
211 (pCD->transientChildren && wmGD.keyboardFocus &&
212 (pCD == FindTransientTreeLeader (wmGD.keyboardFocus))))
214 clientHasFocus = True;
218 clientHasFocus = False;
221 if (clientHasFocus ||
222 ((wmGD.nextKeyboardFocus == pCD) ||
223 (pCD->transientChildren && wmGD.keyboardFocus &&
224 (pCD == FindTransientTreeLeader (wmGD.nextKeyboardFocus)))))
227 * Give up the keyboard focus when minimized (including
228 * the case in which an associated transient window has
229 * the focus). Immediately remove the focus indication
230 * from the window being minimized.
233 if (wmGD.autoKeyFocus &&
234 (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT))
236 AutoResetKeyFocus (pcdLeader, setTime);
240 Do_Focus_Key (NULL, setTime,
241 ALWAYS_SET_FOCUS | WORKSPACE_IF_NULL);
246 SetKeyboardFocus (NULL, 0);
250 /* unmap main client and all transients */
251 UnmapClients (pCD, event_mask);
255 * Display the icon for the minimized client.
258 if (ICON_FRAME_WIN(pCD))
260 if (pCD->clientState & UNSEEN_STATE)
264 XMapWindow (DISPLAY, pCD->iconWindow);
266 XMapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
269 ShowAllIconsForMinimizedClient (pCD);
272 SetClientWMState (pCD, IconicState, MINIMIZED_STATE);
274 if ((pSD->useIconBox) && P_ICON_BOX(pCD))
276 if ((pCD->clientFlags & ICON_BOX) && ACTIVE_ICON_TEXT_WIN)
279 * Hide active icon text window and reparent it to
282 HideActiveIconText((WmScreenData *)NULL);
283 pSD->activeLabelParent = ACTIVE_ROOT;
284 XReparentWindow(DISPLAY, ACTIVE_ICON_TEXT_WIN ,
287 if (ICON_FRAME_WIN(pCD))
290 * force icon appearance in icon box to change
292 IconExposureProc (pCD, True);
299 case UNSEEN_STATE | NORMAL_STATE:
300 case UNSEEN_STATE | MAXIMIZED_STATE:
301 case UNSEEN_STATE | MINIMIZED_STATE:
303 if (wmGD.keyboardFocus == pCD)
306 * Give up the keyboard focus
308 Do_Focus_Key ((ClientData *)NULL,
309 CurrentTime, ALWAYS_SET_FOCUS);
310 SetKeyboardFocus (NULL, 0);
313 if (!(pCD->clientState & UNSEEN_STATE) &&
314 (((pCD->clientState & ~UNSEEN_STATE) == NORMAL_STATE) ||
315 ((pCD->clientState & ~UNSEEN_STATE) == MAXIMIZED_STATE)))
317 /* unmap main client and all transients */
318 UnmapClients (pcdLeader, event_mask);
322 if (pCD->clientFrameWin)
324 if (!P_ICON_BOX(pCD))
326 if (ICON_FRAME_WIN(pCD))
328 XUnmapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
331 XUnmapWindow (DISPLAY, pCD->iconWindow);
335 switch (newState & ~UNSEEN_STATE)
337 case MINIMIZED_STATE:
338 SetClientWMState (pCD, IconicState, newState);
342 case MAXIMIZED_STATE:
344 SetClientWMState (pCD, NormalState, newState);
351 } /* END OF FUNCTION SetClientStateWithEventMask */
355 /*************************************<->*************************************
357 * SetupWindowStateWithEventMask (pCD, newState, setTime, event_mask)
362 * This function is used to setup a client window in the Normal or Maximized
368 * pCD = This is a pointer to the window data for the window that
369 * is to have its state changed.
371 * newState = This is the state that the client window is to be changed to.
373 * setTime = timestamp for state setting operations
375 * event_mask = what to grab to prevent stray events going somewhere
379 * pCD.clientState = new client state
381 *************************************<->***********************************/
383 static void SetupWindowStateWithEventMask (ClientData *pCD, int newState,
384 Time setTime, unsigned int event_mask)
388 WmWorkspaceData *pWS_i;
389 WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
391 currentState = pCD->clientState;
394 * A transient window is not restored or maximized if the transient leader
398 if (newState == NORMAL_STATE)
400 if (pCD->maxConfig == True)
403 * The configuration function uses maxConfig to determine
404 * what the current configuration is (and then resets
405 * maxConfig) and uses the state paramenter to determine
406 * what the new configuration is.
409 ConfigureNewState (pCD);
412 else /* MAXIMIZED_STATE */
414 if (pCD->maxConfig == False)
416 ConfigureNewState (pCD);
420 if (currentState == MINIMIZED_STATE)
422 Boolean clearIconFocus;
425 * give up keyboard focus
428 if ((wmGD.keyboardFocus == pCD) ||
429 (wmGD.nextKeyboardFocus == pCD))
431 Do_Focus_Key (NULL, setTime, ALWAYS_SET_FOCUS | WORKSPACE_IF_NULL);
434 if (wmGD.keyboardFocus == pCD)
436 clearIconFocus = True;
440 clearIconFocus = False;
444 * The wm icon frame window and the client icon window
445 * (if it is being used) are mapped and the client window and
446 * client frame are unmapped.
449 if (ICON_FRAME_WIN(pCD))
451 if (pSD->useIconBox && P_ICON_BOX(pCD) &&
452 !(pCD->clientFlags & ICON_BOX))
454 ShowClientIconState(pCD, newState);
458 Boolean doGrab = False;
460 doGrab = (Success == XGrabPointer
461 (DISPLAY, DefaultRootWindow(DISPLAY),
462 False, event_mask, GrabModeAsync, GrabModeAsync,
463 None, None, CurrentTime));
464 XUnmapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
467 XUnmapWindow (DISPLAY, pCD->iconWindow);
469 if (event_mask && doGrab)
472 XMaskEvent(DISPLAY, event_mask, &event);
473 XUngrabPointer(DISPLAY,CurrentTime);
475 if (wmGD.iconAutoPlace)
477 for (wsI = 0; wsI < pCD->numInhabited; wsI++)
479 iplace = pCD->pWsList[wsI].iconPlace;
480 if (iplace != NO_ICON_PLACE)
482 pWS_i = GetWorkspaceData (pCD->pSD,
483 pCD->pWsList[wsI].wsID);
484 pWS_i->IPData.placeList[iplace].pCD =
493 ClearFocusIndication (pCD, False /*no refresh*/);
494 wmGD.keyboardFocus = NULL;
498 if ((currentState != NORMAL_STATE) && (currentState != MAXIMIZED_STATE))
501 * Note that maximized state is considered a NormalState in
502 * the ICCC. SetClientWMState also sets the state in the
506 if (currentState == MINIMIZED_STATE)
509 * Raise the window(s) when they are deiconified.
512 pCD->clientState = newState;
513 wmGD.bSuspendSecondaryRestack = True;
514 F_Raise (NULL, pCD, NULL);
515 wmGD.bSuspendSecondaryRestack = False;
518 if ( (!(pCD->clientFlags & ICON_BOX)) ||
519 ((pCD->clientFlags & ICON_BOX) && (!(firstTime))) )
521 if ((currentState == WITHDRAWN_STATE) &&
522 (pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUBPANEL) &&
523 !(pCD->transientChildren))
525 if (pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUB_RESTORED)
527 pCD->dtwmBehaviors &= ~DtWM_BEHAVIOR_SUB_RESTORED;
528 pCD->dtwmBehaviors &= ~DtWM_BEHAVIOR_SUBPANEL;
529 XMapWindow (DISPLAY, pCD->client);
530 XMapWindow (DISPLAY, pCD->clientFrameWin);
534 SlideWindowOut (pCD);
538 MapClientWindows (pCD);
543 * Set the WM_STATE property of the window and any associated
544 * transients, along with the clientState value. The call
545 * is made with an indication of NORMAL_STATE to insure
546 * that transient window clientState values are setup
547 * correctly. The top-level window clientState is set later.
550 SetClientWMState (pCD, NormalState, NORMAL_STATE);
552 pCD->clientState = newState;
554 if ((wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT) &&
555 (currentState == MINIMIZED_STATE) && wmGD.deiconifyKeyFocus)
557 ClientData *pcdFocus;
559 pcdFocus = FindTransientFocus (pCD);
562 Do_Focus_Key (pcdFocus, setTime, ALWAYS_SET_FOCUS);
566 if ( pSD->useIconBox && P_ICON_BOX(pCD) &&
567 (!(pCD->clientFlags & ICON_BOX)) && (ICON_FRAME_WIN(pCD)))
570 * force icon appearance in icon box to change
573 IconExposureProc (pCD, True);
576 } /* END OF FUNCTION SetupWindowStateWithEventMask */
581 /*************************************<->*************************************
583 * ConfigureNewState (pcd)
588 * Configure the window to a new state
593 * pcd - pointer to client data
601 * o This is only good for going between NORMAL and MAXIMIZED state.
603 *************************************<->***********************************/
605 void ConfigureNewState (ClientData *pcd)
607 WmHeadInfo_t *WmHI = NULL;
611 pcd->maxConfig = FALSE;
612 RegenerateClientFrame(pcd);
613 XResizeWindow (DISPLAY, pcd->client,
614 (unsigned int) pcd->clientWidth,
615 (unsigned int) pcd->clientHeight);
620 * Update client config to reflect underlying head, if MultiHead is active
622 if (WmHI = GetHeadInfo(pcd)) {
623 FrameToClient(pcd, &WmHI->x_org, &WmHI->y_org,
624 &WmHI->width, &WmHI->height);
625 pcd->maxX = WmHI->x_org;
626 pcd->maxY = WmHI->y_org;
627 pcd->maxWidth = WmHI->width;
628 pcd->maxHeight = WmHI->height;
631 XResizeWindow (DISPLAY, pcd->client,
632 (unsigned int) pcd->maxWidth,
633 (unsigned int) pcd->maxHeight);
634 pcd->maxConfig = TRUE;
635 RegenerateClientFrame(pcd);
637 SendConfigureNotify (pcd);
640 * Force repaint if size doesn't change to update frame appearance.
643 if ((pcd->clientWidth == pcd->maxWidth) &&
644 (pcd->clientHeight == pcd->maxHeight))
646 FrameExposureProc (pcd);
649 } /* END OF FUNCTION ConfigureNewState */
653 /*************************************<->*************************************
655 * UnmapClients (pCD, event_mask)
660 * Unmap the window(s). The indicated client may be the head of a transient
661 * tree - if it is unmap all windows in the transient tree.
666 * pCD = pointer to client data of window(s) to be unmapped
667 * event_mask = what to grab to prevent stray events going somewhere. Our
668 * passive grab has just been activated -- but it is dropped when the
669 * window is unmapped and the ButtonRelease event can go to the window
670 * now exposed. Avoid this by grabbing the ButtonRelease before the unmap
672 * Also done for icon being unmapped.
674 *************************************<->***********************************/
676 static void UnmapClients (ClientData *pCD, unsigned int event_mask)
679 Boolean doGrab = False;
681 pNext = pCD->transientChildren;
684 /* unmap all children first */
685 if (pNext->transientChildren)
686 UnmapClients (pNext, (unsigned int) 0);
688 /* then unmap all siblings at this level */
689 XUnmapWindow (DISPLAY, pNext->clientFrameWin);
690 XUnmapWindow (DISPLAY, pNext->client);
691 pNext->wmUnmapCount++;
692 pNext = pNext->transientSiblings;
696 doGrab = (Success == XGrabPointer (DISPLAY, DefaultRootWindow(DISPLAY),
697 False, event_mask, GrabModeAsync, GrabModeAsync,
698 None, None, CurrentTime));
699 /* unmap this primary window */
700 XUnmapWindow (DISPLAY, pCD->clientFrameWin);
701 XUnmapWindow (DISPLAY, pCD->client);
702 if (event_mask && doGrab)
705 XMaskEvent(DISPLAY, event_mask, &event);
706 XUngrabPointer(DISPLAY,CurrentTime);
710 } /* END OF FUNCTION UnmapClients */
714 /*************************************<->*************************************
716 * SetClientWMState (pCD, wmState, mwmState)
721 * Set a new window manage state for a client window or a tree of transient
726 * pCD = pointer to client data
728 * wmState = new state for WM_STATE property
730 * mwmState = mwm client state
732 *************************************<->***********************************/
734 void SetClientWMState (ClientData *pCD, int wmState, int mwmState)
739 bToUnseen = (mwmState & UNSEEN_STATE) != 0;
740 mwmState &= ~UNSEEN_STATE;
742 SetClientWsIndex (pCD);
743 pNext = pCD->transientChildren;
746 if (pNext->transientChildren)
748 SetClientWMState (pNext, wmState, mwmState);
751 SetClientWsIndex (pNext);
752 SetWMState (pNext->client, wmState, ICON_FRAME_WIN(pNext));
753 if (pNext->maxConfig && mwmState == NORMAL_STATE)
755 pNext->clientState = MAXIMIZED_STATE;
757 else if (!pNext->maxConfig && mwmState == MAXIMIZED_STATE)
759 pNext->clientState = NORMAL_STATE;
763 pNext->clientState = mwmState;
766 pNext->clientState |= UNSEEN_STATE;
767 pNext = pNext->transientSiblings;
770 SetWMState (pCD->client, wmState, ICON_FRAME_WIN(pCD));
771 pCD->clientState = mwmState;
773 pCD->clientState |= UNSEEN_STATE;
775 } /* END OF FUNCTION SetClientWMState */
777 #define SLIDE_UP_PERCENTAGE 5
778 #define SLIDE_UP_DIVISOR (100/SLIDE_UP_PERCENTAGE)
779 #define SLIDE_UP_INTERVAL 15
781 /******************************<->*************************************
783 * void SlideOutTimerProc (client_data, id)
787 * An XtTimerCallbackProc to process slide up mapping of a panel
791 * client_data = pointer to a SlideOutRec
799 ******************************<->***********************************/
801 SlideOutTimerProc ( XtPointer client_data, XtIntervalId *id)
803 SlideOutRec *pSOR = (SlideOutRec *) client_data;
804 Boolean bDone = False;
809 * compute next increment;
811 switch (pSOR->direction)
816 pSOR->currY -= pSOR->incHeight;
817 pSOR->currHeight += pSOR->incHeight;
818 if ((pSOR->currY < pSOR->pCD->frameInfo.y) ||
819 (pSOR->currHeight > pSOR->pCD->frameInfo.height))
821 pSOR->currY = pSOR->pCD->frameInfo.y;
822 pSOR->currHeight = pSOR->pCD->frameInfo.height;
824 bDone = (pSOR->currY == pSOR->pCD->frameInfo.y);
828 pSOR->currY += pSOR->incHeight;
829 if (pSOR->incHeight >= pSOR->currHeight)
831 pSOR->currHeight = 0;
836 pSOR->currHeight -= pSOR->incHeight;
844 pSOR->currHeight += pSOR->incHeight;
845 if (pSOR->currHeight > pSOR->pCD->frameInfo.height)
847 pSOR->currHeight = pSOR->pCD->frameInfo.height;
850 (pSOR->currHeight == pSOR->pCD->frameInfo.height);
854 if (pSOR->incHeight >= pSOR->currHeight)
856 pSOR->currHeight = 0;
861 pSOR->currHeight -= pSOR->incHeight;
870 if (pSOR->currHeight > 0)
872 XMoveResizeWindow (DISPLAY, pSOR->coverWin,
873 pSOR->currX, pSOR->currY,
874 pSOR->currWidth, pSOR->currHeight);
876 XMoveResizeWindow (DISPLAY, pSOR->pCD->clientFrameWin,
877 pSOR->currX, pSOR->currY,
878 pSOR->currWidth, pSOR->currHeight);
882 * See if we need to continue
888 /* Time to really unmanage the slide-up */
889 XtUnmanageChild (pSOR->wSubpanel);
893 WmSubpanelPosted (DISPLAY1, pSOR->pCD->client);
894 SendConfigureNotify(pSOR->pCD);
898 XDestroyWindow (DISPLAY, pSOR->coverWin);
899 pSOR->pCD->pSOR = NULL;
900 XtFree ((char *)pSOR);
901 wmGD.iSlideUpsInProgress -= 1;
905 /* re-arm the timer */
906 XtAppAddTimeOut(wmGD.mwmAppContext, pSOR->interval,
907 SlideOutTimerProc, (XtPointer)pSOR);
908 XSync (DISPLAY, False);
912 } /* END OF FUNCTION SlideOutTimerProc */
916 /*************************************<->*************************************
918 * SlideWindowOut (pCD)
923 * Maps a window with a slide-out effect.
928 * pCD = pointer to client data
932 * Only supports slide-up or slide-down
934 *************************************<->***********************************/
937 SlideWindowOut (ClientData *pCD)
946 * Hmmm. We're already sliding this window.
947 * If we're supposed to go in the other direction,
948 * then turn it around.
950 if (pSOR->mapping == True)
953 * We're already mapping this guy, ignore this
954 * and finish what we've already got going.
961 * We're not mapping this guy. Reverse course!!
963 pSOR->mapping = True;
965 /* insure the client window is mapped */
966 XMapWindow (DISPLAY, pCD->client);
968 /* handle the rest on the next timeout */
973 /* map the primary window */
974 XMapWindow (DISPLAY, pCD->client);
975 pSOR = (SlideOutRec *) XtMalloc (sizeof(SlideOutRec));
979 * Compute this ahead of time so we can check against
980 * the window size. If the window is short, we'll
981 * just map it, avoiding a lot of processing.
983 pSOR->incHeight = (Dimension) (DisplayHeight(DISPLAY,
984 SCREEN_FOR_CLIENT(pCD))/SLIDE_UP_DIVISOR);
987 if ((pCD->slideDirection != SLIDE_NOT) && pSOR &&
988 (pSOR->incHeight < pCD->frameInfo.height))
990 XSetWindowAttributes window_attribs;
991 XWindowChanges window_changes;
995 * Set up data for processing slide up
998 pSOR->interval = SLIDE_UP_INTERVAL;
999 pSOR->direction = pCD->slideDirection;
1000 pSOR->mapping = True;
1001 pSOR->wSubpanel = NULL;
1002 pSOR->pCD->pSOR = pSOR;
1004 switch (pSOR->direction)
1008 pSOR->currWidth = pCD->frameInfo.width;
1009 pSOR->currHeight = pSOR->incHeight;
1010 pSOR->currX = pCD->frameInfo.x;
1011 pSOR->currY = pCD->frameInfo.y +
1012 (pCD->frameInfo.height - pSOR->currHeight);
1017 pSOR->currWidth = pCD->frameInfo.width;
1018 pSOR->currHeight = pSOR->incHeight;
1019 pSOR->currX = pCD->frameInfo.x;
1020 pSOR->currY = pCD->frameInfo.y;
1025 * Create screening window to hide the slide-up from button
1026 * events until it is all the way up.
1028 mask = CWOverrideRedirect;
1029 window_attribs.override_redirect = True;
1030 pSOR->coverWin = XCreateWindow(DISPLAY,
1031 RootWindow (DISPLAY, SCREEN_FOR_CLIENT(pCD)),
1032 pSOR->currX, pSOR->currY,
1033 pSOR->currWidth, pSOR->currHeight, 0,
1034 CopyFromParent,InputOnly,CopyFromParent,
1035 mask, &window_attribs);
1038 * Put screen window above the slide-up client
1040 mask = CWStackMode | CWSibling;
1041 window_changes.stack_mode = Above;
1042 window_changes.sibling = pCD->clientFrameWin;
1043 XConfigureWindow (DISPLAY, pSOR->coverWin, mask, &window_changes);
1046 * Start slide-up processing
1048 XMoveResizeWindow (DISPLAY, pSOR->coverWin, pSOR->currX, pSOR->currY,
1049 pSOR->currWidth, pSOR->currHeight);
1050 XMoveResizeWindow (DISPLAY, pCD->clientFrameWin,
1051 pSOR->currX, pSOR->currY, pSOR->currWidth, pSOR->currHeight);
1052 XMapWindow (DISPLAY, pSOR->coverWin);
1053 XMapWindow (DISPLAY, pCD->clientFrameWin);
1054 XSync (DISPLAY, False);
1056 XtAppAddTimeOut(wmGD.mwmAppContext, pSOR->interval,
1057 SlideOutTimerProc, (XtPointer)pSOR);
1059 wmGD.iSlideUpsInProgress += 1;
1065 * Not sliding because no direction specified or our window
1066 * is just a little guy.
1068 XMapWindow (DISPLAY, pCD->clientFrameWin);
1071 XtFree ((char *) pSOR);
1076 } /* END OF FUNCTION SlideOutWindow */
1080 /*************************************<->*************************************
1082 * SlideSubpanelBackIn (pCD, wSubpanel)
1087 * Slides a subpanel back in
1092 * pCD = pointer to client data
1093 * wSubpanel = subpanel widget to unmanage
1098 *************************************<->***********************************/
1101 SlideSubpanelBackIn (ClientData *pCD, Widget wSubpanel)
1110 * Hmmm. We're already sliding this window.
1111 * If we're supposed to go in the other direction,
1112 * then turn it around.
1114 if (pSOR->mapping == False)
1117 * We're already unmapping this guy, ignore this
1118 * and finish what we've already got going.
1125 * We're mapping this guy. Reverse course!!
1127 pSOR->mapping = False;
1128 pSOR->wSubpanel = wSubpanel;
1130 /* handle the rest on the next timeout */
1135 pSOR = (SlideOutRec *) XtMalloc (sizeof(SlideOutRec));
1139 * Compute this ahead of time to check if our window
1140 * is short. If it is, we'll just unmap it, avoiding
1141 * a lot of extra work.
1143 pSOR->incHeight = (Dimension) (DisplayHeight(DISPLAY,
1144 SCREEN_FOR_CLIENT(pCD))/SLIDE_UP_DIVISOR);
1147 if ((pCD->slideDirection != SLIDE_NOT) && pSOR &&
1148 (pSOR->incHeight < pCD->frameInfo.height))
1150 XSetWindowAttributes window_attribs;
1151 XWindowChanges window_changes;
1155 * Set up data for processing slide up
1158 pSOR->interval = SLIDE_UP_INTERVAL;
1159 pSOR->direction = pCD->slideDirection;
1160 pSOR->mapping = False;
1161 pSOR->wSubpanel = wSubpanel;
1162 pSOR->pCD->pSOR = pSOR;
1165 pSOR->currWidth = pCD->frameInfo.width;
1166 pSOR->currHeight = pCD->frameInfo.height;
1167 pSOR->currX = pCD->frameInfo.x;
1168 pSOR->currY = pCD->frameInfo.y;
1170 switch (pSOR->direction)
1173 pSOR->currHeight -= pSOR->incHeight;
1174 pSOR->currY += pSOR->incHeight;
1178 pSOR->currHeight -= pSOR->incHeight;
1183 * Create screening window to hide the slide-up from button
1184 * events until it is all the way up.
1186 mask = CWOverrideRedirect;
1187 window_attribs.override_redirect = True;
1188 pSOR->coverWin = XCreateWindow(DISPLAY,
1189 RootWindow (DISPLAY, SCREEN_FOR_CLIENT(pCD)),
1190 pSOR->currX, pSOR->currY,
1191 pSOR->currWidth, pSOR->currHeight, 0,
1192 CopyFromParent,InputOnly,CopyFromParent,
1193 mask, &window_attribs);
1196 * Put screen window above the slide-up client
1198 mask = CWStackMode | CWSibling;
1199 window_changes.stack_mode = Above;
1200 window_changes.sibling = pCD->clientFrameWin;
1201 XConfigureWindow (DISPLAY, pSOR->coverWin, mask, &window_changes);
1204 * Start slide-up processing
1206 XMapWindow (DISPLAY, pSOR->coverWin);
1208 if (pSOR->currHeight > 0)
1210 XMoveResizeWindow (DISPLAY, pCD->clientFrameWin,
1211 pSOR->currX, pSOR->currY,
1212 pSOR->currWidth, pSOR->currHeight);
1214 XMoveResizeWindow (DISPLAY, pSOR->coverWin,
1215 pSOR->currX, pSOR->currY,
1216 pSOR->currWidth, pSOR->currHeight);
1218 XSync (DISPLAY, False);
1221 XtAppAddTimeOut(wmGD.mwmAppContext, pSOR->interval,
1222 SlideOutTimerProc, (XtPointer)pSOR);
1224 wmGD.iSlideUpsInProgress += 1;
1230 * Not sliding because no direction specified or our window
1231 * is just a little guy.
1233 /* Just unmanage the slide-up */
1234 XtUnmanageChild (wSubpanel);
1237 XtFree ((char *) pSOR);
1242 } /* END OF FUNCTION SlideOutWindow */
1245 /*************************************<->*************************************
1247 * MapClientWindows (pCD)
1252 * Maps the window. If this is a transient tree then all the windows in
1253 * the transient tree are mapped.
1258 * pCD = pointer to client data
1260 *************************************<->***********************************/
1262 void MapClientWindows (ClientData *pCD)
1267 pNext = pCD->transientChildren;
1270 /* map all transient children first */
1271 if (pNext->transientChildren)
1273 MapClientWindows (pNext);
1276 /* then map all siblings at this level */
1277 XMapWindow (DISPLAY, pNext->client);
1278 XMapWindow (DISPLAY, pNext->clientFrameWin);
1280 pNext = pNext->transientSiblings;
1283 /* map the primary window */
1284 XMapWindow (DISPLAY, pCD->client);
1285 XMapWindow (DISPLAY, pCD->clientFrameWin);
1287 } /* END OF FUNCTION MapClientWindows */
1291 /*************************************<->*************************************
1293 * ShowIconForMinimizedClient (pWS, pCD)
1298 * This function shows the icon for the specified client. If the icon
1299 * is in an icon box then the "minimized" icon is displayed. If the icon
1300 * is on the root window it is mapped.
1305 * pWS = pointer to workspace data
1306 * pCD = pointer to client data
1308 *************************************<->***********************************/
1310 void ShowIconForMinimizedClient (WmWorkspaceData *pWS, ClientData *pCD)
1312 WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
1315 * Handle auto-placement for root icons (icons not in an icon
1318 if (wmGD.iconAutoPlace && !P_ICON_BOX(pCD))
1320 if ((ICON_PLACE(pCD) == NO_ICON_PLACE) ||
1321 ((pWS->IPData.placeList[ICON_PLACE(pCD)].pCD) &&
1322 (pWS->IPData.placeList[ICON_PLACE(pCD)].pCD != pCD)))
1325 * Icon place not defined or occupied by another client,
1326 * find a free place to put the icon.
1329 if ((ICON_PLACE(pCD) = GetNextIconPlace (&pWS->IPData))
1333 CvtIconPositionToPlace (&pWS->IPData,
1337 CvtIconPlaceToPosition (&pWS->IPData, ICON_PLACE(pCD),
1338 &ICON_X(pCD), &ICON_Y(pCD));
1342 pWS->IPData.placeList[ICON_PLACE(pCD)].pCD = pCD;
1346 * If icon on root window and this workspace is active, the
1347 * make sure it's in the right place.
1349 if ((pWS == pSD->pActiveWS) && !P_ICON_BOX(pCD))
1351 XMoveWindow (DISPLAY, ICON_FRAME_WIN(pCD),
1352 ICON_X(pCD), ICON_Y(pCD));
1355 if (pCD->iconWindow)
1357 XMapWindow (DISPLAY, pCD->iconWindow);
1360 if ((pSD->useIconBox) && P_ICON_BOX(pCD))
1362 ShowClientIconState (pCD, MINIMIZED_STATE );
1366 XWindowChanges windowChanges;
1369 * Map the icon on the screen at the appropriate place in the
1373 if (wmGD.lowerOnIconify)
1375 if ((&pCD->iconEntry != pSD->lastClient) &&
1378 if (pSD->lastClient->type == MINIMIZED_STATE)
1380 windowChanges.sibling =
1381 ICON_FRAME_WIN(pSD->lastClient->pCD);
1385 windowChanges.sibling =
1386 pSD->lastClient->pCD->clientFrameWin;
1388 windowChanges.stack_mode = Below;
1389 XConfigureWindow (DISPLAY, ICON_FRAME_WIN(pCD),
1390 (CWSibling | CWStackMode), &windowChanges);
1391 MoveEntryInList (pWS, &pCD->iconEntry,
1392 False /*on bottom*/, NULL);
1397 windowChanges.sibling = pCD->clientFrameWin;
1398 windowChanges.stack_mode = Below;
1399 XConfigureWindow (DISPLAY, ICON_FRAME_WIN(pCD),
1400 (CWSibling | CWStackMode), &windowChanges);
1401 MoveEntryInList (pWS, &pCD->iconEntry, False /*below*/,
1405 if (pWS == pSD->pActiveWS)
1407 XMapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
1411 } /* END OF FUNCTION ShowIconForMinimizedClient */
1413 /*************************************<->*************************************
1415 * ShowAllIconsForMinimizedClient (pCD)
1420 * This function places icons in all the workspaces for the minimized
1421 * client. Since there is only one clientState per client (not per
1422 * workspace), this loops over all workspace in which the client
1423 * resides and places an icon in each.
1428 * pCD = pointer to client data
1432 * This operates by setting up the currentWsc index for each workspace
1433 * and calling ShowIconForMinimizedClient, which makes heavy use of
1434 * the macros that use the currentWsc index.
1436 *************************************<->***********************************/
1438 void ShowAllIconsForMinimizedClient (ClientData *pCD)
1440 int saveWsc = pCD->currentWsc;
1442 WmWorkspaceData *pWS;
1444 for (tmpWsc = 0; tmpWsc < pCD->numInhabited; tmpWsc++)
1446 pCD->currentWsc = tmpWsc;
1447 pWS = GetWorkspaceData (PSD_FOR_CLIENT(pCD),
1448 pCD->pWsList[tmpWsc].wsID);
1449 ShowIconForMinimizedClient(pWS, pCD);
1452 pCD->currentWsc = saveWsc;
1454 } /* END OF FUNCTION ShowAllIconsForMinimizedClient */