aboutsummaryrefslogtreecommitdiff
path: root/sway/tree
diff options
context:
space:
mode:
Diffstat (limited to 'sway/tree')
-rw-r--r--sway/tree/arrange.c16
-rw-r--r--sway/tree/container.c174
-rw-r--r--sway/tree/root.c5
-rw-r--r--sway/tree/view.c26
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;
}