From 4f5e0e794f61cdcea2652f964ec25d0b7418f69b Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sun, 24 Nov 2013 13:44:30 +0100 Subject: [PATCH] =?UTF-8?q?persist=20root=20window=E2=80=99s=20background?= =?UTF-8?q?=20contents=20to=20a=20pixmap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The commit title is fairly technical, so I’ll try to explain. Recently, users of GDM3 (I’m sure) and LightDM (I think) have reported that when switching to a new workspace, the contents of the previous workspace are still visible. i3bar updates, though, so it is the X11 root window which is not being updated here. When using GDM3, X11 will be started with -background none, and no background pixmap or pixel is set. Then, apparently, gnome-settings-daemon will display a fade animation from whatever is currently on the window to the destination contents. I think this is to avoid flickering when logging in, which would occur when just setting a specific background pixmap or pixel. So, this commit will, when i3 starts first (not on restarts), copy the contents of the X11 root window (typicall a grey background, at least on my machine with GDM3) into a pixmap and set that pixmap as background pixmap. That way, the content will be preserved and one has a background, instead of what is perceived as a bug :). This commit has some chance of breakage, so I’m prepared to revert it unless we can figure out the issues and roll forward. --- src/main.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/main.c b/src/main.c index 2b397181f..a20fe31b0 100644 --- a/src/main.c +++ b/src/main.c @@ -794,6 +794,27 @@ int main(int argc, char *argv[]) { } xcb_ungrab_server(conn); + if (autostart) { + LOG("This is not an in-place restart, copying root window contents to a pixmap\n"); + xcb_screen_t *root = xcb_aux_get_screen(conn, conn_screen); + uint16_t width = root->width_in_pixels; + uint16_t height = root->height_in_pixels; + xcb_pixmap_t pixmap = xcb_generate_id(conn); + xcb_gcontext_t gc = xcb_generate_id(conn); + + xcb_create_pixmap(conn, root->root_depth, pixmap, root->root, width, height); + + xcb_create_gc(conn, gc, root->root, + XCB_GC_FUNCTION | XCB_GC_PLANE_MASK | XCB_GC_FILL_STYLE | XCB_GC_SUBWINDOW_MODE, + (uint32_t[]){ XCB_GX_COPY, ~0, XCB_FILL_STYLE_SOLID, XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS }); + + xcb_copy_area(conn, root->root, pixmap, gc, 0, 0, 0, 0, width, height); + xcb_change_window_attributes_checked(conn, root->root, XCB_CW_BACK_PIXMAP, (uint32_t[]){ pixmap }); + xcb_flush(conn); + xcb_free_gc(conn, gc); + xcb_free_pixmap(conn, pixmap); + } + struct sigaction action; action.sa_sigaction = handle_signal;