]> git.sur5r.net Git - i3/i3/commitdiff
Map window/its decoration *after* calling render_layout()
authorMichael Stapelberg <michael@stapelberg.de>
Sat, 25 Jul 2009 20:29:28 +0000 (22:29 +0200)
committerMichael Stapelberg <michael@stapelberg.de>
Sat, 25 Jul 2009 20:29:28 +0000 (22:29 +0200)
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.

include/xcb.h
src/layout.c
src/manage.c
src/resize.c
src/util.c
src/xcb.c
src/xinerama.c

index b540a5cc18773c976248527f63da3990e04cd295..16ce3ce8a226840e5b9d3c80160fc3628eb34494 100644 (file)
@@ -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
index 89c561eae83ab79a3071769ea46db477cc19c216..ce1541ab62e977691996888b68ecf99ea3e5c561 100644 (file)
@@ -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++;
 
index f7630eb098941d47f995a2fc1f1c871c590e8a08..9ddcab42e51dbedad3d900cc96ca6b04e7ba2260 100644 (file)
@@ -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);
 }
index 3d6344202a63bc642e64d4f1be05d796cc126a7c..52b064b4fd0887421041716154a92fdbecc247a2 100644 (file)
@@ -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);
 
index 26b339a9ca9a4d1ee20aded778dc9d11154e2fb1..108bf4a1327e171a8b07569baf21b1320ac7729e 100644 (file)
@@ -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). */
index 4ad69db1baf1b83fce4bee64b7c1929b3aa8e909..96a3ce15bcb5ca358a31a1fd45a1e8ec4c6764ed 100644 (file)
--- 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;
 }
index 2bb8b2986900ee027bfea6e2a9efe65e1bcf9c32..1b410e037f053d78a2da2d51effd3d924eecd46b 100644 (file)
@@ -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);