1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
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
|