aboutsummaryrefslogtreecommitdiff
path: root/sway/tree
diff options
context:
space:
mode:
Diffstat (limited to 'sway/tree')
-rw-r--r--sway/tree/arrange.c18
-rw-r--r--sway/tree/container.c87
-rw-r--r--sway/tree/layout.c83
-rw-r--r--sway/tree/view.c73
4 files changed, 156 insertions, 105 deletions
diff --git a/sway/tree/arrange.c b/sway/tree/arrange.c
index 533cf71c..5452b13c 100644
--- a/sway/tree/arrange.c
+++ b/sway/tree/arrange.c
@@ -220,8 +220,22 @@ static void arrange_workspace(struct sway_container *workspace) {
container_set_dirty(workspace);
wlr_log(WLR_DEBUG, "Arranging workspace '%s' at %f, %f", workspace->name,
workspace->x, workspace->y);
- arrange_floating(workspace->sway_workspace->floating);
- arrange_children_of(workspace);
+ if (workspace->sway_workspace->fullscreen) {
+ struct sway_container *fs = workspace->sway_workspace->fullscreen;
+ fs->x = workspace->parent->x;
+ fs->y = workspace->parent->y;
+ fs->width = workspace->parent->width;
+ fs->height = workspace->parent->height;
+ if (fs->type == C_VIEW) {
+ view_autoconfigure(fs->sway_view);
+ } else {
+ arrange_children_of(fs);
+ }
+ container_set_dirty(fs);
+ } else {
+ arrange_floating(workspace->sway_workspace->floating);
+ arrange_children_of(workspace);
+ }
}
static void arrange_output(struct sway_container *output) {
diff --git a/sway/tree/container.c b/sway/tree/container.c
index 237e1a35..6ebf2653 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -1130,3 +1130,90 @@ void container_end_mouse_operation(struct sway_container *container) {
}
}
}
+
+static void set_fullscreen_iterator(struct sway_container *con, void *data) {
+ if (con->type != C_VIEW) {
+ return;
+ }
+ if (con->sway_view->impl->set_fullscreen) {
+ bool *enable = data;
+ con->sway_view->impl->set_fullscreen(con->sway_view, *enable);
+ }
+}
+
+void container_set_fullscreen(struct sway_container *container, bool enable) {
+ if (container->is_fullscreen == enable) {
+ return;
+ }
+
+ struct sway_container *workspace = container_parent(container, C_WORKSPACE);
+ if (enable && workspace->sway_workspace->fullscreen) {
+ container_set_fullscreen(workspace->sway_workspace->fullscreen, false);
+ }
+
+ container_for_each_descendant_dfs(container,
+ set_fullscreen_iterator, &enable);
+
+ container->is_fullscreen = enable;
+
+ if (enable) {
+ workspace->sway_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_container *focus, *focus_ws;
+ wl_list_for_each(seat, &input_manager->seats, link) {
+ focus = seat_get_focus(seat);
+ if (focus) {
+ focus_ws = focus;
+ if (focus_ws->type != C_WORKSPACE) {
+ focus_ws = container_parent(focus_ws, C_WORKSPACE);
+ }
+ if (focus_ws == workspace) {
+ seat_set_focus(seat, container);
+ }
+ }
+ }
+ } else {
+ workspace->sway_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;
+ } else {
+ container->width = container->saved_width;
+ container->height = container->saved_height;
+ }
+ }
+
+ container_end_mouse_operation(container);
+
+ ipc_event_window(container, "fullscreen_mode");
+}
+
+bool container_is_fullscreen_or_child(struct sway_container *container) {
+ do {
+ if (container->is_fullscreen) {
+ return true;
+ }
+ container = container->parent;
+ } while (container && container->type != C_WORKSPACE);
+
+ return false;
+}
+
+struct sway_container *container_wrap_children(struct sway_container *parent) {
+ struct sway_container *middle = container_create(C_CONTAINER);
+ middle->layout = parent->layout;
+ while (parent->children->length) {
+ struct sway_container *child = parent->children->items[0];
+ container_remove_child(child);
+ container_add_child(middle, child);
+ }
+ container_add_child(parent, middle);
+ return middle;
+}
diff --git a/sway/tree/layout.c b/sway/tree/layout.c
index 2b3263f8..ab5acc16 100644
--- a/sway/tree/layout.c
+++ b/sway/tree/layout.c
@@ -66,10 +66,9 @@ static int index_child(const struct sway_container *child) {
static void container_handle_fullscreen_reparent(struct sway_container *con,
struct sway_container *old_parent) {
- if (con->type != C_VIEW || !con->sway_view->is_fullscreen) {
+ if (!con->is_fullscreen) {
return;
}
- struct sway_view *view = con->sway_view;
struct sway_container *old_workspace = old_parent;
if (old_workspace && old_workspace->type != C_WORKSPACE) {
old_workspace = container_parent(old_workspace, C_WORKSPACE);
@@ -85,19 +84,27 @@ static void container_handle_fullscreen_reparent(struct sway_container *con,
// Mark the new workspace as fullscreen
if (new_workspace->sway_workspace->fullscreen) {
- view_set_fullscreen(new_workspace->sway_workspace->fullscreen, false);
+ container_set_fullscreen(
+ new_workspace->sway_workspace->fullscreen, false);
}
- new_workspace->sway_workspace->fullscreen = view;
- // Resize view to new output dimensions
+ new_workspace->sway_workspace->fullscreen = con;
+
+ // Resize container to new output dimensions
struct sway_container *output = new_workspace->parent;
- view->x = output->x;
- view->y = output->y;
- view->width = output->width;
- view->height = output->height;
con->x = output->x;
con->y = output->y;
con->width = output->width;
con->height = output->height;
+
+ if (con->type == C_VIEW) {
+ struct sway_view *view = con->sway_view;
+ view->x = output->x;
+ view->y = output->y;
+ view->width = output->width;
+ view->height = output->height;
+ } else {
+ arrange_windows(new_workspace);
+ }
}
void container_insert_child(struct sway_container *parent,
@@ -146,7 +153,7 @@ void container_add_child(struct sway_container *parent,
}
struct sway_container *container_remove_child(struct sway_container *child) {
- if (child->type == C_VIEW && child->sway_view->is_fullscreen) {
+ if (child->is_fullscreen) {
struct sway_container *workspace = container_parent(child, C_WORKSPACE);
workspace->sway_workspace->fullscreen = NULL;
}
@@ -229,10 +236,10 @@ void container_move_to(struct sway_container *container,
if (focus_ws->type != C_WORKSPACE) {
focus_ws = container_parent(focus_ws, C_WORKSPACE);
}
- seat_set_focus(seat,
- new_workspace->sway_workspace->fullscreen->swayc);
- if (focus_ws != new_workspace) {
- seat_set_focus(seat, focus);
+ if (focus_ws == new_workspace) {
+ struct sway_container *new_focus = seat_get_focus_inactive(seat,
+ new_workspace->sway_workspace->fullscreen);
+ seat_set_focus(seat, new_focus);
}
}
}
@@ -375,10 +382,16 @@ void container_move(struct sway_container *container,
struct sway_container *sibling = NULL;
struct sway_container *current = container;
struct sway_container *parent = current->parent;
+ struct sway_container *top = &root_container;
// If moving a fullscreen view, only consider outputs
- if (container->type == C_VIEW && container->sway_view->is_fullscreen) {
+ if (container->is_fullscreen) {
current = container_parent(container, C_OUTPUT);
+ } else if (container_is_fullscreen_or_child(container)) {
+ // If we've fullscreened a split container, only allow the child to move
+ // around within the fullscreen parent.
+ struct sway_container *ws = container_parent(container, C_WORKSPACE);
+ top = ws->sway_workspace->fullscreen;
}
struct sway_container *new_parent = container_flatten(parent);
@@ -388,7 +401,7 @@ void container_move(struct sway_container *container,
}
while (!sibling) {
- if (current->type == C_ROOT) {
+ if (current == top) {
return;
}
@@ -452,8 +465,9 @@ void container_move(struct sway_container *container,
if ((index == parent->children->length - 1 && offs > 0)
|| (index == 0 && offs < 0)) {
if (current->parent == container->parent) {
- if (parent->layout == L_TABBED
- || parent->layout == L_STACKED) {
+ if (!parent->is_fullscreen &&
+ (parent->layout == L_TABBED ||
+ parent->layout == L_STACKED)) {
move_out_of_tabs_stacks(container, current,
move_dir, offs);
return;
@@ -474,8 +488,8 @@ void container_move(struct sway_container *container,
sibling = parent->children->items[index + offs];
wlr_log(WLR_DEBUG, "Selecting sibling id:%zd", sibling->id);
}
- } else if (parent->layout == L_TABBED
- || parent->layout == L_STACKED) {
+ } else if (!parent->is_fullscreen && (parent->layout == L_TABBED ||
+ parent->layout == L_STACKED)) {
move_out_of_tabs_stacks(container, current, move_dir, offs);
return;
} else {
@@ -707,16 +721,16 @@ struct sway_container *container_get_in_direction(
return NULL;
}
- if (container->type == C_VIEW && container->sway_view->is_fullscreen) {
- if (dir == MOVE_PARENT || dir == MOVE_CHILD) {
+ if (dir == MOVE_CHILD) {
+ return seat_get_focus_inactive(seat, container);
+ }
+ if (container->is_fullscreen) {
+ if (dir == MOVE_PARENT) {
return NULL;
}
container = container_parent(container, C_OUTPUT);
parent = container->parent;
} else {
- if (dir == MOVE_CHILD) {
- return seat_get_focus_inactive(seat, container);
- }
if (dir == MOVE_PARENT) {
if (parent->type == C_OUTPUT) {
return NULL;
@@ -767,7 +781,8 @@ struct sway_container *container_get_in_direction(
}
sway_assert(next_workspace, "Next container has no workspace");
if (next_workspace->sway_workspace->fullscreen) {
- return next_workspace->sway_workspace->fullscreen->swayc;
+ return seat_get_focus_inactive(seat,
+ next_workspace->sway_workspace->fullscreen);
}
if (next->children && next->children->length) {
// TODO consider floating children as well
@@ -1014,13 +1029,13 @@ void container_swap(struct sway_container *con1, struct sway_container *con2) {
wlr_log(WLR_DEBUG, "Swapping containers %zu and %zu", con1->id, con2->id);
- int fs1 = con1->type == C_VIEW && con1->sway_view->is_fullscreen;
- int fs2 = con2->type == C_VIEW && con2->sway_view->is_fullscreen;
+ int fs1 = con1->is_fullscreen;
+ int fs2 = con2->is_fullscreen;
if (fs1) {
- view_set_fullscreen(con1->sway_view, false);
+ container_set_fullscreen(con1, false);
}
if (fs2) {
- view_set_fullscreen(con2->sway_view, false);
+ container_set_fullscreen(con2, false);
}
struct sway_seat *seat = input_manager_get_default_seat(input_manager);
@@ -1053,10 +1068,10 @@ void container_swap(struct sway_container *con1, struct sway_container *con2) {
prev_workspace_name = stored_prev_name;
}
- if (fs1 && con2->type == C_VIEW) {
- view_set_fullscreen(con2->sway_view, true);
+ if (fs1) {
+ container_set_fullscreen(con2, true);
}
- if (fs2 && con1->type == C_VIEW) {
- view_set_fullscreen(con1->sway_view, true);
+ if (fs2) {
+ container_set_fullscreen(con1, true);
}
}
diff --git a/sway/tree/view.c b/sway/tree/view.c
index beeb8144..82c3ad4a 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -225,7 +225,7 @@ void view_autoconfigure(struct sway_view *view) {
struct sway_container *output = container_parent(view->swayc, C_OUTPUT);
- if (view->is_fullscreen) {
+ if (view->swayc->is_fullscreen) {
view->x = output->x;
view->y = output->y;
view->width = output->width;
@@ -233,10 +233,6 @@ void view_autoconfigure(struct sway_view *view) {
return;
}
- if (container_is_floating(view->swayc)) {
- return;
- }
-
struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
int other_views = 0;
@@ -349,68 +345,6 @@ void view_set_tiled(struct sway_view *view, bool tiled) {
}
}
-void view_set_fullscreen(struct sway_view *view, bool fullscreen) {
- if (view->is_fullscreen == fullscreen) {
- return;
- }
-
- struct sway_container *workspace =
- container_parent(view->swayc, C_WORKSPACE);
-
- if (view->impl->set_fullscreen) {
- view->impl->set_fullscreen(view, fullscreen);
- }
-
- view->is_fullscreen = fullscreen;
-
- if (fullscreen) {
- if (workspace->sway_workspace->fullscreen) {
- view_set_fullscreen(workspace->sway_workspace->fullscreen, false);
- }
- workspace->sway_workspace->fullscreen = view;
- view->saved_x = view->x;
- view->saved_y = view->y;
- view->saved_width = view->width;
- view->saved_height = view->height;
- view->swayc->saved_x = view->swayc->x;
- view->swayc->saved_y = view->swayc->y;
- view->swayc->saved_width = view->swayc->width;
- view->swayc->saved_height = view->swayc->height;
-
- struct sway_seat *seat;
- struct sway_container *focus, *focus_ws;
- wl_list_for_each(seat, &input_manager->seats, link) {
- focus = seat_get_focus(seat);
- if (focus) {
- focus_ws = focus;
- if (focus && focus_ws->type != C_WORKSPACE) {
- focus_ws = container_parent(focus_ws, C_WORKSPACE);
- }
- seat_set_focus(seat, view->swayc);
- if (focus_ws != workspace) {
- seat_set_focus(seat, focus);
- }
- }
- }
- } else {
- workspace->sway_workspace->fullscreen = NULL;
- if (container_is_floating(view->swayc)) {
- view->x = view->saved_x;
- view->y = view->saved_y;
- view->width = view->saved_width;
- view->height = view->saved_height;
- container_set_geometry_from_floating_view(view->swayc);
- } else {
- view->swayc->width = view->swayc->saved_width;
- view->swayc->height = view->swayc->saved_height;
- }
- }
-
- container_end_mouse_operation(view->swayc);
-
- ipc_event_window(view->swayc, "fullscreen_mode");
-}
-
void view_close(struct sway_view *view) {
if (view->impl->close) {
view->impl->close(view);
@@ -680,7 +614,7 @@ void view_unmap(struct sway_view *view) {
struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
struct sway_container *parent;
- if (view->is_fullscreen) {
+ if (view->swayc->is_fullscreen) {
ws->sway_workspace->fullscreen = NULL;
parent = container_destroy(view->swayc);
@@ -1133,7 +1067,8 @@ bool view_is_visible(struct sway_view *view) {
container = container->parent;
}
// Check view isn't hidden by another fullscreen view
- if (workspace->sway_workspace->fullscreen && !view->is_fullscreen) {
+ if (workspace->sway_workspace->fullscreen &&
+ !container_is_fullscreen_or_child(view->swayc)) {
return false;
}
// Check the workspace is visible