From 8559fb73ee47d22cdde350790df2839be0b2d231 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Thu, 4 Apr 2024 21:21:13 +0900 Subject: [PATCH 1/4] core: add move_view_to_output overload that takes flags --- src/api/wayfire/core.hpp | 29 +++++++++++++++++++++++++---- src/core/core.cpp | 3 ++- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/api/wayfire/core.hpp b/src/api/wayfire/core.hpp index 7f6c9c5b5..7f38fa0c5 100644 --- a/src/api/wayfire/core.hpp +++ b/src/api/wayfire/core.hpp @@ -309,11 +309,32 @@ class compositor_core_t : public wf::object_base_t, public signal::provider_t }; /** - * Change the view's output to new_output. If the reconfigure flag is - * set, it will adjust the view geometry for the new output and clamp - * it to the output geometry so it is at an expected size and position. + * Flags for move_view_to_output. */ -void move_view_to_output(wayfire_toplevel_view v, wf::output_t *new_output, bool reconfigure); +enum +{ + /** + * Adjust the view geometry for the new output and clamp it to the output geometry so it is + * at an expected size and position. + */ + VIEW_TO_OUTPUT_FLAG_RECONFIGURE = 1 << 0, +}; + +/** + * Change the view's output to new_output. + */ +void move_view_to_output(wayfire_toplevel_view v, wf::output_t *new_output, unsigned flags); + +/** + * Change the view's output to new_output. Equivalent to calling the move_view_to_output with + * the RECONFIGURE flag set to the specified value and no other flags set. + */ +inline void move_view_to_output(wayfire_toplevel_view v, wf::output_t *new_output, + bool reconfigure) +{ + unsigned flags = reconfigure ? VIEW_TO_OUTPUT_FLAG_RECONFIGURE : 0; + move_view_to_output(v, new_output, flags); +} /** * Start a move of a view to a new workspace set (and thus potentially to a new output). diff --git a/src/core/core.cpp b/src/core/core.cpp index 84baa8a78..0f525cc0f 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -492,13 +492,14 @@ void wf::start_move_view_to_wset(wayfire_toplevel_view v, std::shared_ptradd_view(v); } -void wf::move_view_to_output(wayfire_toplevel_view v, wf::output_t *new_output, bool reconfigure) +void wf::move_view_to_output(wayfire_toplevel_view v, wf::output_t *new_output, unsigned flags) { auto old_output = v->get_output(); auto old_wset = v->get_wset(); uint32_t edges; bool fullscreen; + bool reconfigure = flags & VIEW_TO_OUTPUT_FLAG_RECONFIGURE; wf::geometry_t view_g; wf::geometry_t old_output_g; wf::geometry_t new_output_g; From b99cb040c43a1f571654bc076003d3f2f707d44c Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Fri, 29 Mar 2024 20:22:22 +0900 Subject: [PATCH 2/4] core: transfer views to same workspace as on destroyed output Currently, when an output is destroyed, views are transferred to the new output in roughly the same position as they were on the old output, but they are all transferred to the first workspace. This is annoying: if they were not on the first workspace, then the user must have moved them, and after they're transferred, the user must will have to move them agein. Instead, in the (common?) case that the old and the new output have the same number of workspaces, move each view to the same workspace it was on before. --- src/api/wayfire/core.hpp | 7 ++++++- src/core/core.cpp | 12 ++++++++++-- src/core/output-layout.cpp | 3 ++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/api/wayfire/core.hpp b/src/api/wayfire/core.hpp index 7f38fa0c5..3519266b2 100644 --- a/src/api/wayfire/core.hpp +++ b/src/api/wayfire/core.hpp @@ -317,7 +317,12 @@ enum * Adjust the view geometry for the new output and clamp it to the output geometry so it is * at an expected size and position. */ - VIEW_TO_OUTPUT_FLAG_RECONFIGURE = 1 << 0, + VIEW_TO_OUTPUT_FLAG_RECONFIGURE = 1 << 0, + /** + * If the new output has the same workspace geometry as the current output, move the view to the + * same workspace as it is currently on. + */ + VIEW_TO_OUTPUT_FLAG_SAME_WORKSPACE = 1 << 1, }; /** diff --git a/src/core/core.cpp b/src/core/core.cpp index 0f525cc0f..906328bb0 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -496,10 +496,13 @@ void wf::move_view_to_output(wayfire_toplevel_view v, wf::output_t *new_output, { auto old_output = v->get_output(); auto old_wset = v->get_wset(); + auto old_ws = old_wset->get_view_main_workspace(v); + auto new_wset = new_output->wset(); uint32_t edges; bool fullscreen; - bool reconfigure = flags & VIEW_TO_OUTPUT_FLAG_RECONFIGURE; + bool reconfigure = flags & VIEW_TO_OUTPUT_FLAG_RECONFIGURE; + bool same_workspace = flags & VIEW_TO_OUTPUT_FLAG_SAME_WORKSPACE; wf::geometry_t view_g; wf::geometry_t old_output_g; wf::geometry_t new_output_g; @@ -519,7 +522,7 @@ void wf::move_view_to_output(wayfire_toplevel_view v, wf::output_t *new_output, assert(new_output); - start_move_view_to_wset(v, new_output->wset()); + start_move_view_to_wset(v, new_wset); if (new_output == wf::get_core().seat->get_active_output()) { wf::get_core().seat->focus_view(v); @@ -537,6 +540,11 @@ void wf::move_view_to_output(wayfire_toplevel_view v, wf::output_t *new_output, { auto new_g = wf::clamp(view_g, new_output->workarea->get_workarea()); v->set_geometry(new_g); + if (same_workspace && + (old_wset->get_workspace_grid_size() == new_wset->get_workspace_grid_size())) + { + v->get_wset()->move_to_workspace(v, old_ws); + } } } diff --git a/src/core/output-layout.cpp b/src/core/output-layout.cpp index c2a4741cd..3bb297897 100644 --- a/src/core/output-layout.cpp +++ b/src/core/output-layout.cpp @@ -165,7 +165,8 @@ void transfer_views(wf::output_t *from, wf::output_t *to) auto views = from->wset()->get_views(WSET_SORT_STACKING); for (auto& view : views) { - move_view_to_output(view, to, true); + unsigned flags = VIEW_TO_OUTPUT_FLAG_RECONFIGURE | VIEW_TO_OUTPUT_FLAG_SAME_WORKSPACE; + move_view_to_output(view, to, flags); } } From 74c21813effb0f50c8a3f2c75163015e45142620 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Sun, 7 Apr 2024 14:58:17 +0900 Subject: [PATCH 3/4] output-layout: make NOOP-1 output larger. When outputs are unplugged, views are temporarily moved to the NOOP-1 output. Because this output is currently only 1280x720, windoes moved to it get moved and cropped to match its small screen size. Make the output 4k so windows stay where they are unless the user is running a display larger than 4k. This does not affect the WL-x outputs used when running in headless mode, which continue to be created as 1280x720 by wlroots code (attempt_headless_backend). --- src/core/output-layout.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/output-layout.cpp b/src/core/output-layout.cpp index 3bb297897..7b675f67f 100644 --- a/src/core/output-layout.cpp +++ b/src/core/output-layout.cpp @@ -1120,7 +1120,9 @@ class output_layout_t::impl if (!noop_output) { - auto handle = wlr_headless_add_output(noop_backend, 1280, 720); + // NOOP output should be at least as large as actual screen sizes. Otherwise, when + // when windows are temporarily mapped to it, they will be moved/cropped to match it. + auto handle = wlr_headless_add_output(noop_backend, 3840, 2160); handle->data = WF_NOOP_OUTPUT_MAGIC; strcpy(handle->name, "NOOP-1"); From c97972f7dd17b904da6e19bddd6bdc2d15271719 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Fri, 12 Apr 2024 12:39:03 +0900 Subject: [PATCH 4/4] output-layout: keep active workspace when destroying output Currently, when destroying the current output, core focuses the next output (if any) but does not switch to the same workspace that the user was previously using. Switch to the same workspace so the user can pick up where they left off. --- src/core/output-layout.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/core/output-layout.cpp b/src/core/output-layout.cpp index 7b675f67f..410f8f0b1 100644 --- a/src/core/output-layout.cpp +++ b/src/core/output-layout.cpp @@ -547,7 +547,13 @@ struct output_layout_output_t /* It doesn't make sense to transfer to another output if we're * going to shut down the compositor */ - transfer_views(wo, shutdown ? nullptr : get_core().seat->get_active_output()); + wf::output_t *new_output = shutdown ? nullptr : get_core().seat->get_active_output(); + transfer_views(wo, new_output); + if (new_output && + (wo->wset()->get_workspace_grid_size() == new_output->wset()->get_workspace_grid_size())) + { + new_output->wset()->set_workspace(wo->wset()->get_current_workspace()); + } wf::output_removed_signal data2; data2.output = wo;