This code wraps DtXinerama for now; I have some plans to additionally
support RandR through the same interface in the future.
=Addresses=
* maximization
* sane initial window placement (for most windows)
Firefox is strange situation. When maximized, it expands to double the
X Screen width even on single head displays. This patch fixes this
behavior on multihead, so I'd guess maxWidth gets set wrong on creation.
Will require more investigation.
=Improvements to be made=
Apparently some windows, such as the dtmail preferences dialog, are
spawned using different placement code. That one just appears at
origin. I'd welcome information regarding other anomalies, or places
where CDE breaks with multihead.
There's some disagreement regarding integer coordinate types
(see code comment WmMultiHead.c:91) which causes compiler warnings.
Please advise on a proper resolution as time allows.
My Imakefile additions get the job done, but may not match convention.
-- Matthew R. Trower
>From 7eece4588c25105630acad7da926f88b13a9433f Mon Sep 17 00:00:00 2001
From: "Matthew R. Trower" <d...@blackshard.net>
Date: Thu, 23 Jun 2016 02:25:00 -0500
Subject: [PATCH] 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).
---
cde/programs/dtwm/Imakefile | 10 ++--
cde/programs/dtwm/WmMultiHead.c | 113 ++++++++++++++++++++++++++++++++++++++++
cde/programs/dtwm/WmMultiHead.h | 37 +++++++++++++
cde/programs/dtwm/WmWinInfo.c | 26 +++++++--
cde/programs/dtwm/WmWinState.c | 16 ++++++
5 files changed, 194 insertions(+), 8 deletions(-)
create mode 100644 cde/programs/dtwm/WmMultiHead.c
create mode 100644 cde/programs/dtwm/WmMultiHead.h
diff --git a/cde/programs/dtwm/Imakefile b/cde/programs/dtwm/Imakefile
index fa10741..258127a 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 0000000..4de6c6b
--- /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 <stdio.h>
+#include <stdlib.h>
+
+/*
+ * Included Files:
+ */
+#include <DtXinerama.h>
+
+#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 0000000..112b03f
--- /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 74cd77d..8f0d972 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 9e63a4b..c1e289c 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);
--
1.9.4
------------------------------------------------------------------------------
Attend Shape: An AT&T Tech Expo July 15-16. Meet us at AT&T Park in San
Francisco, CA to explore cutting-edge tech and listen to tech luminaries
present their vision of the future. This family event has something for
everyone, including kids. Get more information and register today.
http://sdm.link/attshape
_______________________________________________
cdesktopenv-devel mailing list
cdesktopenv-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/cdesktopenv-devel