diff options
Diffstat (limited to 'sway/tree')
-rw-r--r-- | sway/tree/arrange.c | 16 | ||||
-rw-r--r-- | sway/tree/container.c | 174 | ||||
-rw-r--r-- | sway/tree/root.c | 5 | ||||
-rw-r--r-- | sway/tree/view.c | 26 |
4 files changed, 156 insertions, 65 deletions
diff --git a/sway/tree/arrange.c b/sway/tree/arrange.c index f78d95a4..da372aa4 100644 --- a/sway/tree/arrange.c +++ b/sway/tree/arrange.c @@ -261,9 +261,19 @@ void arrange_root(void) { root->y = layout_box->y; root->width = layout_box->width; root->height = layout_box->height; - for (int i = 0; i < root->outputs->length; ++i) { - struct sway_output *output = root->outputs->items[i]; - arrange_output(output); + + if (root->fullscreen_global) { + struct sway_container *fs = root->fullscreen_global; + fs->x = root->x; + fs->y = root->y; + fs->width = root->width; + fs->height = root->height; + arrange_container(fs); + } else { + for (int i = 0; i < root->outputs->length; ++i) { + struct sway_output *output = root->outputs->items[i]; + arrange_output(output); + } } } diff --git a/sway/tree/container.c b/sway/tree/container.c index 0c0684c0..d8ad3bc0 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -92,7 +92,7 @@ void container_begin_destroy(struct sway_container *con) { } // The workspace must have the fullscreen pointer cleared so that the // seat code can find an appropriate new focus. - if (con->is_fullscreen && con->workspace) { + if (con->fullscreen_mode == FULLSCREEN_WORKSPACE && con->workspace) { con->workspace->fullscreen = NULL; } wl_signal_emit(&con->node.events.destroy, &con->node); @@ -106,6 +106,10 @@ void container_begin_destroy(struct sway_container *con) { root_scratchpad_remove_container(con); } + if (con->fullscreen_mode == FULLSCREEN_GLOBAL) { + container_fullscreen_disable(con); + } + if (con->parent || con->workspace) { container_detach(con); } @@ -840,15 +844,15 @@ void container_floating_move_to_center(struct sway_container *con) { return; } struct sway_workspace *ws = con->workspace; - bool full = con->is_fullscreen; - if (full) { - container_set_fullscreen(con, false); + enum sway_fullscreen_mode fullscreen_mode = con->fullscreen_mode; + if (fullscreen_mode) { + container_fullscreen_disable(con); } double new_lx = ws->x + (ws->width - con->width) / 2; double new_ly = ws->y + (ws->height - con->height) / 2; container_floating_translate(con, new_lx - con->x, new_ly - con->y); - if (full) { - container_set_fullscreen(con, true); + if (fullscreen_mode) { + container_set_fullscreen(con, fullscreen_mode); } } @@ -877,59 +881,125 @@ static void set_fullscreen_iterator(struct sway_container *con, void *data) { } } -void container_set_fullscreen(struct sway_container *container, bool enable) { - if (container->is_fullscreen == enable) { +static void container_fullscreen_workspace(struct sway_container *con) { + if (!sway_assert(con->fullscreen_mode == FULLSCREEN_NONE, + "Expected a non-fullscreen container")) { return; } + bool enable = true; + set_fullscreen_iterator(con, &enable); + container_for_each_child(con, set_fullscreen_iterator, &enable); - struct sway_workspace *workspace = container->workspace; - if (enable && workspace->fullscreen) { - container_set_fullscreen(workspace->fullscreen, false); + con->workspace->fullscreen = con; + con->saved_x = con->x; + con->saved_y = con->y; + con->saved_width = con->width; + con->saved_height = con->height; + + struct sway_seat *seat; + struct sway_workspace *focus_ws; + wl_list_for_each(seat, &server.input->seats, link) { + focus_ws = seat_get_focused_workspace(seat); + if (focus_ws == con->workspace) { + seat_set_focus_container(seat, con); + } } - set_fullscreen_iterator(container, &enable); - container_for_each_child(container, set_fullscreen_iterator, &enable); + con->fullscreen_mode = FULLSCREEN_WORKSPACE; + container_end_mouse_operation(con); + ipc_event_window(con, "fullscreen_mode"); +} + +static void container_fullscreen_global(struct sway_container *con) { + if (!sway_assert(con->fullscreen_mode == FULLSCREEN_NONE, + "Expected a non-fullscreen container")) { + return; + } + bool enable = true; + set_fullscreen_iterator(con, &enable); + container_for_each_child(con, set_fullscreen_iterator, &enable); - container->is_fullscreen = enable; + root->fullscreen_global = con; + con->saved_x = con->x; + con->saved_y = con->y; + con->saved_width = con->width; + con->saved_height = con->height; - if (enable) { - workspace->fullscreen = container; - container->saved_x = container->x; - container->saved_y = container->y; - container->saved_width = container->width; - container->saved_height = container->height; - - struct sway_seat *seat; - struct sway_workspace *focus_ws; - wl_list_for_each(seat, &server.input->seats, link) { - focus_ws = seat_get_focused_workspace(seat); - if (focus_ws) { - if (focus_ws == workspace) { - seat_set_focus_container(seat, container); - } - } + struct sway_seat *seat; + wl_list_for_each(seat, &server.input->seats, link) { + struct sway_container *focus = seat_get_focused_container(seat); + if (focus && focus != con) { + seat_set_focus_container(seat, con); } - } else { - workspace->fullscreen = NULL; - if (container_is_floating(container)) { - container->x = container->saved_x; - container->y = container->saved_y; - container->width = container->saved_width; - container->height = container->saved_height; - struct sway_output *output = - container_floating_find_output(container); - if (workspace->output != output) { - container_floating_move_to_center(container); + } + + con->fullscreen_mode = FULLSCREEN_GLOBAL; + container_end_mouse_operation(con); + ipc_event_window(con, "fullscreen_mode"); +} + +void container_fullscreen_disable(struct sway_container *con) { + if (!sway_assert(con->fullscreen_mode != FULLSCREEN_NONE, + "Expected a fullscreen container")) { + return; + } + bool enable = false; + set_fullscreen_iterator(con, &enable); + container_for_each_child(con, set_fullscreen_iterator, &enable); + + if (container_is_floating(con)) { + con->x = con->saved_x; + con->y = con->saved_y; + } + con->width = con->saved_width; + con->height = con->saved_height; + + if (con->fullscreen_mode == FULLSCREEN_WORKSPACE) { + con->workspace->fullscreen = NULL; + if (container_is_floating(con)) { + struct sway_output *output = container_floating_find_output(con); + if (con->workspace->output != output) { + container_floating_move_to_center(con); } - } else { - container->width = container->saved_width; - container->height = container->saved_height; } + } else { + root->fullscreen_global = NULL; } - container_end_mouse_operation(container); + con->fullscreen_mode = FULLSCREEN_NONE; + container_end_mouse_operation(con); + ipc_event_window(con, "fullscreen_mode"); +} + +void container_set_fullscreen(struct sway_container *con, + enum sway_fullscreen_mode mode) { + if (con->fullscreen_mode == mode) { + return; + } - ipc_event_window(container, "fullscreen_mode"); + switch (mode) { + case FULLSCREEN_NONE: + container_fullscreen_disable(con); + break; + case FULLSCREEN_WORKSPACE: + if (root->fullscreen_global) { + container_fullscreen_disable(root->fullscreen_global); + } + if (con->workspace->fullscreen) { + container_fullscreen_disable(con->workspace->fullscreen); + } + container_fullscreen_workspace(con); + break; + case FULLSCREEN_GLOBAL: + if (root->fullscreen_global) { + container_fullscreen_disable(root->fullscreen_global); + } + if (con->fullscreen_mode == FULLSCREEN_WORKSPACE) { + container_fullscreen_disable(con); + } + container_fullscreen_global(con); + break; + } } bool container_is_floating_or_child(struct sway_container *container) { @@ -941,7 +1011,7 @@ bool container_is_floating_or_child(struct sway_container *container) { bool container_is_fullscreen_or_child(struct sway_container *container) { do { - if (container->is_fullscreen) { + if (container->fullscreen_mode) { return true; } container = container->parent; @@ -1111,12 +1181,12 @@ list_t *container_get_current_siblings(struct sway_container *container) { } void container_handle_fullscreen_reparent(struct sway_container *con) { - if (!con->is_fullscreen || !con->workspace || + if (con->fullscreen_mode != FULLSCREEN_WORKSPACE || !con->workspace || con->workspace->fullscreen == con) { return; } if (con->workspace->fullscreen) { - container_set_fullscreen(con->workspace->fullscreen, false); + container_fullscreen_disable(con->workspace->fullscreen); } con->workspace->fullscreen = con; @@ -1171,9 +1241,12 @@ void container_add_child(struct sway_container *parent, } void container_detach(struct sway_container *child) { - if (child->is_fullscreen) { + if (child->fullscreen_mode == FULLSCREEN_WORKSPACE) { child->workspace->fullscreen = NULL; } + if (child->fullscreen_mode == FULLSCREEN_GLOBAL) { + root->fullscreen_global = NULL; + } struct sway_container *old_parent = child->parent; struct sway_workspace *old_workspace = child->workspace; @@ -1387,4 +1460,3 @@ void container_raise_floating(struct sway_container *con) { node_set_dirty(&floater->workspace->node); } } - diff --git a/sway/tree/root.c b/sway/tree/root.c index 99cf91a7..476e47a3 100644 --- a/sway/tree/root.c +++ b/sway/tree/root.c @@ -101,7 +101,10 @@ void root_scratchpad_show(struct sway_container *con) { // If the current con or any of its parents are in fullscreen mode, we // first need to disable it before showing the scratchpad con. if (new_ws->fullscreen) { - container_set_fullscreen(new_ws->fullscreen, false); + container_fullscreen_disable(new_ws->fullscreen); + } + if (root->fullscreen_global) { + container_fullscreen_disable(root->fullscreen_global); } // Show the container diff --git a/sway/tree/view.c b/sway/tree/view.c index 8795e04f..561c6ef1 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -203,12 +203,18 @@ void view_autoconfigure(struct sway_view *view) { } struct sway_output *output = con->workspace->output; - if (con->is_fullscreen) { + if (con->fullscreen_mode == FULLSCREEN_WORKSPACE) { con->content_x = output->lx; con->content_y = output->ly; con->content_width = output->width; con->content_height = output->height; return; + } else if (con->fullscreen_mode == FULLSCREEN_GLOBAL) { + con->content_x = root->x; + con->content_y = root->y; + con->content_width = root->width; + con->content_height = root->height; + return; } struct sway_workspace *ws = view->container->workspace; @@ -648,7 +654,10 @@ void view_unmap(struct sway_view *view) { workspace_consider_destroy(ws); } - if (ws && !ws->node.destroying) { + if (root->fullscreen_global) { + // Container may have been a child of the root fullscreen container + arrange_root(); + } else if (ws && !ws->node.destroying) { arrange_workspace(ws); workspace_detect_urgent(ws); } @@ -1008,14 +1017,11 @@ bool view_is_visible(struct sway_view *view) { con = con->parent; } // Check view isn't hidden by another fullscreen view - if (workspace->fullscreen && - !container_is_fullscreen_or_child(view->container)) { - // However, if we're transient for the fullscreen view and we allow - // "popups" during fullscreen then it might be visible - if (!container_is_transient_for(view->container, - workspace->fullscreen)) { - return false; - } + struct sway_container *fs = root->fullscreen_global ? + root->fullscreen_global : workspace->fullscreen; + if (fs && !container_is_fullscreen_or_child(view->container) && + !container_is_transient_for(view->container, fs)) { + return false; } return true; } |