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 If ``True'' or ``true'', this resource enables the use of direct
presentation on unredirected windows. This is not yet complete presentation on unredirected windows. This is not yet complete
pending the installation of required functionality in the X server. 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 .IP
.SH ENVIRONMENT .SH ENVIRONMENT
Several environment variables exist that modify the behavior of the Several environment variables exist that modify the behavior of the

View file

@ -253,6 +253,11 @@ struct _XdgDecoration
XdgToplevel *toplevel; XdgToplevel *toplevel;
}; };
enum
{
NetWmPingMask = 1,
};
/* iconv context used to convert between UTF-8 and Latin-1. */ /* iconv context used to convert between UTF-8 and Latin-1. */
static iconv_t latin_1_cd; static iconv_t latin_1_cd;
@ -264,6 +269,9 @@ static Bool apply_state_workaround;
at almost the same time. */ at almost the same time. */
static Bool batch_state_changes; static Bool batch_state_changes;
/* Mask consisting of currently enabled window manager protocols. */
static int window_manager_protocols;
static XdgUnmapCallback * static XdgUnmapCallback *
RunOnUnmap (XdgToplevel *toplevel, void (*unmap) (void *), RunOnUnmap (XdgToplevel *toplevel, void (*unmap) (void *),
void *data) void *data)
@ -1035,7 +1043,8 @@ Attach (Role *role, XdgRoleImplementation *impl)
/* _NET_WM_PING should be disabled when the window manager kills /* _NET_WM_PING should be disabled when the window manager kills
clients using XKillClient. */ clients using XKillClient. */
protocols[nproto++] = _NET_WM_PING; if (window_manager_protocols & NetWmPingMask)
protocols[nproto++] = _NET_WM_PING;
if (XLFrameClockSyncSupported ()) if (XLFrameClockSyncSupported ())
protocols[nproto++] = _NET_WM_SYNC_REQUEST; protocols[nproto++] = _NET_WM_SYNC_REQUEST;
@ -2378,12 +2387,82 @@ XLHandleXEventForXdgToplevels (XEvent *event)
return False; 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 void
XLInitXdgToplevels (void) XLInitXdgToplevels (void)
{ {
const char *wm_protocols;
latin_1_cd = iconv_open ("ISO-8859-1", "UTF-8"); latin_1_cd = iconv_open ("ISO-8859-1", "UTF-8");
apply_state_workaround = (getenv ("APPLY_STATE_WORKAROUND") != NULL); apply_state_workaround = (getenv ("APPLY_STATE_WORKAROUND") != NULL);
batch_state_changes = !getenv ("DIRECT_STATE_CHANGES"); 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 Bool