blob: 9689ad1ab60a7532b0a5d3f3e7a9313c1432d5a4 (
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
|
--- a/src/join-views.cpp
+++ b/src/join-views.cpp
@@ -1,3 +1,5 @@
+#include <map>
+#include <memory>
#include <wayfire/signal-definitions.hpp>
#include <wayfire/per-output-plugin.hpp>
#include <wayfire/plugins/common/shared-core-data.hpp>
@@ -5,41 +7,62 @@
class JoinViewsSingleton
{
+ /* One geometry-changed connection per mapped view, so every parent keeps
+ * positioning its children -- not just the most recently mapped view. */
+ using geometry_conn_t = wf::signal::connection_t<wf::view_geometry_changed_signal>;
+ std::map<wf::view_interface_t*, std::shared_ptr<geometry_conn_t>> geometry_conns;
+
+ void reposition_children(wayfire_toplevel_view view)
+ {
+ if (!view || !view->is_mapped())
+ {
+ return;
+ }
+
+ auto parent_geometry = view->get_pending_geometry();
+ int cx = parent_geometry.x + parent_geometry.width / 2;
+ int cy = parent_geometry.y + parent_geometry.height / 2;
+ for (auto child : view->children)
+ {
+ auto target = child->get_pending_geometry();
+ target.x = cx - target.width / 2;
+ target.y = cy - target.height / 2;
+ child->set_geometry(target);
+ }
+ }
+
public:
- wf::signal::connection_t<wf::view_geometry_changed_signal> on_geometry_changed{[=
- ] (wf::view_geometry_changed_signal *ev)
+ wf::signal::connection_t<wf::view_mapped_signal> on_view_map{[=] (wf::view_mapped_signal *ev)
{
- auto view = wf::toplevel_cast(ev->view);
- if (!view || !view->is_mapped())
+ auto view = ev->view;
+ if (!view || geometry_conns.count(view.get()))
{
return;
}
- auto parent_geometry = view->get_pending_geometry();
- int cx = parent_geometry.x + parent_geometry.width / 2;
- int cy = parent_geometry.y + parent_geometry.height / 2;
- for (auto child : view->children)
+ auto conn = std::make_shared<geometry_conn_t>(
+ [=] (wf::view_geometry_changed_signal *gev)
{
- auto target = child->get_pending_geometry();
- target.x = cx - target.width / 2;
- target.y = cy - target.height / 2;
- child->set_geometry(target);
- }
+ reposition_children(gev->view);
+ });
+ view->connect(conn.get());
+ geometry_conns[view.get()] = conn;
}
};
- wf::signal::connection_t<wf::view_mapped_signal> on_view_map{[=] (wf::view_mapped_signal *ev)
+ wf::signal::connection_t<wf::view_unmapped_signal> on_view_unmap{[=] (wf::view_unmapped_signal *ev)
{
- auto view = ev->view;
- /* Make sure only a single connection is made */
- on_geometry_changed.disconnect();
- view->connect(&on_geometry_changed);
+ if (ev->view)
+ {
+ geometry_conns.erase(ev->view.get());
+ }
}
};
void handle_new_output(wf::output_t *output)
{
output->connect(&on_view_map);
+ output->connect(&on_view_unmap);
}
JoinViewsSingleton()
|