Don't steal the _NET_WM_CM_Sn selection (#301)

Before becoming the selection owner for _NET_WM_CM_Sn, compton will now check if
that selection is already owned (which means that another composite manager is
already running). If this check fails, startup will be refused. This behaviour
is required by EWMH / ICCCM.

Because this should catch all composite managers, the error message that was
used before when another manager is already running is reworded to mention that
the other manager does not follow EWMH.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2015-10-24 12:32:55 +02:00 committed by Yuxuan Shui
parent cfdb946992
commit f8ea3e8668
1 changed files with 10 additions and 2 deletions

View File

@ -3323,7 +3323,8 @@ xerror(Display __attribute__((unused)) *dpy, XErrorEvent *ev) {
if (ev->request_code == ps->composite_opcode if (ev->request_code == ps->composite_opcode
&& ev->minor_code == X_CompositeRedirectSubwindows) { && ev->minor_code == X_CompositeRedirectSubwindows) {
fprintf(stderr, "Another composite manager is already running\n"); fprintf(stderr, "Another composite manager is already running "
"(and does not handle _NET_WM_CM_Sn correctly)\n");
exit(1); exit(1);
} }
@ -4895,6 +4896,7 @@ register_cm(session_t *ps) {
if (!ps->o.no_x_selection) { if (!ps->o.no_x_selection) {
unsigned len = strlen(REGISTER_PROP) + 2; unsigned len = strlen(REGISTER_PROP) + 2;
int s = ps->scr; int s = ps->scr;
Atom atom;
while (s >= 10) { while (s >= 10) {
++len; ++len;
@ -4904,7 +4906,13 @@ register_cm(session_t *ps) {
char *buf = malloc(len); char *buf = malloc(len);
snprintf(buf, len, REGISTER_PROP "%d", ps->scr); snprintf(buf, len, REGISTER_PROP "%d", ps->scr);
buf[len - 1] = '\0'; buf[len - 1] = '\0';
XSetSelectionOwner(ps->dpy, get_atom(ps, buf), ps->reg_win, 0); atom = get_atom(ps, buf);
if (XGetSelectionOwner(ps->dpy, atom) != None) {
fprintf(stderr, "Another composite manager is already running\n");
return false;
}
XSetSelectionOwner(ps->dpy, atom, ps->reg_win, 0);
free(buf); free(buf);
} }