Merge pull request #3368 from orestisf1993/render_root
(floating) global fullscreen bugs & others
This commit is contained in:
commit
4cba9fcbda
|
@ -120,6 +120,14 @@ Con *con_parent_with_orientation(Con *con, orientation_t orientation);
|
||||||
*/
|
*/
|
||||||
Con *con_get_fullscreen_con(Con *con, fullscreen_mode_t fullscreen_mode);
|
Con *con_get_fullscreen_con(Con *con, fullscreen_mode_t fullscreen_mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the fullscreen node that covers the given workspace if it exists.
|
||||||
|
* This is either a CF_GLOBAL fullscreen container anywhere or a CF_OUTPUT
|
||||||
|
* fullscreen container in the workspace.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Con *con_get_fullscreen_covering_ws(Con *ws);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the container is internal, such as __i3_scratch
|
* Returns true if the container is internal, such as __i3_scratch
|
||||||
*
|
*
|
||||||
|
|
|
@ -254,7 +254,7 @@ static int route_click(Con *con, xcb_button_press_event_t *event, const bool mod
|
||||||
|
|
||||||
/* 3: For floating containers, we also want to raise them on click.
|
/* 3: For floating containers, we also want to raise them on click.
|
||||||
* We will skip handling events on floating cons in fullscreen mode */
|
* We will skip handling events on floating cons in fullscreen mode */
|
||||||
Con *fs = (ws ? con_get_fullscreen_con(ws, CF_OUTPUT) : NULL);
|
Con *fs = con_get_fullscreen_covering_ws(ws);
|
||||||
if (floatingcon != NULL && fs != con) {
|
if (floatingcon != NULL && fs != con) {
|
||||||
/* 4: floating_modifier plus left mouse button drags */
|
/* 4: floating_modifier plus left mouse button drags */
|
||||||
if (mod_pressed && event->detail == XCB_BUTTON_CLICK_LEFT) {
|
if (mod_pressed && event->detail == XCB_BUTTON_CLICK_LEFT) {
|
||||||
|
|
|
@ -1272,7 +1272,7 @@ void cmd_focus_direction(I3_CMD, const char *direction) {
|
||||||
static void cmd_focus_force_focus(Con *con) {
|
static void cmd_focus_force_focus(Con *con) {
|
||||||
/* Disable fullscreen container in workspace with container to be focused. */
|
/* Disable fullscreen container in workspace with container to be focused. */
|
||||||
Con *ws = con_get_workspace(con);
|
Con *ws = con_get_workspace(con);
|
||||||
Con *fullscreen_on_ws = (focused && focused->fullscreen_mode == CF_GLOBAL) ? focused : con_get_fullscreen_con(ws, CF_OUTPUT);
|
Con *fullscreen_on_ws = con_get_fullscreen_covering_ws(ws);
|
||||||
if (fullscreen_on_ws && fullscreen_on_ws != con && !con_has_parent(con, fullscreen_on_ws)) {
|
if (fullscreen_on_ws && fullscreen_on_ws != con && !con_has_parent(con, fullscreen_on_ws)) {
|
||||||
con_disable_fullscreen(fullscreen_on_ws);
|
con_disable_fullscreen(fullscreen_on_ws);
|
||||||
}
|
}
|
||||||
|
|
20
src/con.c
20
src/con.c
|
@ -509,6 +509,23 @@ Con *con_get_fullscreen_con(Con *con, fullscreen_mode_t fullscreen_mode) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the fullscreen node that covers the given workspace if it exists.
|
||||||
|
* This is either a CF_GLOBAL fullscreen container anywhere or a CF_OUTPUT
|
||||||
|
* fullscreen container in the workspace.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Con *con_get_fullscreen_covering_ws(Con *ws) {
|
||||||
|
if (!ws) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
Con *fs = con_get_fullscreen_con(croot, CF_GLOBAL);
|
||||||
|
if (!fs) {
|
||||||
|
return con_get_fullscreen_con(ws, CF_OUTPUT);
|
||||||
|
}
|
||||||
|
return fs;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the container is internal, such as __i3_scratch
|
* Returns true if the container is internal, such as __i3_scratch
|
||||||
*
|
*
|
||||||
|
@ -1694,8 +1711,7 @@ adjacent_t con_adjacent_borders(Con *con) {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int con_border_style(Con *con) {
|
int con_border_style(Con *con) {
|
||||||
Con *fs = con_get_fullscreen_con(con->parent, CF_OUTPUT);
|
if (con->fullscreen_mode == CF_OUTPUT || con->fullscreen_mode == CF_GLOBAL) {
|
||||||
if (fs == con) {
|
|
||||||
DLOG("this one is fullscreen! overriding BS_NONE\n");
|
DLOG("this one is fullscreen! overriding BS_NONE\n");
|
||||||
return BS_NONE;
|
return BS_NONE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -310,16 +310,12 @@ static void handle_configure_request(xcb_configure_request_event_t *event) {
|
||||||
|
|
||||||
DLOG("Configure request!\n");
|
DLOG("Configure request!\n");
|
||||||
|
|
||||||
Con *workspace = con_get_workspace(con),
|
Con *workspace = con_get_workspace(con);
|
||||||
*fullscreen = NULL;
|
if (workspace && (strcmp(workspace->name, "__i3_scratch") == 0)) {
|
||||||
|
DLOG("This is a scratchpad container, ignoring ConfigureRequest\n");
|
||||||
/* There might not be a corresponding workspace for dock cons, therefore we
|
goto out;
|
||||||
* have to be careful here. */
|
|
||||||
if (workspace) {
|
|
||||||
fullscreen = con_get_fullscreen_con(workspace, CF_OUTPUT);
|
|
||||||
if (!fullscreen)
|
|
||||||
fullscreen = con_get_fullscreen_con(workspace, CF_GLOBAL);
|
|
||||||
}
|
}
|
||||||
|
Con *fullscreen = con_get_fullscreen_covering_ws(workspace);
|
||||||
|
|
||||||
if (fullscreen != con && con_is_floating(con) && con_is_leaf(con)) {
|
if (fullscreen != con && con_is_floating(con) && con_is_leaf(con)) {
|
||||||
/* find the height for the decorations */
|
/* find the height for the decorations */
|
||||||
|
@ -332,12 +328,6 @@ static void handle_configure_request(xcb_configure_request_event_t *event) {
|
||||||
bsr.height -= deco_height;
|
bsr.height -= deco_height;
|
||||||
}
|
}
|
||||||
Con *floatingcon = con->parent;
|
Con *floatingcon = con->parent;
|
||||||
|
|
||||||
if (strcmp(con_get_workspace(floatingcon)->name, "__i3_scratch") == 0) {
|
|
||||||
DLOG("This is a scratchpad container, ignoring ConfigureRequest\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Rect newrect = floatingcon->rect;
|
Rect newrect = floatingcon->rect;
|
||||||
|
|
||||||
if (event->value_mask & XCB_CONFIG_WINDOW_X) {
|
if (event->value_mask & XCB_CONFIG_WINDOW_X) {
|
||||||
|
@ -395,15 +385,14 @@ static void handle_configure_request(xcb_configure_request_event_t *event) {
|
||||||
DLOG("Dock client will not be moved, we only support moving it to another output.\n");
|
DLOG("Dock client will not be moved, we only support moving it to another output.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fake_absolute_configure_notify(con);
|
goto out;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->value_mask & XCB_CONFIG_WINDOW_STACK_MODE) {
|
if (event->value_mask & XCB_CONFIG_WINDOW_STACK_MODE) {
|
||||||
DLOG("window 0x%08x wants to be stacked %d\n", event->window, event->stack_mode);
|
DLOG("window 0x%08x wants to be stacked %d\n", event->window, event->stack_mode);
|
||||||
|
|
||||||
/* Emacs and IntelliJ Idea “request focus” by stacking their window
|
/* Emacs and IntelliJ Idea “request focus” by stacking their window
|
||||||
* above all others. */
|
* above all others. */
|
||||||
if (event->stack_mode != XCB_STACK_MODE_ABOVE) {
|
if (event->stack_mode != XCB_STACK_MODE_ABOVE) {
|
||||||
DLOG("stack_mode != XCB_STACK_MODE_ABOVE, ignoring ConfigureRequest\n");
|
DLOG("stack_mode != XCB_STACK_MODE_ABOVE, ignoring ConfigureRequest\n");
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -414,23 +403,17 @@ static void handle_configure_request(xcb_configure_request_event_t *event) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
Con *ws = con_get_workspace(con);
|
if (workspace == NULL) {
|
||||||
if (ws == NULL) {
|
|
||||||
DLOG("Window is not being managed, ignoring ConfigureRequest\n");
|
DLOG("Window is not being managed, ignoring ConfigureRequest\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(ws->name, "__i3_scratch") == 0) {
|
if (config.focus_on_window_activation == FOWA_FOCUS || (config.focus_on_window_activation == FOWA_SMART && workspace_is_visible(workspace))) {
|
||||||
DLOG("This is a scratchpad container, ignoring ConfigureRequest\n");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.focus_on_window_activation == FOWA_FOCUS || (config.focus_on_window_activation == FOWA_SMART && workspace_is_visible(ws))) {
|
|
||||||
DLOG("Focusing con = %p\n", con);
|
DLOG("Focusing con = %p\n", con);
|
||||||
workspace_show(ws);
|
workspace_show(workspace);
|
||||||
con_activate(con);
|
con_activate(con);
|
||||||
tree_render();
|
tree_render();
|
||||||
} else if (config.focus_on_window_activation == FOWA_URGENT || (config.focus_on_window_activation == FOWA_SMART && !workspace_is_visible(ws))) {
|
} else if (config.focus_on_window_activation == FOWA_URGENT || (config.focus_on_window_activation == FOWA_SMART && !workspace_is_visible(workspace))) {
|
||||||
DLOG("Marking con = %p urgent\n", con);
|
DLOG("Marking con = %p urgent\n", con);
|
||||||
con_set_urgency(con, true);
|
con_set_urgency(con, true);
|
||||||
tree_render();
|
tree_render();
|
||||||
|
|
|
@ -378,9 +378,7 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
|
||||||
|
|
||||||
/* handle fullscreen containers */
|
/* handle fullscreen containers */
|
||||||
Con *ws = con_get_workspace(nc);
|
Con *ws = con_get_workspace(nc);
|
||||||
Con *fs = (ws ? con_get_fullscreen_con(ws, CF_OUTPUT) : NULL);
|
Con *fs = con_get_fullscreen_covering_ws(ws);
|
||||||
if (fs == NULL)
|
|
||||||
fs = con_get_fullscreen_con(croot, CF_GLOBAL);
|
|
||||||
|
|
||||||
if (xcb_reply_contains_atom(state_reply, A__NET_WM_STATE_FULLSCREEN)) {
|
if (xcb_reply_contains_atom(state_reply, A__NET_WM_STATE_FULLSCREEN)) {
|
||||||
/* If this window is already fullscreen (after restarting!), skip
|
/* If this window is already fullscreen (after restarting!), skip
|
||||||
|
|
25
src/render.c
25
src/render.c
|
@ -234,25 +234,22 @@ static void render_root(Con *con, Con *fullscreen) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Con *workspace = TAILQ_FIRST(&(content->focus_head));
|
Con *workspace = TAILQ_FIRST(&(content->focus_head));
|
||||||
Con *fullscreen = con_get_fullscreen_con(workspace, CF_OUTPUT);
|
Con *fullscreen = con_get_fullscreen_covering_ws(workspace);
|
||||||
Con *child;
|
Con *child;
|
||||||
TAILQ_FOREACH(child, &(workspace->floating_head), floating_windows) {
|
TAILQ_FOREACH(child, &(workspace->floating_head), floating_windows) {
|
||||||
/* Don’t render floating windows when there is a fullscreen window
|
if (fullscreen != NULL) {
|
||||||
* on that workspace. Necessary to make floating fullscreen work
|
/* Don’t render floating windows when there is a fullscreen
|
||||||
* correctly (ticket #564). */
|
* window on that workspace. Necessary to make floating
|
||||||
/* If there is no fullscreen->window, this cannot be a
|
* fullscreen work correctly (ticket #564). Exception to the
|
||||||
* transient window, so we _know_ we need to skip it. This
|
* above rule: smart popup_during_fullscreen handling (popups
|
||||||
* happens during restarts where the container already exists,
|
* belonging to the fullscreen app will be rendered). */
|
||||||
* but the window was not yet associated. */
|
if (config.popup_during_fullscreen != PDF_SMART) {
|
||||||
if (fullscreen != NULL && fullscreen->window == NULL)
|
continue;
|
||||||
continue;
|
}
|
||||||
if (fullscreen != NULL && fullscreen->window != NULL) {
|
|
||||||
Con *floating_child = con_descend_focused(child);
|
Con *floating_child = con_descend_focused(child);
|
||||||
Con *transient_con = floating_child;
|
Con *transient_con = floating_child;
|
||||||
bool is_transient_for = false;
|
bool is_transient_for = false;
|
||||||
/* Exception to the above rule: smart
|
|
||||||
* popup_during_fullscreen handling (popups belonging to
|
|
||||||
* the fullscreen app will be rendered). */
|
|
||||||
while (transient_con != NULL &&
|
while (transient_con != NULL &&
|
||||||
transient_con->window != NULL &&
|
transient_con->window != NULL &&
|
||||||
transient_con->window->transient_for != XCB_NONE) {
|
transient_con->window->transient_for != XCB_NONE) {
|
||||||
|
|
Loading…
Reference in New Issue