1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
--- a/plugins/grid/grid.cpp
+++ b/plugins/grid/grid.cpp
@@ -24,8 +24,18 @@
#include <wayfire/view-transform.hpp>
#include "wayfire/plugins/ipc/ipc-activator.hpp"
#include "wayfire/signal-provider.hpp"
-
+#include <wayfire/view-helpers.hpp>
+
+namespace
+{
const std::string grid_view_id = "grid-view";
+
+class grid_scope_toggle_data_t : public wf::custom_data_t
+{
+ public:
+ std::string monitor;
+ std::string physical_policy = "physical";
+};
class wf_grid_slot_data : public wf::custom_data_t
{
@@ -63,6 +73,7 @@
wf::ipc_activator_t bindings[10];
wf::ipc_activator_t restore{"grid/restore"};
wf::ipc_activator_t zone_maximize{"grid/zone_maximize"};
+ wf::ipc_activator_t toggle_scope{"grid/toggle_scope"};
wf::ipc_activator_t use_virtual{"grid/use_virtual"}, use_physical{"grid/use_physical"},
reset_scope{"grid/reset_scope"}, next_monitor{"grid/next_monitor"};
wf::option_wrapper_t<std::string> default_scope{"core/window_scope"}, scope_rules{"core/window_scope_rules"};
@@ -262,6 +273,46 @@
use_virtual.set_handler(scope_handler("virtual"));
use_physical.set_handler(scope_handler("physical"));
reset_scope.set_handler(scope_handler("auto"));
+ toggle_scope.set_handler([this] (wf::output_t*, wayfire_view view)
+ {
+ auto top = wf::toplevel_cast(wf::find_topmost_parent(view));
+ auto wo = top ? top->get_output() : nullptr;
+ auto layout = wo ? wo->get_data<wf::output_stitch_layout_t>() : nullptr;
+ // Scope changes are valid for simpletile-owned views too. Ordinary
+ // Grid movement remains subject to can_adjust_view().
+ if (!top || !top->is_mapped() || !layout || layout->zones.empty() ||
+ !wo->can_activate_plugin(&grab_interface)) return false;
+
+ auto remembered = top->get_data_safe<grid_scope_toggle_data_t>();
+ auto policy = wf::window_scope_policy(top);
+ top->get_data_safe<wf_grid_slot_data>()->zone.clear();
+ if (policy != "virtual")
+ {
+ auto physical = wf::window_scope_zone(top);
+ if (!physical) return false;
+ remembered->monitor = physical->name;
+ remembered->physical_policy = policy;
+ wf::set_window_scope(top, "virtual");
+ } else
+ {
+ auto physical = find_zone(wo, remembered->monitor);
+ if (!physical)
+ {
+ physical = zone_for_window(top);
+ remembered->physical_policy = "physical";
+ }
+
+ if (!physical) return false;
+ // Place in the remembered zone first. Returning to the ordinary
+ // physical policy then keeps that monitor without pinning the
+ // window there, so subsequent dragging can change monitors.
+ wf::set_window_scope(top, physical->name);
+ if (remembered->physical_policy == "physical")
+ wf::set_window_scope(top, "physical");
+ }
+
+ return true;
+ });
next_monitor.set_handler([this] (wf::output_t *wo, wayfire_view view)
{
auto top = wf::toplevel_cast(view);
@@ -636,4 +687,5 @@
};
};
+}
DECLARE_WAYFIRE_PLUGIN(wayfire_grid);
--- a/metadata/grid.xml
+++ b/metadata/grid.xml
@@ -4,6 +4,11 @@
<_short>Grid</_short>
<_long>A plugin to position the windows in certain regions of the output.</_long>
<category>Window Management</category>
+ <option name="toggle_scope" type="activator">
+ <_short>Toggle physical and VIRTUAL scope</_short>
+ <_long>Switch the focused window between its physical monitor and the combined desktop. Returning to physical scope uses the remembered monitor, or the monitor containing most of the window. Works with floating, snapped and simpletile windows.</_long>
+ <default></default>
+ </option>
<option name="use_virtual" type="activator"><_short>Use VIRTUAL for this window</_short><_long>Override this window's scope to span the combined desktop.</_long><default></default></option>
<option name="use_physical" type="activator"><_short>Use physical monitor for this window</_short><_long>Override this window's scope to its current physical monitor.</_long><default></default></option>
<option name="reset_scope" type="activator"><_short>Restore application scope policy</_short><_long>Remove this window's manual scope override.</_long><default></default></option>
|