[PATCH xf86-video-nested 3/3] Resize client (XSetWMNormalHints()) on mode switch

Daniel Martin consume.noise at gmail.com
Wed Jul 11 15:30:26 PDT 2012


If the user switched the mode, call XSetWMNormalHints() accordingly.
---
 src/client.h     |  4 ++++
 src/driver.c     |  4 ++++
 src/xlibclient.c | 33 ++++++++++++++++++++++++++-------
 3 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/src/client.h b/src/client.h
index 4c73b3c..dd811ec 100644
--- a/src/client.h
+++ b/src/client.h
@@ -62,6 +62,10 @@ void NestedClientUpdateScreen(NestedClientPrivatePtr pPriv,
                               int16_t x2,
                               int16_t y2);
 
+void NestedClientResizeScreen(NestedClientPrivatePtr pPriv,
+                              int16_t width,
+                              int16_t height);
+
 void NestedClientHideCursor(NestedClientPrivatePtr pPriv);
 
 void NestedClientCheckEvents(NestedClientPrivatePtr pPriv);
diff --git a/src/driver.c b/src/driver.c
index 2cae14e..0f9e675 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -678,6 +678,10 @@ static Bool NestedSwitchMode(SWITCH_MODE_ARGS_DECL) {
 static void NestedAdjustFrame(ADJUST_FRAME_ARGS_DECL) {
     SCRN_INFO_PTR(arg);
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NestedAdjustFrame\n");
+    if (pScrn->currentMode->HDisplay == pScrn->virtualX &&
+        pScrn->currentMode->VDisplay == pScrn->virtualY) {
+        NestedClientResizeScreen(PCLIENTDATA(pScrn), pScrn->virtualX, pScrn->virtualY);
+    }
 }
 
 static Bool NestedEnterVT(VT_FUNC_ARGS_DECL) {
diff --git a/src/xlibclient.c b/src/xlibclient.c
index 1f0d3b7..398a9ad 100644
--- a/src/xlibclient.c
+++ b/src/xlibclient.c
@@ -95,6 +95,17 @@ NestedClientValidDepth(int depth) {
     return TRUE;
 }
 
+static void
+NestedClientSetXSizeHints(NestedClientPrivatePtr pPriv, int width, int height) {
+    XSizeHints sizeHints;
+    sizeHints.flags = PPosition | PSize | PMinSize | PMaxSize;
+    sizeHints.min_width = width;
+    sizeHints.max_width = width;
+    sizeHints.min_height = height;
+    sizeHints.max_height = height;
+    XSetWMNormalHints(pPriv->display, pPriv->window, &sizeHints);
+}
+
 static Bool
 NestedClientTryXShm(NestedClientPrivatePtr pPriv, int scrnIndex, int width, int height, int depth) {
     int shmMajor, shmMinor;
@@ -169,7 +180,6 @@ NestedClientCreateScreen(int scrnIndex,
                          Pixel *retGreenMask,
                          Pixel *retBlueMask) {
     NestedClientPrivatePtr pPriv;
-    XSizeHints sizeHints;
     Bool supported;
     char windowTitle[32];
 
@@ -196,12 +206,7 @@ NestedClientCreateScreen(int scrnIndex,
     pPriv->window = XCreateSimpleWindow(pPriv->display, pPriv->rootWindow,
     originX, originY, width, height, 0, 0, 0);
 
-    sizeHints.flags = PPosition | PSize | PMinSize | PMaxSize;
-    sizeHints.min_width = width;
-    sizeHints.max_width = width;
-    sizeHints.min_height = height;
-    sizeHints.max_height = height;
-    XSetWMNormalHints(pPriv->display, pPriv->window, &sizeHints);
+    NestedClientSetXSizeHints(pPriv, width, height);
 
     sprintf(windowTitle, "Screen %d", scrnIndex);
 
@@ -302,6 +307,20 @@ NestedClientUpdateScreen(NestedClientPrivatePtr pPriv, int16_t x1,
 }
 
 void
+NestedClientResizeScreen(NestedClientPrivatePtr pPriv, int16_t width, int16_t height) {
+    /* In case you're switching to a smaller mode and your window manager
+     * doesn't resize the client window correctly, you would see artefacts
+     * from the previous mode at the borders. To prevent this, we blank the
+     * image. */
+    if (width < pPriv->img->width || height < pPriv->img->height) {
+       memset(pPriv->img->data, 0, pPriv->img->bytes_per_line * pPriv->img->height);
+       NestedClientUpdateScreen(pPriv, 0, 0, pPriv->img->width, pPriv->img->height);
+    }
+
+    NestedClientSetXSizeHints(pPriv, width, height);
+}
+
+void
 NestedClientCheckEvents(NestedClientPrivatePtr pPriv) {
     XEvent ev;
 
-- 
1.7.11.1



More information about the xorg-devel mailing list