From: Matthew R. Trower Date: Thu, 23 Jun 2016 07:25:00 +0000 (-0500) Subject: dtwm: basic multihead(xinerama only) support X-Git-Tag: 2.2.4a~206 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=341494d91c661a635ff01f4ca553f6a8eddeee7e;p=oweals%2Fcde.git dtwm: basic multihead(xinerama only) support * maximization (also partially fixes strange Firefox behaviour) * sane initial window placement Firefox is stranger than most; it appears to maximize to double X Screen width even on single head displays. Fixed (on multihead). --- diff --git a/cde/programs/dtwm/Imakefile b/cde/programs/dtwm/Imakefile index fa10741f..258127a4 100644 --- a/cde/programs/dtwm/Imakefile +++ b/cde/programs/dtwm/Imakefile @@ -15,8 +15,8 @@ DEPEND_DEFINES = $(DEPENDDEFINES) DEFINES = $(MWMDEFINES) $(DTWMDEFINES) -DMULTIBYTE -DMINIMAL_DT DEPLIBS = DepDtClientLibs -LOCAL_LIBRARIES = DtClientLibs -SYS_LIBRARIES = DtClientSysLibs DtClientExtraLibs +LOCAL_LIBRARIES = DtClientLibs -lDtXinerama +SYS_LIBRARIES = DtClientSysLibs DtClientExtraLibs -lXinerama #if defined(HPArchitecture) EXTRA_DEFINES = -D_HPUX_SOURCE @@ -32,7 +32,8 @@ SRCSXM = \ WmMenu.c WmProperty.c WmProtocol.c \ WmResCvt.c WmResParse.c WmResource.c \ WmSignal.c WmWinConf.c WmWinInfo.c \ - WmWinList.c WmWinState.c version.c + WmWinList.c WmWinState.c version.c \ + WmMultihead.c SRCSDT = \ Button.c Callback.c Clock.c \ @@ -53,7 +54,8 @@ OBJSXM = \ WmMenu.o WmProperty.o WmProtocol.o \ WmResCvt.o WmResParse.o WmResource.o \ WmSignal.o WmWinConf.o WmWinInfo.o \ - WmWinList.o WmWinState.o version.o + WmWinList.o WmWinState.o version.o \ + WmMultiHead.o OBJSDT = \ Button.o Callback.o Clock.o \ diff --git a/cde/programs/dtwm/WmMultiHead.c b/cde/programs/dtwm/WmMultiHead.c new file mode 100644 index 00000000..4de6c6b9 --- /dev/null +++ b/cde/programs/dtwm/WmMultiHead.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2016 Matthew R. Trower + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include + +/* + * Included Files: + */ +#include + +#include "WmMultiHead.h" + +/* + * Global Variables + */ +DtXineramaInfo_t *DtXI = NULL;/* Xinerama data is static for life of X server */ + + +/*************************************<->************************************* + * + * GetHeadInfo (pcd) + * + * + * Description: + * ----------- + * Search for the head containing target client. + * + * + * Inputs: + * ------ + * + * + * Outputs: + * ------- + * Return = head metrics on success, NULL on failure. + * menuWidget, and menuButtons members. + * + * + * Comments: + * -------- + * + * Can fail if: + * + * - MultiHead(eg. Xinerama) is not active + * - Client does not fall within any existing head + * - malloc error + * - pcd is NULL + * + *************************************<->***********************************/ +WmHeadInfo_t *GetHeadInfo(const ClientData *pcd) { + WmHeadInfo_t *WmHI = NULL; + + if (!DtXI) + DtXI = _DtXineramaInit(DISPLAY); + + if (!pcd || !DtXI) + return NULL; + + if (!(WmHI = (WmHeadInfo_t *)malloc(sizeof(WmHeadInfo_t)))) { +#ifdef DEBUG + fprintf(stderr, "(dtwm) _GetScreenInfo: malloc failed\n"); +#endif + + free(DtXI); + return NULL; + } + + /* + * TODO + * + * DtXineramaInfo_t uses unsigned ints + * XineramaScreenInfo uses shorts(?) + * ClientData uses ints + * FrameToClient and friends use a mixture (!) + * + * Explicit casting would shut the compiler up, but wouldn't change the + * fundamental fact that we can't agree on coordinate types. + */ + int idx = 0; + while (_DtXineramaGetScreen(DtXI, idx++, + &WmHI->width, &WmHI->height, &WmHI->x_org, &WmHI->y_org)) { + + if (pcd->clientX >= WmHI->x_org && + pcd->clientY >= WmHI->y_org && + pcd->clientX <= WmHI->x_org + WmHI->width && + pcd->clientY <= WmHI->y_org + WmHI->height) + + return WmHI; + } + + /* No valid screen */ + return NULL; +} diff --git a/cde/programs/dtwm/WmMultiHead.h b/cde/programs/dtwm/WmMultiHead.h new file mode 100644 index 00000000..112b03f4 --- /dev/null +++ b/cde/programs/dtwm/WmMultiHead.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016 Matthew R. Trower + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef _WmMultiHead_h +#define _WmMultiHead_h + +#include "WmGlobal.h" + +typedef struct _WmHeadInfo { + int x_org; + int y_org; + unsigned int width; + unsigned int height; +} WmHeadInfo_t, *WmHeadInfoPtr_t; + +WmHeadInfo_t *GetHeadInfo(const ClientData *pcd); + +#endif _WmMultiHead_h diff --git a/cde/programs/dtwm/WmWinInfo.c b/cde/programs/dtwm/WmWinInfo.c index 74cd77d3..8f0d9729 100644 --- a/cde/programs/dtwm/WmWinInfo.c +++ b/cde/programs/dtwm/WmWinInfo.c @@ -80,6 +80,7 @@ static char rcsid[] = "$TOG: WmWinInfo.c /main/18 1999/02/04 15:17:25 mgreess $" #include "WmPresence.h" #endif /* WSM */ #include "WmXSMP.h" +#include "WmMultiHead.h" #ifdef PANELIST static void AdjustSlideOutGeometry (ClientData *pCD); @@ -3676,11 +3677,14 @@ FindClientPlacement (ClientData *pCD) Boolean placed = False; int frameWidth; int frameHeight; + int screenX; + int screenY; int screenWidth; int screenHeight; int borderWidth = 0; Boolean offScreenX; Boolean offScreenY; + WmHeadInfo_t *WmHI = NULL; if (!clientPlacementInitialized) @@ -3704,8 +3708,22 @@ FindClientPlacement (ClientData *pCD) frameWidth = pCD->clientWidth + (2 * pCD->clientOffset.x); frameHeight = pCD->clientHeight + pCD->clientOffset.y + pCD->clientOffset.x; - screenWidth = DisplayWidth (DISPLAY, SCREEN_FOR_CLIENT(pCD)); - screenHeight = DisplayHeight (DISPLAY, SCREEN_FOR_CLIENT(pCD)); + + if (WmHI = GetHeadInfo(wmGD.keyboardFocus)) { + /* Use Head metrics for placeable area */ + screenX = WmHI->x_org; + screenY = WmHI->y_org; + screenWidth = WmHI->width; + screenHeight = WmHI->height; + + free(WmHI); + } else { + /* Use X Screen metrics for placeable area */ + screenX = 0; + screenY = 0; + screenWidth = DisplayWidth (DISPLAY, SCREEN_FOR_CLIENT(pCD)); + screenHeight = DisplayHeight (DISPLAY, SCREEN_FOR_CLIENT(pCD)); + } while (!placed) { @@ -3796,8 +3814,8 @@ FindClientPlacement (ClientData *pCD) * The window has been placed, now update the placement information. */ - pCD->clientX = clientPlacementX; - pCD->clientY = clientPlacementY; + pCD->clientX = clientPlacementX + screenX; + pCD->clientY = clientPlacementY + screenY; clientPlacementX += clientPlacementOffset; if (clientPlacementX >= screenWidth) diff --git a/cde/programs/dtwm/WmWinState.c b/cde/programs/dtwm/WmWinState.c index 9e63a4b2..c1e289cf 100644 --- a/cde/programs/dtwm/WmWinState.c +++ b/cde/programs/dtwm/WmWinState.c @@ -50,6 +50,7 @@ static char rcsid[] = "$XConsortium: WmWinState.c /main/6 1996/06/20 09:39:39 rs */ #include "WmCDecor.h" +#include "WmCDInfo.h" #include "WmFunction.h" #include "WmIDecor.h" #include "WmIPlace.h" @@ -71,6 +72,7 @@ static char rcsid[] = "$XConsortium: WmWinState.c /main/6 1996/06/20 09:39:39 rs * Function Declarations: */ +#include "WmMultiHead.h" #include "WmWinState.h" #ifdef PANELIST static void SlideWindowOut (ClientData *pCD); @@ -655,6 +657,8 @@ static void SetupWindowStateWithEventMask (ClientData *pCD, int newState, void ConfigureNewState (ClientData *pcd) { + WmHeadInfo_t *WmHI = NULL; + if (pcd->maxConfig) { pcd->maxConfig = FALSE; @@ -665,6 +669,18 @@ void ConfigureNewState (ClientData *pcd) } else { + /* + * Update client config to reflect underlying head, if MultiHead is active + */ + if (WmHI = GetHeadInfo(pcd)) { + FrameToClient(pcd, &WmHI->x_org, &WmHI->y_org, + &WmHI->width, &WmHI->height); + pcd->maxX = WmHI->x_org; + pcd->maxY = WmHI->y_org; + pcd->maxWidth = WmHI->width; + pcd->maxHeight = WmHI->height; + } + XResizeWindow (DISPLAY, pcd->client, (unsigned int) pcd->maxWidth, (unsigned int) pcd->maxHeight);