From 9fbe13b9be18c732b58033a57a22a299af91a170 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Wed, 18 Jul 2018 16:13:28 +1000 Subject: Implement floating_modifier and mouse operations for floating views This implements the following: * `floating_modifier` configuration directive * Drag a floating window by its title bar * Hold mod + drag a floating window from anywhere * Resize a floating view by dragging the border * Resize a floating view by holding mod and right clicking anywhere on the view * Resize a floating view and keep aspect ratio by holding shift while resizing using either method * Mouse cursor turns into resize when hovering floating border or corner --- sway/tree/layout.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sway/tree/layout.c') diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 1f898f8a..533906fa 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -562,6 +562,7 @@ void container_move(struct sway_container *container, workspace_detect_urgent(last_ws); workspace_detect_urgent(next_ws); } + container_end_mouse_operation(container); } enum sway_container_layout container_get_default_layout( -- cgit v1.2.3 From 81e8f31cc6f284b54ab206e14af7ecbc1a9ed1bb Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sun, 22 Jul 2018 14:10:40 +1000 Subject: Implement scratchpad Implements the following commands: * move scratchpad * scratchpad show * [criteria] scratchpad show Also fixes these: * Fix memory leak when executing command with criteria (use `list_free(views)` instead of `free(views)`) * Fix crash when running `move to` with no further arguments --- sway/tree/layout.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sway/tree/layout.c') diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 533906fa..af37611f 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -135,6 +135,10 @@ void container_add_child(struct sway_container *parent, list_add(parent->children, child); child->parent = parent; container_handle_fullscreen_reparent(child, old_parent); + if (old_parent) { + container_set_dirty(old_parent); + } + container_set_dirty(child); } struct sway_container *container_remove_child(struct sway_container *child) { @@ -153,6 +157,9 @@ struct sway_container *container_remove_child(struct sway_container *child) { child->parent = NULL; container_notify_subtree_changed(parent); + container_set_dirty(parent); + container_set_dirty(child); + return parent; } -- cgit v1.2.3 From 12e90fa6006b2cf17a5b5983b5a6e2e70cda58d3 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sun, 22 Jul 2018 22:28:20 +1000 Subject: Store scratchpad list in sway_root instead of server --- sway/tree/layout.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sway/tree/layout.c') diff --git a/sway/tree/layout.c b/sway/tree/layout.c index af37611f..a2be0ef3 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -42,6 +42,7 @@ void layout_init(void) { wl_list_init(&root_container.sway_root->xwayland_unmanaged); wl_list_init(&root_container.sway_root->drag_icons); wl_signal_init(&root_container.sway_root->events.new_container); + root_container.sway_root->scratchpad = create_list(); root_container.sway_root->output_layout_change.notify = output_layout_handle_change; -- cgit v1.2.3 From 24ad1c3983192b47345566fd876e26b45160d68e Mon Sep 17 00:00:00 2001 From: Pascal Pascher Date: Tue, 24 Jul 2018 22:16:06 +0200 Subject: Added meson option "enable_xwayland" (default: true) to enable/disable xwayland support --- sway/tree/layout.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sway/tree/layout.c') diff --git a/sway/tree/layout.c b/sway/tree/layout.c index a2be0ef3..91350c3f 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -39,7 +39,9 @@ void layout_init(void) { root_container.sway_root = calloc(1, sizeof(*root_container.sway_root)); root_container.sway_root->output_layout = wlr_output_layout_create(); wl_list_init(&root_container.sway_root->outputs); + #ifdef HAVE_XWAYLAND wl_list_init(&root_container.sway_root->xwayland_unmanaged); + #endif wl_list_init(&root_container.sway_root->drag_icons); wl_signal_init(&root_container.sway_root->events.new_container); root_container.sway_root->scratchpad = create_list(); -- cgit v1.2.3 From 2bf893248a94c7f70a9557aad4a8228731041eeb Mon Sep 17 00:00:00 2001 From: Pascal Pascher Date: Tue, 24 Jul 2018 23:37:41 +0200 Subject: style fixes, exclude sway/desctop/xwayland.c when enable_xwayland: false --- sway/tree/layout.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sway/tree/layout.c') diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 91350c3f..3d361ea5 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -39,9 +39,9 @@ void layout_init(void) { root_container.sway_root = calloc(1, sizeof(*root_container.sway_root)); root_container.sway_root->output_layout = wlr_output_layout_create(); wl_list_init(&root_container.sway_root->outputs); - #ifdef HAVE_XWAYLAND +#ifdef HAVE_XWAYLAND wl_list_init(&root_container.sway_root->xwayland_unmanaged); - #endif +#endif wl_list_init(&root_container.sway_root->drag_icons); wl_signal_init(&root_container.sway_root->events.new_container); root_container.sway_root->scratchpad = create_list(); -- cgit v1.2.3 From 79a45d4a4049e3b9235915cd308ed2995623f833 Mon Sep 17 00:00:00 2001 From: Pascal Pascher Date: Wed, 25 Jul 2018 12:17:10 +0200 Subject: more style fixes, included "sway/config.h" where needed --- sway/tree/layout.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sway/tree/layout.c') diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 3d361ea5..91f6accd 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -6,6 +6,7 @@ #include #include #include +#include "sway/config.h" #include "sway/debug.h" #include "sway/tree/arrange.h" #include "sway/tree/container.h" -- cgit v1.2.3 From f95cb9a7c17251c43b1d1058092e0a15d1fe8dd9 Mon Sep 17 00:00:00 2001 From: Pascal Pascher Date: Wed, 25 Jul 2018 13:32:20 +0200 Subject: reverted includes of "sway/config.h" and replaced with "config.h" from meson build --- sway/tree/layout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sway/tree/layout.c') diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 91f6accd..2b3263f8 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -6,7 +6,7 @@ #include #include #include -#include "sway/config.h" +#include "config.h" #include "sway/debug.h" #include "sway/tree/arrange.h" #include "sway/tree/container.h" -- cgit v1.2.3 From 27a20a488465468511de9b2307941ac1bc4db8bf Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Wed, 25 Jul 2018 20:56:23 +1000 Subject: Allow containers to be fullscreen --- sway/tree/layout.c | 83 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 34 deletions(-) (limited to 'sway/tree/layout.c') 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); } } -- cgit v1.2.3 From 08cfba2192f5770d975c5fe70789a81aaee4dc7e Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Thu, 26 Jul 2018 18:36:46 +1000 Subject: Allow containers to float Things worth noting: * When a fullscreen view unmaps, the check to unset fullscreen on the workspace has been moved out of view_unmap and into container_destroy, because containers can be fullscreen too * The calls to `container_reap_empty_recursive(workspace)` have been removed from `container_set_floating`. That function reaps upwards so it wouldn't do anything. I'm probably the one who originally added it... * My fix (b14bd1b0b1536039e4f46fe94515c7c44e7afc61) for the tabbed child crash has a side effect where when you close a floating container, focus is not given to the tiled container again. I've removed my fix and removed the call to `send_cursor_motion` from `seat_set_focus_warp`. We should consider calling it from somewhere earlier in the call stack. --- sway/tree/layout.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'sway/tree/layout.c') diff --git a/sway/tree/layout.c b/sway/tree/layout.c index ab5acc16..a0764a54 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -387,9 +387,11 @@ void container_move(struct sway_container *container, // If moving a fullscreen view, only consider outputs if (container->is_fullscreen) { current = container_parent(container, C_OUTPUT); - } else if (container_is_fullscreen_or_child(container)) { + } else if (container_is_fullscreen_or_child(container) || + container_is_floating_or_child(container)) { // If we've fullscreened a split container, only allow the child to move // around within the fullscreen parent. + // Same with floating a split container. struct sway_container *ws = container_parent(container, C_WORKSPACE); top = ws->sway_workspace->fullscreen; } @@ -465,6 +467,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->parent->layout == L_FLOATING) { + return; + } if (!parent->is_fullscreen && (parent->layout == L_TABBED || parent->layout == L_STACKED)) { @@ -488,10 +493,14 @@ 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->is_fullscreen && (parent->layout == L_TABBED || + } else if (!parent->is_fullscreen && + parent->parent->layout != L_FLOATING && + (parent->layout == L_TABBED || parent->layout == L_STACKED)) { move_out_of_tabs_stacks(container, current, move_dir, offs); return; + } else if (parent->parent->layout == L_FLOATING) { + return; } else { wlr_log(WLR_DEBUG, "Moving up to find a parallel container"); current = current->parent; @@ -717,10 +726,6 @@ struct sway_container *container_get_in_direction( enum movement_direction dir) { struct sway_container *parent = container->parent; - if (container_is_floating(container)) { - return NULL; - } - if (dir == MOVE_CHILD) { return seat_get_focus_inactive(seat, container); } @@ -732,7 +737,7 @@ struct sway_container *container_get_in_direction( parent = container->parent; } else { if (dir == MOVE_PARENT) { - if (parent->type == C_OUTPUT) { + if (parent->type == C_OUTPUT || container_is_floating(container)) { return NULL; } else { return parent; -- cgit v1.2.3 From 4bf253855f1946ffca5a41085b8ae3eb79ca62c4 Mon Sep 17 00:00:00 2001 From: Ian Fan Date: Wed, 18 Jul 2018 10:47:44 +0100 Subject: ipc: fix workspace::move calls argument order --- sway/tree/layout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sway/tree/layout.c') diff --git a/sway/tree/layout.c b/sway/tree/layout.c index a0764a54..b833e8e1 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -217,7 +217,7 @@ void container_move_to(struct sway_container *container, container_sort_workspaces(new_parent); seat_set_focus(seat, new_parent); workspace_output_raise_priority(container, old_parent, new_parent); - ipc_event_workspace(container, NULL, "move"); + ipc_event_workspace(NULL, container, "move"); } container_notify_subtree_changed(old_parent); container_notify_subtree_changed(new_parent); -- cgit v1.2.3 From e0e638281e193103b44105cb1689b2ec25cae7e8 Mon Sep 17 00:00:00 2001 From: Ian Fan Date: Wed, 18 Jul 2018 10:50:48 +0100 Subject: ipc: add window::move events --- sway/tree/layout.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sway/tree/layout.c') diff --git a/sway/tree/layout.c b/sway/tree/layout.c index b833e8e1..a0f9b6de 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -218,6 +218,8 @@ void container_move_to(struct sway_container *container, seat_set_focus(seat, new_parent); workspace_output_raise_priority(container, old_parent, new_parent); ipc_event_workspace(NULL, container, "move"); + } else if (container->type == C_VIEW) { + ipc_event_window(container, "move"); } container_notify_subtree_changed(old_parent); container_notify_subtree_changed(new_parent); @@ -578,6 +580,10 @@ void container_move(struct sway_container *container, container_notify_subtree_changed(old_parent); container_notify_subtree_changed(container->parent); + if (container->type == C_VIEW) { + ipc_event_window(container, "move"); + } + if (old_parent) { seat_set_focus(config->handler_context.seat, old_parent); seat_set_focus(config->handler_context.seat, container); -- cgit v1.2.3 From b2ac234569ff98de583d9e7755526cadf960f772 Mon Sep 17 00:00:00 2001 From: Ian Fan Date: Wed, 18 Jul 2018 21:52:15 +0100 Subject: ipc: fix workspace::focus event behaviour --- sway/tree/layout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sway/tree/layout.c') diff --git a/sway/tree/layout.c b/sway/tree/layout.c index a0f9b6de..9fbbccaf 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -598,7 +598,7 @@ void container_move(struct sway_container *container, next_ws = container_parent(next_ws, C_WORKSPACE); } if (last_ws && next_ws && last_ws != next_ws) { - ipc_event_workspace(last_ws, container, "focus"); + ipc_event_workspace(last_ws, next_ws, "focus"); workspace_detect_urgent(last_ws); workspace_detect_urgent(next_ws); } -- cgit v1.2.3 From 03eaf444a4a432e5712d40f93d849b51d2028b63 Mon Sep 17 00:00:00 2001 From: Ian Fan Date: Wed, 18 Jul 2018 21:55:14 +0100 Subject: ipc: prevent emitting a workspace::focus event when moving a container to a different workspace or output When a container is moved from, say, workspace 1 to workspace 2, workspace 2 is focused in order to arrange the windows before focus is moved back to workspace 1, which caused a workspace:focus event from workspace 2 to workspace 1 to be emitted. This commit inhibits that event. --- sway/tree/layout.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sway/tree/layout.c') diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 9fbbccaf..1f82e534 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -1001,13 +1001,13 @@ static void swap_focus(struct sway_container *con1, if (focus == con1 && (con2->parent->layout == L_TABBED || con2->parent->layout == L_STACKED)) { if (workspace_is_visible(ws2)) { - seat_set_focus_warp(seat, con2, false); + seat_set_focus_warp(seat, con2, false, true); } seat_set_focus(seat, ws1 != ws2 ? con2 : con1); } else if (focus == con2 && (con1->parent->layout == L_TABBED || con1->parent->layout == L_STACKED)) { if (workspace_is_visible(ws1)) { - seat_set_focus_warp(seat, con1, false); + seat_set_focus_warp(seat, con1, false, true); } seat_set_focus(seat, ws1 != ws2 ? con1 : con2); } else if (ws1 != ws2) { -- cgit v1.2.3