From 1917368502c6e2a2eeaf0cba118122add60b1626 Mon Sep 17 00:00:00 2001 From: martin Date: Sun, 26 Mar 2017 15:01:23 +0200 Subject: [PATCH] Fix covering of composited notifications (#204) Use the XComposite extension to get the composite overlay window, instead of just using the normal root window. This ensures that composited windows are covered. This time, we hide it behind a config option because it might break things more than it fixes. --- README.md | 1 + configure.ac | 2 +- i3lock.1 | 5 +++++ i3lock.c | 7 ++++++- travis/Dockerfile | 2 +- xcb.c | 32 ++++++++++++++++++++++++++++++-- 6 files changed, 44 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c6dd54d..bdac61c 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ Requirements - libxcb-util - libpam-dev - libcairo-dev +- libxcb-composite0 - libxcb-xinerama - libxcb-randr - libev diff --git a/configure.ac b/configure.ac index 9171521..57ad7f4 100644 --- a/configure.ac +++ b/configure.ac @@ -90,7 +90,7 @@ AC_SEARCH_LIBS([iconv_open], [iconv], , [AC_MSG_FAILURE([cannot find the require dnl Each prefix corresponds to a source tarball which users might have dnl downloaded in a newer version and would like to overwrite. -PKG_CHECK_MODULES([XCB], [xcb xcb-xkb xcb-xinerama xcb-randr]) +PKG_CHECK_MODULES([XCB], [xcb xcb-xkb xcb-xinerama xcb-randr xcb-composite]) PKG_CHECK_MODULES([XCB_IMAGE], [xcb-image]) PKG_CHECK_MODULES([XCB_UTIL], [xcb-event xcb-util xcb-atom]) PKG_CHECK_MODULES([XCB_UTIL_XRM], [xcb-xrm]) diff --git a/i3lock.1 b/i3lock.1 index 434638b..ba98e9f 100644 --- a/i3lock.1 +++ b/i3lock.1 @@ -115,6 +115,11 @@ Lock the console to disable TTY switching (Linux only). Enables debug logging. Note, that this will log the password used for authentication to stdout. +.TP +.B \-o, \-\-use-composite-overlay +Use the composite overlay window. For some compositors it might fix windows +appearing on top of the lock screen, for other compositors it might break. + .SH DPMS The \-d (\-\-dpms) option was removed from i3lock in version 2.8. There were diff --git a/i3lock.c b/i3lock.c index 51fa633..1268757 100644 --- a/i3lock.c +++ b/i3lock.c @@ -87,6 +87,7 @@ extern auth_state_t auth_state; int failed_attempts = 0; bool show_failed_attempts = false; bool retry_verification = false; +bool use_composite_overlay = false; static struct xkb_state *xkb_state; static struct xkb_context *xkb_context; @@ -895,6 +896,7 @@ int main(int argc, char *argv[]) { {"inactivity-timeout", required_argument, NULL, 'I'}, {"show-failed-attempts", no_argument, NULL, 'f'}, {"lock-console", no_argument, NULL, 'l'}, + {"use-composite-overlay", no_argument, NULL, 'o'}, {NULL, no_argument, NULL, 0}}; if ((pw = getpwuid(getuid())) == NULL) @@ -967,9 +969,12 @@ int main(int argc, char *argv[]) { errx(EXIT_FAILURE, "TTY switch locking is only supported on Linux."); #endif break; + case 'o': + use_composite_overlay = true; + break; default: errx(EXIT_FAILURE, "Syntax: i3lock [-v] [-n] [-b] [-d] [-c color] [-u] [-p win|default]" - " [-i image.png] [-t] [-e] [-I timeout] [-f] [-l]"); + " [-i image.png] [-t] [-e] [-I timeout] [-f] [-l] [-o]"); } } diff --git a/travis/Dockerfile b/travis/Dockerfile index 5381276..d58e8a3 100644 --- a/travis/Dockerfile +++ b/travis/Dockerfile @@ -19,7 +19,7 @@ RUN apt-get update && \ build-essential clang git autoconf automake libxcb-randr0-dev pkg-config libpam0g-dev \ libcairo2-dev libxcb1-dev libxcb-dpms0-dev libxcb-image0-dev libxcb-util0-dev \ libxcb-xrm-dev libev-dev libxcb-xinerama0-dev libxcb-xkb-dev libxkbcommon-dev \ - libxkbcommon-x11-dev && \ + libxkbcommon-x11-dev libxcb-composite0-dev && \ rm -rf /var/lib/apt/lists/* WORKDIR /usr/src diff --git a/xcb.c b/xcb.c index 280be55..78a8725 100644 --- a/xcb.c +++ b/xcb.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,7 @@ #include "unlock_indicator.h" extern auth_state_t auth_state; +extern bool use_composite_overlay; xcb_connection_t *conn; xcb_screen_t *screen; @@ -107,6 +109,32 @@ xcb_window_t open_fullscreen_window(xcb_connection_t *conn, xcb_screen_t *scr, c uint32_t mask = 0; uint32_t values[3]; xcb_window_t win = xcb_generate_id(conn); + xcb_window_t parent_win = scr->root; + + /* Check whether the composite extension is available */ + + if (use_composite_overlay) { + const xcb_query_extension_reply_t *extension_query = NULL; + xcb_generic_error_t *error = NULL; + xcb_composite_get_overlay_window_cookie_t cookie; + xcb_composite_get_overlay_window_reply_t *composite_reply = NULL; + + extension_query = xcb_get_extension_data(conn, &xcb_composite_id); + if (extension_query && extension_query->present) { + /* When composition is used, we need to use the composite overlay + * window instead of the normal root window to be able to cover + * composited windows */ + cookie = xcb_composite_get_overlay_window(conn, scr->root); + composite_reply = xcb_composite_get_overlay_window_reply(conn, cookie, &error); + + if (!error && composite_reply) { + parent_win = composite_reply->overlay_win; + } + + free(composite_reply); + free(error); + } + } if (pixmap == XCB_NONE) { mask |= XCB_CW_BACK_PIXEL; @@ -128,8 +156,8 @@ xcb_window_t open_fullscreen_window(xcb_connection_t *conn, xcb_screen_t *scr, c xcb_create_window(conn, XCB_COPY_FROM_PARENT, - win, /* the window id */ - scr->root, /* parent == root */ + win, /* the window id */ + parent_win, 0, 0, scr->width_in_pixels, scr->height_in_pixels, /* dimensions */