From 36f804e549121fb56aa71979b7da5d75f2cc7cbe Mon Sep 17 00:00:00 2001 From: Ulrich Sibiller Date: Sun, 2 May 2021 18:42:44 +0200 Subject: 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 --- 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) -- cgit v1.2.3