From 58a954db7f06a1d29dfd7843af105f0840e859a4 Mon Sep 17 00:00:00 2001 From: hujianwei Date: Thu, 20 Oct 2022 11:07:46 +0000 Subject: [PATCH] Allow disabling _NET_WM_PING Some window managers look up client PIDs via the resource extension, which means killing stuck clients will actually kill the protocol translator. Provide a mechanism to turn _NET_WM_PING off. * 12to11.man: Document new resource WmProtocols.wmProtocols. * xdg_toplevel.c (Attach): Don't enable _NET_WM_PING if it is turned off. (ReadWmProtocolsString, ParseWmProtocols): New functions. (XLInitXdgToplevels): Call them. --- 12to11.man | 6 ++++ xdg_toplevel.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 86 insertions(+), 1 deletion(-) diff --git a/12to11.man b/12to11.man index 7f7acdc..37974cd 100644 --- a/12to11.man +++ b/12to11.man @@ -115,6 +115,12 @@ either be \fBpicture\fP (the XRender based compositor) or \fBegl\fP If ``True'' or ``true'', this resource enables the use of direct presentation on unredirected windows. This is not yet complete pending the installation of required functionality in the X server. +.TP +.B wmProtocols \fP (class \fBWmProtocols\fP) +Comma-separated list of window manager protocols, similar to +\fBinputStyles\fP, that the protocol translator should enable or +disable. The current (and default) list of supported protocols are: +\fBnetWmPing\fB. .IP .SH ENVIRONMENT Several environment variables exist that modify the behavior of the diff --git a/xdg_toplevel.c b/xdg_toplevel.c index 9edafd8..bcd2227 100644 --- a/xdg_toplevel.c +++ b/xdg_toplevel.c @@ -253,6 +253,11 @@ struct _XdgDecoration XdgToplevel *toplevel; }; +enum + { + NetWmPingMask = 1, + }; + /* iconv context used to convert between UTF-8 and Latin-1. */ static iconv_t latin_1_cd; @@ -264,6 +269,9 @@ static Bool apply_state_workaround; at almost the same time. */ static Bool batch_state_changes; +/* Mask consisting of currently enabled window manager protocols. */ +static int window_manager_protocols; + static XdgUnmapCallback * RunOnUnmap (XdgToplevel *toplevel, void (*unmap) (void *), void *data) @@ -1035,7 +1043,8 @@ Attach (Role *role, XdgRoleImplementation *impl) /* _NET_WM_PING should be disabled when the window manager kills clients using XKillClient. */ - protocols[nproto++] = _NET_WM_PING; + if (window_manager_protocols & NetWmPingMask) + protocols[nproto++] = _NET_WM_PING; if (XLFrameClockSyncSupported ()) protocols[nproto++] = _NET_WM_SYNC_REQUEST; @@ -2378,12 +2387,82 @@ XLHandleXEventForXdgToplevels (XEvent *event) return False; } +static void +ReadWmProtocolsString (const char **string_return) +{ + XrmDatabase rdb; + XrmName namelist[3]; + XrmClass classlist[3]; + XrmValue value; + XrmRepresentation type; + + rdb = XrmGetDatabase (compositor.display); + + if (!rdb) + return; + + namelist[1] = XrmStringToQuark ("wmProtocols"); + namelist[0] = app_quark; + namelist[2] = NULLQUARK; + + classlist[1] = XrmStringToQuark ("WmProtocols"); + classlist[0] = resource_quark; + classlist[2] = NULLQUARK; + + if (XrmQGetResource (rdb, namelist, classlist, + &type, &value) + && type == QString) + *string_return = (const char *) value.addr; +} + +static int +ParseWmProtocols (const char *string) +{ + const char *end, *sep; + char *buffer; + int wm_protocols; + + wm_protocols = 0; + end = string + strlen (string); + + while (string < end) + { + /* Find the next comma. */ + sep = strchr (string, ','); + + if (!sep) + sep = end; + + /* Copy the text between string and sep into buffer. */ + buffer = alloca (sep - string + 1); + memcpy (buffer, string, sep - string); + buffer[sep - string] = '\0'; + + if (!strcmp (buffer, "netWmPing")) + wm_protocols |= NetWmPingMask; + else + fprintf (stderr, "Warning: encountered invalid window manager " + "protocol: %s\n", buffer); + + string = sep + 1; + } + + return wm_protocols; +} + void XLInitXdgToplevels (void) { + const char *wm_protocols; + latin_1_cd = iconv_open ("ISO-8859-1", "UTF-8"); apply_state_workaround = (getenv ("APPLY_STATE_WORKAROUND") != NULL); batch_state_changes = !getenv ("DIRECT_STATE_CHANGES"); + + /* Determine which window manager protocols are to be enabled. */ + wm_protocols = "netWmPing,"; + ReadWmProtocolsString (&wm_protocols); + window_manager_protocols = ParseWmProtocols (wm_protocols); } Bool