From 71d21cb2eeed1b7127e730e69be6322bde833910 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Fri, 29 Mar 2024 20:22:22 +0900 Subject: [PATCH] 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 | 19 +++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/api/wayfire/core.hpp b/src/api/wayfire/core.hpp index e6762c635..5de01dee6 100644 --- a/src/api/wayfire/core.hpp +++ b/src/api/wayfire/core.hpp @@ -317,7 +317,12 @@ enum view_to_output_flag * Adjust the view geometry for the new output and clamp it to the output geometry so it is * at an expected size and position. */ - RECONFIGURE = 1 << 0, + 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. + */ + SAME_WORKSPACE = 1 << 1, }; /** diff --git a/src/core/core.cpp b/src/core/core.cpp index 408a3c8d8..121f4bd95 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -497,10 +497,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 & wf::view_to_output_flag::RECONFIGURE; + bool reconfigure = flags & wf::view_to_output_flag::RECONFIGURE; + bool same_workspace = flags & wf::view_to_output_flag::SAME_WORKSPACE; wf::geometry_t view_g; wf::geometry_t old_output_g; wf::geometry_t new_output_g; @@ -516,11 +519,18 @@ void wf::move_view_to_output(wayfire_toplevel_view v, wf::output_t *new_output, auto ratio_y = (double)new_output_g.height / old_output_g.height; view_g.x *= ratio_x; view_g.y *= ratio_y; + + auto config = wf::get_core().output_layout->get_current_configuration(); + float old_scale = config[old_output->handle].scale; + float new_scale = config[new_output->handle].scale; + float scale = old_scale / new_scale; + view_g.width *= scale; + view_g.height *= scale; } 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); @@ -538,6 +548,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); + } } }