[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#990649: nxagent: Tricky minimize/maximize/restore issue in rootless mode



Package: nxagent
Version: 3.5.99.26-1
Serverity: important
Tags: patch

When running nxagent in rootless mode (e.g. for published server-side applications), X clients that don't use a window manager but prefer client side rendered window management controls in some case can't be closed, maximized, restored, etc.

The reason for this is a wrong translation of XIDs in nxagent for rootless session windows.

The full story is here:
https://github.com/ArcticaProject/nx-libs/issues/1015

Patch to fix this is attached.

Mike
--

DAS-NETZWERKTEAM
c\o Technik- und Ökologiezentrum Eckernförde
Mike Gabriel, Marienthaler Str. 17, 24340 Eckernförde
mobile: +49 (1520) 1976 148
landline: +49 (4351) 850 8940

GnuPG Fingerprint: 9BFB AEE8 6C0A A5FF BF22  0782 9AF4 6B30 2577 1B31
mail: mike.gabriel@das-netzwerkteam.de, http://das-netzwerkteam.de

>From 36f804e549121fb56aa71979b7da5d75f2cc7cbe Mon Sep 17 00:00:00 2001
From: Ulrich Sibiller <uli42@gmx.de>
Date: Sun, 2 May 2021 18:42:44 +0200
Subject: [PATCH] Forward ClientMessages to nxproxy side

This should help with clients requesting window manager actions like
maximizing or minimizing. This is a first version as it only handles
messages of type WM_STATE_CHANGE and _NET_WM_STATE. But ICCCM and EWMH
know some more.

The other direction, setting of properties by the WM, is already
implemented in Rootless.c.

Fixes ArcticaProject/nx-libs#1015

Signed-off-by: Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
---
 nx-X11/programs/Xserver/hw/nxagent/Events.c   | 64 +++++++++++++++++++
 nx-X11/programs/Xserver/hw/nxagent/Events.h   |  2 +
 nx-X11/programs/Xserver/hw/nxagent/NXevents.c |  6 ++
 3 files changed, 72 insertions(+)

diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.c b/nx-X11/programs/Xserver/hw/nxagent/Events.c
index a342cdee1..2a3654731 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.c
@@ -4505,6 +4505,70 @@ int nxagentWaitEvents(Display *dpy, useconds_t msec)
   return 1;
 }
 
+void ForwardClientMessage(ClientPtr client, xSendEventReq *stuff)
+{
+    Atom netwmstate = MakeAtom("_NET_WM_STATE", strlen("_NET_WM_STATE"), False);
+    Atom wmchangestate = MakeAtom("WM_CHANGE_STATE", strlen("WM_CHANGE_STATE"), False);
+    WindowPtr pWin = (WindowPtr)SecurityLookupWindow(stuff->destination, client,
+                                                     DixReadAccess);
+
+    if (stuff->event.u.clientMessage.u.l.type == netwmstate || stuff->event.u.clientMessage.u.l.type == wmchangestate)
+    {
+        if (pWin->drawable.id == pWin->drawable.pScreen->root->drawable.id)
+        {
+            #ifdef DEBUG
+            fprintf(stderr, "%s: dest [0x%x] window [0x%x] clmsg.type [%d]->[%d]\n", __func__, stuff->destination, stuff->event.u.clientMessage.window, stuff->event.u.clientMessage.u.l.type, nxagentLocalToRemoteAtom(stuff->event.u.clientMessage.u.l.type));
+            #endif
+
+            XEvent X = {0};
+            X.xany.type = ClientMessage;
+
+            WindowPtr pWin2 = (WindowPtr)SecurityLookupWindow(stuff->event.u.clientMessage.window, client,
+                                                              DixReadAccess);
+            X.xclient.window = nxagentWindowPriv(pWin2)->window;
+            X.xclient.format = stuff->event.u.u.detail;
+            X.xclient.send_event = True;
+            X.xclient.serial = 0;
+
+            if (X.xclient.format == 32)
+            {
+                X.xclient.message_type = nxagentLocalToRemoteAtom(stuff->event.u.clientMessage.u.l.type);
+                X.xclient.data.l[0] = stuff->event.u.clientMessage.u.l.longs0;
+                X.xclient.data.l[1] = nxagentLocalToRemoteAtom(stuff->event.u.clientMessage.u.l.longs1);
+                X.xclient.data.l[2] = nxagentLocalToRemoteAtom(stuff->event.u.clientMessage.u.l.longs2);
+                X.xclient.data.l[3] = nxagentLocalToRemoteAtom(stuff->event.u.clientMessage.u.l.longs3);
+                X.xclient.data.l[4] = nxagentLocalToRemoteAtom(stuff->event.u.clientMessage.u.l.longs4);
+                //X.xclient.data.l[3] = stuff->event.u.clientMessage.u.l.longs3;
+                //X.xclient.data.l[4] = stuff->event.u.clientMessage.u.l.longs4;
+                #ifdef DEBUG
+                for (int i = 0; i < 5; i++)
+                {
+                    fprintf(stderr, "%s: data[%d] [%ld]\n", __func__, i, X.xclient.data.l[i]);
+                }
+                #endif
+            }
+            else
+                return; // ERROR!
+
+            #ifdef DEBUG
+            fprintf(stderr, "%s: window [0x%lx]\n", __func__, X.xclient.window);
+            fprintf(stderr, "%s: message_type [%ld]\n", __func__, X.xclient.message_type);
+            fprintf(stderr, "%s: format [%d]\n", __func__, X.xclient.format);
+            #endif
+
+            XlibWindow dest;
+            dest = DefaultRootWindow(nxagentDisplay);
+
+            Status stat = XSendEvent(nxagentDisplay, dest, stuff->propagate, stuff->eventMask, &X);
+            XFlush(nxagentDisplay);
+            #ifdef DEBUG
+            fprintf(stderr, "%s: send to window [0x%lx]\n", __func__, dest);
+            fprintf(stderr, "%s: return Status [%d]\n", __func__, stat);
+            #endif
+        }
+    }
+}
+
 #ifdef NX_DEBUG_INPUT
 
 void nxagentGuessDumpInputInfo(ClientPtr client, Atom property, char *data)
diff --git a/nx-X11/programs/Xserver/hw/nxagent/Events.h b/nx-X11/programs/Xserver/hw/nxagent/Events.h
index 42784a8f3..a334897ec 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/Events.h
+++ b/nx-X11/programs/Xserver/hw/nxagent/Events.h
@@ -222,4 +222,6 @@ int nxagentPendingEvents(Display *dpy);
 
 int nxagentWaitEvents(Display *, useconds_t msec);
 
+void ForwardClientMessage(ClientPtr client, xSendEventReq *stuff);
+
 #endif /* __Events_H__ */
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
index 84414c11f..fccc718b0 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXevents.c
@@ -425,6 +425,12 @@ ProcSendEvent(ClientPtr client)
 
     REQUEST_SIZE_MATCH(xSendEventReq);
 
+    if (nxagentOption(Rootless) && stuff->event.u.u.type == ClientMessage)
+    {
+        ForwardClientMessage(client, stuff);
+        return Success;
+    }
+
     if (stuff -> event.u.u.type == SelectionNotify)
     {
 	if (nxagentSendNotify(&stuff->event) == 1)
-- 
2.30.2

Attachment: pgp0hfldyxBei.pgp
Description: Digitale PGP-Signatur


Reply to: