From: Michael Stapelberg Date: Sat, 25 Jul 2009 20:29:28 +0000 (+0200) Subject: Map window/its decoration *after* calling render_layout() X-Git-Tag: 3.c~50 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=163c9ad7dbd82905088ba6b6cc1c4ee9ed210258;p=i3%2Fi3 Map window/its decoration *after* calling render_layout() Thus, no more flickering because the window was first mapped and then moved. Especially users of multiple monitors should be happy now ;-). Rather radical change, though, so be prepared for problems. --- diff --git a/include/xcb.h b/include/xcb.h index b540a5cc..16ce3ce8 100644 --- a/include/xcb.h +++ b/include/xcb.h @@ -89,7 +89,7 @@ uint32_t get_colorpixel(xcb_connection_t *conn, char *hex); * */ xcb_window_t create_window(xcb_connection_t *conn, Rect r, uint16_t window_class, - int cursor, uint32_t mask, uint32_t *values); + int cursor, bool map, uint32_t mask, uint32_t *values); /** * Changes a single value in the graphic context (so one doesn’t have to diff --git a/src/layout.c b/src/layout.c index 89c561ea..ce1541ab 100644 --- a/src/layout.c +++ b/src/layout.c @@ -282,9 +282,6 @@ void render_container(xcb_connection_t *conn, Container *container) { Client *client; int num_clients = 0, current_client = 0; - if (container->currently_focused == NULL) - return; - CIRCLEQ_FOREACH(client, &(container->clients), clients) num_clients++; diff --git a/src/manage.c b/src/manage.c index f7630eb0..9ddcab42 100644 --- a/src/manage.c +++ b/src/manage.c @@ -140,9 +140,6 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child, values[0] = CHILD_EVENT_MASK; xcb_change_window_attributes(conn, child, mask, values); - /* Map the window first to avoid flickering */ - xcb_map_window(conn, child); - /* Place requests for properties ASAP */ wm_type_cookie = xcb_get_any_property_unchecked(conn, false, child, atoms[_NET_WM_WINDOW_TYPE], UINT32_MAX); strut_cookie = xcb_get_any_property_unchecked(conn, false, child, atoms[_NET_WM_STRUT_PARTIAL], UINT32_MAX); @@ -201,7 +198,7 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child, height + 2 + 2 + font->height}; /* 2 px border plus font’s height */ /* Yo dawg, I heard you like windows, so I create a window around your window… */ - new->frame = create_window(conn, framerect, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_CURSOR_LEFT_PTR, mask, values); + new->frame = create_window(conn, framerect, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_CURSOR_LEFT_PTR, false, mask, values); /* Set WM_STATE_NORMAL because GTK applications don’t want to drag & drop if we don’t. * Also, xprop(1) needs that to work. */ @@ -351,14 +348,6 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child, uint32_t values[] = { XCB_STACK_MODE_BELOW }; xcb_configure_window(conn, new->frame, XCB_CONFIG_WINDOW_STACK_MODE, values); } - } else if (!new->dock) { - /* Focus the new window if we’re not in fullscreen mode and if it is not a dock window */ - if (new->container->workspace->fullscreen_client == NULL) { - if (!client_is_floating(new)) - new->container->currently_focused = new; - if (new->container == CUR_CELL) - xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, new->child, XCB_CURRENT_TIME); - } } /* Insert into the currently active container, if it’s not a dock window */ @@ -420,4 +409,19 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child, } render_layout(conn); + + /* Map the window first to avoid flickering */ + xcb_map_window(conn, new->frame); + xcb_map_window(conn, child); + if (CUR_CELL->workspace->fullscreen_client == NULL && !new->dock) { + /* Focus the new window if we’re not in fullscreen mode and if it is not a dock window */ + if (new->container->workspace->fullscreen_client == NULL) { + if (!client_is_floating(new)) + new->container->currently_focused = new; + if (new->container == CUR_CELL) + xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, new->child, XCB_CURRENT_TIME); + } + } + + xcb_flush(conn); } diff --git a/src/resize.c b/src/resize.c index 3d634420..52b064b4 100644 --- a/src/resize.c +++ b/src/resize.c @@ -61,7 +61,7 @@ int resize_graphical_handler(xcb_connection_t *conn, Workspace *ws, int first, i /* Open a new window, the resizebar. Grab the pointer and move the window around as the user moves the pointer. */ Rect grabrect = {0, 0, root_screen->width_in_pixels, root_screen->height_in_pixels}; - xcb_window_t grabwin = create_window(conn, grabrect, XCB_WINDOW_CLASS_INPUT_ONLY, -1, mask, values); + xcb_window_t grabwin = create_window(conn, grabrect, XCB_WINDOW_CLASS_INPUT_ONLY, -1, true, mask, values); Rect helprect; if (orientation == O_VERTICAL) { @@ -87,7 +87,7 @@ int resize_graphical_handler(xcb_connection_t *conn, Workspace *ws, int first, i xcb_window_t helpwin = create_window(conn, helprect, XCB_WINDOW_CLASS_INPUT_OUTPUT, (orientation == O_VERTICAL ? XCB_CURSOR_SB_V_DOUBLE_ARROW : - XCB_CURSOR_SB_H_DOUBLE_ARROW), mask, values); + XCB_CURSOR_SB_H_DOUBLE_ARROW), true, mask, values); xcb_circulate_window(conn, XCB_CIRCULATE_RAISE_LOWEST, helpwin); diff --git a/src/util.c b/src/util.c index 26b339a9..108bf4a1 100644 --- a/src/util.c +++ b/src/util.c @@ -438,7 +438,7 @@ void switch_layout_mode(xcb_connection_t *conn, Container *container, int mode) XCB_EVENT_MASK_EXPOSURE; /* …our window needs to be redrawn */ struct Stack_Window *stack_win = &(container->stack_win); - stack_win->window = create_window(conn, rect, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_CURSOR_LEFT_PTR, mask, values); + stack_win->window = create_window(conn, rect, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_CURSOR_LEFT_PTR, true, mask, values); /* Initialize the entry for our cached pixmap. It will be * created as soon as it’s needed (see cached_pixmap_prepare). */ diff --git a/src/xcb.c b/src/xcb.c index 4ad69db1..96a3ce15 100644 --- a/src/xcb.c +++ b/src/xcb.c @@ -90,7 +90,7 @@ uint32_t get_colorpixel(xcb_connection_t *conn, char *hex) { * */ xcb_window_t create_window(xcb_connection_t *conn, Rect dims, uint16_t window_class, int cursor, - uint32_t mask, uint32_t *values) { + bool map, uint32_t mask, uint32_t *values) { xcb_window_t root = xcb_setup_roots_iterator(xcb_get_setup(conn)).data->root; xcb_window_t result = xcb_generate_id(conn); xcb_cursor_t cursor_id = xcb_generate_id(conn); @@ -121,7 +121,8 @@ xcb_window_t create_window(xcb_connection_t *conn, Rect dims, uint16_t window_cl xcb_change_window_attributes(conn, result, XCB_CW_CURSOR, &cursor_id); /* Map the window (= make it visible) */ - xcb_map_window(conn, result); + if (map) + xcb_map_window(conn, result); return result; } diff --git a/src/xinerama.c b/src/xinerama.c index 2bb8b298..1b410e03 100644 --- a/src/xinerama.c +++ b/src/xinerama.c @@ -114,7 +114,7 @@ static void initialize_screen(xcb_connection_t *conn, i3Screen *screen, Workspac font->height + 6}; uint32_t mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK; uint32_t values[] = {1, XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS}; - screen->bar = create_window(conn, bar_rect, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_CURSOR_LEFT_PTR, mask, values); + screen->bar = create_window(conn, bar_rect, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_CURSOR_LEFT_PTR, true, mask, values); screen->bargc = xcb_generate_id(conn); xcb_create_gc(conn, screen->bargc, screen->bar, 0, 0);