2 * (c) Copyright 1989, 1990, 1991, 1992 OPEN SOFTWARE FOUNDATION, INC.
10 static char rcsid[] = "$XConsortium: WmWinState.c /main/6 1996/06/20 09:39:39 rswiston $"
14 * (c) Copyright 1987, 1988, 1989, 1990 HEWLETT-PACKARD COMPANY */
22 #include "WmProtocol.h"
26 * include extern functions
30 #include "WmFunction.h"
33 #include "WmIconBox.h"
34 #include "WmKeyFocus.h"
36 #include "WmPanelP.h" /* for typedef in WmManage.h */
39 #include "WmProperty.h"
40 #include "WmWinInfo.h"
41 #include "WmWinList.h"
43 #include "WmWrkspace.h"
48 * Function Declarations:
51 #include "WmWinState.h"
53 static void SlideWindowOut (ClientData *pCD);
55 static void UnmapClients (ClientData *pCD, unsigned int event_mask);
56 static void SetupWindowStateWithEventMask (ClientData *pCD, int newState, Time setTime, unsigned int event_mask);
66 /******************************<->*************************************
68 * SetClientState (pCD, newState, setTime)
73 * This function is used to change the state of a client window (between
74 * withdrawn, normal, minimized, maximized).
79 * pCD = This is a pointer to the window data for the window that
80 * is to have its state changed. The fields that are used
81 * are clientState, ...
83 * newState = This is the state that the client window is to be changed to.
85 * setTime = timestamp for state setting operations
90 * pCD.clientState = new client state
92 ******************************<->***********************************/
94 void SetClientState (ClientData *pCD, int newState, Time setTime)
96 SetClientStateWithEventMask(pCD, newState, setTime, (unsigned int)0);
97 } /* END OF FUNCTION SetClientState */
99 void SetClientStateWithEventMask (ClientData *pCD, int newState, Time setTime, unsigned int event_mask)
101 ClientData *pcdLeader;
103 WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
105 Boolean notShowing = (newState & UNSEEN_STATE);
108 currentState = pCD->clientState;
109 if (currentState == newState)
111 /* no change in state */
117 * Undo the old state and setup the new state. If this is a transient
118 * window then insure that it is put in a state that is compatible
119 * with its transient leader (e.g., it cannot be minimized separately).
122 pcdLeader = (pCD->transientLeader) ? FindTransientTreeLeader (pCD) : pCD;
124 SetClientWsIndex (pCD);
127 if (pCD->transientLeader)
129 if ((pcdLeader->clientState == MINIMIZED_STATE) &&
130 (newState != WITHDRAWN_STATE))
132 newState = MINIMIZED_STATE;
136 newState |= UNSEEN_STATE;
140 else if ((newState == MINIMIZED_STATE) &&
141 (pcdLeader->clientState != MINIMIZED_STATE))
143 if (currentState == WITHDRAWN_STATE)
145 newState = NORMAL_STATE;
149 newState |= UNSEEN_STATE;
155 newState = currentState;
159 newState |= UNSEEN_STATE;
164 if (newState == currentState)
174 case UNSEEN_STATE | WITHDRAWN_STATE:
176 case 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);
193 XMapWindow (DISPLAY, pCD->client);
194 XMapWindow (DISPLAY, pCD->clientFrameWin);
195 #if defined(PANELIST)
196 WmStopWaiting(); /* in WmIPC.c */
197 #endif /* PANELIST */
202 case MINIMIZED_STATE:
204 Boolean clientHasFocus;
207 * Transient windows are minimized with the rest of the transient
208 * tree, including the transient leader.
211 if ((pCD->clientState == NORMAL_STATE) ||
212 (pCD->clientState == MAXIMIZED_STATE))
214 if ((wmGD.keyboardFocus == pCD) ||
215 (pCD->transientChildren && wmGD.keyboardFocus &&
216 (pCD == FindTransientTreeLeader (wmGD.keyboardFocus))))
218 clientHasFocus = True;
222 clientHasFocus = False;
225 if (clientHasFocus ||
226 ((wmGD.nextKeyboardFocus == pCD) ||
227 (pCD->transientChildren && wmGD.keyboardFocus &&
228 (pCD == FindTransientTreeLeader (wmGD.nextKeyboardFocus)))))
231 * Give up the keyboard focus when minimized (including
232 * the case in which an associated transient window has
233 * the focus). Immediately remove the focus indication
234 * from the window being minimized.
237 if (wmGD.autoKeyFocus &&
238 (wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT))
240 AutoResetKeyFocus (pcdLeader, setTime);
244 Do_Focus_Key (NULL, setTime,
245 ALWAYS_SET_FOCUS | WORKSPACE_IF_NULL);
250 SetKeyboardFocus (NULL, 0);
254 /* unmap main client and all transients */
255 UnmapClients (pCD, event_mask);
259 * Display the icon for the minimized client.
262 if (ICON_FRAME_WIN(pCD))
265 if (pCD->clientState & UNSEEN_STATE)
269 XMapWindow (DISPLAY, pCD->iconWindow);
271 XMapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
274 ShowAllIconsForMinimizedClient (pCD);
276 ShowIconForMinimizedClient (pSD->pActiveWS, pCD);
280 SetClientWMState (pCD, IconicState, MINIMIZED_STATE);
282 if ((pSD->useIconBox) && P_ICON_BOX(pCD))
284 if ((pCD->clientFlags & ICON_BOX) && ACTIVE_ICON_TEXT_WIN)
287 * Hide active icon text window and reparent it to
290 HideActiveIconText((WmScreenData *)NULL);
291 pSD->activeLabelParent = ACTIVE_ROOT;
292 XReparentWindow(DISPLAY, ACTIVE_ICON_TEXT_WIN ,
295 if (ICON_FRAME_WIN(pCD))
298 * force icon appearance in icon box to change
300 IconExposureProc (pCD, True);
308 case UNSEEN_STATE | NORMAL_STATE:
309 case UNSEEN_STATE | MAXIMIZED_STATE:
310 case UNSEEN_STATE | MINIMIZED_STATE:
312 if (wmGD.keyboardFocus == pCD)
315 * Give up the keyboard focus
317 Do_Focus_Key ((ClientData *)NULL,
318 CurrentTime, ALWAYS_SET_FOCUS);
319 SetKeyboardFocus (NULL, 0);
322 if (!(pCD->clientState & UNSEEN_STATE) &&
323 (((pCD->clientState & ~UNSEEN_STATE) == NORMAL_STATE) ||
324 ((pCD->clientState & ~UNSEEN_STATE) == MAXIMIZED_STATE)))
326 /* unmap main client and all transients */
327 UnmapClients (pcdLeader, event_mask);
331 if (pCD->clientFrameWin)
333 if (!P_ICON_BOX(pCD))
335 if (ICON_FRAME_WIN(pCD))
337 XUnmapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
340 XUnmapWindow (DISPLAY, pCD->iconWindow);
344 switch (newState & ~UNSEEN_STATE)
346 case MINIMIZED_STATE:
347 SetClientWMState (pCD, IconicState, newState);
351 case MAXIMIZED_STATE:
353 SetClientWMState (pCD, NormalState, newState);
361 } /* END OF FUNCTION SetClientStateWithEventMask */
365 /*************************************<->*************************************
367 * SetupWindowStateWithEventMask (pCD, newState, setTime, event_mask)
372 * This function is used to setup a client window in the Normal or Maximized
378 * pCD = This is a pointer to the window data for the window that
379 * is to have its state changed.
381 * newState = This is the state that the client window is to be changed to.
383 * setTime = timestamp for state setting operations
385 * event_mask = what to grab to prevent stray events going somewhere
389 * pCD.clientState = new client state
391 *************************************<->***********************************/
393 static void SetupWindowStateWithEventMask (ClientData *pCD, int newState,
394 Time setTime, unsigned int event_mask)
399 WmWorkspaceData *pWS_i;
401 WmWorkspaceData *pWS = PSD_FOR_CLIENT(pCD)->pActiveWS;
403 WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
405 currentState = pCD->clientState;
408 * A transient window is not restored or maximized if the transient leader
412 if (newState == NORMAL_STATE)
414 if (pCD->maxConfig == True)
417 * The configuration function uses maxConfig to determine
418 * what the current configuration is (and then resets
419 * maxConfig) and uses the state paramenter to determine
420 * what the new configuration is.
423 ConfigureNewState (pCD);
426 else /* MAXIMIZED_STATE */
428 if (pCD->maxConfig == False)
430 ConfigureNewState (pCD);
434 if (currentState == MINIMIZED_STATE)
436 Boolean clearIconFocus;
439 * give up keyboard focus
442 if ((wmGD.keyboardFocus == pCD) ||
443 (wmGD.nextKeyboardFocus == pCD))
445 Do_Focus_Key (NULL, setTime, ALWAYS_SET_FOCUS | WORKSPACE_IF_NULL);
448 if (wmGD.keyboardFocus == pCD)
450 clearIconFocus = True;
454 clearIconFocus = False;
458 * The wm icon frame window and the client icon window
459 * (if it is being used) are mapped and the client window and
460 * client frame are unmapped.
463 if (ICON_FRAME_WIN(pCD))
465 if (pSD->useIconBox && P_ICON_BOX(pCD) &&
466 !(pCD->clientFlags & ICON_BOX))
468 ShowClientIconState(pCD, newState);
472 Boolean doGrab = False;
474 doGrab = (Success == XGrabPointer
475 (DISPLAY, DefaultRootWindow(DISPLAY),
476 False, event_mask, GrabModeAsync, GrabModeAsync,
477 None, None, CurrentTime));
478 XUnmapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
481 XUnmapWindow (DISPLAY, pCD->iconWindow);
483 if (event_mask && doGrab)
486 XMaskEvent(DISPLAY, event_mask, &event);
487 XUngrabPointer(DISPLAY,CurrentTime);
490 if (wmGD.iconAutoPlace)
492 for (wsI = 0; wsI < pCD->numInhabited; wsI++)
494 iplace = pCD->pWsList[wsI].iconPlace;
495 if (iplace != NO_ICON_PLACE)
497 pWS_i = GetWorkspaceData (pCD->pSD,
498 pCD->pWsList[wsI].wsID);
499 pWS_i->IPData.placeList[iplace].pCD =
505 if ((wmGD.iconAutoPlace) && (ICON_PLACE(pCD) != NO_ICON_PLACE))
507 pWS->IPData.placeList[ICON_PLACE(pCD)].pCD =
515 ClearFocusIndication (pCD, False /*no refresh*/);
516 wmGD.keyboardFocus = NULL;
520 if ((currentState != NORMAL_STATE) && (currentState != MAXIMIZED_STATE))
523 * Note that maximized state is considered a NormalState in
524 * the ICCC. SetClientWMState also sets the state in the
528 if (currentState == MINIMIZED_STATE)
531 * Raise the window(s) when they are deiconified.
534 pCD->clientState = newState;
536 wmGD.bSuspendSecondaryRestack = True;
538 F_Raise (NULL, pCD, NULL);
540 wmGD.bSuspendSecondaryRestack = False;
544 if ( (!(pCD->clientFlags & ICON_BOX)) ||
545 ((pCD->clientFlags & ICON_BOX) && (!(firstTime))) )
548 if ((currentState == WITHDRAWN_STATE) &&
549 (pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUBPANEL) &&
550 !(pCD->transientChildren))
552 if (pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUB_RESTORED)
554 pCD->dtwmBehaviors &= ~DtWM_BEHAVIOR_SUB_RESTORED;
555 pCD->dtwmBehaviors &= ~DtWM_BEHAVIOR_SUBPANEL;
556 XMapWindow (DISPLAY, pCD->client);
557 XMapWindow (DISPLAY, pCD->clientFrameWin);
561 SlideWindowOut (pCD);
565 #endif /* PANELIST */
566 MapClientWindows (pCD);
571 * Set the WM_STATE property of the window and any associated
572 * transients, along with the clientState value. The call
573 * is made with an indication of NORMAL_STATE to insure
574 * that transient window clientState values are setup
575 * correctly. The top-level window clientState is set later.
578 SetClientWMState (pCD, NormalState, NORMAL_STATE);
580 pCD->clientState = newState;
582 if ((wmGD.keyboardFocusPolicy == KEYBOARD_FOCUS_EXPLICIT) &&
583 (currentState == MINIMIZED_STATE) && wmGD.deiconifyKeyFocus)
585 ClientData *pcdFocus;
587 pcdFocus = FindTransientFocus (pCD);
590 Do_Focus_Key (pcdFocus, setTime, ALWAYS_SET_FOCUS);
594 if ( pSD->useIconBox && P_ICON_BOX(pCD) &&
595 (!(pCD->clientFlags & ICON_BOX)) && (ICON_FRAME_WIN(pCD)))
598 * force icon appearance in icon box to change
601 IconExposureProc (pCD, True);
604 } /* END OF FUNCTION SetupWindowStateWithEventMask */
609 /*************************************<->*************************************
611 * ConfigureNewState (pcd)
616 * Configure the window to a new state
621 * pcd - pointer to client data
629 * o This is only good for going between NORMAL and MAXIMIZED state.
631 *************************************<->***********************************/
633 void ConfigureNewState (ClientData *pcd)
637 pcd->maxConfig = FALSE;
638 RegenerateClientFrame(pcd);
639 XResizeWindow (DISPLAY, pcd->client,
640 (unsigned int) pcd->clientWidth,
641 (unsigned int) pcd->clientHeight);
645 XResizeWindow (DISPLAY, pcd->client,
646 (unsigned int) pcd->maxWidth,
647 (unsigned int) pcd->maxHeight);
648 pcd->maxConfig = TRUE;
649 RegenerateClientFrame(pcd);
651 SendConfigureNotify (pcd);
654 * Force repaint if size doesn't change to update frame appearance.
657 if ((pcd->clientWidth == pcd->maxWidth) &&
658 (pcd->clientHeight == pcd->maxHeight))
660 FrameExposureProc (pcd);
663 } /* END OF FUNCTION ConfigureNewState */
667 /*************************************<->*************************************
669 * UnmapClients (pCD, event_mask)
674 * Unmap the window(s). The indicated client may be the head of a transient
675 * tree - if it is unmap all windows in the transient tree.
680 * pCD = pointer to client data of window(s) to be unmapped
681 * event_mask = what to grab to prevent stray events going somewhere. Our
682 * passive grab has just been activated -- but it is dropped when the
683 * window is unmapped and the ButtonRelease event can go to the window
684 * now exposed. Avoid this by grabbing the ButtonRelease before the unmap
686 * Also done for icon being unmapped.
688 *************************************<->***********************************/
690 static void UnmapClients (ClientData *pCD, unsigned int event_mask)
693 Boolean doGrab = False;
695 pNext = pCD->transientChildren;
698 /* unmap all children first */
699 if (pNext->transientChildren)
700 UnmapClients (pNext, (unsigned int) 0);
702 /* then unmap all siblings at this level */
703 XUnmapWindow (DISPLAY, pNext->clientFrameWin);
704 XUnmapWindow (DISPLAY, pNext->client);
705 pNext->wmUnmapCount++;
706 pNext = pNext->transientSiblings;
710 doGrab = (Success == XGrabPointer (DISPLAY, DefaultRootWindow(DISPLAY),
711 False, event_mask, GrabModeAsync, GrabModeAsync,
712 None, None, CurrentTime));
713 /* unmap this primary window */
714 XUnmapWindow (DISPLAY, pCD->clientFrameWin);
715 XUnmapWindow (DISPLAY, pCD->client);
716 if (event_mask && doGrab)
719 XMaskEvent(DISPLAY, event_mask, &event);
720 XUngrabPointer(DISPLAY,CurrentTime);
724 } /* END OF FUNCTION UnmapClients */
728 /*************************************<->*************************************
730 * SetClientWMState (pCD, wmState, mwmState)
735 * Set a new window manage state for a client window or a tree of transient
740 * pCD = pointer to client data
742 * wmState = new state for WM_STATE property
744 * mwmState = mwm client state
746 *************************************<->***********************************/
748 void SetClientWMState (ClientData *pCD, int wmState, int mwmState)
754 bToUnseen = (mwmState & UNSEEN_STATE) != 0;
755 mwmState &= ~UNSEEN_STATE;
759 SetClientWsIndex (pCD);
761 pNext = pCD->transientChildren;
764 if (pNext->transientChildren)
766 SetClientWMState (pNext, wmState, mwmState);
770 SetClientWsIndex (pNext);
772 SetWMState (pNext->client, wmState, ICON_FRAME_WIN(pNext));
773 if (pNext->maxConfig && mwmState == NORMAL_STATE)
775 pNext->clientState = MAXIMIZED_STATE;
778 else if (!pNext->maxConfig && mwmState == MAXIMIZED_STATE)
780 pNext->clientState = NORMAL_STATE;
785 pNext->clientState = mwmState;
789 pNext->clientState |= UNSEEN_STATE;
791 pNext = pNext->transientSiblings;
794 SetWMState (pCD->client, wmState, ICON_FRAME_WIN(pCD));
795 pCD->clientState = mwmState;
798 pCD->clientState |= UNSEEN_STATE;
801 } /* END OF FUNCTION SetClientWMState */
805 #define SLIDE_UP_PERCENTAGE 5
806 #define SLIDE_UP_DIVISOR (100/SLIDE_UP_PERCENTAGE)
807 #define SLIDE_UP_INTERVAL 15
809 /******************************<->*************************************
811 * void SlideOutTimerProc (client_data, id)
815 * An XtTimerCallbackProc to process slide up mapping of a panel
819 * client_data = pointer to a SlideOutRec
827 ******************************<->***********************************/
829 SlideOutTimerProc ( XtPointer client_data, XtIntervalId *id)
831 SlideOutRec *pSOR = (SlideOutRec *) client_data;
832 Boolean bDone = False;
837 * compute next increment;
839 switch (pSOR->direction)
844 pSOR->currY -= pSOR->incHeight;
845 pSOR->currHeight += pSOR->incHeight;
846 if ((pSOR->currY < pSOR->pCD->frameInfo.y) ||
847 (pSOR->currHeight > pSOR->pCD->frameInfo.height))
849 pSOR->currY = pSOR->pCD->frameInfo.y;
850 pSOR->currHeight = pSOR->pCD->frameInfo.height;
852 bDone = (pSOR->currY == pSOR->pCD->frameInfo.y);
856 pSOR->currY += pSOR->incHeight;
857 if (pSOR->incHeight >= pSOR->currHeight)
859 pSOR->currHeight = 0;
864 pSOR->currHeight -= pSOR->incHeight;
872 pSOR->currHeight += pSOR->incHeight;
873 if (pSOR->currHeight > pSOR->pCD->frameInfo.height)
875 pSOR->currHeight = pSOR->pCD->frameInfo.height;
878 (pSOR->currHeight == pSOR->pCD->frameInfo.height);
882 if (pSOR->incHeight >= pSOR->currHeight)
884 pSOR->currHeight = 0;
889 pSOR->currHeight -= pSOR->incHeight;
898 if (pSOR->currHeight > 0)
900 XMoveResizeWindow (DISPLAY, pSOR->coverWin,
901 pSOR->currX, pSOR->currY,
902 pSOR->currWidth, pSOR->currHeight);
904 XMoveResizeWindow (DISPLAY, pSOR->pCD->clientFrameWin,
905 pSOR->currX, pSOR->currY,
906 pSOR->currWidth, pSOR->currHeight);
910 * See if we need to continue
916 /* Time to really unmanage the slide-up */
917 XtUnmanageChild (pSOR->wSubpanel);
921 WmSubpanelPosted (DISPLAY1, pSOR->pCD->client);
922 SendConfigureNotify(pSOR->pCD);
926 XDestroyWindow (DISPLAY, pSOR->coverWin);
927 pSOR->pCD->pSOR = NULL;
928 XtFree ((char *)pSOR);
929 wmGD.iSlideUpsInProgress -= 1;
933 /* re-arm the timer */
934 XtAppAddTimeOut(wmGD.mwmAppContext, pSOR->interval,
935 SlideOutTimerProc, (XtPointer)pSOR);
936 XSync (DISPLAY, False);
940 } /* END OF FUNCTION SlideOutTimerProc */
944 /*************************************<->*************************************
946 * SlideWindowOut (pCD)
951 * Maps a window with a slide-out effect.
956 * pCD = pointer to client data
960 * Only supports slide-up or slide-down
962 *************************************<->***********************************/
965 SlideWindowOut (ClientData *pCD)
974 * Hmmm. We're already sliding this window.
975 * If we're supposed to go in the other direction,
976 * then turn it around.
978 if (pSOR->mapping == True)
981 * We're already mapping this guy, ignore this
982 * and finish what we've already got going.
989 * We're not mapping this guy. Reverse course!!
991 pSOR->mapping = True;
993 /* insure the client window is mapped */
994 XMapWindow (DISPLAY, pCD->client);
996 /* handle the rest on the next timeout */
1001 /* map the primary window */
1002 XMapWindow (DISPLAY, pCD->client);
1003 pSOR = (SlideOutRec *) XtMalloc (sizeof(SlideOutRec));
1007 * Compute this ahead of time so we can check against
1008 * the window size. If the window is short, we'll
1009 * just map it, avoiding a lot of processing.
1011 pSOR->incHeight = (Dimension) (DisplayHeight(DISPLAY,
1012 SCREEN_FOR_CLIENT(pCD))/SLIDE_UP_DIVISOR);
1015 if ((pCD->slideDirection != SLIDE_NOT) && pSOR &&
1016 (pSOR->incHeight < pCD->frameInfo.height))
1018 XSetWindowAttributes window_attribs;
1019 XWindowChanges window_changes;
1023 * Set up data for processing slide up
1026 pSOR->interval = SLIDE_UP_INTERVAL;
1027 pSOR->direction = pCD->slideDirection;
1028 pSOR->mapping = True;
1029 pSOR->wSubpanel = NULL;
1030 pSOR->pCD->pSOR = pSOR;
1032 switch (pSOR->direction)
1036 pSOR->currWidth = pCD->frameInfo.width;
1037 pSOR->currHeight = pSOR->incHeight;
1038 pSOR->currX = pCD->frameInfo.x;
1039 pSOR->currY = pCD->frameInfo.y +
1040 (pCD->frameInfo.height - pSOR->currHeight);
1045 pSOR->currWidth = pCD->frameInfo.width;
1046 pSOR->currHeight = pSOR->incHeight;
1047 pSOR->currX = pCD->frameInfo.x;
1048 pSOR->currY = pCD->frameInfo.y;
1053 * Create screening window to hide the slide-up from button
1054 * events until it is all the way up.
1056 mask = CWOverrideRedirect;
1057 window_attribs.override_redirect = True;
1058 pSOR->coverWin = XCreateWindow(DISPLAY,
1059 RootWindow (DISPLAY, SCREEN_FOR_CLIENT(pCD)),
1060 pSOR->currX, pSOR->currY,
1061 pSOR->currWidth, pSOR->currHeight, 0,
1062 CopyFromParent,InputOnly,CopyFromParent,
1063 mask, &window_attribs);
1066 * Put screen window above the slide-up client
1068 mask = CWStackMode | CWSibling;
1069 window_changes.stack_mode = Above;
1070 window_changes.sibling = pCD->clientFrameWin;
1071 XConfigureWindow (DISPLAY, pSOR->coverWin, mask, &window_changes);
1074 * Start slide-up processing
1076 XMoveResizeWindow (DISPLAY, pSOR->coverWin, pSOR->currX, pSOR->currY,
1077 pSOR->currWidth, pSOR->currHeight);
1078 XMoveResizeWindow (DISPLAY, pCD->clientFrameWin,
1079 pSOR->currX, pSOR->currY, pSOR->currWidth, pSOR->currHeight);
1080 XMapWindow (DISPLAY, pSOR->coverWin);
1081 XMapWindow (DISPLAY, pCD->clientFrameWin);
1082 XSync (DISPLAY, False);
1084 XtAppAddTimeOut(wmGD.mwmAppContext, pSOR->interval,
1085 SlideOutTimerProc, (XtPointer)pSOR);
1087 wmGD.iSlideUpsInProgress += 1;
1093 * Not sliding because no direction specified or our window
1094 * is just a little guy.
1096 XMapWindow (DISPLAY, pCD->clientFrameWin);
1099 XtFree ((char *) pSOR);
1104 } /* END OF FUNCTION SlideOutWindow */
1108 /*************************************<->*************************************
1110 * SlideSubpanelBackIn (pCD, wSubpanel)
1115 * Slides a subpanel back in
1120 * pCD = pointer to client data
1121 * wSubpanel = subpanel widget to unmanage
1126 *************************************<->***********************************/
1129 SlideSubpanelBackIn (ClientData *pCD, Widget wSubpanel)
1138 * Hmmm. We're already sliding this window.
1139 * If we're supposed to go in the other direction,
1140 * then turn it around.
1142 if (pSOR->mapping == False)
1145 * We're already unmapping this guy, ignore this
1146 * and finish what we've already got going.
1153 * We're mapping this guy. Reverse course!!
1155 pSOR->mapping = False;
1156 pSOR->wSubpanel = wSubpanel;
1158 /* handle the rest on the next timeout */
1163 pSOR = (SlideOutRec *) XtMalloc (sizeof(SlideOutRec));
1167 * Compute this ahead of time to check if our window
1168 * is short. If it is, we'll just unmap it, avoiding
1169 * a lot of extra work.
1171 pSOR->incHeight = (Dimension) (DisplayHeight(DISPLAY,
1172 SCREEN_FOR_CLIENT(pCD))/SLIDE_UP_DIVISOR);
1175 if ((pCD->slideDirection != SLIDE_NOT) && pSOR &&
1176 (pSOR->incHeight < pCD->frameInfo.height))
1178 XSetWindowAttributes window_attribs;
1179 XWindowChanges window_changes;
1183 * Set up data for processing slide up
1186 pSOR->interval = SLIDE_UP_INTERVAL;
1187 pSOR->direction = pCD->slideDirection;
1188 pSOR->mapping = False;
1189 pSOR->wSubpanel = wSubpanel;
1190 pSOR->pCD->pSOR = pSOR;
1193 pSOR->currWidth = pCD->frameInfo.width;
1194 pSOR->currHeight = pCD->frameInfo.height;
1195 pSOR->currX = pCD->frameInfo.x;
1196 pSOR->currY = pCD->frameInfo.y;
1198 switch (pSOR->direction)
1201 pSOR->currHeight -= pSOR->incHeight;
1202 pSOR->currY += pSOR->incHeight;
1206 pSOR->currHeight -= pSOR->incHeight;
1211 * Create screening window to hide the slide-up from button
1212 * events until it is all the way up.
1214 mask = CWOverrideRedirect;
1215 window_attribs.override_redirect = True;
1216 pSOR->coverWin = XCreateWindow(DISPLAY,
1217 RootWindow (DISPLAY, SCREEN_FOR_CLIENT(pCD)),
1218 pSOR->currX, pSOR->currY,
1219 pSOR->currWidth, pSOR->currHeight, 0,
1220 CopyFromParent,InputOnly,CopyFromParent,
1221 mask, &window_attribs);
1224 * Put screen window above the slide-up client
1226 mask = CWStackMode | CWSibling;
1227 window_changes.stack_mode = Above;
1228 window_changes.sibling = pCD->clientFrameWin;
1229 XConfigureWindow (DISPLAY, pSOR->coverWin, mask, &window_changes);
1232 * Start slide-up processing
1234 XMapWindow (DISPLAY, pSOR->coverWin);
1236 if (pSOR->currHeight > 0)
1238 XMoveResizeWindow (DISPLAY, pCD->clientFrameWin,
1239 pSOR->currX, pSOR->currY,
1240 pSOR->currWidth, pSOR->currHeight);
1242 XMoveResizeWindow (DISPLAY, pSOR->coverWin,
1243 pSOR->currX, pSOR->currY,
1244 pSOR->currWidth, pSOR->currHeight);
1246 XSync (DISPLAY, False);
1249 XtAppAddTimeOut(wmGD.mwmAppContext, pSOR->interval,
1250 SlideOutTimerProc, (XtPointer)pSOR);
1252 wmGD.iSlideUpsInProgress += 1;
1258 * Not sliding because no direction specified or our window
1259 * is just a little guy.
1261 /* Just unmanage the slide-up */
1262 XtUnmanageChild (wSubpanel);
1265 XtFree ((char *) pSOR);
1270 } /* END OF FUNCTION SlideOutWindow */
1271 #endif /* PANELIST */
1274 /*************************************<->*************************************
1276 * MapClientWindows (pCD)
1281 * Maps the window. If this is a transient tree then all the windows in
1282 * the transient tree are mapped.
1287 * pCD = pointer to client data
1289 *************************************<->***********************************/
1291 void MapClientWindows (ClientData *pCD)
1296 pNext = pCD->transientChildren;
1299 /* map all transient children first */
1300 if (pNext->transientChildren)
1302 MapClientWindows (pNext);
1305 /* then map all siblings at this level */
1306 XMapWindow (DISPLAY, pNext->client);
1307 XMapWindow (DISPLAY, pNext->clientFrameWin);
1309 pNext = pNext->transientSiblings;
1312 /* map the primary window */
1313 XMapWindow (DISPLAY, pCD->client);
1314 XMapWindow (DISPLAY, pCD->clientFrameWin);
1316 } /* END OF FUNCTION MapClientWindows */
1320 /*************************************<->*************************************
1322 * ShowIconForMinimizedClient (pWS, pCD)
1327 * This function shows the icon for the specified client. If the icon
1328 * is in an icon box then the "minimized" icon is displayed. If the icon
1329 * is on the root window it is mapped.
1334 * pWS = pointer to workspace data
1335 * pCD = pointer to client data
1337 *************************************<->***********************************/
1339 void ShowIconForMinimizedClient (WmWorkspaceData *pWS, ClientData *pCD)
1341 WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
1344 * Handle auto-placement for root icons (icons not in an icon
1347 if (wmGD.iconAutoPlace && !P_ICON_BOX(pCD))
1349 if ((ICON_PLACE(pCD) == NO_ICON_PLACE) ||
1350 ((pWS->IPData.placeList[ICON_PLACE(pCD)].pCD) &&
1351 (pWS->IPData.placeList[ICON_PLACE(pCD)].pCD != pCD)))
1354 * Icon place not defined or occupied by another client,
1355 * find a free place to put the icon.
1358 if ((ICON_PLACE(pCD) = GetNextIconPlace (&pWS->IPData))
1362 CvtIconPositionToPlace (&pWS->IPData,
1366 CvtIconPlaceToPosition (&pWS->IPData, ICON_PLACE(pCD),
1367 &ICON_X(pCD), &ICON_Y(pCD));
1370 XMoveWindow (DISPLAY, ICON_FRAME_WIN(pCD),
1371 ICON_X(pCD), ICON_Y(pCD));
1376 pWS->IPData.placeList[ICON_PLACE(pCD)].pCD = pCD;
1381 * If icon on root window and this workspace is active, the
1382 * make sure it's in the right place.
1384 if ((pWS == pSD->pActiveWS) && !P_ICON_BOX(pCD))
1386 XMoveWindow (DISPLAY, ICON_FRAME_WIN(pCD),
1387 ICON_X(pCD), ICON_Y(pCD));
1390 if (pCD->iconWindow)
1392 XMapWindow (DISPLAY, pCD->iconWindow);
1395 if ((pSD->useIconBox) && P_ICON_BOX(pCD))
1397 ShowClientIconState (pCD, MINIMIZED_STATE );
1401 XWindowChanges windowChanges;
1404 * Map the icon on the screen at the appropriate place in the
1408 if (wmGD.lowerOnIconify)
1410 if ((&pCD->iconEntry != pSD->lastClient) &&
1413 if (pSD->lastClient->type == MINIMIZED_STATE)
1415 windowChanges.sibling =
1416 ICON_FRAME_WIN(pSD->lastClient->pCD);
1420 windowChanges.sibling =
1421 pSD->lastClient->pCD->clientFrameWin;
1423 windowChanges.stack_mode = Below;
1424 XConfigureWindow (DISPLAY, ICON_FRAME_WIN(pCD),
1425 (CWSibling | CWStackMode), &windowChanges);
1426 MoveEntryInList (pWS, &pCD->iconEntry,
1427 False /*on bottom*/, NULL);
1432 windowChanges.sibling = pCD->clientFrameWin;
1433 windowChanges.stack_mode = Below;
1434 XConfigureWindow (DISPLAY, ICON_FRAME_WIN(pCD),
1435 (CWSibling | CWStackMode), &windowChanges);
1436 MoveEntryInList (pWS, &pCD->iconEntry, False /*below*/,
1441 if (pWS == pSD->pActiveWS)
1443 XMapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
1446 XMapWindow (DISPLAY, ICON_FRAME_WIN(pCD));
1450 } /* END OF FUNCTION ShowIconForMinimizedClient */
1454 /*************************************<->*************************************
1456 * ShowAllIconsForMinimizedClient (pCD)
1461 * This function places icons in all the workspaces for the minimized
1462 * client. Since there is only one clientState per client (not per
1463 * workspace), this loops over all workspace in which the client
1464 * resides and places an icon in each.
1469 * pCD = pointer to client data
1473 * This operates by setting up the currentWsc index for each workspace
1474 * and calling ShowIconForMinimizedClient, which makes heavy use of
1475 * the macros that use the currentWsc index.
1477 *************************************<->***********************************/
1479 void ShowAllIconsForMinimizedClient (ClientData *pCD)
1481 int saveWsc = pCD->currentWsc;
1483 WmWorkspaceData *pWS;
1485 for (tmpWsc = 0; tmpWsc < pCD->numInhabited; tmpWsc++)
1487 pCD->currentWsc = tmpWsc;
1488 pWS = GetWorkspaceData (PSD_FOR_CLIENT(pCD),
1489 pCD->pWsList[tmpWsc].wsID);
1490 ShowIconForMinimizedClient(pWS, pCD);
1493 pCD->currentWsc = saveWsc;
1495 } /* END OF FUNCTION ShowAllIconsForMinimizedClient */