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, 1993 OPEN SOFTWARE FOUNDATION, INC.
32 static char rcsid[] = "$TOG: WmWinInfo.c /main/18 1999/02/04 15:17:25 mgreess $"
36 * (c) Copyright 1987, 1988, 1989, 1990 HEWLETT-PACKARD COMPANY */
45 #include "WmResNames.h"
47 #define MWM_NEED_ICONBOX
48 #include "WmIBitmap.h"
56 #define makemult(a, b) ((b==1) ? (a) : (((int)((a) / (b))) * (b)) )
59 * include extern functions
61 #include "WmWinInfo.h"
68 #include "WmIconBox.h"
73 #include "WmProperty.h"
74 #include "WmResource.h"
76 #include "WmWrkspace.h"
78 #include "WmWinList.h"
80 #include "WmPresence.h"
83 #include "WmMultiHead.h"
86 static void AdjustSlideOutGeometry (ClientData *pCD);
87 static void FixSubpanelEmbeddedClientGeometry (ClientData *pCD);
90 #ifndef NO_MESSAGE_CATALOG
91 # define LOCALE_MSG GETMESSAGE(70, 7, "[XmbTextPropertyToTextList]:\n Locale (%.100s) not supported. (Check $LANG).")
93 # define LOCALE_MSG "[XmbTextPropertyToTextList]:\n Locale (%.100s) not supported. (Check $LANG)."
100 WmWorkspaceData *pIconBoxInitialWS;
105 /*************************************<->*************************************
107 * GetClientInfo (pSD, clientWindow, manageFlags)
112 * This function is used to initialize client window data based on the
113 * contents of client window properties and the client window configuration.
118 * pSD = pointer to screen data for screen that client lives in
120 * clientWindow = window id for the client window that is to be managed
122 * manageFlags = flags that indicate wm state info
127 * Return = pointer to an initialized client data structure for the
128 * specified client window
130 *************************************<->***********************************/
133 GetClientInfo (WmScreenData *pSD, Window clientWindow, long manageFlags)
137 XSetWindowAttributes sAttributes;
141 * Allocate and initialize a client data structure:
144 if (!(pCD = (ClientData *)XtMalloc (sizeof (ClientData))))
146 /* unable to allocate space */
147 Warning (((char *)GETMESSAGE(70, 1, "Insufficient memory for client data")));
153 * Initialize the data structure:
156 pCD->client = clientWindow;
157 pCD->clientID = ++(pSD->clientCounter);
158 pCD->clientFlags = WM_INITIALIZATION;
161 pCD->pIconBox = NULL;
163 pCD->thisIconBox = NULL;
168 #endif /* PANELIST */
169 pCD->wmUnmapCount = 0;
170 pCD->transientFor = (Window)0L;
171 pCD->transientLeader = NULL;
172 pCD->transientChildren = NULL;
173 pCD->transientSiblings = NULL;
175 pCD->primaryStackPosition = 0;
177 pCD->fullModalCount = 0;
178 pCD->primaryModalCount = 0;
179 pCD->focusPriority = 0;
180 pCD->focusAutoRaiseDisabled = False;
181 pCD->focusAutoRaiseDisablePending = False;
183 pCD->clientClass = NULL;
184 pCD->clientName = NULL;
185 pCD->clientFrameWin = (Window)0L;
187 pCD->iconFrameWin = (Window)0L;
189 pCD->iconWindow = (Window)0L;
190 pCD->iconPixmap = (Pixmap)0L;
192 pCD->iconPlace = NO_ICON_PLACE;
194 pCD->clientProtocols = NULL;
195 pCD->clientProtocolCount = 0;
196 pCD->mwmMessages = NULL;
197 pCD->mwmMessagesCount = 0;
198 pCD->clientCmapCount = 0;
199 pCD->clientCmapIndex = 0;
200 pCD->clientCmapFlagsInitialized = FALSE;
201 pCD->systemMenuSpec = NULL;
203 pCD->putInAll = False;
204 pCD->pWorkspaceHints = NULL;
205 pCD->numInhabited = 0;
207 pCD->dtwmFunctions = DtWM_FUNCTION_OCCUPY_WS;
208 pCD->dtwmBehaviors = 0L;
209 pCD->paInitialProperties = NULL;
210 pCD->numInitialProperties = 0;
213 pCD->decorFlags = 0L;
214 pCD->pTitleGadgets = NULL;
215 pCD->cTitleGadgets = 0;
216 pCD->pResizeGadgets = NULL;
217 pCD->clientTitleWin = (Window)0L;
218 pCD->pclientTopShadows = NULL;
219 pCD->pclientBottomShadows = NULL;
220 pCD->pclientTitleTopShadows = NULL;
221 pCD->pclientTitleBottomShadows = NULL;
222 pCD->pclientMatteTopShadows = NULL;
223 pCD->pclientMatteBottomShadows = NULL;
224 pCD->piconTopShadows = NULL;
225 pCD->piconBottomShadows = NULL;
226 pCD->internalBevel = (wmGD.frameStyle == WmSLAB) ? 0 :
227 FRAME_INTERNAL_SHADOW_WIDTH;
229 pCD->bPseudoTransient = False;
230 #endif /* NO_OL_COMPAT */
232 pCD->maxWidth = pCD->maxWidthLimit = BIGSIZE;
233 pCD->maxHeight = pCD->maxHeightLimit = BIGSIZE;
234 pCD->maxConfig = FALSE;
236 pCD->dataType = CLIENT_DATA_TYPE;
237 pCD->window_status = 0L;
239 pCD->clientEntry.nextSibling = NULL;
240 pCD->clientEntry.prevSibling = NULL;
241 pCD->clientEntry.pCD = NULL;
243 pCD->smClientID = (String)NULL;
246 * Do special processing for client windows that are controlled by
247 * the window manager.
250 if (manageFlags & MANAGEW_WM_CLIENTS)
253 WmWorkspaceData *pWS;
255 if (manageFlags & MANAGEW_ICON_BOX)
257 pWS = pIconBoxInitialWS;
261 pWS = pSD->pActiveWS;
263 return (GetWmClientInfo (pWS, pCD, manageFlags));
265 return (GetWmClientInfo (pSD->pActiveWS, pCD, manageFlags));
271 * Register the client window to facilitate event handling:
274 XSaveContext (DISPLAY, clientWindow, wmGD.windowContextType, (caddr_t)pCD);
278 * Listen for property change events on the window so that we keep
279 * in sync with the hints.
281 sAttributes.event_mask = (PropertyChangeMask | ColormapChangeMask);
282 XChangeWindowAttributes (DISPLAY, pCD->client, CWEventMask,
286 * Get window configuration attributes. WmGetWindowAttributes sets
287 * up the global window attributes cache with the client window
291 if (!WmGetWindowAttributes (clientWindow))
294 * Cannot get window attributes. Do not manage window.
295 * (error message within WmGetWindowAttributes)
298 UnManageWindow (pCD);
301 pCD->xBorderWidth = wmGD.windowAttributes.border_width;
305 * Get the initial list of properties on this window.
306 * Save it to optimize subsequent property fetching.
308 GetInitialPropertyList (pCD);
312 * Retrieve and process WM_CLASS hints client window property info:
315 ProcessWmClass (pCD);
319 * Retrieve and process WM_TRANSIENT_FOR client window property info:
322 ProcessWmTransientFor (pCD);
325 * Get client window resource data (from resources, .mwmrc):
326 * Moved prior to GetClientWorkspaceInfo() because the
327 * ignoreWMSaveHints resource may affect that function.
330 ProcessClientResources (pCD);
333 * Retreive and process SM_CLIENT_ID client window property info
334 * and WMSAVE_HINT client window property info:
335 * must be done prior to calling GetClientWorkspaceInfo().
337 ProcessSmClientID (pCD);
338 ProcessWmSaveHint (pCD);
342 * Set client's workspace information. NOTE: this also may
343 * set the geometry, initial state, etc. For Sm-aware clients,
344 * this info will be in private DB; for older clients, it will
345 * be contained in the screen's pDtSessionItems.
347 if (!GetClientWorkspaceInfo (pCD, manageFlags))
349 XtFree ((char *)pCD);
354 * Restore client's per-workspace icon information.
356 LoadClientIconPositions(pCD);
359 * Retrieve and process _DT_WM_HINTS client window property
360 * (results are used in ProcessMwmHints)
362 ProcessDtWmHints (pCD);
366 * For Sm-aware clients, retrieve geometry and initial state
369 FindClientDBMatch(pCD, (char **)NULL);
374 * Retrieve and process M_CLIENT_DECOR client window property info:
377 ProcessMwmHints (pCD);
381 * Retrieve and process WM_HINTS client window property info:
384 ProcessWmHints (pCD, True /*first time*/);
388 * Set offset from frame of client window
391 SetClientOffset (pCD);
395 * Retrieve and process WM_NORMAL_HINTS client window property info:
399 ProcessWmNormalHints (pCD, True /*first time*/, manageFlags);
403 * Retrieve and process WM_NAME client window property info (this
404 * property contains the window title NOT the window resource name):
407 ProcessWmWindowTitle (pCD, TRUE);
411 * Retrieve and process WM_ICON_NAME client window property info:
414 ProcessWmIconTitle (pCD, TRUE);
418 * Retrieve and process the WM_PROTOCOLS property.
421 ProcessWmProtocols (pCD);
425 * If necessary retrieve and process the _MWM_MESSAGES property.
428 if (pCD->protocolFlags & PROTOCOL_MWM_MESSAGES)
430 ProcessMwmMessages (pCD);
435 * Make or find a system menu for the client.
440 MakeSystemMenu (pCD);
444 pCD->systemMenuSpec = NULL;
449 * Setup the colormap data for the client window. This includes
450 * retrieving and processing client window properties that deal with
451 * subwindow colormaps.
454 InitCColormapData (pCD);
457 /* successful return */
462 } /* END OF FUNCTION GetClientInfo */
466 /*************************************<->*************************************
468 * GetWmClientInfo (pWS, pCD, manageFlags)
473 * This function is used to initialize client window data for a window
474 * that is controlled by the window manager (e.g., the icon box). The
475 * client window may get made in the process.
480 * pWS = pointer to workspace data
482 * pCD = pointer to client window data structure
484 * manageFlags = flags that indicate wm state info
489 * Return = pointer to an initialized client data structure or NULL
490 * if the client data could not be initialized
492 *************************************<->***********************************/
494 GetWmClientInfo (WmWorkspaceData *pWS,
505 * Set up the client class and name for resource retrieval.
506 * Get client specific resource data (from resources, .mwmrc).
509 if (manageFlags & MANAGEW_ICON_BOX)
511 SetIconBoxInfo (pWS, pCD);
513 else if (manageFlags & MANAGEW_CONFIRM_BOX)
515 pCD->clientClass = WmCConfirmbox;
516 pCD->clientName = WmNconfirmbox;
517 pCD->iconImage = NULL;
518 pCD->useClientIcon = False;
519 pCD->focusAutoRaise = True;
520 pCD->internalBevel = (wmGD.frameStyle == WmSLAB) ? 0 :
521 FRAME_INTERNAL_SHADOW_WIDTH;
523 pCD->maximumClientSize.width = 0;
524 pCD->maximumClientSize.height = 0;
525 pCD->systemMenu = NULL;
530 * Set up transient for data.
533 if (manageFlags & MANAGEW_ICON_BOX)
539 * Set up WM_HINTS type information.
542 pCD->inputFocusModel = True;
543 pCD->clientState = NORMAL_STATE;
545 if (ICON_DECORATION(pCD) & ICON_IMAGE_PART)
547 if (manageFlags & MANAGEW_ICON_BOX)
549 pCD->clientFlags |= ICON_BOX;
552 if (!pCD->useClientIcon && pCD->iconImage)
555 * Make a client supplied icon image.
556 * Do not use the default icon image if iconImage is not found.
559 pCD->iconPixmap = MakeNamedIconPixmap (pCD, pCD->iconImage);
562 if (!pCD->iconPixmap)
565 * Use a built-in icon image for the window manager client.
566 * The image may differ from the default icon image, depending on
567 * the particular client (eg the iconbox).
570 if (manageFlags & MANAGEW_ICON_BOX)
573 * Make a default iconBox icon image.
576 iconBitmap = XCreateBitmapFromData (DISPLAY,
577 ROOT_FOR_CLIENT(pCD), (char *)iconBox_bits,
578 iconBox_width, iconBox_height);
580 pCD->iconPixmap = MakeIconPixmap (pCD,
581 iconBitmap, (Pixmap)0L,
582 iconBox_width, iconBox_height, 1);
590 * Allocate initial workspace ID list
593 if ((pCD->pWsList = (WsClientData *)
594 XtMalloc(pCD->pSD->numWorkspaces * sizeof(WsClientData))) == NULL)
596 Warning (((char *)GETMESSAGE(70, 2, "Insufficient memory for client data")));
599 pCD->sizeWsList = pCD->pSD->numWorkspaces;
600 for (i = 0; i < pCD->pSD->numWorkspaces; i++)
602 pCD->pWsList[i].wsID = 0L;
603 pCD->pWsList[i].iconPlace = NO_ICON_PLACE;
604 pCD->pWsList[i].iconX = 0;
605 pCD->pWsList[i].iconY = 0;
606 pCD->pWsList[i].iconFrameWin = (Window)0L;
607 pCD->pWsList[i].pIconBox = NULL;
610 * Internally managed clients must be specifically inserted
611 * into workspaces the first time by calling
612 * PutClientIntoWorkspace.
614 pCD->numInhabited = 0;
616 pCD->iconPlace = NO_ICON_PLACE;
620 pCD->windowGroup = 0L;
622 pCD->bPseudoTransient = False;
623 #endif /* NO_OL_COMPAT */
627 * Set up _MWM_HINTS data.
630 * Fix the client functions and decorations fields if they have
631 * default resource values.
635 if (manageFlags & MANAGEW_CONFIRM_BOX)
637 pCD->clientFunctions = WM_FUNC_NONE;
638 pCD->clientDecoration = WM_DECOR_BORDER;
642 if (pCD->clientFunctions & WM_FUNC_DEFAULT)
644 pCD->clientFunctions = WM_FUNC_ALL;
647 if (pCD->clientDecoration & WM_DECOR_DEFAULT)
649 pCD->clientDecoration = WM_DECOR_ALL;
652 if (manageFlags & MANAGEW_ICON_BOX)
654 pCD->clientFunctions &= ICON_BOX_FUNCTIONS;
656 pCD->dtwmFunctions &= ~DtWM_FUNCTION_OCCUPY_WS;
659 if (wmGD.useFrontPanel && pCD->pSD->iconBoxControl)
662 * If there's a front panel button for the icon
663 * box, then use it to "hide" the box on "close"
665 pCD->clientFunctions &= ~MWM_FUNC_MINIMIZE;
666 pCD->clientFunctions |= MWM_FUNC_CLOSE;
669 #endif /* PANELIST */
673 if (!(pCD->clientFunctions & MWM_FUNC_RESIZE))
675 pCD->clientDecoration &= ~MWM_DECOR_RESIZEH;
678 if (!(pCD->clientFunctions & MWM_FUNC_MINIMIZE))
680 pCD->clientDecoration &= ~MWM_DECOR_MINIMIZE;
683 if (!(pCD->clientFunctions & MWM_FUNC_MAXIMIZE))
685 pCD->clientDecoration &= ~MWM_DECOR_MAXIMIZE;
689 pCD->decor = pCD->clientDecoration;
691 if (manageFlags & MANAGEW_ICON_BOX)
693 pCD->inputMode = MWM_INPUT_MODELESS;
695 else if (manageFlags & MANAGEW_CONFIRM_BOX)
697 pCD->inputMode = MWM_INPUT_SYSTEM_MODAL;
701 * Set up WM_NORMAL_HINTS data.
704 pCD->icccVersion = ICCC_CURRENT;
705 pCD->sizeFlags = US_POSITION | US_SIZE;
708 * Any calls to create Window Manager clients should
709 * return with the values for the following fields set.
710 * If it fails, it should free any space allocated and
716 * pCD->clientHeight =
726 * pCD->oldMaxHeight =
728 * AND PROBABLY SHOULD SET
729 * pCD->client = THE_WINDOW_THE_FUNCTION_CREATES
732 pCD->windowGravity = NorthWestGravity;
735 * Create IconBox window
738 if (manageFlags & MANAGEW_ICON_BOX)
740 if (!MakeIconBox (pWS, pCD))
743 * May want a more verbose message here
746 Warning (((char *)GETMESSAGE(70, 3, "Couldn't make icon box")));
750 PutClientIntoWorkspace (pWS, pCD);
753 else if (manageFlags & MANAGEW_CONFIRM_BOX)
756 unsigned int cbWidth, cbHeight;
759 XGetGeometry (DISPLAY, pCD->client, &root,
760 &(pCD->clientX), &(pCD->clientY),
762 (unsigned int*)&(pCD->xBorderWidth), &depth);
764 pCD->clientWidth = cbWidth;
765 pCD->clientHeight = cbHeight;
766 pCD->minWidth = pCD->baseWidth = pCD->maxWidth = pCD->clientWidth;
767 pCD->minHeight = pCD->baseHeight = pCD->maxHeight = pCD->clientHeight;
768 pCD->oldMaxWidth = pCD->maxWidth;
769 pCD->oldMaxHeight = pCD->maxHeight;
772 pCD->clientFlags |= CONFIRM_BOX;
774 PutClientIntoWorkspace (ACTIVE_WS, pCD);
779 * Set offset from frame of client window (need client size information).
786 * Register the client window to facilitate event handling.
789 XSaveContext (DISPLAY, pCD->client, wmGD.windowContextType, (caddr_t)pCD);
793 * Set up WM_PROTOCOLS data.
796 pCD->clientProtocolCount = 0;
797 pCD->protocolFlags = 0;
801 * Make the system menu.
804 if (manageFlags & MANAGEW_ICON_BOX)
806 #if ((!defined(WSM)) || defined(MWM_QATS_PROTOCOL))
807 /** BEGIN FIX CR 6941 **/
808 MenuItem *iconBoxMenuItems, *lastItem;
810 /* This MenuSpec is not added to pSD->acceleratorMenuSpecs */
811 pCD->systemMenuSpec =
812 MAKE_MENU (PSD_FOR_CLIENT(pCD), pCD, pCD->systemMenu,
813 F_CONTEXT_WINDOW, F_CONTEXT_WINDOW|F_CONTEXT_ICON,
815 if (pCD->systemMenuSpec != (MenuSpec *) NULL)
817 pCD->systemMenuSpec = DuplicateMenuSpec(pCD->systemMenuSpec);
818 XtFree(pCD->systemMenuSpec->name);
819 pCD->systemMenuSpec->name = XtNewString("IconBoxMenu");
820 iconBoxMenuItems = GetIconBoxMenuItems (PSD_FOR_CLIENT(pCD));
822 /* Find the last menu item in the menu spec's list. */
823 for (lastItem = pCD->systemMenuSpec->menuItems;
824 lastItem->nextMenuItem != (MenuItem *) NULL;
825 lastItem = lastItem->nextMenuItem)
827 lastItem->nextMenuItem = iconBoxMenuItems;
829 /* Now recreate the menu widgets since we've appended the
830 icon box menu items */
831 DestroyMenuSpecWidgets(pCD->systemMenuSpec);
832 pCD->systemMenuSpec->menuWidget =
833 CreateMenuWidget (PSD_FOR_CLIENT(pCD), pCD, "IconBoxMenu",
834 PSD_FOR_CLIENT(pCD)->screenTopLevelW, TRUE,
835 pCD->systemMenuSpec, NULL);
837 /** END FIX CR 6941 **/
839 pCD->systemMenuSpec =
840 MAKE_MENU (PSD_FOR_CLIENT(pCD), pCD, pCD->systemMenu,
841 F_CONTEXT_WINDOW, F_CONTEXT_WINDOW|F_CONTEXT_ICON,
842 GetIconBoxMenuItems(PSD_FOR_CLIENT(pCD)),
844 #endif /* !defined(WSM) || defined(MWM_QATS_PROTOCOL) */
850 * Setup the colormap data.
853 pCD->clientColormap = PSD_FOR_CLIENT(pCD)->workspaceColormap;
857 * Return the pointer to the client data.
863 } /* END OF FUNCTION GetWmClientInfo */
867 /*************************************<->*************************************
869 * ProcessWmClass (pCD)
874 * This function retrieves the contents of the WM_CLASS property on the
875 * cient window. The resource class and the resource name are saved in
876 * the ClientData structure (note that the space for the strings is
877 * allocated using Xmalloc).
882 * pCD - pointer to client data
891 *************************************<->***********************************/
894 ProcessWmClass (ClientData *pCD)
896 XClassHint classHint;
900 classHint.res_class = "";
901 classHint.res_name = "";
902 XGetClassHint (DISPLAY, pCD->client, &classHint);
905 if ((HasProperty (pCD, XA_WM_CLASS)) &&
906 (XGetClassHint (DISPLAY, pCD->client, &classHint)))
908 if (XGetClassHint (DISPLAY, pCD->client, &classHint))
912 /* the WM_CLASS property exists for the client window */
913 pCD->clientClass = classHint.res_class;
914 pCD->clientName = classHint.res_name;
916 /* else no WM_CLASS property; assume clientClass, clientName are NULL */
918 } /* END OF FUNCTION ProcessWmClass */
922 /*************************************<->*************************************
924 * ProcessSmClientID (pCD)
929 * This function retrieves the contents of the SM_CLIENT_ID property on the
930 * cient window. The value is saved in the ClientData structure
931 * (note that the space for the strings is allocated using Xmalloc).
936 * pCD - pointer to client data
945 *************************************<->***********************************/
948 ProcessSmClientID (ClientData *pCD)
952 unsigned long nitems, leftover;
955 if (pCD->smClientID != (String)NULL)
957 XFree(pCD->smClientID);
958 pCD->smClientID = (String)NULL;
961 if ((XGetWindowProperty(DISPLAY, pCD->client, wmGD.xa_SM_CLIENT_ID,
962 0L, (long)1000000, False, AnyPropertyType,
963 &actualType, &actualFormat, &nitems,
964 &leftover, (unsigned char **)&clientID)
966 (actualType != None) && (actualFormat == 8))
968 /* the SM_CLIENT_ID property exists for the client window */
969 pCD->smClientID = clientID;
972 } /* END OF FUNCTION ProcessSmClientID */
976 /*************************************<->*************************************
978 * ProcessWmSaveHint (pCD)
983 * This function retrieves the contents of the WMSAVE_HINT property on the
984 * cient window. The value is saved in the ClientData structure.
989 * pCD - pointer to client data
998 *************************************<->***********************************/
1001 ProcessWmSaveHint (ClientData *pCD)
1005 unsigned long nitems, leftover;
1006 BITS32 *saveHintFlags = (BITS32 *)NULL;
1008 if ((XGetWindowProperty(DISPLAY, pCD->client, wmGD.xa_WMSAVE_HINT,
1009 0L, (long)1000000, False, AnyPropertyType,
1010 &actualType, &actualFormat, &nitems,
1011 &leftover, (unsigned char **)&saveHintFlags)
1013 (actualType != None) && (actualFormat == 32))
1015 /* the WMSAVE_HINT property exists for the client window */
1016 pCD->wmSaveHintFlags = (int)*saveHintFlags;
1018 else pCD->wmSaveHintFlags = 0;
1021 XFree(saveHintFlags);
1023 } /* END OF FUNCTION ProcessWmSaveHint */
1026 /*************************************<->*************************************
1028 * ProcessWmHints (pCD, firstTime)
1033 * This function retrieves the contents of the WM_HINTS property on the
1039 * pCD = pointer to client data for the window with the property
1041 * firstTime = if True this is the first time the property has been processed
1046 * pCD = initialize various WM_HINTS related fields
1052 *************************************<->***********************************/
1055 ProcessWmHints (ClientData *pCD, Boolean firstTime)
1057 register XWMHints *pXWMHints;
1058 register long flags;
1062 WmWorkspaceData *pWsTmp;
1066 int tmpIconX, tmpIconY;
1070 * If the WM_HINTS property does not exist the flags field will be
1071 * set to 0. If flags is 0 don't reference the WMHints structure
1072 * since they may be none.
1076 if (firstTime && !HasProperty (pCD, XA_WM_HINTS))
1080 pXWMHints = XGetWMHints (DISPLAY, pCD->client);
1084 flags = pXWMHints->flags;
1093 * Parse the WM_HINTS information. If this is the first time the hints
1094 * have been processed then parse all fields and set defaults where hint
1095 * fields are not set. If this is not the first time do selective
1101 #ifndef NO_OL_COMPAT
1104 unsigned int numIDs = 0;
1107 * Save the window group.
1110 if (flags & WindowGroupHint)
1112 pCD->windowGroup = pXWMHints->window_group;
1114 * Pretend this is a transient window
1116 if ((pCD->bPseudoTransient) &&
1117 (pCD->transientFor == (Window)0L))
1119 pCD->clientFlags |= CLIENT_TRANSIENT;
1122 * Treat this like a transient window. This is transient
1123 * for the window group window.
1126 if ((pCD->client != pCD->windowGroup) &&
1127 !XFindContext (DISPLAY, pCD->windowGroup,
1128 wmGD.windowContextType, (caddr_t *)&leader))
1130 pCD->transientFor = pCD->windowGroup;
1131 pCD->transientLeader = leader;
1134 * Insure it is in the same set of workspaces
1137 if (pCD->transientLeader &&
1138 GetLeaderPresence(pCD, &pIDs, &numIDs))
1140 ProcessWorkspaceHintList (pCD, pIDs, numIDs);
1147 pCD->windowGroup = 0L;
1149 #endif /* NO_OL_COMPAT */
1151 * The window manger does not do anything with the input hint. Input
1152 * always goes to the selected window.
1155 if (flags & InputHint)
1157 pCD->inputFocusModel = pXWMHints->input;
1161 pCD->inputFocusModel = True;
1166 * The default state is NORMAL_STATE. States other than iconic
1167 * (e.g., ZoomState from the R2 ICCC) indicate to the window manager
1168 * that the NORMAL_STATE is to be used.
1171 if (pCD->clientFlags & SM_CLIENT_STATE)
1173 if ((pCD->clientState == MINIMIZED_STATE) &&
1174 (!(pCD->clientFunctions & MWM_FUNC_MINIMIZE)))
1176 pCD->clientState = NORMAL_STATE;
1180 if ((flags & StateHint) && (pXWMHints->initial_state == IconicState) &&
1181 (pCD->clientFunctions & MWM_FUNC_MINIMIZE))
1183 pCD->clientState = MINIMIZED_STATE;
1188 * States other than iconic are treated as normal.
1190 pCD->clientState = NORMAL_STATE;
1195 if (!ClientInWorkspace (PSD_FOR_CLIENT(pCD)->pActiveWS, pCD))
1197 pCD->clientState |= UNSEEN_STATE;
1203 * If an icon is to be made for the client then ...
1204 * save the icon image if useClientIcon is True or there is no
1205 * user specified icon image. A client supplied image may be a
1206 * pixmap or a window (a client icon window takes precedence over
1210 if ((pCD->clientFunctions & MWM_FUNC_MINIMIZE) &&
1211 (pCD->transientLeader == NULL))
1213 if ((ICON_DECORATION(pCD) & ICON_IMAGE_PART) &&
1214 (pCD->useClientIcon || !pCD->iconImage))
1216 if ((flags & IconWindowHint) &&
1217 (pXWMHints->icon_window != pCD->client))
1220 * An icon window has been supplied that is different from
1221 * the client window. Check out the window and get it
1222 * ready to be reparented to the window manager supplied
1226 if (!SetupClientIconWindow (pCD, pXWMHints->icon_window))
1229 * Cannot use the client supplied icon window. Use
1230 * an icon image if specified or a default image.
1234 if (!pCD->iconWindow && (flags & IconPixmapHint))
1236 iconMask = (flags & IconMaskHint) ?
1237 pXWMHints->icon_mask : (Pixmap) NULL;
1239 * A client supplied icon window is NOT
1240 * available so use the client supplied icon image.
1243 if ((pCD->iconPixmap =
1244 MakeClientIconPixmap (pCD,
1245 pXWMHints->icon_pixmap, iconMask)) != None)
1248 * Indicate that a client supplied icon image is being
1252 pCD->iconFlags |= ICON_HINTS_PIXMAP;
1257 * Cannot make a client supplied image. Use a user
1258 * specified icon image if it is available or a default
1265 if ((ICON_DECORATION(pCD) & ICON_IMAGE_PART) && !pCD->iconPixmap)
1268 * Use a user supplied icon image if it is available or a
1269 * default icon image.
1275 * Try to make a user specified icon image.
1279 MakeNamedIconPixmap (pCD, pCD->iconImage);
1282 if (!pCD->iconPixmap)
1285 * The icon image was not provided or not available.
1286 * Use the default icon image.
1289 pCD->iconPixmap = MakeNamedIconPixmap (pCD, NULL);
1295 * Save the client (user?) supplied icon position:
1298 if ((flags & IconPositionHint) ||
1299 (pCD->clientFlags & (SM_ICON_X | SM_ICON_Y)))
1301 pCD->iconFlags |= ICON_HINTS_POSITION;
1302 if (wmGD.iconAutoPlace)
1306 * Initialize icon placement data in all inhabited
1309 for (iws = 0; iws< pCD->numInhabited; iws++)
1311 pWsc = &(pCD->pWsList[iws]);
1312 if ((pWsTmp=GetWorkspaceData(pCD->pSD, pWsc->wsID)))
1314 tmpIconX = (pCD->clientFlags & SM_ICON_X) ?
1315 pWsc->iconX : pXWMHints->icon_x;
1316 tmpIconY = (pCD->clientFlags & SM_ICON_Y) ?
1317 pWsc->iconY : pXWMHints->icon_y;
1319 FindIconPlace (pCD, &(pWsTmp->IPData),
1320 tmpIconX, tmpIconY);
1321 if (pWsc->iconPlace != NO_ICON_PLACE)
1323 CvtIconPlaceToPosition ( &(pWsTmp->IPData),
1333 for (iws = 0; iws< pCD->numInhabited; iws++)
1335 pWsc = &(pCD->pWsList[iws]);
1336 if ((pWsTmp=GetWorkspaceData(pCD->pSD, pWsc->wsID)))
1338 if (!(pCD->clientFlags & SM_ICON_X))
1339 pWsc->iconX = pXWMHints->icon_x;
1340 if (!(pCD->clientFlags & SM_ICON_Y))
1341 pWsc->iconY = pXWMHints->icon_y;
1347 tmpIconX = (pCD->clientFlags & SM_ICON_X) ?
1348 pCD->iconX : pXWMHints->icon_x;
1349 tmpIconY = (pCD->clientFlags & SM_ICON_Y) ?
1350 pCD->iconY : pXWMHints->icon_y;
1352 FindIconPlace (pCD, &(pCD->pSD->pActiveWS->IPData),
1353 tmpIconX, tmpIconY);
1354 if (pCD->iconPlace != NO_ICON_PLACE)
1356 CvtIconPlaceToPosition (&(pCD->pSD->pActiveWS->IPData),
1357 pCD->iconPlace, &pCD->iconX, &pCD->iconY);
1362 if (!(pCD->clientFlags & SM_ICON_X))
1363 pCD->iconX = pXWMHints->icon_x;
1364 if (!(pCD->clientFlags & SM_ICON_Y))
1365 pCD->iconY = pXWMHints->icon_y;
1371 if (wmGD.iconAutoPlace)
1375 * Initialize icon placement data in all inhabited
1378 for (iws = 0; iws< pCD->numInhabited; iws++)
1380 pWsc = &(pCD->pWsList[iws]);
1381 pWsc->iconPlace = NO_ICON_PLACE;
1386 pCD->iconPlace = NO_ICON_PLACE;
1396 * Save the window group.
1399 if (flags & WindowGroupHint)
1401 pCD->windowGroup = pXWMHints->window_group;
1405 pCD->windowGroup = 0L;
1407 #endif /* NO_OL_COMPAT */
1409 else /* not the first time the hints are processed */
1411 if (flags & IconPixmapHint)
1414 * Process an icon image change if the icon image was initially
1415 * set up with a client supplied icon image OR, if the client
1416 * now wants to supply an image.
1418 iconMask = (flags & IconMaskHint)?
1419 pXWMHints->icon_mask : (Pixmap) NULL;
1422 MakeClientIconPixmap (pCD, pXWMHints->icon_pixmap,
1426 * Made new icon image; free up the old image and display
1429 if (pCD->iconFlags & ICON_HINTS_PIXMAP)
1432 * ICON_HINTS_PIXMAP was set either initally or
1433 * below because a new pixmap was made for the client.
1434 * It is now safe to free the previous pixmap since it
1435 * is not the shared default iconPixmap
1437 if (pCD->iconPixmap)
1439 XFreePixmap (DISPLAY, pCD->iconPixmap);
1444 pCD->iconFlags |= ICON_HINTS_PIXMAP;
1447 pCD->iconPixmap = iconPixmap;
1450 * Display new icon image if the icon is showing:
1453 if (((pCD->clientState == MINIMIZED_STATE) ||
1454 ((pCD->pSD->useIconBox) && (P_ICON_BOX(pCD)))) &&
1455 ICON_FRAME_WIN(pCD))
1457 IconExposureProc (pCD, True);
1465 XFree ((char*)pXWMHints);
1469 } /* END OF FUNCTION ProcessWmHints */
1473 /*************************************<->*************************************
1475 * ProcessWmNormalHints (pCD, firstTime, manageFlags)
1480 * This function retrieves the contents of the WM_NORMAL_HINTS property on
1481 * the cient window. There are several versions of the property that must be
1482 * handled (currently R2 and CURRENT).
1487 * pCD = pointer to client data for the window with the property
1489 * firstTime = if True this is the first time the property has been processed
1491 * manageFlags = flags that indicate wm state information
1496 * pCD = client location and size fields set
1501 * If the hints are being reprocessed (!firstTime) the configuration values
1502 * will be ignored. The size constraint values will be processed but the
1503 * client configuration will not be changed even if it is not in line with
1504 * the new values. Reconfigurations subsequent to the hints changes will
1505 * be done with the new constraints.
1507 *************************************<->***********************************/
1510 ProcessWmNormalHints (ClientData *pCD, Boolean firstTime, long manageFlags)
1512 register SizeHints *pNormalHints;
1513 register long flags;
1515 unsigned long decoration;
1516 unsigned int boxdim, tmpMin;
1517 unsigned int oldWidthInc, oldHeightInc;
1518 unsigned int oldBaseWidth, oldBaseHeight;
1519 unsigned int incWidth, incHeight;
1522 * Use a custom verion of the Xlib routine to get WM_NORMAL_HINTS.
1523 * A custom version is necessary to handle the different versions
1524 * of WM_NORMAL_HINTS that may be encountered. If the WM_NORMAL_HINTS
1525 * property does not exist the flags field will be set to 0.
1528 pNormalHints = GetNormalHints (pCD);
1530 pCD->icccVersion = pNormalHints->icccVersion;
1534 * Parse the WM_NORMAL_HINTS information:
1537 if (((flags = pNormalHints->flags) == 0) && !firstTime)
1544 * Process the size only if this is the first time the hints are
1545 * being processed for the window.
1551 * Process client window size flags and information:
1554 pCD->sizeFlags = flags & (US_POSITION | US_SIZE | P_POSITION | P_SIZE);
1557 * The R2 conventions and Xlib manual indicate that the window size
1558 * and position should be taken out of the WM_NORMAL_HINTS property
1559 * if they are specified there. The current conventions indicate that
1560 * the size and position information should be gotten from the window
1561 * configuration. Mwm 1.1 always uses the current conventions.
1566 * Maintain R2 compatiblity code for CND product xnm
1568 if ((pNormalHints->icccVersion == ICCC_R2) &&
1569 (flags & (US_POSITION | P_POSITION)) &&
1570 !(manageFlags & MANAGEW_WM_RESTART))
1572 if (!(pCD->clientFlags & SM_X))
1573 pCD->clientX = pNormalHints->x;
1574 if (!(pCD->clientFlags & SM_Y))
1575 pCD->clientY = pNormalHints->y;
1579 if (!(pCD->clientFlags & SM_X))
1580 pCD->clientX = wmGD.windowAttributes.x;
1581 if (!(pCD->clientFlags & SM_Y))
1582 pCD->clientY = wmGD.windowAttributes.y;
1584 #else /* R2_COMPAT */
1585 if (!(pCD->clientFlags & SM_X))
1586 pCD->clientX = wmGD.windowAttributes.x;
1587 if (!(pCD->clientFlags & SM_Y))
1588 pCD->clientY = wmGD.windowAttributes.y;
1589 #endif /* R2_COMPAT */
1592 * Use current conventions for initial window dimensions.
1597 * Maintain R2 compatiblity code for CND product xnm
1599 if ((pNormalHints->icccVersion == ICCC_R2) &&
1600 (flags & (US_SIZE | P_SIZE)) &&
1601 !(manageFlags & MANAGEW_WM_RESTART))
1603 if (!(pCD->clientFlags & SM_WIDTH))
1604 pCD->clientWidth = pNormalHints->width;
1605 if (!(pCD->clientFlags & SM_HEIGHT))
1606 pCD->clientHeight = pNormalHints->height;
1610 if (!(pCD->clientFlags & SM_WIDTH))
1611 pCD->clientWidth = wmGD.windowAttributes.width;
1612 if (!(pCD->clientFlags & SM_HEIGHT))
1613 pCD->clientHeight = wmGD.windowAttributes.height;
1615 #else /* R2_COMPAT */
1616 if (!(pCD->clientFlags & SM_WIDTH))
1617 pCD->clientWidth = wmGD.windowAttributes.width;
1618 if (!(pCD->clientFlags & SM_HEIGHT))
1619 pCD->clientHeight = wmGD.windowAttributes.height;
1620 #endif /* R2_COMPAT */
1624 * Process the minimum size:
1627 if (flags & P_MIN_SIZE)
1630 (pNormalHints->min_width < 0) ? 0 : pNormalHints->min_width;
1632 (pNormalHints->min_height < 0) ? 0 : pNormalHints->min_height;
1633 if (pCD->minWidth > MAX_MAX_SIZE(pCD).width)
1635 pCD->minWidth = MAX_MAX_SIZE(pCD).width;
1637 if (pCD->minHeight > MAX_MAX_SIZE(pCD).height)
1639 pCD->minHeight = MAX_MAX_SIZE(pCD).height;
1650 * Process the resizing increments:
1655 oldWidthInc = (pCD->widthInc == 0) ? 1 : pCD->widthInc;
1656 oldHeightInc = (pCD->heightInc == 0) ? 1 : pCD->heightInc;
1659 if (flags & P_RESIZE_INC)
1662 (pNormalHints->width_inc < 1) ? 1 : pNormalHints->width_inc;
1664 (pNormalHints->height_inc < 1) ? 1 : pNormalHints->height_inc;
1674 * Process the base size:
1679 oldBaseWidth = pCD->baseWidth;
1680 oldBaseHeight = pCD->baseHeight;
1683 if (flags & P_BASE_SIZE)
1686 (pNormalHints->base_width < 0) ? 0 : pNormalHints->base_width;
1688 (pNormalHints->base_height < 0) ? 0 : pNormalHints->base_height;
1690 else if ((pNormalHints->icccVersion == ICCC_R2) &&
1692 (!firstTime && (flags & P_MIN_SIZE))))
1695 * In this version of the hints the minimum size was effectively
1698 pCD->baseWidth = pCD->minWidth;
1699 pCD->baseHeight = pCD->minHeight;
1703 if (flags & P_MIN_SIZE)
1705 pCD->baseWidth = pCD->minWidth;
1706 pCD->baseHeight = pCD->minHeight;
1711 pCD->baseHeight = 0;
1717 if (pCD->clientFlags & SM_WIDTH)
1719 pCD->clientWidth = ((pCD->clientWidth * pCD->widthInc) +
1722 if (pCD->clientFlags & SM_HEIGHT)
1724 pCD->clientHeight =((pCD->clientHeight * pCD->heightInc) +
1730 * Process the maximum width. NOTE: maximumClientSize.width
1731 * and maximumClientSize.height will be set to BIGSIZE if
1732 * maximumClientSize is either set to 'horizontal' or 'vertical'.
1735 pCD->oldMaxWidth = pCD->maxWidth;
1736 if (pCD->maximumClientSize.width)
1738 /* If maximumClientSize is full 'horizontal' */
1739 if (IS_MAXIMIZE_HORIZONTAL(pCD))
1741 /* go to min (full screen width, max maximum width) */
1742 pCD->maxWidth = DisplayWidth (DISPLAY, SCREEN_FOR_CLIENT(pCD)) -
1743 (2 * pCD->clientOffset.x);
1746 * Hack to set max client to the current client height, maxHeight
1747 * will be kept up to date whenever the window is reconfigured
1749 pCD->maxHeight = pCD->clientHeight;
1754 pCD->maxWidth = (pCD->maximumClientSize.width *
1755 pCD->widthInc) + pCD->baseWidth;
1760 if (flags & P_MAX_SIZE)
1762 if (pNormalHints->max_width < 0)
1764 /* go to min (full screen width, max maximum width) */
1765 pCD->maxWidth = DisplayWidth (DISPLAY, SCREEN_FOR_CLIENT(pCD)) -
1766 (2 * pCD->clientOffset.x);
1770 pCD->maxWidth = pNormalHints->max_width;
1773 /* Don't reset maxWidth if it has been set earlier */
1774 else if (!IS_MAXIMIZE_VERTICAL(pCD))
1778 /* go to min (full screen width, max maximum width) */
1779 pCD->maxWidth = DisplayWidth (DISPLAY,
1780 SCREEN_FOR_CLIENT(pCD)) -
1781 (2 * pCD->clientOffset.x);
1785 /* reset the maxHeight before further processing */
1786 pCD->maxWidth = pCD->maxWidthLimit;
1792 * If the hints changed we need to adjust the maximum
1793 * size (if not specified in the hints).
1796 ((oldBaseWidth != pCD->baseWidth) ||
1797 (oldWidthInc != pCD->widthInc)))
1799 incWidth = (pCD->maxWidth - oldBaseWidth) / oldWidthInc;
1801 (incWidth * pCD->widthInc) + pCD->baseWidth;
1805 /* reset the maxHeight before further processing */
1806 pCD->maxWidth = pCD->maxWidthLimit;
1809 if (pCD->maxWidth > MAX_MAX_SIZE(pCD).width)
1811 pCD->maxWidth = MAX_MAX_SIZE(pCD).width;
1818 * Process the maximum height.
1821 pCD->oldMaxHeight = pCD->maxHeight;
1822 if (pCD->maximumClientSize.height)
1824 /* If maximumClientSize is full 'vertical' */
1825 if (IS_MAXIMIZE_VERTICAL(pCD))
1827 /* go to min (full screen height, max maximum height) */
1828 pCD->maxHeight = DisplayHeight (DISPLAY, SCREEN_FOR_CLIENT(pCD)) -
1829 (pCD->clientOffset.x +
1830 pCD->clientOffset.y);
1832 * Hack to set max client to the current client width, maxWidth
1833 * will be kept up to date whenever the window is reconfigured
1835 pCD->maxWidth = pCD->clientWidth;
1840 pCD->maxHeight = (pCD->maximumClientSize.height *
1841 pCD->heightInc) + pCD->baseHeight;
1846 if (flags & P_MAX_SIZE)
1848 if (pNormalHints->max_height < 0)
1850 /* go to min (full screen height, max maximum height) */
1851 pCD->maxHeight = DisplayHeight (
1852 DISPLAY, SCREEN_FOR_CLIENT(pCD)) -
1853 (pCD->clientOffset.x +
1854 pCD->clientOffset.y);
1858 pCD->maxHeight = pNormalHints->max_height;
1861 /* Don't reset maxHeight if it has been set above */
1862 else if (!IS_MAXIMIZE_HORIZONTAL(pCD))
1866 /* go to min (full screen height, max maximum height) */
1867 pCD->maxHeight = DisplayHeight (DISPLAY,
1868 SCREEN_FOR_CLIENT(pCD)) -
1869 (pCD->clientOffset.x +
1870 pCD->clientOffset.y);
1874 /* reset the maxHeight before further processing */
1875 pCD->maxHeight = pCD->maxHeightLimit;
1881 * If the hints changed we need to adjust the maximum
1882 * size (if not specified in the hints).
1885 ((oldBaseHeight != pCD->baseHeight) ||
1886 (oldHeightInc != pCD->heightInc)))
1888 incHeight = (pCD->maxHeight - oldBaseHeight) / oldHeightInc;
1890 (incHeight * pCD->heightInc) + pCD->baseHeight;
1894 /* reset the maxHeight before further processing */
1895 pCD->maxHeight = pCD->maxHeightLimit;
1898 if (pCD->maxHeight > MAX_MAX_SIZE(pCD).height)
1900 pCD->maxHeight = MAX_MAX_SIZE(pCD).height;
1905 * Make sure not to exceed the maximumMaximumSize (width and height)
1908 if (pCD->maxWidth > MAX_MAX_SIZE(pCD).width)
1910 pCD->maxWidth = MAX_MAX_SIZE(pCD).width;
1913 if (pCD->maxHeight > MAX_MAX_SIZE(pCD).height)
1915 pCD->maxHeight = MAX_MAX_SIZE(pCD).height;
1919 * Get the initial aspect ratios, if available. Only use them if:
1923 * 0 <= minAspect.x / minAspect.y <= maxAspect.x / maxAspect.y
1926 if (flags & P_ASPECT)
1928 pCD->minAspect.x = pNormalHints->min_aspect.x;
1929 pCD->minAspect.y = pNormalHints->min_aspect.y;
1930 pCD->maxAspect.x = pNormalHints->max_aspect.x;
1931 pCD->maxAspect.y = pNormalHints->max_aspect.y;
1933 if (pCD->minAspect.y > 0 &&
1934 pCD->maxAspect.y > 0 &&
1935 pCD->minAspect.x > 0 &&
1936 pCD->maxAspect.x > 0 &&
1937 (pCD->minAspect.x * pCD->maxAspect.y <=
1938 pCD->maxAspect.x * pCD->minAspect.y))
1940 pCD->sizeFlags |= P_ASPECT;
1944 pCD->sizeFlags &= ~P_ASPECT;
1948 /* compute for minimum frame size */
1949 if ((decoration = pCD->decor) & MWM_DECOR_TITLE)
1951 boxdim = TitleBarHeight(pCD);
1953 ((decoration & MWM_DECOR_MENU) ? boxdim : 0) +
1954 ((decoration & MWM_DECOR_MINIMIZE) ? boxdim : 0) +
1955 ((decoration & MWM_DECOR_MAXIMIZE) ? boxdim : 0) -
1956 2*(pCD->matteWidth);
1964 * Process the window gravity (for positioning):
1967 if (flags & P_WIN_GRAVITY)
1969 pCD->windowGravity = pNormalHints->win_gravity;
1973 if (pNormalHints->icccVersion == ICCC_R2)
1975 pCD->windowGravity = wmGD.windowAttributes.win_gravity;
1979 pCD->windowGravity = NorthWestGravity;
1985 * Make sure that all the window sizing constraints are compatible:
1991 * minWidth >= tmpMin
1992 * minWidth >= max (baseWidth, widthInc) > 0
1993 * & an integral number of widthInc from baseWidth.
1994 * minHeight >= max (baseHeight, heightInc) > 0
1995 * & an integral number of heightInc from baseHeight.
1998 if (pCD->minWidth < tmpMin)
2000 if ((diff = ((tmpMin - pCD->baseWidth)%pCD->widthInc)) != 0)
2002 pCD->minWidth = tmpMin + pCD->widthInc - diff;
2006 pCD->minWidth = tmpMin;
2010 if (pCD->minWidth < pCD->baseWidth)
2012 pCD->minWidth = pCD->baseWidth;
2015 if (pCD->minWidth == 0)
2017 pCD->minWidth = pCD->widthInc;
2019 else if ((diff = ((pCD->minWidth - pCD->baseWidth)%pCD->widthInc)) != 0)
2021 pCD->minWidth += pCD->widthInc - diff;
2024 if (pCD->minHeight < pCD->baseHeight)
2026 pCD->minHeight = pCD->baseHeight;
2029 if (pCD->minHeight == 0)
2031 pCD->minHeight = pCD->heightInc;
2033 else if ((diff = ((pCD->minHeight - pCD->baseHeight) % pCD->heightInc)) !=0)
2035 pCD->minHeight += pCD->heightInc - diff;
2041 * maxWidth >= minWidth
2042 * & an integral number of widthInc from baseWidth.
2043 * maxHeight >= minHeight
2044 * & an integral number of heightInc from baseHeight.
2047 if (pCD->maxWidth < pCD->minWidth)
2049 pCD->maxWidth = pCD->minWidth;
2053 * Hack to use maxWidthLimit as the real maxWidth when maximumClientSize
2054 * set to 'vertical'.
2056 if (IS_MAXIMIZE_VERTICAL(pCD))
2058 /* go to min (full screen width, max maximum width) */
2059 pCD->maxWidthLimit = DisplayWidth (DISPLAY, SCREEN_FOR_CLIENT(pCD)) -
2060 (2 * pCD->clientOffset.x);
2064 pCD->maxWidthLimit = pCD->maxWidth;
2067 pCD->maxWidth -= ((pCD->maxWidth - pCD->baseWidth) % pCD->widthInc);
2071 pCD->oldMaxWidth = pCD->maxWidth;
2074 if (pCD->maxHeight < pCD->minHeight)
2076 pCD->maxHeight = pCD->minHeight;
2080 * Hack to use maxHeightLimit as the real maxHeight when maximumClientSize
2081 * set to 'horizontal'.
2083 if (IS_MAXIMIZE_HORIZONTAL(pCD))
2085 /* go to min (full screen height, max maximum height) */
2086 pCD->maxHeightLimit = DisplayHeight (DISPLAY, SCREEN_FOR_CLIENT(pCD)) -
2087 (pCD->clientOffset.x +
2088 pCD->clientOffset.y);
2092 pCD->maxHeightLimit = pCD->maxHeight;
2095 pCD->maxHeight -= ((pCD->maxHeight - pCD->baseHeight) % pCD->heightInc);
2099 pCD->oldMaxHeight = pCD->maxHeight;
2102 if (!firstTime && pCD->maxConfig)
2105 * If the hints changed while we were maximized then
2106 * we may need to adjust the normalized size of the window.
2109 ((oldBaseWidth != pCD->baseWidth) ||
2110 (oldBaseHeight != pCD->baseHeight) ||
2111 (oldWidthInc != pCD->widthInc) ||
2112 (oldHeightInc != pCD->heightInc)))
2114 incWidth = (pCD->clientWidth - oldBaseWidth) / oldWidthInc;
2115 incHeight = (pCD->clientHeight - oldBaseHeight) / oldHeightInc;
2117 (incWidth * pCD->widthInc) + pCD->baseWidth;
2119 (incHeight * pCD->heightInc) + pCD->baseHeight;
2124 * If using aspect ratios, make:
2126 * minWidth / maxHeight <= minAspect.x / minAspect.y
2127 * <= maxAspect.x / maxAspect.y
2128 * <= maxWidth / minHeight
2131 if (pCD->sizeFlags & P_ASPECT)
2133 if (pCD->minWidth * pCD->minAspect.y >
2134 pCD->minAspect.x * pCD->maxHeight)
2136 pCD->minAspect.x = pCD->minWidth;
2137 pCD->minAspect.y = pCD->maxHeight;
2140 if (pCD->maxAspect.x * pCD->minHeight >
2141 pCD->maxWidth * pCD->maxAspect.y)
2143 pCD->maxAspect.x = pCD->maxWidth;
2144 pCD->maxAspect.y = pCD->minHeight;
2147 FixWindowSize (pCD, (unsigned int *) &(pCD->maxWidth),
2148 (unsigned int *) &(pCD->maxHeight),
2149 (unsigned int) (pCD->widthInc),
2150 (unsigned int) (pCD->heightInc));
2154 * If this is the first time, make sure the client dimensions are within
2155 * range and that they satisfy any aspect ratio constraints:
2157 * 0 < minWidth <= clientWidth <= maxWidth
2158 * 0 < minHeight <= clientHeight <= maxHeight
2160 * minAspect.x / minAspect.y <= clientWidth / clientHeight
2161 * <= maxAspect.x / maxAspect.y
2163 * Initial max width/height are set to max of max size or normal
2164 * client size unless a maximumClientSize was specified.
2169 if (!pCD->maximumClientSize.width)
2171 if (pCD->clientWidth > pCD->pSD->maximumMaximumSize.width)
2173 pCD->clientWidth = pCD->pSD->maximumMaximumSize.width;
2177 if (!pCD->maximumClientSize.height)
2179 if (pCD->clientHeight > pCD->pSD->maximumMaximumSize.height)
2181 pCD->clientHeight = pCD->pSD->maximumMaximumSize.height;
2185 FixWindowSize (pCD, (unsigned int *) &(pCD->clientWidth),
2186 (unsigned int *) &(pCD->clientHeight),
2187 (unsigned int) (pCD->widthInc),
2188 (unsigned int) (pCD->heightInc));
2191 } /* END OF FUNCTION ProcessWmNormalHints */
2194 /*************************************<->*************************************
2196 * WmICCCMToXmString (wmNameProp)
2201 * This function uses a property (WM_NAME or WM_ICON_NAME) that was
2202 * retrieved from the window, and converts it to XmString.
2206 * wmNameProp - the text property
2210 * Return = new XmString, or NULL if the property didn't have a value.
2212 *************************************<->***********************************/
2215 WmICCCMToXmString (XTextProperty *wmNameProp)
2218 XmString xms_return;
2219 XmStringTable xmsTable;
2220 int i, nStrings = -1;
2223 if (wmNameProp->value == 0 || strlen((char *)wmNameProp->value) == 0)
2225 return (XmString)NULL;
2228 if (((status = XmCvtTextPropertyToXmStringTable(DISPLAY, wmNameProp,
2229 &xmsTable, &nStrings))
2230 != Success) || (nStrings <= 0))
2234 case XConverterNotFound:
2235 #ifndef MOTIF_ONE_DOT_ONE
2236 sprintf(msg, GETMESSAGE (70,5,
2237 "Window manager cannot convert property %.100s as clientTitle/iconTitle: XmbTextPropertyToTextList"),
2238 XGetAtomName (DISPLAY,wmNameProp->encoding));
2240 #endif /* MOTIF_ONE_DOT_ONE */
2244 sprintf(msg, GETMESSAGE (70, 6,
2245 "insufficient memory to convert property %.100s as clientTitle/iconTitle: XmbTextPropertyToTextList"),
2246 XGetAtomName(DISPLAY,wmNameProp->encoding));
2250 case XLocaleNotSupported:
2251 if ((wmNameProp->encoding == XA_STRING) ||
2252 (wmNameProp->encoding == wmGD.xa_COMPOUND_TEXT))
2254 sprintf(msg, LOCALE_MSG, setlocale(LC_ALL, NULL));
2258 /* Atom was neither STRING nor COMPOUND_TEXT */
2259 sprintf(msg, GETMESSAGE(70, 8,
2260 "Window manager received unknown property as clientTitle/iconTitle: %.100s. Property ignored."),
2261 XGetAtomName(DISPLAY, wmNameProp->encoding));
2267 /* Couldn't convert using Xm; apply a default */
2268 return XmCvtCTToXmString((char*)wmNameProp->value);
2271 xms_return = xmsTable[0];
2272 for (i = 1; i < nStrings; i++)
2274 #ifdef CONCAT_TEXTLIST
2275 xms_return = XmStringConcatAndFree(xms_return, xmsTable[i]);
2277 XmStringFree(xmsTable[i]);
2278 #endif /* CONCAT_TEXTLIST */
2280 XtFree((char *)xmsTable);
2286 /*************************************<->*************************************
2288 * ProcessWmWindowTitle (pCD, firstTime)
2293 * This function retrieves the contents of the WM_NAME property on the
2294 * cient window. A default name is set if the property does not exist.
2299 * pCD - pointer to client data structure
2300 * firstTime - false if the window is already managed and the title
2306 * pCD - clientTitle, iconTitle
2308 *************************************<->***********************************/
2311 ProcessWmWindowTitle (ClientData *pCD, Boolean firstTime)
2313 XTextProperty wmNameProp;
2314 XmString title_xms = NULL;
2316 if ((pCD->clientDecoration & MWM_DECOR_TITLE) &&
2318 (!firstTime || HasProperty (pCD, XA_WM_NAME)) &&
2320 XGetWMName(DISPLAY, pCD->client, &wmNameProp))
2322 title_xms = WmICCCMToXmString(&wmNameProp);
2323 if (wmNameProp.value)
2324 XFree ((char*)wmNameProp.value);
2329 if (!firstTime && (pCD->iconTitle == pCD->clientTitle))
2332 * The client window title is being used for the icon title so
2333 * change the icon title with the window title.
2335 pCD->iconTitle = title_xms;
2336 RedisplayIconTitle (pCD);
2339 if ((pCD->clientFlags & CLIENT_HINTS_TITLE) &&
2340 pCD->clientTitle != wmGD.clientDefaultTitle)
2342 XmStringFree (pCD->clientTitle);
2345 pCD->clientTitle = title_xms;
2346 pCD->clientFlags |= CLIENT_HINTS_TITLE;
2350 DrawWindowTitle (pCD, True);
2354 * The client frame does not have a place to put the title or the WM_NAME
2355 * property does not exist or there was some error in getting
2356 * the property information, so use a default value.
2360 if (pCD->clientName)
2362 pCD->clientTitle = XmStringCreateLocalized(pCD->clientName);
2366 pCD->clientTitle = wmGD.clientDefaultTitle;
2371 * If this is a tear-off menu, then make sure title text is not clipped
2375 if ((pCD->window_status & MWM_TEAROFF_WINDOW) ||
2376 (pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUBPANEL))
2377 #else /* PANELIST */
2378 if (pCD->window_status & MWM_TEAROFF_WINDOW)
2379 #endif /* PANELIST */
2381 unsigned int boxdim = TitleBarHeight (pCD);
2382 unsigned long decor = pCD->decor;
2383 XmFontList fontList;
2386 if (DECOUPLE_TITLE_APPEARANCE(pCD))
2387 fontList = CLIENT_TITLE_APPEARANCE(pCD).fontList;
2389 fontList = CLIENT_APPEARANCE(pCD).fontList;
2392 * Calculations derived from GetTextBox() and GetFramePartInfo()
2394 minWidth = XmStringWidth(fontList, pCD->clientTitle) +
2396 ((pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUBPANEL) ? 4 : 0) +
2397 #endif /* PANELIST */
2398 ((decor & MWM_DECOR_MENU) ? boxdim : 0) +
2399 ((decor & MWM_DECOR_MINIMIZE) ? boxdim : 0) +
2400 ((decor & MWM_DECOR_MAXIMIZE) ? boxdim : 0) +
2401 WM_TOP_TITLE_SHADOW + WM_BOTTOM_TITLE_SHADOW +
2402 WM_TOP_TITLE_PADDING + WM_BOTTOM_TITLE_PADDING;
2404 if (minWidth > pCD->minWidth)
2406 pCD->minWidth = minWidth;
2409 if ((pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUBPANEL) &&
2410 (pCD->clientWidth < pCD->minWidth))
2412 FixSubpanelEmbeddedClientGeometry (pCD);
2414 #endif /* PANELIST */
2417 } /* END OF FUNCTION ProcessWmWindowTitle */
2421 /*************************************<->*************************************
2423 * FixSubpanelEmbeddedClientGeometry ( pCD )
2428 * This function adjusts the embedded clients in a subpanel if the
2429 * geometry of the subpanel is adjusted.
2434 * pCD - pointer to client data structure
2442 * Only handles change in width right now.
2444 *************************************<->***********************************/
2447 FixSubpanelEmbeddedClientGeometry (ClientData *pCD)
2449 WmScreenData *pSD = PSD_FOR_CLIENT(pCD);
2455 * Get the widget for the subpanel
2457 wSubpanel = WmPanelistWindowToSubpanel (DISPLAY1, pCD->client);
2459 if (pSD->wPanelist && wSubpanel)
2461 WmFpEmbeddedClientData *pECD;
2465 * set new shell width to minimum width
2467 if (pCD->clientWidth < pCD->minWidth)
2470 XtSetArg (al[ac], XmNwidth, pCD->minWidth); ac++;
2471 XtSetValues (wSubpanel, al, ac);
2475 * Cause update of client geometries.
2477 /* WmPanelistSetClientGeometry (pSD->wPanelist); */
2480 * Update all affected reparented controls.
2483 for (i=0; i<pSD->numEmbeddedClients; i++)
2485 pECD = &(((WmFpEmbeddedClientData *) pSD->pECD)[i]);
2489 ClientData *pCD2 = pECD->pCD;
2491 if ((pCD2->clientWidth != pECD->width) ||
2492 (pCD2->clientHeight != pECD->height) ||
2493 (pCD2->clientX != pECD->x) ||
2494 (pCD2->clientY != pECD->y))
2496 pCD2->clientX = pECD->x;
2497 pCD2->clientY = pECD->y;
2498 pCD2->clientWidth = pECD->width;
2499 pCD2->clientHeight = pECD->height;
2501 XMoveResizeWindow (DISPLAY1, pCD2->client,
2502 pECD->x, pECD->y, pECD->width, pECD->height);
2507 } /* END OF FUNCTION FixEmbeddedClientGeometry */
2509 #endif /* PANELIST */
2512 /*************************************<->*************************************
2514 * ProcessWmIconTitle (pCD, firstTime)
2519 * This function retrieves the contents of the WM_ICON_NAME property on the
2520 * cient window. The value of the property is a string that is used for the
2521 * icon title. A default title is set if the property does not exist.
2526 * pCD - pointer to client data structure
2528 * firstTime - false if the window is already managed and the title
2536 *************************************<->***********************************/
2539 ProcessWmIconTitle (ClientData *pCD, Boolean firstTime)
2541 XTextProperty wmIconNameProp;
2542 XmString icon_xms = NULL;
2544 if ((pCD->clientFunctions & MWM_FUNC_MINIMIZE) &&
2545 (pCD->transientLeader == NULL) &&
2547 (!firstTime || HasProperty(pCD, XA_WM_ICON_NAME)) &&
2549 XGetWMIconName (DISPLAY, pCD->client, &wmIconNameProp))
2551 icon_xms = WmICCCMToXmString(&wmIconNameProp);
2552 if (wmIconNameProp.value)
2553 XFree ((char*)wmIconNameProp.value);
2558 if ((pCD->iconFlags & ICON_HINTS_TITLE) &&
2559 pCD->iconTitle != wmGD.iconDefaultTitle)
2561 XmStringFree (pCD->iconTitle);
2564 pCD->iconTitle = icon_xms;
2565 pCD->iconFlags |= ICON_HINTS_TITLE;
2569 RedisplayIconTitle (pCD);
2573 * The WM_ICON_NAME property does not exist (or there was some error
2574 * in getting * the property information), so use a default value.
2578 if (pCD->clientTitle && (pCD->clientTitle != wmGD.clientDefaultTitle))
2580 pCD->iconTitle = pCD->clientTitle;
2584 pCD->iconTitle = wmGD.iconDefaultTitle;
2588 } /* END OF FUNCTION ProcessWmIconTitle */
2592 /*************************************<->*************************************
2594 * ProcessWmTransientFor (pCD)
2599 * This function retrieves the contents of the WM_TRANSIENT_FOR property on
2605 * pCD = pointer to the client data structure for the window with the property
2610 * pCD.transientFor = if tranient then this is the associated main window
2612 * pCD.clientFlags = indicate that this is a transient window
2614 *************************************<->***********************************/
2617 ProcessWmTransientFor (ClientData *pCD)
2624 if ((HasProperty (pCD, XA_WM_TRANSIENT_FOR)) &&
2625 (XGetTransientForHint (DISPLAY, pCD->client, &window)))
2627 if (XGetTransientForHint (DISPLAY, pCD->client, &window))
2630 pCD->clientFlags |= CLIENT_TRANSIENT;
2633 * Only save the (leader) transientFor window if it is NOT the
2634 * client window and it is already managed by the window manager.
2637 if ((pCD->client != window) &&
2638 !XFindContext (DISPLAY, window, wmGD.windowContextType,
2639 (caddr_t *)&leader))
2641 pCD->transientFor = window;
2642 pCD->transientLeader = leader;
2645 else { /* else this is not a transient window */
2646 pCD->clientFlags &= ~CLIENT_TRANSIENT;
2647 pCD->transientFor = (Window)0L;
2648 pCD->transientLeader = NULL;
2652 } /* END OF FUNCTION ProcessWmTransientFor */
2656 /*************************************<->*************************************
2658 * MakeSystemMenu (pCD)
2663 * This function finds or makes a system menu for the client. A check
2664 * is made for the _MWM_MENU property and, if present, client-specific
2665 * items are added to the custom system menu. Any custom system menu
2666 * must be destroyed when the client is unmanaged (or killed).
2671 * pCD = pointer to the client data structure for the managed window
2676 * pCD.systemMenuSpec = system menu specification for the client, not added
2677 * to wmGD.acceleratorMenuSpecs
2679 *************************************<->***********************************/
2682 MakeSystemMenu (ClientData *pCD)
2684 #if ((!defined(WSM)) || defined(MWM_QATS_PROTOCOL))
2686 #endif /* !defined(WSM) || defined(MWM_QATS_PROTOCOL) */
2688 pCD->mwmMenuItems = GetMwmMenuItems(pCD);
2689 pCD->systemMenuSpec =
2690 MAKE_MENU (PSD_FOR_CLIENT(pCD), pCD, pCD->systemMenu, F_CONTEXT_WINDOW,
2691 F_CONTEXT_WINDOW|F_CONTEXT_ICON, pCD->mwmMenuItems, TRUE);
2693 #ifdef NO_MESSAGE_CATALOG
2694 if (pCD->systemMenuSpec == NULL)
2697 * As the lookup has failed, let's try just one more time.
2699 Warning("Retrying - using builtin window menu\n");
2701 pCD->systemMenuSpec =
2702 MAKE_MENU(PSD_FOR_CLIENT(pCD), pCD, builtinSystemMenuName,
2704 F_CONTEXT_WINDOW|F_CONTEXT_ICON, pCD->mwmMenuItems, TRUE);
2708 #if defined(MWM_QATS_PROTOCOL)
2709 /* Added to fix CDExc23338
2710 * Not sure what the MWM_QATS_PROTOCOL is trying to accomplish here,
2711 * but this code is causing the system menu to loose it's default
2712 * actions whenever client defined actions are added. I thought
2713 * it prudent to minimize the changes. It could be that the
2714 * #if ((!defined(WSM)) || defined(MWM_QATS_PROTOCOL))
2716 * #if ((!defined(WSM)) && defined(MWM_QATS_PROTOCOL))
2717 * throughout the wm code, but I am loath to make such a change
2718 * without any documentation.
2721 #if ((!defined(WSM)) || defined(MWM_QATS_PROTOCOL))
2722 /** BEGIN FIX CR 6941 **/
2724 /* if we still don't have a menu spec, then just abort. */
2725 if (pCD->systemMenuSpec == NULL)
2728 pCD->systemMenuSpec = DuplicateMenuSpec(pCD->systemMenuSpec);
2729 XtFree(pCD->systemMenuSpec->name);
2730 pCD->systemMenuSpec->name = XtNewString("ProtocolsMenu");
2732 /* Find the last menu item in the menu spec's list. */
2733 for (lastItem = pCD->systemMenuSpec->menuItems;
2734 lastItem->nextMenuItem != (MenuItem *) NULL;
2735 lastItem = lastItem->nextMenuItem)
2737 lastItem->nextMenuItem = pCD->mwmMenuItems;
2739 /* Now recreate the menu widgets since we've appended the
2740 protocol menu items */
2741 DestroyMenuSpecWidgets(pCD->systemMenuSpec);
2742 pCD->systemMenuSpec->menuWidget =
2743 CreateMenuWidget (PSD_FOR_CLIENT(pCD), pCD, "ProtocolsMenu",
2744 PSD_FOR_CLIENT(pCD)->screenTopLevelW, TRUE,
2745 pCD->systemMenuSpec, NULL);
2746 /** END FIX CR 6941 **/
2747 #endif /* !defined(WSM) || defined(MWM_QATS_PROTOCOL) */
2748 #endif /* defined(MWM_QATS_PROTOCOL) */
2750 } /* END OF FUNCTION MakeSystemMenu */
2754 /*************************************<->*************************************
2756 * InitCColormapData (pCD)
2761 * This function initializes colormap data for the client window that is
2762 * by the window manager in maintaining the colormap focus. This may
2763 * involve retrieving and processing properties that deal with subwindow
2769 * pCD = pointer to the client data structure for the managed window
2774 * pCD.clientColormap = client colormap to be installed when the client
2775 * window gets the colormap focus
2777 * pCD = (cmapWindows, clientCmapList, clientCmapCount, clientCmapIndex)
2779 *************************************<->***********************************/
2782 InitCColormapData (ClientData *pCD)
2785 if (wmGD.windowAttributes.colormap == None)
2787 pCD->clientColormap = WORKSPACE_COLORMAP(pCD);
2791 pCD->clientColormap = wmGD.windowAttributes.colormap;
2795 * Process subwindow colormap windows if they are specified.
2798 ProcessWmColormapWindows (pCD);
2801 } /* END OF FUNCTION InitCColormapData */
2805 /*************************************<->*************************************
2807 * CalculateGravityOffset (pCD, xoff, yoff)
2812 * This function calculates the window offsets based on the window gravity
2813 * and the window frame client offset.
2818 * pCD = pointer to client data (client window configuration fields)
2819 * xoff = pointer to xoffset
2820 * yoff = pointer to yoffset
2825 * xoff = pointer to xoffset set
2826 * yoff = pointer to yoffset set
2828 *************************************<->***********************************/
2831 CalculateGravityOffset (ClientData *pCD, int *xoff, int *yoff)
2833 int borderWidth = pCD->xBorderWidth;
2835 if (pCD->windowGravity < ForgetGravity ||
2836 pCD->windowGravity > StaticGravity)
2843 switch (pCD->windowGravity)
2845 case NorthWestGravity:
2848 *xoff = pCD->clientOffset.x;
2849 *yoff = pCD->clientOffset.y;
2855 *xoff = borderWidth;
2856 *yoff = pCD->clientOffset.y;
2860 case NorthEastGravity:
2862 *xoff = -(pCD->clientOffset.x - (2 * borderWidth));
2863 *yoff = pCD->clientOffset.y;
2869 *xoff = -(pCD->clientOffset.x - (2 * borderWidth));
2870 *yoff = borderWidth +
2871 (pCD->clientOffset.y - pCD->clientOffset.x)/2;
2875 case SouthEastGravity:
2877 *xoff = -(pCD->clientOffset.x - (2 * borderWidth));
2878 *yoff = -(pCD->clientOffset.x - (2 * borderWidth));
2884 *xoff = borderWidth;
2885 *yoff = -(pCD->clientOffset.x - (2 * borderWidth));
2889 case SouthWestGravity:
2891 *xoff = pCD->clientOffset.x;
2892 *yoff = -(pCD->clientOffset.x - (2 * borderWidth));
2898 *xoff = pCD->clientOffset.x;
2899 *yoff = borderWidth +
2900 (pCD->clientOffset.y - pCD->clientOffset.x)/2;
2912 } /* END OF FUNCTION CalculateGravityOffset */
2916 /*************************************<->*************************************
2918 * InitClientPlacement (pCD, manageFlags)
2923 * This function sets up the initial client window placement (for both
2924 * the normal and maximized state).
2929 * pCD = pointer to client data (client window configuration fields)
2931 * manageFlags = flags that indicate wm state information (e.g. whether
2932 * the window manager is starting up or restarting)
2937 * Return = True if position changed by this routine.
2938 * pCD = changes to the client window configuration fields
2940 *************************************<->***********************************/
2943 InitClientPlacement (ClientData *pCD, long manageFlags)
2945 Boolean interactivelyPlaced = False;
2946 Boolean autoPlaced = False;
2947 Boolean rval = False;
2949 int origX, origY, origWidth, origHeight;
2956 * Save initial client values
2958 origX = pCD->clientX;
2959 origY = pCD->clientY;
2960 origWidth = pCD->clientWidth;
2961 origHeight = pCD->clientHeight;
2964 * Do interactive placement if...
2965 * + the resource is turned on
2966 * + the window's coming up on the active screen
2969 * + position specified in DB or by Session Manager
2970 * + the user has specified a position
2971 * + the window is coming up iconic
2972 * + the window is transient
2973 * + we're system modal
2976 if (wmGD.interactivePlacement &&
2977 (!(pCD->clientFlags & (SM_X | SM_Y))) &&
2978 !(pCD->sizeFlags & US_POSITION) &&
2979 (pCD->clientState != MINIMIZED_STATE) &&
2980 (manageFlags == MANAGEW_NORMAL) &&
2981 !(pCD->clientFlags & CLIENT_TRANSIENT) &&
2982 (pCD->inputMode != MWM_INPUT_SYSTEM_MODAL) &&
2984 (ClientInWorkspace(PSD_FOR_CLIENT(pCD)->pActiveWS, pCD)))
2986 (PSD_FOR_CLIENT(pCD) == ACTIVE_PSD))
2990 * Interactively place the window on the screen.
2992 interactivelyPlaced = True;
2993 PlaceWindowInteractively (pCD);
2998 * Check out the configuration values to insure that they are within
3002 FixWindowConfiguration (pCD, (unsigned int *) &(pCD->clientWidth),
3003 (unsigned int *) &(pCD->clientHeight),
3004 (unsigned int) (pCD->widthInc),
3005 (unsigned int) (pCD->heightInc));
3008 * Do autoplacement of the client window if appropriate.
3011 if ((manageFlags == MANAGEW_NORMAL) && !interactivelyPlaced &&
3012 (!(pCD->clientFlags & (SM_X | SM_Y))) &&
3013 !(pCD->sizeFlags & US_POSITION) &&
3014 !(pCD->clientFlags & CLIENT_TRANSIENT) &&
3015 (pCD->inputMode != MWM_INPUT_SYSTEM_MODAL) && wmGD.clientAutoPlace)
3018 * if (PPosition is on or nonzero), then use current value for
3019 * clientX and clientY which was set to windowAttributes.x,y
3020 * by ProcessWmNormalHints(), else autoplace client.
3023 if ((pCD->sizeFlags & P_POSITION) &&
3024 ((pCD->usePPosition == USE_PPOSITION_ON) ||
3025 ((pCD->usePPosition == USE_PPOSITION_NONZERO) &&
3026 ((pCD->clientX != 0) || (pCD->clientY != 0)))))
3032 FindClientPlacement (pCD);
3038 * Do PositionIsFrame processing:
3039 * Use window gravity to allow the user to specify the window
3040 * position on the screen without having to know the dimensions
3041 * of the decoration that mwm is adding.
3044 if ((wmGD.positionIsFrame) &&
3045 !interactivelyPlaced && !autoPlaced)
3047 CalculateGravityOffset (pCD, &xoff, &yoff);
3048 if (!(pCD->clientFlags & SM_X))
3049 pCD->clientX += xoff;
3050 if (!(pCD->clientFlags & SM_Y))
3051 pCD->clientY += yoff;
3056 * Do PositionOnScreen processing:
3062 if (pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUBPANEL)
3064 if (pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUB_RESTORED)
3070 AdjustSlideOutGeometry (pCD);
3074 #endif /* PANELIST */
3076 if (((wmGD.positionOnScreen) && !interactivelyPlaced) &&
3077 (!(pCD->clientFlags & (SM_X | SM_Y))))
3079 PlaceFrameOnScreen (pCD, &pCD->clientX, &pCD->clientY,
3080 pCD->clientWidth, pCD->clientHeight);
3085 * Position the maximized frame:
3088 pCD->maxX = pCD->clientX;
3089 pCD->maxY = pCD->clientY;
3090 PlaceFrameOnScreen (pCD, &pCD->maxX, &pCD->maxY, pCD->maxWidth,
3094 if (!wmGD.iconAutoPlace)
3097 if (!(pCD->iconFlags & ICON_HINTS_POSITION))
3099 for (iwsc=0; iwsc<pCD->numInhabited; iwsc++)
3101 pCD->pWsList[iwsc].iconX = pCD->clientX;
3102 pCD->pWsList[iwsc].iconY = pCD->clientY;
3103 PlaceIconOnScreen (pCD, &pCD->pWsList[iwsc].iconX,
3104 &pCD->pWsList[iwsc].iconY);
3108 if (!(pCD->iconFlags & ICON_HINTS_POSITION))
3110 pCD->iconX = pCD->clientX;
3111 pCD->iconY = pCD->clientY;
3113 PlaceIconOnScreen (pCD, &pCD->iconX, &pCD->iconY);
3118 * if client size or position has been changed by this routine,
3119 * then indicate in return value
3121 if ((origX != pCD->clientX) || (origY != pCD->clientY) ||
3122 (origWidth != pCD->clientWidth) || (origHeight != pCD->clientHeight))
3129 } /* END OF FUNCTION InitClientPlacement */
3133 /******************************<->*************************************
3135 * void AdjustSlideOutGeometry (pCD)
3139 * Adjusts the geometry of the slide out panel
3143 * pCD = pointer to a client data of slide out
3150 * Subpanel is to appear above or below the front panel, centered
3151 * on the vertical axis of the spawning control.
3152 ******************************<->***********************************/
3154 AdjustSlideOutGeometry ( ClientData *pCD)
3156 ClientData *pCD_FP = NULL;
3157 WmPanelistObject pPanelist;
3159 pCD->slideDirection = SLIDE_NORTH; /* assume up for now */
3160 pPanelist = (WmPanelistObject) pCD->pSD->wPanelist;
3161 (void) XFindContext (DISPLAY, XtWindow(O_Shell(pPanelist)),
3162 wmGD.windowContextType, (caddr_t *)&pCD_FP);
3167 * Adjust slide up position if coming from front
3169 * (Assumes no nesting of panels !!!)
3170 * (Assumes horizontal oriented front panel!!!)
3172 if (pCD->transientLeader == pCD_FP)
3175 * Subpanel should be sort-of centered already,
3176 * adjust by width of window manager frame.
3178 pCD->clientX -= pCD->frameInfo.lowerBorderWidth;
3181 * Adjust to slide up above front panel.
3183 pCD->clientY = pCD_FP->frameInfo.y -
3184 pCD->frameInfo.lowerBorderWidth -
3185 pCD->clientHeight + 3;
3187 /* RICK -- added the (+ 3) */
3190 if (pCD->clientY < 0)
3193 * Adjust to slide down below front panel.
3195 pCD->clientY = pCD_FP->frameInfo.y +
3196 pCD_FP->frameInfo.height +
3197 pCD->frameInfo.titleBarHeight +
3198 pCD->frameInfo.upperBorderWidth - 3;
3199 pCD->slideDirection = SLIDE_SOUTH;
3200 /* RICK -- added the (- 3) */
3203 if ((pCD->clientY + pCD->clientHeight +
3204 pCD->frameInfo.lowerBorderWidth) >
3205 XDisplayHeight (DISPLAY, pCD->pSD->screen))
3208 * If the bottom of the slide-up is off the bottom
3209 * of the screen, then don't slide, just pop it up.
3211 pCD->slideDirection = SLIDE_NOT;
3214 PlaceFrameOnScreen (pCD, &pCD->clientX, &pCD->clientY,
3215 pCD->clientWidth, pCD->clientHeight);
3220 #endif /* PANELIST */
3223 /*************************************<->*************************************
3225 * PlaceFrameOnScreen (pCD, pX, pY, w, h)
3230 * This function is used to nudge a client window so that it is totally
3231 * onscreen if possible. At least the top left corner will be onscreen.
3236 * pCD - pointer to client data
3237 * pX - pointer to x-coord
3238 * pY - pointer to y-coord
3239 * w - width of window
3240 * h - height of window
3252 *************************************<->***********************************/
3255 PlaceFrameOnScreen (ClientData *pCD, int *pX, int *pY, int w, int h)
3267 clientOffsetX = pCD->clientOffset.x;
3268 clientOffsetY = pCD->clientOffset.y;
3269 frameX = *pX - clientOffsetX;
3270 frameY = *pY - clientOffsetY;
3271 frameWidth = w + (2 * clientOffsetX);
3272 frameHeight = h + clientOffsetX + clientOffsetY;
3273 screenWidth = DisplayWidth (DISPLAY, SCREEN_FOR_CLIENT(pCD));
3274 screenHeight = DisplayHeight (DISPLAY, SCREEN_FOR_CLIENT(pCD));
3276 if ((frameX + frameWidth) > screenWidth)
3278 frameX -= (frameX + frameWidth) - screenWidth;
3280 if ((frameY + frameHeight) > screenHeight)
3282 frameY -= (frameY + frameHeight) - screenHeight;
3293 *pX = frameX + clientOffsetX;
3294 *pY = frameY + clientOffsetY;
3296 } /* END OF FUNCTION PlaceFrameOnScreen */
3300 /*************************************<->*************************************
3302 * PlaceIconOnScreen (pCD, pX, pY)
3307 * This function positions an icon on-screen.
3312 * pCD - pointer to client data
3313 * pX - pointer to x-coord
3314 * pY - pointer to y-coord
3324 *************************************<->***********************************/
3327 PlaceIconOnScreen (ClientData *pCD, int *pX, int *pY)
3335 screenWidth = DisplayWidth (DISPLAY, SCREEN_FOR_CLIENT(pCD));
3336 screenHeight = DisplayHeight (DISPLAY, SCREEN_FOR_CLIENT(pCD));
3340 if ((iconX + ICON_WIDTH(pCD)) > screenWidth)
3342 iconX = screenWidth - ICON_WIDTH(pCD);
3349 if ((iconY + ICON_HEIGHT(pCD)) > screenHeight)
3351 iconY = screenHeight - ICON_HEIGHT(pCD);
3362 } /* END OF FUNCTION PlaceIconOnScreen */
3366 /*************************************<->*************************************
3368 * FixWindowConfiguration (pCD, pWidth, pHeight, widthInc, heightInc)
3373 * This function adjusts the configuration for the client window so that
3374 * it is in line with the client window's sizing constraints.
3379 * pCD = a pointer to the client window data
3380 * pWidth, pHeight = pointers to the window configuration values
3381 * widthInc, heightInc = window size increment values
3386 * pWidth, pHeight = adjusted configuration values are returned here
3389 *************************************<->***********************************/
3392 FixWindowConfiguration (ClientData *pCD, unsigned int *pWidth, unsigned int *pHeight, unsigned int widthInc, unsigned int heightInc)
3397 * Make sure we're on width/height increment boundaries.
3400 if ((int) *pWidth < pCD->minWidth)
3402 *pWidth = pCD->minWidth;
3404 else if ((delta = (*pWidth - pCD->baseWidth) % pCD->widthInc))
3409 if ((int) *pHeight < pCD->minHeight)
3411 *pHeight = pCD->minHeight;
3413 else if ((delta = (*pHeight - pCD->baseHeight) % pCD->heightInc))
3419 * Constrain size within bounds.
3422 FixWindowSize (pCD, pWidth, pHeight, widthInc, heightInc);
3424 } /* END OF FUNCTION FixWindowConfiguration */
3428 /*************************************<->*************************************
3430 * FixWindowSize (pCD, pWidth, pHeight, widthInc, heightInc)
3435 * This function adjusts the client window width and height so that
3436 * it is in line with its sizing constraints.
3441 * pCD = a pointer to the client window data
3442 * pWidth, pHeight = pointers to the window size values
3443 * widthInc, heightInc = window size increment values
3449 * pWidth, pHeight = adjusted size values.
3452 *************************************<->***********************************/
3455 FixWindowSize (ClientData *pCD, unsigned int *pWidth, unsigned int *pHeight, unsigned int widthInc, unsigned int heightInc)
3457 register int deltaW;
3458 register int deltaH;
3459 WmScreenData *pSD = pCD->pSD;
3462 * All occurrences of maxHeight and maxWidth in this routing has been
3463 * hacked to use maxHeightLimit and maxWidthLimit as the real max when
3464 * maximumClientSize is set to 'horizontal' or 'vertical', since
3465 * pCD->maxHeight and pCD->maxWidth is fiddle to on reconfiguration.
3468 if ((int) *pWidth < pCD->minWidth)
3470 *pWidth = pCD->minWidth;
3472 else if (*pWidth > pCD->maxWidthLimit &&
3474 !(pCD->clientFlags & CLIENT_WM_CLIENTS))
3476 *pWidth = pCD->maxWidthLimit;
3479 if ((int) *pHeight < pCD->minHeight)
3481 *pHeight = pCD->minHeight;
3483 else if (*pHeight > pCD->maxHeightLimit &&
3485 !(pCD->clientFlags & CLIENT_WM_CLIENTS))
3487 *pHeight = pCD->maxHeightLimit;
3490 if ((pCD->sizeFlags & P_ASPECT) &&
3491 *pWidth * pCD->maxAspect.y > *pHeight * pCD->maxAspect.x)
3493 * Client aspect is too big.
3494 * Candidate height >= client height:
3495 * Try to increase the client's height without violating bounds.
3496 * If this fails, use maximum height and try to decrease its width.
3497 * Candidate height < client height:
3498 * Try to decrease the client's width without violating bounds.
3499 * If this fails, use minimum width and try to increase its height.
3502 if ((*pHeight >= pCD->clientHeight) ||
3503 (*pWidth > pCD->clientWidth))
3505 * Candidate height >= client height:
3506 * Try to increase the client's height without violating bounds.
3507 * If this fails, use maximum height and try to decrease its width.
3510 deltaH = makemult (*pWidth * pCD->maxAspect.y / pCD->maxAspect.x -
3511 *pHeight, heightInc);
3512 if (*pHeight + deltaH <= pCD->maxHeightLimit ||
3513 !pSD->limitResize ||
3514 pCD->clientFlags & CLIENT_WM_CLIENTS)
3520 *pHeight = pCD->maxHeightLimit;
3521 deltaW = makemult (*pWidth - *pHeight * pCD->maxAspect.x /
3522 pCD->maxAspect.y, widthInc);
3523 if (*pWidth - deltaW >= pCD->minWidth)
3529 *pWidth = pCD->minWidth;
3535 * Candidate height < client height and candidate width <= client width.
3536 * Try to decrease the client's width without violating bounds.
3537 * If this fails, use minimum width and try to increase its height.
3540 deltaW = makemult (*pWidth - *pHeight * pCD->maxAspect.x /
3541 pCD->maxAspect.y, widthInc);
3543 if (*pWidth - deltaW >= pCD->minWidth)
3549 *pWidth = pCD->minWidth;
3550 deltaH = makemult (*pWidth * pCD->maxAspect.y /
3551 pCD->maxAspect.x - *pHeight, heightInc);
3552 if (*pHeight + deltaH <= pCD->maxHeightLimit ||
3553 !pSD->limitResize ||
3554 pCD->clientFlags & CLIENT_WM_CLIENTS)
3560 *pHeight = pCD->maxHeightLimit;
3566 else if ((pCD->sizeFlags & P_ASPECT) &&
3567 *pHeight * pCD->minAspect.x > *pWidth * pCD->minAspect.y)
3569 * Client aspect is too small.
3570 * Candidate width >= client width:
3571 * Try to increase the client's width without violating bounds.
3572 * If this fails, use maximum width and try to decrease its height.
3573 * Candidate width < client width:
3574 * Try to decrease the client's height without violating bounds.
3575 * If this fails, use minimum height and try to increase its width.
3578 if ((*pWidth >= pCD->clientWidth) ||
3579 (*pHeight > pCD->clientHeight))
3581 * Candidate width >= client width:
3582 * Try to increase the client's width without violating bounds.
3583 * If this fails, use maximum width and try to decrease its height.
3586 deltaW = makemult (*pHeight * pCD->minAspect.x / pCD->minAspect.y -
3588 if (*pWidth + deltaW <= pCD->maxWidthLimit ||
3589 !pSD->limitResize ||
3590 pCD->clientFlags & CLIENT_WM_CLIENTS)
3596 *pWidth = pCD->maxWidthLimit;
3597 deltaH = makemult (*pHeight - *pWidth * pCD->minAspect.y /
3598 pCD->minAspect.x, heightInc);
3599 if (*pHeight - deltaH >= pCD->minHeight)
3605 *pHeight = pCD->minHeight;
3611 * Candidate width < client width and Candidate height <= client height:
3612 * Try to decrease the client's height without violating bounds.
3613 * If this fails, use minimum height and try to increase its width.
3616 deltaH = makemult (*pHeight - *pWidth * pCD->minAspect.y /
3617 pCD->minAspect.x, heightInc);
3618 if (*pHeight - deltaH >= pCD->minHeight)
3624 *pHeight = pCD->minHeight;
3625 deltaW = makemult (*pHeight * pCD->minAspect.x /
3626 pCD->minAspect.y - *pWidth, widthInc);
3627 if (*pWidth + deltaW <= pCD->maxWidthLimit ||
3628 !pSD->limitResize ||
3629 pCD->clientFlags & CLIENT_WM_CLIENTS)
3635 *pWidth = pCD->maxWidthLimit;
3640 } /* END OF FUNCTION FixWindowSize */
3644 /*************************************<->*************************************
3646 * FindClientPlacement (pCD)
3651 * This function finds a position for the client window on the screen.
3652 * Windows positions are stepped down the screen. An attempt is made
3653 * to keep windows from being clipped by the edge of the screen.
3658 * pCD = pointer to client data (client window configuration fields)
3663 * pCD = changes to the client window configuration fields
3665 *************************************<->***********************************/
3668 FindClientPlacement (ClientData *pCD)
3670 static Boolean clientPlacementInitialized = False;
3671 static int clientPlacementOffset;
3672 static int clientPlacementX;
3673 static int clientPlacementY;
3674 static int clientPlacementOrigin;
3675 static int clientPlacementXOrigin;
3677 Boolean placed = False;
3684 int borderWidth = 0;
3687 WmHeadInfo_t *WmHI = NULL;
3690 if (!clientPlacementInitialized)
3692 if (pCD->clientDecoration & WM_DECOR_RESIZEH)
3694 borderWidth = ((RESIZE_BORDER_WIDTH(pCD) > FRAME_BORDER_WIDTH(pCD))
3695 ? RESIZE_BORDER_WIDTH(pCD) : FRAME_BORDER_WIDTH(pCD));
3699 borderWidth = pCD->matteWidth;
3701 clientPlacementOffset = TitleTextHeight(pCD) + borderWidth;
3702 clientPlacementOrigin = clientPlacementOffset;
3703 clientPlacementX = clientPlacementOrigin;
3704 clientPlacementY = clientPlacementOrigin;
3705 clientPlacementXOrigin = clientPlacementX;
3706 clientPlacementInitialized = True;
3709 frameWidth = pCD->clientWidth + (2 * pCD->clientOffset.x);
3710 frameHeight = pCD->clientHeight + pCD->clientOffset.y + pCD->clientOffset.x;
3712 if (WmHI = GetHeadInfo(wmGD.keyboardFocus)) {
3713 /* Use Head metrics for placeable area */
3714 screenX = WmHI->x_org;
3715 screenY = WmHI->y_org;
3716 screenWidth = WmHI->width;
3717 screenHeight = WmHI->height;
3721 /* Use X Screen metrics for placeable area */
3724 screenWidth = DisplayWidth (DISPLAY, SCREEN_FOR_CLIENT(pCD));
3725 screenHeight = DisplayHeight (DISPLAY, SCREEN_FOR_CLIENT(pCD));
3730 if ((clientPlacementX - pCD->clientOffset.x + frameWidth)
3739 if ((clientPlacementY - pCD->clientOffset.y + frameHeight)
3749 if (offScreenX || offScreenY)
3751 if (clientPlacementX == clientPlacementOrigin)
3754 * Placement location is already as far to the NW as it is
3760 else if (clientPlacementY == clientPlacementOrigin)
3763 * Placement location is as far to the N as it is going to go.
3764 * Use the current placement if the window is not off the
3765 * screen in the x coordinate otherwise reset the placement
3766 * back to the NW origin.
3771 clientPlacementXOrigin = clientPlacementOrigin;
3772 clientPlacementX = clientPlacementXOrigin;
3779 * If window is off the right edge of screen, just move
3780 * window in the X direction onto screen. Process similarly
3781 * for windows that are off the bottom of the screen.
3784 if (offScreenX && !offScreenY)
3786 clientPlacementX = clientPlacementOrigin;
3788 else if (offScreenY && !offScreenX)
3790 clientPlacementY = clientPlacementOrigin;
3796 * Reset the placement location back to the NW of the
3797 * current location. Go as far N as possible and step the
3798 * x coordinate to the E.
3801 clientPlacementXOrigin += clientPlacementOffset;
3802 clientPlacementX = clientPlacementXOrigin;
3803 clientPlacementY = clientPlacementOrigin;
3814 * The window has been placed, now update the placement information.
3817 pCD->clientX = clientPlacementX + screenX;
3818 pCD->clientY = clientPlacementY + screenY;
3819 clientPlacementX += clientPlacementOffset;
3821 if (clientPlacementX >= screenWidth)
3823 clientPlacementXOrigin = clientPlacementOrigin;
3824 clientPlacementX = clientPlacementXOrigin;
3826 clientPlacementY += clientPlacementOffset;
3829 * Reset Y position to top of screen so that windows start new column of
3830 * placement that is offset from the previous column. Previously, the new
3831 * column was place right over the old column, obscuring it.
3832 * NOTE: column == diagonal
3835 if (clientPlacementY >= (screenHeight / 3))
3837 clientPlacementY = clientPlacementOrigin;
3841 } /* END OF FUNCTION FindClientPlacement */
3845 /*************************************<->*************************************
3847 * WmGetWindowAttributes (window)
3852 * This function gets window attributes if necessary and saves them in the
3853 * global window attribute cache. If the window attributes are already
3854 * there then no X call is made.
3859 * window = get attributes for window with this id
3864 * wmGD.attributesWindow = set to window that matches windowAttributes
3866 * wmGD.windowAttributes = XWindowAttributes of window
3871 * The attributes in the global cache are (known) current only for a
3872 * single pass through the wm event processing loop. They (should be)
3873 * regularly cleared.
3875 *************************************<->***********************************/
3878 WmGetWindowAttributes (Window window)
3880 if (wmGD.attributesWindow != window)
3882 if (!XGetWindowAttributes (DISPLAY, window, &wmGD.windowAttributes))
3885 * Cannot get window attributes.
3888 wmGD.attributesWindow = (Window)0L;
3891 wmGD.attributesWindow = window;
3896 } /* END OF FUNCTION WmGetWindowAttributes */
3900 /*************************************<->*************************************
3902 * SetupClientIconWindow (pCD, window)
3907 * This function prepares a client supplied icon window for insertion into
3908 * a window manager icon frame.
3913 * pCD = pointer to client data
3915 * window = client supplied icon window
3920 * pCD = (iconWindow)
3922 * Return = True if the icon window can be used
3924 *************************************<->***********************************/
3927 SetupClientIconWindow (ClientData *pCD, Window window)
3933 * Check to see if the icon window can be used (i.e there is no conflict
3937 if (!XFindContext (DISPLAY, window, wmGD.windowContextType,
3940 if (window == pCD->client)
3943 * The proposed icon window is the same as the client!
3950 * The proposed icon window is already being managed.
3951 * Assume that we managed it by mistake. Unmanage the
3952 * window and use it as the icon window for this client.
3955 UnManageWindow (pcd);
3958 /* update client data */
3959 pCD->iconWindow = window;
3961 /* put in window manager's save set */
3962 XChangeSaveSet (DISPLAY, pCD->iconWindow, SetModeInsert);
3963 pCD->clientFlags |= ICON_IN_SAVE_SET;
3967 } /* END OF FUNCTION SetupClientIconWindow */
3971 /*************************************<->*************************************
3973 * ProcessMwmHints (pCD)
3978 * Process the _MWM_HINTS property on the window (if any). Setup the
3979 * applicable function and decoration masks.
3984 * pCD = pointer to client data
3989 * pCD = may be changed.
3991 *************************************<->***********************************/
3994 ProcessMwmHints (ClientData *pCD)
3996 PropMwmHints *pHints;
4000 * Fix the client functions and decorations fields if they have
4001 * default resource values.
4004 if (pCD->clientFunctions & WM_FUNC_DEFAULT)
4006 if (pCD->clientFlags & CLIENT_TRANSIENT)
4008 pCD->clientFunctions = TRANSIENT_FUNCTIONS(pCD);
4012 pCD->clientFunctions = WM_FUNC_ALL;
4015 if (pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUBPANEL)
4017 pCD->clientFunctions &= WM_FUNC_SUBPANEL_DEFAULT;
4018 pCD->dtwmFunctions &= ~DtWM_FUNCTION_OCCUPY_WS;
4020 else if (pCD->dtwmBehaviors & DtWM_BEHAVIOR_PANEL)
4022 pCD->clientFunctions &= WM_FUNC_PANEL_DEFAULT;
4023 pCD->dtwmFunctions &= ~DtWM_FUNCTION_OCCUPY_WS;
4025 #endif /* PANELIST */
4028 if (pCD->clientDecoration & WM_DECOR_DEFAULT)
4030 if (pCD->clientFlags & CLIENT_TRANSIENT)
4032 pCD->clientDecoration = TRANSIENT_DECORATION(pCD);
4036 pCD->clientDecoration = WM_DECOR_ALL;
4039 if (pCD->dtwmBehaviors & DtWM_BEHAVIOR_SUBPANEL)
4041 pCD->clientDecoration = pCD->pSD->subpanelDecoration;
4043 else if (pCD->dtwmBehaviors & DtWM_BEHAVIOR_PANEL)
4045 pCD->clientDecoration &= WM_DECOR_PANEL_DEFAULT;
4047 #endif /* PANELIST */
4052 * Retrieve the _MWM_HINTS property if it exists.
4055 pCD->inputMode = MWM_INPUT_MODELESS;
4057 if ((pHints = GetMwmHints (pCD)) != NULL)
4059 if (pHints->flags & MWM_HINTS_FUNCTIONS)
4061 if (pHints->functions & MWM_FUNC_ALL)
4063 /* client indicating inapplicable functions */
4064 pCD->clientFunctions &= ~(pHints->functions);
4068 /* client indicating applicable functions */
4069 pCD->clientFunctions &= pHints->functions;
4072 if (!(pCD->clientFlags & GOT_DT_WM_HINTS) &&
4076 * !!! Backward compatibility heurisitic !!!
4078 * If client doesn't want any functions and
4079 * no DT_WM_HINTS specified, then remove
4080 * workspace functions.
4082 pCD->dtwmFunctions &= ~DtWM_FUNCTION_OCCUPY_WS;
4085 /* !!! check for some minimal level of functionality? !!! */
4088 if (pHints->flags & MWM_HINTS_DECORATIONS)
4090 if (pHints->decorations & MWM_DECOR_ALL)
4092 /* client indicating decorations to be removed */
4093 pCD->clientDecoration &= ~(pHints->decorations);
4097 /* client indicating decorations to be added */
4098 pCD->clientDecoration &= pHints->decorations;
4102 * Fix up decoration configuration.
4105 if (pCD->clientDecoration &
4106 (MWM_DECOR_MENU | MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE))
4108 pCD->clientDecoration |= MWM_DECOR_TITLE;
4110 if (pCD->clientDecoration & MWM_DECOR_RESIZEH)
4112 pCD->clientDecoration |= MWM_DECOR_BORDER;
4116 if (pHints->flags & MWM_HINTS_INPUT_MODE)
4118 if ((pHints->inputMode == MWM_INPUT_PRIMARY_APPLICATION_MODAL) ||
4119 (pHints->inputMode == MWM_INPUT_FULL_APPLICATION_MODAL) ||
4120 ((pHints->inputMode == MWM_INPUT_SYSTEM_MODAL) &&
4121 !wmGD.systemModalActive))
4124 pCD->inputMode = pHints->inputMode;
4129 * Don't allow a system modal window to be a secondary window
4130 * (except with respect to applicable functions and frame
4131 * decorations). Also, don't allow system modal window to
4135 if (pCD->inputMode == MWM_INPUT_SYSTEM_MODAL)
4137 pCD->transientLeader = NULL;
4138 if (pCD->clientFunctions & MWM_FUNC_MINIMIZE)
4140 pCD->clientFunctions &= ~(MWM_FUNC_MINIMIZE);
4145 if (pHints->flags & MWM_HINTS_STATUS)
4147 pCD->window_status = pHints->status;
4150 XFree ((char*)pHints);
4152 #ifndef NO_OL_COMPAT
4155 ProcessOLDecoration (pCD);
4157 #endif /* NO_OL_COMPAT */
4161 * If primary window can't move between workspaces, then
4162 * secondary window shouldn't either.
4164 if (pCD->transientLeader &&
4165 !(pCD->transientLeader->dtwmFunctions & DtWM_FUNCTION_OCCUPY_WS))
4167 pCD->dtwmFunctions &= ~DtWM_FUNCTION_OCCUPY_WS;
4172 * Fix up functions based on system modal settings. System modal
4173 * windows and their descendents cannot be minimized.
4176 if (!((FindTransientTreeLeader (pCD))->clientFunctions&MWM_FUNC_MINIMIZE))
4178 pCD->clientFunctions &= ~MWM_FUNC_MINIMIZE;
4183 * Fix up decoration configuration based on applicable functions.
4186 if (!(pCD->clientFunctions & MWM_FUNC_RESIZE))
4188 pCD->clientDecoration &= ~MWM_DECOR_RESIZEH;
4191 if (!(pCD->clientFunctions & MWM_FUNC_MINIMIZE))
4193 pCD->clientDecoration &= ~MWM_DECOR_MINIMIZE;
4196 if (!(pCD->clientFunctions & MWM_FUNC_MAXIMIZE))
4198 pCD->clientDecoration &= ~MWM_DECOR_MAXIMIZE;
4201 pCD->decor = pCD->clientDecoration; /* !!! combine decor ... !!! */
4204 } /* END OF ProcessMwmHints */