From 8fa32b3db5f40109489fe7455935b8887c0df89f Mon Sep 17 00:00:00 2001 From: Liang Chang Date: Thu, 19 Aug 2021 07:17:51 +0800 Subject: [PATCH 1/8] dtwm: Trigger fullscreen in an "edge trigger" manner to avoid wrong behaviors caused by some unusual operations. E.g., after entered fullscreen, applications change windows to other states instead of leaving fullscreen. --- cde/programs/dtwm/WmCEvent.c | 4 +++- cde/programs/dtwm/WmEwmh.c | 8 +------- cde/programs/dtwm/WmGlobal.h | 2 +- cde/programs/dtwm/WmManage.c | 1 + cde/programs/dtwm/WmWinInfo.c | 2 +- cde/programs/dtwm/WmWinState.c | 14 ++++++++++++-- 6 files changed, 19 insertions(+), 12 deletions(-) diff --git a/cde/programs/dtwm/WmCEvent.c b/cde/programs/dtwm/WmCEvent.c index 9ce30f7ac..1245c9f65 100644 --- a/cde/programs/dtwm/WmCEvent.c +++ b/cde/programs/dtwm/WmCEvent.c @@ -2575,9 +2575,11 @@ void HandleClientMessage (ClientData *pCD, XClientMessageEvent *clientEvent) } else if (clientEvent->data.l[0] == NormalState) { - if (pCD->isFullscreen) + if (pCD->enterFullscreen) { + Boolean enterFullscreen = pCD->enterFullscreen; SetClientState (pCD, NORMAL_STATE, GetTimestamp ()); + pCD->enterFullscreen = enterFullscreen; newState = MAXIMIZED_STATE; } else diff --git a/cde/programs/dtwm/WmEwmh.c b/cde/programs/dtwm/WmEwmh.c index fbafdf9bb..0a1714fbf 100644 --- a/cde/programs/dtwm/WmEwmh.c +++ b/cde/programs/dtwm/WmEwmh.c @@ -149,16 +149,10 @@ static void ProcessNetWmStateFullscreen (ClientData *pCD, Boolean en) if (pHints != &hints) XFree (pHints); - pCD->isFullscreen = en; + pCD->enterFullscreen = en; XSendEvent (DISPLAY, ROOT_FOR_CLIENT (pCD), False, SubstructureRedirectMask, (XEvent *) &clientMsgEvent); - - if (en) XChangeProperty (DISPLAY, pCD->client, wmGD.xa_NET_WM_STATE, - XA_ATOM, 32, PropModeReplace, - (unsigned char *) &wmGD.xa_NET_WM_STATE_FULLSCREEN, - 1); - else XDeleteProperty (DISPLAY, pCD->client, wmGD.xa_NET_WM_STATE); } /* END OF FUNCTION ProcessNetWmStateFullscreen */ diff --git a/cde/programs/dtwm/WmGlobal.h b/cde/programs/dtwm/WmGlobal.h index 891c4fb2e..e56e186fa 100644 --- a/cde/programs/dtwm/WmGlobal.h +++ b/cde/programs/dtwm/WmGlobal.h @@ -1629,7 +1629,7 @@ typedef struct _ClientData int xBorderWidth; /* original X border width */ FrameInfo frameInfo; /* frame geometry data */ Boolean decorUpdated; /* True => decoration updated */ - Boolean isFullscreen; /* True => fullscreen */ + Boolean enterFullscreen; /* True => enter fullscreen */ Boolean monitorSizeIsSet; /* True => X, Y, W, H is set */ int monitorX; /* monitor X loc */ int monitorY; /* monitor Y loc */ diff --git a/cde/programs/dtwm/WmManage.c b/cde/programs/dtwm/WmManage.c index a2347f5c3..0f23e002d 100644 --- a/cde/programs/dtwm/WmManage.c +++ b/cde/programs/dtwm/WmManage.c @@ -1008,6 +1008,7 @@ void WithdrawWindow (ClientData *pCD) } } + XDeleteProperty (DISPLAY, pCD->client, wmGD.xa_NET_WM_STATE); XUnmapWindow (DISPLAY, pCD->client); XReparentWindow (DISPLAY, pCD->client, ROOT_FOR_CLIENT(pCD), x, y); diff --git a/cde/programs/dtwm/WmWinInfo.c b/cde/programs/dtwm/WmWinInfo.c index f1dc6d185..b6a816bb7 100644 --- a/cde/programs/dtwm/WmWinInfo.c +++ b/cde/programs/dtwm/WmWinInfo.c @@ -218,7 +218,7 @@ InitClientData (Window clientWindow) pCD->smClientID = (String)NULL; pCD->decorUpdated = False; - pCD->isFullscreen = False; + pCD->enterFullscreen = False; pCD->monitorSizeIsSet = False; return (pCD); diff --git a/cde/programs/dtwm/WmWinState.c b/cde/programs/dtwm/WmWinState.c index 22ab205c0..8ea2fab84 100644 --- a/cde/programs/dtwm/WmWinState.c +++ b/cde/programs/dtwm/WmWinState.c @@ -181,7 +181,6 @@ void SetClientStateWithEventMask (ClientData *pCD, int newState, Time setTime, u * WM_STATE property is set in WithdrawWindow. */ - XDeleteProperty (DISPLAY, pCD->client, wmGD.xa_NET_WM_STATE); UnManageWindow (pCD); break; } @@ -614,10 +613,12 @@ void ConfigureNewState (ClientData *pcd) XResizeWindow (DISPLAY, pcd->client, (unsigned int) pcd->clientWidth, (unsigned int) pcd->clientHeight); + + XDeleteProperty (DISPLAY, pcd->client, wmGD.xa_NET_WM_STATE); } else { - if (pcd->isFullscreen && pcd->monitorSizeIsSet) + if (pcd->enterFullscreen && pcd->monitorSizeIsSet) { pcd->maxX = pcd->monitorX; pcd->maxY = pcd->monitorY; @@ -646,7 +647,16 @@ void ConfigureNewState (ClientData *pcd) (unsigned int) pcd->maxHeight); pcd->maxConfig = TRUE; RegenerateClientFrame(pcd); + + if (pcd->enterFullscreen) + XChangeProperty (DISPLAY, pcd->client, wmGD.xa_NET_WM_STATE, + XA_ATOM, 32, PropModeReplace, + (unsigned char *) &wmGD.xa_NET_WM_STATE_FULLSCREEN, + 1); } + + pcd->enterFullscreen = False; + SendConfigureNotify (pcd); /* From f05bc54cebf35b2ba850a677ad38148304746720 Mon Sep 17 00:00:00 2001 From: Liang Chang Date: Thu, 19 Aug 2021 21:49:03 +0800 Subject: [PATCH 2/8] dtwm: To avoid a segfault, allocate gadget rectangles when regenerate window frame. A typical case, create a frameless window then regenerate it's frame. --- cde/programs/dtwm/WmCDInfo.c | 5 +++-- cde/programs/dtwm/WmCDecor.c | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cde/programs/dtwm/WmCDInfo.c b/cde/programs/dtwm/WmCDInfo.c index dbe26d294..3027701f9 100644 --- a/cde/programs/dtwm/WmCDInfo.c +++ b/cde/programs/dtwm/WmCDInfo.c @@ -989,7 +989,8 @@ int IdentifyFramePart (ClientData *pCD, int x, int y) if (decor & MWM_DECOR_TITLE) { - if ( (x >= pCD->titleRectangle.x) && + if ( pCD->pTitleGadgets && + (x >= pCD->titleRectangle.x) && (x < (int)pCD->titleRectangle.x + (int)pCD->titleRectangle.width) && (y >= pCD->titleRectangle.y) && (y < (int)pCD->titleRectangle.y + (int)pCD->titleRectangle.height) ) @@ -1002,7 +1003,7 @@ int IdentifyFramePart (ClientData *pCD, int x, int y) /* try resize border */ - if (decor & MWM_DECOR_RESIZEH) + if (decor & MWM_DECOR_RESIZEH && pCD->pTitleGadgets) { rval = GadgetID(x, y, pCD->pResizeGadgets, STRETCH_COUNT); } diff --git a/cde/programs/dtwm/WmCDecor.c b/cde/programs/dtwm/WmCDecor.c index c8d6f3a79..fbd73999c 100644 --- a/cde/programs/dtwm/WmCDecor.c +++ b/cde/programs/dtwm/WmCDecor.c @@ -2335,6 +2335,7 @@ void RegenerateClientFrame (ClientData *pcd) } /* recreate gadget rectangles */ + AllocateGadgetRectangles (pcd); ComputeGadgetRectangles (pcd); /* regenerate the graphics */ From d90f765c0aa89d16c21b69f869d51edcee634d5e Mon Sep 17 00:00:00 2001 From: Liang Chang Date: Thu, 19 Aug 2021 23:06:21 +0800 Subject: [PATCH 3/8] dtwm: Create title bar window if clientTitleWin is NULL when regenerate client frame. --- cde/programs/dtwm/WmCDecor.c | 144 +++++++++++++++++++++-------------- 1 file changed, 88 insertions(+), 56 deletions(-) diff --git a/cde/programs/dtwm/WmCDecor.c b/cde/programs/dtwm/WmCDecor.c index fbd73999c..33ddebf2d 100644 --- a/cde/programs/dtwm/WmCDecor.c +++ b/cde/programs/dtwm/WmCDecor.c @@ -104,6 +104,91 @@ static Bevel_Count Bevels[] = + +/*************************************<->************************************* + * + * CreateTitleBarWindow (pcd) + * + * + * Description: + * ----------- + * Create title bar window. + * + * + * Inputs: + * ------ + * pcd - pointer to client data record + * + * Outputs: + * ------- + * pcd - modified + * + * + * Comments: + * -------- + * + *************************************<->***********************************/ + +static void CreateTitleBarWindow (ClientData *pcd) +{ + unsigned int wclass; /* window class */ + unsigned long attr_mask; + XSetWindowAttributes window_attribs; + + /* + * Create title bar window. If the title bar has its own appearance, + * or if there is no border around the client area, + * then we need to create an input/output window to draw in. Otherwise + * we can use an input-only window (to clip the corner resize windows). + */ + attr_mask = CWCursor; + window_attribs.cursor = wmGD.workspaceCursor; + + if (DECOUPLE_TITLE_APPEARANCE(pcd)) + { + /* title bar has a different appearance than rest of frame */ + wclass = InputOutput; + + /* need to handle exposure events */ + attr_mask |= CWEventMask; + window_attribs.event_mask = ExposureMask; + + /* + * Use background pixmap if one is specified, otherwise set the + * appropriate background color. + */ + + if (CLIENT_TITLE_APPEARANCE(pcd).backgroundPixmap) + { + attr_mask |= CWBackPixmap; + window_attribs.background_pixmap = + CLIENT_TITLE_APPEARANCE(pcd).backgroundPixmap; + } + else + { + attr_mask |= CWBackPixel; + window_attribs.background_pixel = + CLIENT_TITLE_APPEARANCE(pcd).background; + } + } + else + { + /* title bar has same appearance as rest of frame */ + wclass = InputOnly; + } + + pcd->clientTitleWin = XCreateWindow(DISPLAY, pcd->clientFrameWin, + (int) pcd->frameInfo.upperBorderWidth, + (int) pcd->frameInfo.upperBorderWidth, + pcd->frameInfo.width - + 2*pcd->frameInfo.upperBorderWidth, + pcd->frameInfo.titleBarHeight, + 0, + CopyFromParent,wclass,CopyFromParent, + attr_mask, &window_attribs); +} + + /*************************************<->************************************* * @@ -341,7 +426,6 @@ void BaseWinExposureProc (ClientData *pcd) Boolean ConstructFrame (ClientData *pcd) { unsigned long decoration = pcd->decor; - unsigned int wclass; /* window class */ unsigned long attr_mask; XSetWindowAttributes window_attribs; int frmX, frmY; @@ -414,60 +498,7 @@ Boolean ConstructFrame (ClientData *pcd) CreateStretcherWindows (pcd); } - /* - * Create title bar window. If the title bar has its own appearance, - * or if there is no border around the client area, - * then we need to create an input/output window to draw in. Otherwise - * we can use an input-only window (to clip the corner resize windows). - */ - if (decoration & MWM_DECOR_TITLE) { - - attr_mask = CWCursor; - window_attribs.cursor = wmGD.workspaceCursor; - - if (DECOUPLE_TITLE_APPEARANCE(pcd)) - { - /* title bar has a different appearance than rest of frame */ - wclass = InputOutput; - - /* need to handle exposure events */ - attr_mask |= CWEventMask; - window_attribs.event_mask = ExposureMask; - - /* - * Use background pixmap if one is specified, otherwise set the - * appropriate background color. - */ - - if (CLIENT_TITLE_APPEARANCE(pcd).backgroundPixmap) - { - attr_mask |= CWBackPixmap; - window_attribs.background_pixmap = - CLIENT_TITLE_APPEARANCE(pcd).backgroundPixmap; - } - else - { - attr_mask |= CWBackPixel; - window_attribs.background_pixel = - CLIENT_TITLE_APPEARANCE(pcd).background; - } - } - else - { - /* title bar has same appearance as rest of frame */ - wclass = InputOnly; - } - - pcd->clientTitleWin = XCreateWindow(DISPLAY, pcd->clientFrameWin, - (int) pcd->frameInfo.upperBorderWidth, - (int) pcd->frameInfo.upperBorderWidth, - pcd->frameInfo.width - - 2*pcd->frameInfo.upperBorderWidth, - pcd->frameInfo.titleBarHeight, - 0, - CopyFromParent,wclass,CopyFromParent, - attr_mask, &window_attribs); - } + if (decoration & MWM_DECOR_TITLE) CreateTitleBarWindow (pcd); /* generate gadget position search structure */ if (!AllocateGadgetRectangles (pcd)) @@ -2272,8 +2303,9 @@ void RegenerateClientFrame (ClientData *pcd) /* resize title bar window */ - if (decor & MWM_DECOR_TITLE) + if (decor & MWM_DECOR_TITLE && !pcd->clientTitleWin) { + CreateTitleBarWindow (pcd); XResizeWindow (DISPLAY, pcd->clientTitleWin, pcd->frameInfo.width - 2*pcd->frameInfo.upperBorderWidth, pcd->frameInfo.titleBarHeight); From 7734a01e41b3a7d044a714e821bb62c158bd4d69 Mon Sep 17 00:00:00 2001 From: Liang Chang Date: Fri, 20 Aug 2021 13:40:05 +0800 Subject: [PATCH 4/8] dtwm: Create stretcher windows when regenerate a frame for a frameless window to make the resize cursors show again. --- cde/programs/dtwm/WmCDecor.c | 25 +++++++++++++++---------- cde/programs/dtwm/WmWinInfo.c | 3 +++ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/cde/programs/dtwm/WmCDecor.c b/cde/programs/dtwm/WmCDecor.c index 33ddebf2d..8b731edf1 100644 --- a/cde/programs/dtwm/WmCDecor.c +++ b/cde/programs/dtwm/WmCDecor.c @@ -1332,6 +1332,8 @@ void CreateStretcherWindows (ClientData *pcd) unsigned long attr_mask; for (iWin = 0; iWin < STRETCH_COUNT; iWin++) { + if (pcd->clientStretchWin[iWin]) continue; + switch (iWin) { case STRETCH_NORTH_WEST: GetFramePartInfo (pcd, FRAME_RESIZE_NW, @@ -2301,16 +2303,6 @@ void RegenerateClientFrame (ClientData *pcd) XMoveResizeWindow (DISPLAY, pcd->clientFrameWin, pcd->frameInfo.x, pcd->frameInfo.y, pcd->frameInfo.width, pcd->frameInfo.height); - - /* resize title bar window */ - if (decor & MWM_DECOR_TITLE && !pcd->clientTitleWin) - { - CreateTitleBarWindow (pcd); - XResizeWindow (DISPLAY, pcd->clientTitleWin, - pcd->frameInfo.width - 2*pcd->frameInfo.upperBorderWidth, - pcd->frameInfo.titleBarHeight); - } - /* resize base window */ XMoveResizeWindow (DISPLAY, pcd->clientBaseWin, BaseWindowX (pcd), BaseWindowY (pcd), @@ -2318,6 +2310,8 @@ void RegenerateClientFrame (ClientData *pcd) /* resize the stretcher windows */ if (SHOW_RESIZE_CURSORS(pcd) && (decor & MWM_DECOR_RESIZEH)) { + CreateStretcherWindows (pcd); + XMoveResizeWindow (DISPLAY, pcd->clientStretchWin[STRETCH_NORTH_WEST], 0, 0, pcd->frameInfo.cornerWidth, @@ -2366,6 +2360,15 @@ void RegenerateClientFrame (ClientData *pcd) pcd->frameInfo.height - 2*pcd->frameInfo.cornerHeight); } + /* resize title bar window */ + if (decor & MWM_DECOR_TITLE && !pcd->clientTitleWin) + { + CreateTitleBarWindow (pcd); + XResizeWindow (DISPLAY, pcd->clientTitleWin, + pcd->frameInfo.width - 2*pcd->frameInfo.upperBorderWidth, + pcd->frameInfo.titleBarHeight); + } + /* recreate gadget rectangles */ AllocateGadgetRectangles (pcd); ComputeGadgetRectangles (pcd); @@ -2378,6 +2381,8 @@ void RegenerateClientFrame (ClientData *pcd) SetFrameShape (pcd); } + /* map all subwindows of client frame */ + XMapSubwindows(DISPLAY, pcd->clientFrameWin); } /* END OF FUNCTION RegenerateClientFrame */ diff --git a/cde/programs/dtwm/WmWinInfo.c b/cde/programs/dtwm/WmWinInfo.c index b6a816bb7..5a877da67 100644 --- a/cde/programs/dtwm/WmWinInfo.c +++ b/cde/programs/dtwm/WmWinInfo.c @@ -113,6 +113,7 @@ WmWorkspaceData *pIconBoxInitialWS; ClientData * InitClientData (Window clientWindow) { + int i; ClientData *pCD; if (!XFindContext (DISPLAY, clientWindow, wmGD.windowContextType, @@ -221,6 +222,8 @@ InitClientData (Window clientWindow) pCD->enterFullscreen = False; pCD->monitorSizeIsSet = False; + for (i = 0; i < STRETCH_COUNT; ++i) pCD->clientStretchWin[i] = (Window)0L; + return (pCD); } /* END OF FUNCTION InitClientData */ From 9a8debd7d1939dca825fcd46f1b251b7104fb908 Mon Sep 17 00:00:00 2001 From: Liang Chang Date: Thu, 9 Sep 2021 14:51:34 +0800 Subject: [PATCH 5/8] dtwm: Add definitions for _NET_WM_NAME and _NET_WM_ICON_NAME. --- cde/programs/dtwm/WmGlobal.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cde/programs/dtwm/WmGlobal.h b/cde/programs/dtwm/WmGlobal.h index e56e186fa..84a6f22de 100644 --- a/cde/programs/dtwm/WmGlobal.h +++ b/cde/programs/dtwm/WmGlobal.h @@ -1935,6 +1935,9 @@ typedef struct _WmGlobalData Atom xa_SM_CLIENT_ID; Atom xa_WMSAVE_HINT; + Atom xa_UTF8_STRING; + Atom xa_NET_WM_NAME; + Atom xa_NET_WM_ICON_NAME; Atom xa_NET_WM_FULLSCREEN_MONITORS; Atom xa_NET_WM_STATE; Atom xa_NET_WM_STATE_FULLSCREEN; From c6e8d60548e93a05efa7cd944c83ede25565e9d7 Mon Sep 17 00:00:00 2001 From: Liang Chang Date: Thu, 9 Sep 2021 23:03:24 +0800 Subject: [PATCH 6/8] dtwm: Add processing functions for _NET_WM_NAME and _NET_WM_ICON_NAME. --- cde/programs/dtwm/WmEwmh.c | 102 ++++++++++++++++++++++++++++++++++--- cde/programs/dtwm/WmEwmh.h | 15 +++--- 2 files changed, 103 insertions(+), 14 deletions(-) diff --git a/cde/programs/dtwm/WmEwmh.c b/cde/programs/dtwm/WmEwmh.c index 0a1714fbf..55b81feac 100644 --- a/cde/programs/dtwm/WmEwmh.c +++ b/cde/programs/dtwm/WmEwmh.c @@ -159,7 +159,57 @@ static void ProcessNetWmStateFullscreen (ClientData *pCD, Boolean en) /*************************************<->************************************* * - * ProcessEwmh (pCD, clientEvent) + * ProcessNetWmNameNetWmIconName (pCD, atom) + * + * + * Description: + * ----------- + * This function retrieves the contents of the _NET_WM_NAME or + * _NET_WM_ICON_NAME property on the cient window. + * + * + * Inputs: + * ------ + * pCD = pointer to client data structure + * atom = _NET_WM_NAME or _NET_WM_ICON_NAME + * + *************************************<->***********************************/ + +static void ProcessNetWmNameNetWmIconName (ClientData *pCD, Atom atom) +{ + Atom actualType; + int actualFormat; + unsigned long nitems; + unsigned long leftover; + unsigned char *netNameProp = NULL; + XTextProperty nameProp = {0}; + + if (XGetWindowProperty (DISPLAY, pCD->client, atom, 0L, 1000000L, False, + wmGD.xa_UTF8_STRING, &actualType, &actualFormat, + &nitems, &leftover, &netNameProp) != Success) + goto done; + + if (actualType != wmGD.xa_UTF8_STRING) goto done; + if (actualFormat != 8) goto done; + + if (Xutf8TextListToTextProperty (DISPLAY, (char **) &netNameProp, 1, + XUTF8StringStyle, &nameProp) != Success) goto done; + + if (atom == wmGD.xa_NET_WM_NAME) + XSetWMName (DISPLAY, pCD->client, &nameProp); + else if (atom == wmGD.xa_NET_WM_ICON_NAME) + XSetWMIconName (DISPLAY, pCD->client, &nameProp); + +done: + if (netNameProp) XFree (netNameProp); + if (nameProp.value) XFree ((char*) nameProp.value); +} /* END OF FUNCTION ProcessNetWmNameNetWmIconName */ + + + +/*************************************<->************************************* + * + * HandleClientMessageEwmh (pCD, clientEvent) * * * Description: @@ -174,7 +224,7 @@ static void ProcessNetWmStateFullscreen (ClientData *pCD, Boolean en) * *************************************<->***********************************/ -void ProcessEwmh (ClientData *pCD, XClientMessageEvent *clientEvent) +void HandleClientMessageEwmh (ClientData *pCD, XClientMessageEvent *clientEvent) { int i; @@ -194,7 +244,36 @@ void ProcessEwmh (ClientData *pCD, XClientMessageEvent *clientEvent) } } } -} /* END OF FUNCTION ProcessEwmh */ +} /* END OF FUNCTION HandleClientMessageEwmh */ + + + +/*************************************<->************************************* + * + * HandlePropertyNotifyEwmh (pCD, clientEvent) + * + * + * Description: + * ----------- + * This function handles PropertyNotify events (indicating EWMH property + * changes) that are reported to the client window. + * + * + * Inputs: + * ------ + * pCD = pointer to client data + * clientEvent = pointer to a client message event on the root window + * + *************************************<->***********************************/ + +void HandlePropertyNotifyEwmh (ClientData *pCD, XPropertyEvent *propertyEvent) +{ + if (propertyEvent->atom == wmGD.xa_NET_WM_NAME || + propertyEvent->atom == wmGD.xa_NET_WM_ICON_NAME) + { + ProcessNetWmNameNetWmIconName (pCD, propertyEvent->atom); + } +} /* END OF FUNCTION HandlePropertyNotifyEwmh */ @@ -217,18 +296,22 @@ void ProcessEwmh (ClientData *pCD, XClientMessageEvent *clientEvent) void SetupWmEwmh (void) { enum { + XA_UTF8_STRING, XA_NET_SUPPORTED, - XA_NET_WM_NAME, XA_NET_SUPPORTING_WM_CHECK, + XA_NET_WM_NAME, + XA_NET_WM_ICON_NAME, XA_NET_WM_FULLSCREEN_MONITORS, XA_NET_WM_STATE, XA_NET_WM_STATE_FULLSCREEN }; static char *atom_names[] = { + "UTF8_STRING", _XA_NET_SUPPORTED, - _XA_NET_WM_NAME, _XA_NET_SUPPORTING_WM_CHECK, + _XA_NET_WM_NAME, + _XA_NET_WM_ICON_NAME, _XA_NET_WM_FULLSCREEN_MONITORS, _XA_NET_WM_STATE, _XA_NET_WM_STATE_FULLSCREEN @@ -240,6 +323,9 @@ void SetupWmEwmh (void) XInternAtoms(DISPLAY, atom_names, XtNumber(atom_names), False, atoms); + wmGD.xa_UTF8_STRING = atoms[XA_UTF8_STRING]; + wmGD.xa_NET_WM_NAME = atoms[XA_NET_WM_NAME]; + wmGD.xa_NET_WM_ICON_NAME = atoms[XA_NET_WM_ICON_NAME]; wmGD.xa_NET_WM_FULLSCREEN_MONITORS = atoms[XA_NET_WM_FULLSCREEN_MONITORS]; wmGD.xa_NET_WM_STATE = atoms[XA_NET_WM_STATE]; wmGD.xa_NET_WM_STATE_FULLSCREEN = atoms[XA_NET_WM_STATE_FULLSCREEN]; @@ -249,8 +335,8 @@ void SetupWmEwmh (void) childWindow = XCreateSimpleWindow(DISPLAY, wmGD.Screens[scr].rootWindow, -1, -1, 1, 1, 0, 0, 0); - XChangeProperty(DISPLAY, childWindow, atoms[XA_NET_WM_NAME], None, 32, - PropModeReplace, "DTWM", 5); + XChangeProperty(DISPLAY, childWindow, atoms[XA_NET_WM_NAME], + atoms[XA_UTF8_STRING], 8, PropModeReplace, "DTWM", 5); XChangeProperty(DISPLAY, childWindow, atoms[XA_NET_SUPPORTING_WM_CHECK], XA_WINDOW, 32, @@ -262,6 +348,6 @@ void SetupWmEwmh (void) XChangeProperty(DISPLAY, wmGD.Screens[scr].rootWindow, atoms[XA_NET_SUPPORTED], XA_ATOM, 32, PropModeReplace, - (unsigned char *)&atoms[XA_NET_SUPPORTING_WM_CHECK], 4); + (unsigned char *)&atoms[XA_NET_SUPPORTING_WM_CHECK], 6); } } /* END OF FUNCTION SetupWmEwmh */ diff --git a/cde/programs/dtwm/WmEwmh.h b/cde/programs/dtwm/WmEwmh.h index 5dd7d9480..b70b4baab 100644 --- a/cde/programs/dtwm/WmEwmh.h +++ b/cde/programs/dtwm/WmEwmh.h @@ -30,14 +30,17 @@ #define _NET_WM_STATE_ADD 1 #define _NET_WM_STATE_TOGGLE 2 -#define _XA_NET_SUPPORTED "_NET_SUPPORTED" -#define _XA_NET_WM_NAME "_NET_WM_NAME" +#define _XA_NET_SUPPORTED "_NET_SUPPORTED" #define _XA_NET_SUPPORTING_WM_CHECK "_NET_SUPPORTING_WM_CHECK" -#define _XA_NET_WM_FULLSCREEN_MONITORS "_NET_WM_FULLSCREEN_MONITORS" -#define _XA_NET_WM_STATE "_NET_WM_STATE" -#define _XA_NET_WM_STATE_FULLSCREEN "_NET_WM_STATE_FULLSCREEN" +#define _XA_NET_WM_NAME "_NET_WM_NAME" +#define _XA_NET_WM_ICON_NAME "_NET_WM_ICON_NAME" +#define _XA_NET_WM_FULLSCREEN_MONITORS "_NET_WM_FULLSCREEN_MONITORS" +#define _XA_NET_WM_STATE "_NET_WM_STATE" +#define _XA_NET_WM_STATE_FULLSCREEN "_NET_WM_STATE_FULLSCREEN" -void ProcessEwmh (ClientData *pCD, XClientMessageEvent *clientEvent); +void HandleClientMessageEwmh (ClientData *pCD, + XClientMessageEvent *clientEvent); +void HandlePropertyNotifyEwmh (ClientData *pCD, XPropertyEvent *propertyEvent); void SetupWmEwmh (void); #endif /* _Dt_WmEwmh_h_ */ From 08ebba5225ea684b1fdbc15f713aa727ac0468c0 Mon Sep 17 00:00:00 2001 From: Liang Chang Date: Fri, 10 Sep 2021 14:36:44 +0800 Subject: [PATCH 7/8] dtwm: Respond to the following EWMH: _NET_WM_NAME _NET_WM_ICON_NAME --- cde/programs/dtwm/WmCEvent.c | 12 +++++++++--- cde/programs/dtwm/WmWinInfo.c | 5 +++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/cde/programs/dtwm/WmCEvent.c b/cde/programs/dtwm/WmCEvent.c index 1245c9f65..4da46eec5 100644 --- a/cde/programs/dtwm/WmCEvent.c +++ b/cde/programs/dtwm/WmCEvent.c @@ -611,7 +611,8 @@ Boolean HandleEventsOnSpecialWindows (XEvent *pEvent) case ClientMessage: { if (pCD = InitClientData (pEvent->xclient.window)) { - ProcessEwmh (pCD, (XClientMessageEvent *) pEvent); + HandleClientMessageEwmh(pCD, + (XClientMessageEvent *) pEvent); dispatchEvent = False; } break; @@ -840,7 +841,8 @@ void HandleCPropertyNotify (ClientData *pCD, XPropertyEvent *propertyEvent) ProcessColormapList (ACTIVE_PSD, pCD); } } - else if (propertyEvent->atom == wmGD.xa_MWM_HINTS) { + else if (propertyEvent->atom == wmGD.xa_MWM_HINTS) + { long suppliedReturn; XSizeHints hintsReturn = {0}; @@ -856,6 +858,10 @@ void HandleCPropertyNotify (ClientData *pCD, XPropertyEvent *propertyEvent) ProcessMwmHints (pCD); SetClientOffset (pCD); } + else + { + HandlePropertyNotifyEwmh (pCD, propertyEvent); + } break; } } @@ -2602,7 +2608,7 @@ void HandleClientMessage (ClientData *pCD, XClientMessageEvent *clientEvent) } else { - ProcessEwmh (pCD, clientEvent); + HandleClientMessageEwmh (pCD, clientEvent); } } /* END OF FUNCTION HandleClientMessage */ diff --git a/cde/programs/dtwm/WmWinInfo.c b/cde/programs/dtwm/WmWinInfo.c index 5a877da67..5aaa07b19 100644 --- a/cde/programs/dtwm/WmWinInfo.c +++ b/cde/programs/dtwm/WmWinInfo.c @@ -261,6 +261,7 @@ GetClientInfo (WmScreenData *pSD, Window clientWindow, long manageFlags) { ClientData *pCD; XSetWindowAttributes sAttributes; + XPropertyEvent propertyEvent; if (!(pCD = InitClientData (clientWindow))) { @@ -420,6 +421,8 @@ GetClientInfo (WmScreenData *pSD, Window clientWindow, long manageFlags) */ ProcessWmWindowTitle (pCD, TRUE); + propertyEvent.atom = wmGD.xa_NET_WM_NAME; + HandlePropertyNotifyEwmh (pCD, &propertyEvent); /* @@ -427,6 +430,8 @@ GetClientInfo (WmScreenData *pSD, Window clientWindow, long manageFlags) */ ProcessWmIconTitle (pCD, TRUE); + propertyEvent.atom = wmGD.xa_NET_WM_ICON_NAME; + HandlePropertyNotifyEwmh (pCD, &propertyEvent); /* From c38a5a8b713f7de086b84e203dd10ea7c3427d99 Mon Sep 17 00:00:00 2001 From: Liang Chang Date: Sun, 31 Oct 2021 22:18:50 +0800 Subject: [PATCH 8/8] dtwm: Respond to the following EWMH: _NET_WM_STATE_MAXIMIZED_VERT _NET_WM_STATE_MAXIMIZED_HORZ A window is maximized if both _NET_WM_STATE_MAXIMIZED_VERT and _NET_WM_STATE_MAXIMIZED_HORZ are set. --- cde/programs/dtwm/WmCEvent.c | 50 ++-- cde/programs/dtwm/WmEwmh.c | 473 ++++++++++++++++----------------- cde/programs/dtwm/WmEwmh.h | 31 ++- cde/programs/dtwm/WmGlobal.h | 15 +- cde/programs/dtwm/WmManage.c | 2 +- cde/programs/dtwm/WmWinConf.c | 6 - cde/programs/dtwm/WmWinInfo.c | 28 +- cde/programs/dtwm/WmWinState.c | 30 ++- 8 files changed, 316 insertions(+), 319 deletions(-) diff --git a/cde/programs/dtwm/WmCEvent.c b/cde/programs/dtwm/WmCEvent.c index 4da46eec5..5b8d47fc6 100644 --- a/cde/programs/dtwm/WmCEvent.c +++ b/cde/programs/dtwm/WmCEvent.c @@ -611,9 +611,17 @@ Boolean HandleEventsOnSpecialWindows (XEvent *pEvent) case ClientMessage: { if (pCD = InitClientData (pEvent->xclient.window)) { - HandleClientMessageEwmh(pCD, - (XClientMessageEvent *) pEvent); - dispatchEvent = False; + XClientMessageEvent *clientEvent = pEvent; + + if (clientEvent->message_type == + wmGD.xa__NET_WM_FULLSCREEN_MONITORS) + { + ProcessNetWmFullscreenMonitors (pCD, + clientEvent->data.l[0], clientEvent->data.l[1], + clientEvent->data.l[2], clientEvent->data.l[3]); + + dispatchEvent = False; + } } break; } @@ -858,9 +866,13 @@ void HandleCPropertyNotify (ClientData *pCD, XPropertyEvent *propertyEvent) ProcessMwmHints (pCD); SetClientOffset (pCD); } - else + else if (propertyEvent->atom == wmGD.xa__NET_WM_NAME) { - HandlePropertyNotifyEwmh (pCD, propertyEvent); + ProcessNetWmName (pCD); + } + else if (propertyEvent->atom == wmGD.xa__NET_WM_ICON_NAME) + { + ProcessNetWmIconName (pCD); } break; } @@ -2581,22 +2593,7 @@ void HandleClientMessage (ClientData *pCD, XClientMessageEvent *clientEvent) } else if (clientEvent->data.l[0] == NormalState) { - if (pCD->enterFullscreen) - { - Boolean enterFullscreen = pCD->enterFullscreen; - SetClientState (pCD, NORMAL_STATE, GetTimestamp ()); - pCD->enterFullscreen = enterFullscreen; - newState = MAXIMIZED_STATE; - } - else - { - if (pCD->decorUpdated) - { - SetClientState (pCD, MAXIMIZED_STATE, GetTimestamp ()); - } - - newState = NORMAL_STATE; - } + newState = NORMAL_STATE; } if (!ClientInWorkspace (ACTIVE_WS, pCD)) { @@ -2606,9 +2603,16 @@ void HandleClientMessage (ClientData *pCD, XClientMessageEvent *clientEvent) SetClientState (pCD, newState, GetTimestamp ()); } - else + else if (clientEvent->message_type == wmGD.xa__NET_WM_FULLSCREEN_MONITORS) { - HandleClientMessageEwmh (pCD, clientEvent); + ProcessNetWmFullscreenMonitors (pCD, + clientEvent->data.l[0], clientEvent->data.l[1], + clientEvent->data.l[2], clientEvent->data.l[3]); + } + else if (clientEvent->message_type == wmGD.xa__NET_WM_STATE) + { + ProcessNetWmState (pCD, clientEvent->data.l[0], clientEvent->data.l[1], + clientEvent->data.l[2]); } } /* END OF FUNCTION HandleClientMessage */ diff --git a/cde/programs/dtwm/WmEwmh.c b/cde/programs/dtwm/WmEwmh.c index 55b81feac..12ef70255 100644 --- a/cde/programs/dtwm/WmEwmh.c +++ b/cde/programs/dtwm/WmEwmh.c @@ -23,50 +23,163 @@ * Floor, Boston, MA 02110-1301 USA */ -/* - * Included Files: - */ +#include #include "WmGlobal.h" +#include "WmEvent.h" #include "WmEwmh.h" - -/* - * include extern functions - */ - #include "WmMultiHead.h" #include "WmProperty.h" +#include "WmWinState.h" +#include "WmWrkspace.h" +static unsigned long GetWindowProperty (Window w, Atom property, Atom reqType, + unsigned char **propReturn) +{ + Atom actualType; + int actualFormat; + unsigned long nitems; + unsigned long leftover; - -/*************************************<->************************************* - * - * ProcessNetWmFullscreenMonitors (pCD, top, bottom, left, right) - * - * - * Description: - * ----------- - * This function retrieves the contents of the _NET_WM_FULLSCREEN_MONITORS - * message. - * - * - * - * Inputs: - * ------ - * pCD = pointer to client data - * top = the monitor whose top edge defines the top edge of the fullscreen - * window - * bottom = the monitor whose bottom edge defines the bottom edge of the - * fullscreen window - * left = the monitor whose left edge defines the left edge of the fullscreen - * window - * right = the monitor whose right edge defines the right edge of the - * fullscreen window - * - *************************************<->***********************************/ + if (XGetWindowProperty (DISPLAY, w, property, 0L, 1000000L, False, reqType, + &actualType, &actualFormat, &nitems, &leftover, + propReturn) != Success) goto err; -static void ProcessNetWmFullscreenMonitors (ClientData *pCD, - long top, long bottom, long left, long right) + if (actualType != reqType) goto err; + + return nitems; + +err: + XFree (*propReturn); + return 0; +} + +static void UpdateNetWmState (ClientData *pCD) +{ + unsigned long nitems; + unsigned long natoms = 0; + Atom *netWmState; + Atom *atoms; + + nitems = GetWindowProperty (pCD->client, wmGD.xa__NET_WM_STATE, XA_ATOM, + (unsigned char **) &netWmState); + + atoms = malloc ((nitems + 2) * sizeof (Atom)); if (!atoms) goto done; + + for (int i = 0; i < nitems; ++i) + if (netWmState[i] == wmGD.xa__NET_WM_STATE_FULLSCREEN || + netWmState[i] == wmGD.xa__NET_WM_STATE_MAXIMIZED_VERT || + netWmState[i] == wmGD.xa__NET_WM_STATE_MAXIMIZED_HORZ) + continue; + else + atoms[natoms++] = netWmState[i]; + + if (pCD->maxConfig) + { + if (pCD->isFullscreen) + { + atoms[natoms++] = wmGD.xa__NET_WM_STATE_FULLSCREEN; + } + else + { + atoms[natoms++] = wmGD.xa__NET_WM_STATE_MAXIMIZED_VERT; + atoms[natoms++] = wmGD.xa__NET_WM_STATE_MAXIMIZED_HORZ; + } + } + + XChangeProperty (DISPLAY, pCD->client, wmGD.xa__NET_WM_STATE, XA_ATOM, 32, + PropModeReplace, (unsigned char *) atoms, natoms); + +done: + XFree (netWmState); + XFree (atoms); +} + +static void ProcessNetWmStateFullscreen (ClientData *pCD, long action) +{ + switch (action) + { + case _NET_WM_STATE_REMOVE: + if (!pCD->isFullscreen) return; + pCD->isFullscreen = False; + break; + case _NET_WM_STATE_ADD: + if (pCD->isFullscreen) return; + pCD->isFullscreen = True; + break; + case _NET_WM_STATE_TOGGLE: + pCD->isFullscreen = !pCD->isFullscreen; + break; + default: + return; + } + + SetClientState (pCD, NORMAL_STATE, GetTimestamp ()); + + if (pCD->isFullscreen) + SetClientState (pCD, MAXIMIZED_STATE, GetTimestamp ()); +} + +static void ProcessNetWmStateMaximized (ClientData *pCD, long action) +{ + int newState; + + switch (action) + { + case _NET_WM_STATE_REMOVE: + if (pCD->clientState != MAXIMIZED_STATE) return; + newState = NORMAL_STATE; + break; + case _NET_WM_STATE_ADD: + if (pCD->clientState == MAXIMIZED_STATE) return; + newState = MAXIMIZED_STATE; + break; + case _NET_WM_STATE_TOGGLE: + newState = pCD->clientState == MAXIMIZED_STATE ? + NORMAL_STATE : MAXIMIZED_STATE; + break; + default: + return; + } + + SetClientState (pCD, newState, GetTimestamp ()); +} + +static void ProcessNetWmNameNetWmIconName (ClientData *pCD, Atom name) +{ + unsigned long nitems; + unsigned char *netNameProp; + XTextProperty nameProp = {0}; + + nitems = GetWindowProperty(pCD->client, name, wmGD.xa_UTF8_STRING, + &netNameProp); + + if (!nitems) goto done; + + if (Xutf8TextListToTextProperty (DISPLAY, (char **) &netNameProp, 1, + XUTF8StringStyle, &nameProp) != Success) goto done; + + if (name == wmGD.xa__NET_WM_NAME) + XSetWMName (DISPLAY, pCD->client, &nameProp); + else if (name == wmGD.xa__NET_WM_ICON_NAME) + XSetWMIconName (DISPLAY, pCD->client, &nameProp); + +done: + XFree (netNameProp); + XFree ((char*) nameProp.value); +} + +/** +* @brief Processes the _NET_WM_FULLSCREEN_MONITORS protocol. +* +* @param pCD +* @param top +* @param bottom +* @param left +* @param right +*/ +void ProcessNetWmFullscreenMonitors (ClientData *pCD, + long top, long bottom, long left, long right) { WmHeadInfo_t *pHeadInfo; @@ -103,251 +216,123 @@ static void ProcessNetWmFullscreenMonitors (ClientData *pCD, free(pHeadInfo); pCD->monitorSizeIsSet = True; -} /* END OF FUNCTION ProcessNetWmFullscreenMonitors */ +} - - -/*************************************<->************************************* - * - * ProcessNetWmStateFullscreen (pCD, en) - * - * - * Description: - * ----------- - * This function retrieves the contents of the _NET_WM_STATE_FULLSCREEN - * message. - * - * - * - * Inputs: - * ------ - * pCD = pointer to client data - * en = enable fullscreen - * - *************************************<->***********************************/ - -static void ProcessNetWmStateFullscreen (ClientData *pCD, Boolean en) +/** +* @brief Processes the _NET_WM_STATE client message. +* +* @param pCD +* @param action +* @param firstProperty +* @param secondProperty +*/ +void ProcessNetWmState (ClientData *pCD, long action, + long firstProperty, long secondProperty) { - PropMwmHints hints = {0}; - PropMwmHints *pHints = GetMwmHints (pCD); - XClientMessageEvent clientMsgEvent = { - .type = ClientMessage, - .window = pCD->client, - .message_type = wmGD.xa_WM_CHANGE_STATE, - .format = 32, - .data.l[0] = NormalState - }; + if (pCD->clientState & UNSEEN_STATE) return; - if (!pHints) pHints = &hints; + if (firstProperty == wmGD.xa__NET_WM_STATE_MAXIMIZED_VERT && + secondProperty == wmGD.xa__NET_WM_STATE_MAXIMIZED_HORZ || + firstProperty == wmGD.xa__NET_WM_STATE_MAXIMIZED_HORZ && + secondProperty == wmGD.xa__NET_WM_STATE_MAXIMIZED_VERT) + ProcessNetWmStateMaximized (pCD, action); + else if (firstProperty == wmGD.xa__NET_WM_STATE_FULLSCREEN || + secondProperty == wmGD.xa__NET_WM_STATE_FULLSCREEN) + ProcessNetWmStateFullscreen (pCD, action); - pHints->flags |= MWM_HINTS_DECORATIONS; - pHints->decorations = en ? WM_DECOR_NONE : WM_DECOR_DEFAULT; + if (!ClientInWorkspace (ACTIVE_WS, pCD)) + SetClientState (pCD, pCD->clientState | UNSEEN_STATE, GetTimestamp ()); - XChangeProperty (DISPLAY, pCD->client, wmGD.xa_MWM_HINTS, wmGD.xa_MWM_HINTS, - 32, PropModeReplace, (unsigned char *) pHints, - sizeof (PropMwmHints) / sizeof (long)); + UpdateNetWmState (pCD); +} - if (pHints != &hints) XFree (pHints); - - pCD->enterFullscreen = en; - - XSendEvent (DISPLAY, ROOT_FOR_CLIENT (pCD), False, SubstructureRedirectMask, - (XEvent *) &clientMsgEvent); -} /* END OF FUNCTION ProcessNetWmStateFullscreen */ - - - -/*************************************<->************************************* - * - * ProcessNetWmNameNetWmIconName (pCD, atom) - * - * - * Description: - * ----------- - * This function retrieves the contents of the _NET_WM_NAME or - * _NET_WM_ICON_NAME property on the cient window. - * - * - * Inputs: - * ------ - * pCD = pointer to client data structure - * atom = _NET_WM_NAME or _NET_WM_ICON_NAME - * - *************************************<->***********************************/ - -static void ProcessNetWmNameNetWmIconName (ClientData *pCD, Atom atom) +/** +* @brief Processes the _NET_WM_NAME property. +* +* @param pCD +*/ +void ProcessNetWmName (ClientData *pCD) { - Atom actualType; - int actualFormat; - unsigned long nitems; - unsigned long leftover; - unsigned char *netNameProp = NULL; - XTextProperty nameProp = {0}; + ProcessNetWmNameNetWmIconName (pCD, wmGD.xa__NET_WM_NAME); +} - if (XGetWindowProperty (DISPLAY, pCD->client, atom, 0L, 1000000L, False, - wmGD.xa_UTF8_STRING, &actualType, &actualFormat, - &nitems, &leftover, &netNameProp) != Success) - goto done; - - if (actualType != wmGD.xa_UTF8_STRING) goto done; - if (actualFormat != 8) goto done; - - if (Xutf8TextListToTextProperty (DISPLAY, (char **) &netNameProp, 1, - XUTF8StringStyle, &nameProp) != Success) goto done; - - if (atom == wmGD.xa_NET_WM_NAME) - XSetWMName (DISPLAY, pCD->client, &nameProp); - else if (atom == wmGD.xa_NET_WM_ICON_NAME) - XSetWMIconName (DISPLAY, pCD->client, &nameProp); - -done: - if (netNameProp) XFree (netNameProp); - if (nameProp.value) XFree ((char*) nameProp.value); -} /* END OF FUNCTION ProcessNetWmNameNetWmIconName */ - - - -/*************************************<->************************************* - * - * HandleClientMessageEwmh (pCD, clientEvent) - * - * - * Description: - * ----------- - * This function retrieves the contents of the EWMH message. - * - * - * Inputs: - * ------ - * pCD = pointer to client data - * clientEvent = pointer to a client message event on the root window - * - *************************************<->***********************************/ - -void HandleClientMessageEwmh (ClientData *pCD, XClientMessageEvent *clientEvent) +/** +* @brief Processes the _NET_WM_ICON_NAME property. +* +* @param pCD +*/ +void ProcessNetWmIconName (ClientData *pCD) { - int i; - - if (clientEvent->message_type == wmGD.xa_NET_WM_FULLSCREEN_MONITORS) - { - ProcessNetWmFullscreenMonitors (pCD, - clientEvent->data.l[0], clientEvent->data.l[1], - clientEvent->data.l[2], clientEvent->data.l[3]); - } - else if (clientEvent->message_type == wmGD.xa_NET_WM_STATE) - { - for (i = 1; i < 3; ++i) - { - if (clientEvent->data.l[i] == wmGD.xa_NET_WM_STATE_FULLSCREEN) - { - ProcessNetWmStateFullscreen (pCD, clientEvent->data.l[0]); - } - } - } -} /* END OF FUNCTION HandleClientMessageEwmh */ - - - -/*************************************<->************************************* - * - * HandlePropertyNotifyEwmh (pCD, clientEvent) - * - * - * Description: - * ----------- - * This function handles PropertyNotify events (indicating EWMH property - * changes) that are reported to the client window. - * - * - * Inputs: - * ------ - * pCD = pointer to client data - * clientEvent = pointer to a client message event on the root window - * - *************************************<->***********************************/ - -void HandlePropertyNotifyEwmh (ClientData *pCD, XPropertyEvent *propertyEvent) -{ - if (propertyEvent->atom == wmGD.xa_NET_WM_NAME || - propertyEvent->atom == wmGD.xa_NET_WM_ICON_NAME) - { - ProcessNetWmNameNetWmIconName (pCD, propertyEvent->atom); - } -} /* END OF FUNCTION HandlePropertyNotifyEwmh */ - - - -/*************************************<->************************************* - * - * SetupWmEwmh () - * - * - * Description: - * ----------- - * This function sets up the window manager handling of the EWMH. - * - * - * Outputs: - * ------- - * (wmGD) = Atoms id's are setup. - * - *************************************<->***********************************/ + ProcessNetWmNameNetWmIconName (pCD, wmGD.xa__NET_WM_ICON_NAME); +} +/** +* @brief Sets up the window manager handling of the EWMH. +*/ void SetupWmEwmh (void) { enum { XA_UTF8_STRING, - XA_NET_SUPPORTED, - XA_NET_SUPPORTING_WM_CHECK, - XA_NET_WM_NAME, - XA_NET_WM_ICON_NAME, - XA_NET_WM_FULLSCREEN_MONITORS, - XA_NET_WM_STATE, - XA_NET_WM_STATE_FULLSCREEN + XA__NET_SUPPORTED, + XA__NET_SUPPORTING_WM_CHECK, + XA__NET_WM_NAME, + XA__NET_WM_ICON_NAME, + XA__NET_WM_FULLSCREEN_MONITORS, + XA__NET_WM_STATE, + XA__NET_WM_STATE_FULLSCREEN, + XA__NET_WM_STATE_MAXIMIZED_VERT, + XA__NET_WM_STATE_MAXIMIZED_HORZ }; static char *atom_names[] = { "UTF8_STRING", - _XA_NET_SUPPORTED, - _XA_NET_SUPPORTING_WM_CHECK, - _XA_NET_WM_NAME, - _XA_NET_WM_ICON_NAME, - _XA_NET_WM_FULLSCREEN_MONITORS, - _XA_NET_WM_STATE, - _XA_NET_WM_STATE_FULLSCREEN + _XA__NET_SUPPORTED, + _XA__NET_SUPPORTING_WM_CHECK, + _XA__NET_WM_NAME, + _XA__NET_WM_ICON_NAME, + _XA__NET_WM_FULLSCREEN_MONITORS, + _XA__NET_WM_STATE, + _XA__NET_WM_STATE_FULLSCREEN, + _XA__NET_WM_STATE_MAXIMIZED_VERT, + _XA__NET_WM_STATE_MAXIMIZED_HORZ }; - int scr; Window childWindow; Atom atoms[XtNumber(atom_names) + 1]; XInternAtoms(DISPLAY, atom_names, XtNumber(atom_names), False, atoms); wmGD.xa_UTF8_STRING = atoms[XA_UTF8_STRING]; - wmGD.xa_NET_WM_NAME = atoms[XA_NET_WM_NAME]; - wmGD.xa_NET_WM_ICON_NAME = atoms[XA_NET_WM_ICON_NAME]; - wmGD.xa_NET_WM_FULLSCREEN_MONITORS = atoms[XA_NET_WM_FULLSCREEN_MONITORS]; - wmGD.xa_NET_WM_STATE = atoms[XA_NET_WM_STATE]; - wmGD.xa_NET_WM_STATE_FULLSCREEN = atoms[XA_NET_WM_STATE_FULLSCREEN]; + wmGD.xa__NET_WM_NAME = atoms[XA__NET_WM_NAME]; + wmGD.xa__NET_WM_ICON_NAME = atoms[XA__NET_WM_ICON_NAME]; + wmGD.xa__NET_WM_FULLSCREEN_MONITORS = atoms[XA__NET_WM_FULLSCREEN_MONITORS]; + wmGD.xa__NET_WM_STATE = atoms[XA__NET_WM_STATE]; + wmGD.xa__NET_WM_STATE_FULLSCREEN = atoms[XA__NET_WM_STATE_FULLSCREEN]; + wmGD.xa__NET_WM_STATE_MAXIMIZED_VERT = + atoms[XA__NET_WM_STATE_MAXIMIZED_VERT]; + wmGD.xa__NET_WM_STATE_MAXIMIZED_HORZ = + atoms[XA__NET_WM_STATE_MAXIMIZED_HORZ]; - for (scr = 0; scr < wmGD.numScreens; scr++) + for (int scr = 0; scr < wmGD.numScreens; ++scr) { childWindow = XCreateSimpleWindow(DISPLAY, wmGD.Screens[scr].rootWindow, -1, -1, 1, 1, 0, 0, 0); - XChangeProperty(DISPLAY, childWindow, atoms[XA_NET_WM_NAME], - atoms[XA_UTF8_STRING], 8, PropModeReplace, "DTWM", 5); + XChangeProperty(DISPLAY, childWindow, atoms[XA__NET_WM_NAME], + atoms[XA_UTF8_STRING], 8, PropModeReplace, + DT_WM_RESOURCE_NAME, 5); XChangeProperty(DISPLAY, childWindow, - atoms[XA_NET_SUPPORTING_WM_CHECK], XA_WINDOW, 32, + atoms[XA__NET_SUPPORTING_WM_CHECK], XA_WINDOW, 32, PropModeReplace, (unsigned char *)&childWindow, 1); XChangeProperty(DISPLAY, wmGD.Screens[scr].rootWindow, - atoms[XA_NET_SUPPORTING_WM_CHECK], XA_WINDOW, 32, + atoms[XA__NET_SUPPORTING_WM_CHECK], XA_WINDOW, 32, PropModeReplace, (unsigned char *)&childWindow, 1); XChangeProperty(DISPLAY, wmGD.Screens[scr].rootWindow, - atoms[XA_NET_SUPPORTED], XA_ATOM, 32, PropModeReplace, - (unsigned char *)&atoms[XA_NET_SUPPORTING_WM_CHECK], 6); + atoms[XA__NET_SUPPORTED], XA_ATOM, 32, PropModeReplace, + (unsigned char *)&atoms[XA__NET_SUPPORTING_WM_CHECK], + 8); } -} /* END OF FUNCTION SetupWmEwmh */ +} diff --git a/cde/programs/dtwm/WmEwmh.h b/cde/programs/dtwm/WmEwmh.h index b70b4baab..804b2aef2 100644 --- a/cde/programs/dtwm/WmEwmh.h +++ b/cde/programs/dtwm/WmEwmh.h @@ -26,21 +26,26 @@ #ifndef _Dt_WmEwmh_h_ #define _Dt_WmEwmh_h_ -#define _NET_WM_STATE_REMOVE 0 -#define _NET_WM_STATE_ADD 1 -#define _NET_WM_STATE_TOGGLE 2 +#define _NET_WM_STATE_REMOVE 0 +#define _NET_WM_STATE_ADD 1 +#define _NET_WM_STATE_TOGGLE 2 -#define _XA_NET_SUPPORTED "_NET_SUPPORTED" -#define _XA_NET_SUPPORTING_WM_CHECK "_NET_SUPPORTING_WM_CHECK" -#define _XA_NET_WM_NAME "_NET_WM_NAME" -#define _XA_NET_WM_ICON_NAME "_NET_WM_ICON_NAME" -#define _XA_NET_WM_FULLSCREEN_MONITORS "_NET_WM_FULLSCREEN_MONITORS" -#define _XA_NET_WM_STATE "_NET_WM_STATE" -#define _XA_NET_WM_STATE_FULLSCREEN "_NET_WM_STATE_FULLSCREEN" +#define _XA__NET_SUPPORTED "_NET_SUPPORTED" +#define _XA__NET_SUPPORTING_WM_CHECK "_NET_SUPPORTING_WM_CHECK" +#define _XA__NET_WM_NAME "_NET_WM_NAME" +#define _XA__NET_WM_ICON_NAME "_NET_WM_ICON_NAME" +#define _XA__NET_WM_FULLSCREEN_MONITORS "_NET_WM_FULLSCREEN_MONITORS" +#define _XA__NET_WM_STATE "_NET_WM_STATE" +#define _XA__NET_WM_STATE_FULLSCREEN "_NET_WM_STATE_FULLSCREEN" +#define _XA__NET_WM_STATE_MAXIMIZED_VERT "_NET_WM_STATE_MAXIMIZED_VERT" +#define _XA__NET_WM_STATE_MAXIMIZED_HORZ "_NET_WM_STATE_MAXIMIZED_HORZ" -void HandleClientMessageEwmh (ClientData *pCD, - XClientMessageEvent *clientEvent); -void HandlePropertyNotifyEwmh (ClientData *pCD, XPropertyEvent *propertyEvent); +void ProcessNetWmFullscreenMonitors (ClientData *pCD, + long top, long bottom, long left, long right); +void ProcessNetWmState (ClientData *pCD, long action, + long firstProperty, long secondProperty); +void ProcessNetWmName (ClientData *pCD); +void ProcessNetWmIconName (ClientData *pCD); void SetupWmEwmh (void); #endif /* _Dt_WmEwmh_h_ */ diff --git a/cde/programs/dtwm/WmGlobal.h b/cde/programs/dtwm/WmGlobal.h index 84a6f22de..3d06f4b3f 100644 --- a/cde/programs/dtwm/WmGlobal.h +++ b/cde/programs/dtwm/WmGlobal.h @@ -1628,8 +1628,7 @@ typedef struct _ClientData Window clientBaseWin; /* for matte & reparenting */ int xBorderWidth; /* original X border width */ FrameInfo frameInfo; /* frame geometry data */ - Boolean decorUpdated; /* True => decoration updated */ - Boolean enterFullscreen; /* True => enter fullscreen */ + Boolean isFullscreen; /* True => fullscreen */ Boolean monitorSizeIsSet; /* True => X, Y, W, H is set */ int monitorX; /* monitor X loc */ int monitorY; /* monitor Y loc */ @@ -1936,11 +1935,13 @@ typedef struct _WmGlobalData Atom xa_WMSAVE_HINT; Atom xa_UTF8_STRING; - Atom xa_NET_WM_NAME; - Atom xa_NET_WM_ICON_NAME; - Atom xa_NET_WM_FULLSCREEN_MONITORS; - Atom xa_NET_WM_STATE; - Atom xa_NET_WM_STATE_FULLSCREEN; + Atom xa__NET_WM_NAME; + Atom xa__NET_WM_ICON_NAME; + Atom xa__NET_WM_FULLSCREEN_MONITORS; + Atom xa__NET_WM_STATE; + Atom xa__NET_WM_STATE_FULLSCREEN; + Atom xa__NET_WM_STATE_MAXIMIZED_VERT; + Atom xa__NET_WM_STATE_MAXIMIZED_HORZ; /* atoms used for workspace management: */ diff --git a/cde/programs/dtwm/WmManage.c b/cde/programs/dtwm/WmManage.c index 0f23e002d..60aab5657 100644 --- a/cde/programs/dtwm/WmManage.c +++ b/cde/programs/dtwm/WmManage.c @@ -1008,7 +1008,7 @@ void WithdrawWindow (ClientData *pCD) } } - XDeleteProperty (DISPLAY, pCD->client, wmGD.xa_NET_WM_STATE); + XDeleteProperty (DISPLAY, pCD->client, wmGD.xa__NET_WM_STATE); XUnmapWindow (DISPLAY, pCD->client); XReparentWindow (DISPLAY, pCD->client, ROOT_FOR_CLIENT(pCD), x, y); diff --git a/cde/programs/dtwm/WmWinConf.c b/cde/programs/dtwm/WmWinConf.c index 397a7c785..c3dd6aa81 100644 --- a/cde/programs/dtwm/WmWinConf.c +++ b/cde/programs/dtwm/WmWinConf.c @@ -1934,12 +1934,6 @@ void ProcessNewConfiguration (ClientData *pCD, int x, int y, unsigned int width, newMax = True; } - if (pCD->decorUpdated) - { - changedValues = CWWidth | CWHeight; - pCD->decorUpdated = False; - } - /* * If the configuration has changed, update client data * diff --git a/cde/programs/dtwm/WmWinInfo.c b/cde/programs/dtwm/WmWinInfo.c index 5aaa07b19..cfde984bd 100644 --- a/cde/programs/dtwm/WmWinInfo.c +++ b/cde/programs/dtwm/WmWinInfo.c @@ -56,6 +56,7 @@ #include "WmCDecor.h" #include "WmCPlace.h" #include "WmError.h" +#include "WmEwmh.h" #include "WmIDecor.h" #include "WmIPlace.h" #include "WmIconBox.h" @@ -218,8 +219,7 @@ InitClientData (Window clientWindow) pCD->smClientID = (String)NULL; - pCD->decorUpdated = False; - pCD->enterFullscreen = False; + pCD->isFullscreen = False; pCD->monitorSizeIsSet = False; for (i = 0; i < STRETCH_COUNT; ++i) pCD->clientStretchWin[i] = (Window)0L; @@ -261,7 +261,6 @@ GetClientInfo (WmScreenData *pSD, Window clientWindow, long manageFlags) { ClientData *pCD; XSetWindowAttributes sAttributes; - XPropertyEvent propertyEvent; if (!(pCD = InitClientData (clientWindow))) { @@ -421,8 +420,7 @@ GetClientInfo (WmScreenData *pSD, Window clientWindow, long manageFlags) */ ProcessWmWindowTitle (pCD, TRUE); - propertyEvent.atom = wmGD.xa_NET_WM_NAME; - HandlePropertyNotifyEwmh (pCD, &propertyEvent); + ProcessNetWmName (pCD); /* @@ -430,8 +428,7 @@ GetClientInfo (WmScreenData *pSD, Window clientWindow, long manageFlags) */ ProcessWmIconTitle (pCD, TRUE); - propertyEvent.atom = wmGD.xa_NET_WM_ICON_NAME; - HandlePropertyNotifyEwmh (pCD, &propertyEvent); + ProcessNetWmIconName (pCD); /* @@ -3861,7 +3858,11 @@ ProcessMwmHints (ClientData *pCD) { if (pHints->flags & MWM_HINTS_FUNCTIONS) { - if (pHints->functions == WM_FUNC_DEFAULT) + if (pHints->functions == WM_FUNC_NONE) + { + pCD->clientFunctions = WM_FUNC_NONE; + } + else if (pHints->functions == WM_FUNC_DEFAULT) { pCD->clientFunctions = WM_FUNC_ALL; } @@ -3873,7 +3874,7 @@ ProcessMwmHints (ClientData *pCD) else { /* client indicating applicable functions */ - pCD->clientFunctions &= pHints->functions; + pCD->clientFunctions |= pHints->functions; } #if 0 if (!(pCD->clientFlags & GOT_DT_WM_HINTS) && @@ -3894,7 +3895,11 @@ ProcessMwmHints (ClientData *pCD) if (pHints->flags & MWM_HINTS_DECORATIONS) { - if (pHints->decorations == WM_DECOR_DEFAULT) + if (pHints->decorations == WM_DECOR_NONE) + { + pCD->clientDecoration = WM_DECOR_NONE; + } + else if (pHints->decorations == WM_DECOR_DEFAULT) { pCD->clientDecoration = WM_DECOR_ALL; } @@ -3906,7 +3911,7 @@ ProcessMwmHints (ClientData *pCD) else { /* client indicating decorations to be added */ - pCD->clientDecoration &= pHints->decorations; + pCD->clientDecoration |= pHints->decorations; } /* @@ -4007,6 +4012,5 @@ ProcessMwmHints (ClientData *pCD) pCD->decor = pCD->clientDecoration; /* !!! combine decor ... !!! */ - pCD->decorUpdated = True; } /* END OF ProcessMwmHints */ diff --git a/cde/programs/dtwm/WmWinState.c b/cde/programs/dtwm/WmWinState.c index 8ea2fab84..b70ca7ff9 100644 --- a/cde/programs/dtwm/WmWinState.c +++ b/cde/programs/dtwm/WmWinState.c @@ -604,21 +604,27 @@ static void SetupWindowStateWithEventMask (ClientData *pCD, int newState, void ConfigureNewState (ClientData *pcd) { - WmHeadInfo_t *WmHI = NULL; - - if (pcd->maxConfig) + if (pcd->maxConfig && !pcd->isFullscreen) { pcd->maxConfig = FALSE; RegenerateClientFrame(pcd); XResizeWindow (DISPLAY, pcd->client, (unsigned int) pcd->clientWidth, (unsigned int) pcd->clientHeight); - - XDeleteProperty (DISPLAY, pcd->client, wmGD.xa_NET_WM_STATE); } else { - if (pcd->enterFullscreen && pcd->monitorSizeIsSet) + long decor; + WmHeadInfo_t *WmHI; + + if (pcd->isFullscreen) + { + decor = pcd->decor; + pcd->decor = WM_DECOR_NONE; + SetClientOffset (pcd); + } + + if (pcd->isFullscreen && pcd->monitorSizeIsSet) { pcd->maxX = pcd->monitorX; pcd->maxY = pcd->monitorY; @@ -648,15 +654,13 @@ void ConfigureNewState (ClientData *pcd) pcd->maxConfig = TRUE; RegenerateClientFrame(pcd); - if (pcd->enterFullscreen) - XChangeProperty (DISPLAY, pcd->client, wmGD.xa_NET_WM_STATE, - XA_ATOM, 32, PropModeReplace, - (unsigned char *) &wmGD.xa_NET_WM_STATE_FULLSCREEN, - 1); + if (pcd->isFullscreen) + { + pcd->decor = decor; + SetClientOffset (pcd); + } } - pcd->enterFullscreen = False; - SendConfigureNotify (pcd); /*