[PATCH xf86-video-nested] xlibclient: Add support for WM_DELETE_WINDOW

Daniel Martin consume.noise at gmail.com
Sun Jul 15 13:47:22 PDT 2012


If we allow the window manager to kill the client on its own, the server
wouldn't do a clean shutdown, resulting in an io error.

For a clean shutdown we've to list WM_DELETE_WINDOW in our WM_PROTOCOLS
property, wait for a ClientMessage event with WM_DELETE_WINDOW in its
payload and call GiveUp(). (Assuming that the window manager supports
WM_PROTOCOLS.)
---
 src/xlibclient.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/src/xlibclient.c b/src/xlibclient.c
index 398a9ad..a4b32fb 100644
--- a/src/xlibclient.c
+++ b/src/xlibclient.c
@@ -49,6 +49,8 @@
 
 #include "nested_input.h"
 
+static Atom WM_DELETE_WINDOW = 0;
+
 struct NestedClientPrivate {
     Display *display;
     int screenNumber;
@@ -96,6 +98,12 @@ NestedClientValidDepth(int depth) {
 }
 
 static void
+NestedClientSetWMProtocols(NestedClientPrivatePtr pPriv) {
+    WM_DELETE_WINDOW = XInternAtom(pPriv->display, "WM_DELETE_WINDOW", False);
+    XSetWMProtocols(pPriv->display, pPriv->window, &WM_DELETE_WINDOW, 1);
+}
+
+static void
 NestedClientSetXSizeHints(NestedClientPrivatePtr pPriv, int width, int height) {
     XSizeHints sizeHints;
     sizeHints.flags = PPosition | PSize | PMinSize | PMaxSize;
@@ -206,6 +214,7 @@ NestedClientCreateScreen(int scrnIndex,
     pPriv->window = XCreateSimpleWindow(pPriv->display, pPriv->rootWindow,
     originX, originY, width, height, 0, 0, 0);
 
+    NestedClientSetWMProtocols(pPriv);
     NestedClientSetXSizeHints(pPriv, width, height);
 
     sprintf(windowTitle, "Screen %d", scrnIndex);
@@ -324,7 +333,9 @@ void
 NestedClientCheckEvents(NestedClientPrivatePtr pPriv) {
     XEvent ev;
 
-    while(XCheckMaskEvent(pPriv->display, ~0, &ev)) {
+    /* XCheckMaskEvent() can't catch ClientMessage events. */
+    while(XPending(pPriv->display)) {
+        XNextEvent(pPriv->display, &ev);
         switch (ev.type) {
         case Expose:
             NestedClientUpdateScreen(pPriv,
@@ -366,6 +377,13 @@ NestedClientCheckEvents(NestedClientPrivatePtr pPriv) {
 
             NestedInputPostKeyboardEvent(pPriv->dev, ev.xkey.keycode, ev.type == KeyPress);
             break;
+
+        case ClientMessage:
+            if (ev.xclient.data.l[0] == WM_DELETE_WINDOW) {
+                xf86DrvMsg(pPriv->scrnIndex, X_INFO, "Shutdown requested.\n");
+                GiveUp(0);
+            }
+            break;
         }
     }
 }
-- 
1.7.11.1



More information about the xorg-devel mailing list