summaryrefslogtreecommitdiff
path: root/gui-wm/wayfire/files/wayfire-0.11.0-workspace-grid-events.patch
blob: 5fff27ed42b6a5da3efbfab2d13593775d801319 (plain)
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
diff --git a/plugins/ipc-rules/ipc-events.hpp b/plugins/ipc-rules/ipc-events.hpp
index 7ad265a..c8bcbf4 100644
--- a/plugins/ipc-rules/ipc-events.hpp
+++ b/plugins/ipc-rules/ipc-events.hpp
@@ -41,6 +41,7 @@ class ipc_rules_events_methods_t : public wf::per_output_tracker_mixin_t<>
         method_repository->unregister_method("window-rules/events/watch");
         method_repository->unregister_method("window-rules/unblock-map");
         fini_output_tracking();
+        grid_watches.clear();
     }
 
     void handle_new_output(wf::output_t *output) override
@@ -55,7 +56,68 @@ class ipc_rules_events_methods_t : public wf::per_output_tracker_mixin_t<>
     }
 
     void handle_output_removed(wf::output_t *output) override
-    {}
+    {
+        grid_watches.erase(output);
+    }
+
+    // Grid signals belong to workspace sets, not outputs. Follow the currently
+    // attached set, and disconnect before an output or subscription disappears.
+    struct grid_watch_t
+    {
+        wf::signal::connection_t<wf::workspace_set_changed_signal> set_changed;
+        wf::signal::connection_t<wf::workspace_grid_changed_signal> grid_changed;
+    };
+
+    std::map<wf::output_t*, std::unique_ptr<grid_watch_t>> grid_watches;
+
+    void bind_workspace_grid(wf::output_t *output)
+    {
+        auto& watch = *grid_watches.at(output);
+        watch.grid_changed.disconnect();
+        auto wset = output->wset();
+        if (!wset)
+        {
+            return;
+        }
+
+        watch.grid_changed = [this, output, weak = std::weak_ptr<wf::workspace_set_t>(wset)]
+            (wf::workspace_grid_changed_signal *ev)
+        {
+            auto set = weak.lock();
+            if (!set || output->wset() != set)
+            {
+                return;
+            }
+
+            wf::json_t data;
+            data["event"] = "wset-grid-changed";
+            data["output"] = (int)output->get_id();
+            data["wset"] = (int)set->get_id();
+            data["previous-grid"] = wf::ipc::dimensions_to_json(ev->old_grid_size);
+            data["new-grid"] = wf::ipc::dimensions_to_json(ev->new_grid_size);
+            data["output-data"] = ipc_rules::output_to_json(output);
+            data["wset-data"] = ipc_rules::wset_to_json(set.get());
+            send_event_to_subscribes(data, "wset-grid-changed");
+        };
+        wset->connect(&watch.grid_changed);
+    }
+
+    void watch_workspace_grid(wf::output_t *output)
+    {
+        if (grid_watches.count(output))
+        {
+            return;
+        }
+
+        auto watch = std::make_unique<grid_watch_t>();
+        watch->set_changed = [this, output] (wf::workspace_set_changed_signal*)
+        {
+            bind_workspace_grid(output);
+        };
+        output->connect(&watch->set_changed);
+        grid_watches[output] = std::move(watch);
+        bind_workspace_grid(output);
+    }
 
     wf::signal::connection_t<wf::ipc_rules::detail::custom_event_signal_t> on_custom_event =
         [=] (wf::ipc_rules::detail::custom_event_signal_t *ev)
@@ -155,6 +217,10 @@ class ipc_rules_events_methods_t : public wf::per_output_tracker_mixin_t<>
         {"view-workspace-changed", get_generic_output_registration_cb(&_view_workspace)},
         {"output-wset-changed", get_generic_output_registration_cb(&on_wset_changed)},
         {"wset-workspace-changed", get_generic_output_registration_cb(&on_wset_workspace_changed)},
+        {"wset-grid-changed", {
+            .register_output = [this] (wf::output_t *output) { watch_workspace_grid(output); },
+            .unregister = [this] () { grid_watches.clear(); },
+        }},
     };
 
     struct client_watch_state_t
diff --git a/metadata/core.xml b/metadata/core.xml
--- a/metadata/core.xml
+++ b/metadata/core.xml
@@ -45,13 +45,13 @@
 		<option name="vwidth" type="int">
 			<_short>Horizontal virtual size</_short>
-			<_long>Sets the number of horizontal workspaces.  Currently, cannot be changed at runtime.</_long>
+			<_long>Sets the number of horizontal workspaces. Changes apply at runtime; the current workspace and windows on removed workspaces are kept within the remaining grid.</_long>
 			<default>3</default>
 			<min>1</min>
 		</option>
 		<option name="vheight" type="int">
 			<_short>Vertical virtual size</_short>
-			<_long>Sets the number of vertical workspaces.  Currently, cannot be changed at runtime.</_long>
+			<_long>Sets the number of vertical workspaces. Changes apply at runtime; the current workspace and windows on removed workspaces are kept within the remaining grid.</_long>
 			<default>3</default>
 			<min>1</min>
 		</option>