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.
This commit is contained in:
parent
ce501c9de9
commit
163c9ad7db
|
@ -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,
|
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
|
* Changes a single value in the graphic context (so one doesn’t have to
|
||||||
|
|
|
@ -282,9 +282,6 @@ void render_container(xcb_connection_t *conn, Container *container) {
|
||||||
Client *client;
|
Client *client;
|
||||||
int num_clients = 0, current_client = 0;
|
int num_clients = 0, current_client = 0;
|
||||||
|
|
||||||
if (container->currently_focused == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
CIRCLEQ_FOREACH(client, &(container->clients), clients)
|
CIRCLEQ_FOREACH(client, &(container->clients), clients)
|
||||||
num_clients++;
|
num_clients++;
|
||||||
|
|
||||||
|
|
28
src/manage.c
28
src/manage.c
|
@ -140,9 +140,6 @@ void reparent_window(xcb_connection_t *conn, xcb_window_t child,
|
||||||
values[0] = CHILD_EVENT_MASK;
|
values[0] = CHILD_EVENT_MASK;
|
||||||
xcb_change_window_attributes(conn, child, mask, values);
|
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 */
|
/* Place requests for properties ASAP */
|
||||||
wm_type_cookie = xcb_get_any_property_unchecked(conn, false, child, atoms[_NET_WM_WINDOW_TYPE], UINT32_MAX);
|
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);
|
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 */
|
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… */
|
/* 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.
|
/* Set WM_STATE_NORMAL because GTK applications don’t want to drag & drop if we don’t.
|
||||||
* Also, xprop(1) needs that to work. */
|
* 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 };
|
uint32_t values[] = { XCB_STACK_MODE_BELOW };
|
||||||
xcb_configure_window(conn, new->frame, XCB_CONFIG_WINDOW_STACK_MODE, values);
|
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 */
|
/* 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);
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
/* Open a new window, the resizebar. Grab the pointer and move the window around
|
||||||
as the user moves the pointer. */
|
as the user moves the pointer. */
|
||||||
Rect grabrect = {0, 0, root_screen->width_in_pixels, root_screen->height_in_pixels};
|
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;
|
Rect helprect;
|
||||||
if (orientation == O_VERTICAL) {
|
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,
|
xcb_window_t helpwin = create_window(conn, helprect, XCB_WINDOW_CLASS_INPUT_OUTPUT,
|
||||||
(orientation == O_VERTICAL ?
|
(orientation == O_VERTICAL ?
|
||||||
XCB_CURSOR_SB_V_DOUBLE_ARROW :
|
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);
|
xcb_circulate_window(conn, XCB_CIRCULATE_RAISE_LOWEST, helpwin);
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
XCB_EVENT_MASK_EXPOSURE; /* …our window needs to be redrawn */
|
||||||
|
|
||||||
struct Stack_Window *stack_win = &(container->stack_win);
|
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
|
/* Initialize the entry for our cached pixmap. It will be
|
||||||
* created as soon as it’s needed (see cached_pixmap_prepare). */
|
* created as soon as it’s needed (see cached_pixmap_prepare). */
|
||||||
|
|
|
@ -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,
|
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 root = xcb_setup_roots_iterator(xcb_get_setup(conn)).data->root;
|
||||||
xcb_window_t result = xcb_generate_id(conn);
|
xcb_window_t result = xcb_generate_id(conn);
|
||||||
xcb_cursor_t cursor_id = xcb_generate_id(conn);
|
xcb_cursor_t cursor_id = xcb_generate_id(conn);
|
||||||
|
@ -121,6 +121,7 @@ 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);
|
xcb_change_window_attributes(conn, result, XCB_CW_CURSOR, &cursor_id);
|
||||||
|
|
||||||
/* Map the window (= make it visible) */
|
/* Map the window (= make it visible) */
|
||||||
|
if (map)
|
||||||
xcb_map_window(conn, result);
|
xcb_map_window(conn, result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -114,7 +114,7 @@ static void initialize_screen(xcb_connection_t *conn, i3Screen *screen, Workspac
|
||||||
font->height + 6};
|
font->height + 6};
|
||||||
uint32_t mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK;
|
uint32_t mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK;
|
||||||
uint32_t values[] = {1, XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS};
|
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);
|
screen->bargc = xcb_generate_id(conn);
|
||||||
xcb_create_gc(conn, screen->bargc, screen->bar, 0, 0);
|
xcb_create_gc(conn, screen->bargc, screen->bar, 0, 0);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue