diff options
Diffstat (limited to 'sway/tree/container.c')
-rw-r--r-- | sway/tree/container.c | 174 |
1 files changed, 123 insertions, 51 deletions
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); } } - |