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.
This commit is contained in:
hujianwei 2022-10-20 11:07:46 +00:00
parent e0e1a6ecb1
commit 58a954db7f
2 changed files with 86 additions and 1 deletions

View file

@ -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

View file

@ -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