Merge lp:~mir-team/miral/move_workspace_content into lp:miral

Proposed by Nick Dedekind on 2017-03-01
Status: Merged
Approved by: Alan Griffiths on 2017-03-02
Approved revision: 525
Merged at revision: 524
Proposed branch: lp:~mir-team/miral/move_workspace_content
Merge into: lp:miral
Diff against target: 240 lines (+134/-0)
10 files modified
debian/libmiral2.symbols (+1/-0)
include/miral/window_manager_tools.h (+9/-0)
miral/basic_window_manager.cpp (+33/-0)
miral/basic_window_manager.h (+4/-0)
miral/symbols.map (+1/-0)
miral/window_management_trace.cpp (+8/-0)
miral/window_management_trace.h (+4/-0)
miral/window_manager_tools.cpp (+5/-0)
miral/window_manager_tools_implementation.h (+3/-0)
test/workspaces.cpp (+66/-0)
To merge this branch: bzr merge lp:~mir-team/miral/move_workspace_content
Reviewer Review Type Date Requested Status
Alan Griffiths 2017-03-01 Approve on 2017-03-02
Review via email: mp+318589@code.launchpad.net

Commit Message

Added move WindowManagerTools::move_workspace_content_to_workspace

Description of the Change

Added move WindowManagerTools::move_workspace_content_to_workspace to move all the windows from one workspace to another.

To post a comment you must log in.
524. By Nick Dedekind on 2017-03-01

merged with trunk

Alan Griffiths (alan-griffiths) wrote :

Just a nit: I see the logic is there (but not the test) for windows that already exist in the target workspace.

Can we add a test that windows in both to and from only appear once after?

review: Needs Fixing
525. By Nick Dedekind on 2017-03-02

added test for moving workspaces with pre-existing

Alan Griffiths (alan-griffiths) wrote :

Great. Thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/libmiral2.symbols'
2--- debian/libmiral2.symbols 2017-02-15 17:32:34 +0000
3+++ debian/libmiral2.symbols 2017-03-02 10:25:41 +0000
4@@ -375,6 +375,7 @@
5 (c++)"miral::WindowManagerTools::create_workspace()@MIRAL_1.3" 1.3.0
6 (c++)"miral::WindowManagerTools::add_tree_to_workspace(miral::Window const&, std::shared_ptr<miral::Workspace> const&)@MIRAL_1.3" 1.3.0
7 (c++)"miral::WindowManagerTools::remove_tree_from_workspace(miral::Window const&, std::shared_ptr<miral::Workspace> const&)@MIRAL_1.3" 1.3.0
8+ (c++)"miral::WindowManagerTools::move_workspace_content_to_workspace(std::shared_ptr<miral::Workspace> const&, std::shared_ptr<miral::Workspace> const&)@MIRAL_1.3" 1.3.0
9 (c++)"miral::WorkspacePolicy::advise_adding_to_workspace(std::shared_ptr<miral::Workspace> const&, std::vector<miral::Window, std::allocator<miral::Window> > const&)@MIRAL_1.3" 1.3.0
10 (c++)"miral::WorkspacePolicy::advise_removing_from_workspace(std::shared_ptr<miral::Workspace> const&, std::vector<miral::Window, std::allocator<miral::Window> > const&)@MIRAL_1.3" 1.3.0
11 (c++)"miral::WindowManagerTools::for_each_window_in_workspace(std::shared_ptr<miral::Workspace> const&, std::function<void (miral::Window const&)> const&)@MIRAL_1.3" 1.3.0
12
13=== modified file 'include/miral/window_manager_tools.h'
14--- include/miral/window_manager_tools.h 2017-02-14 17:11:07 +0000
15+++ include/miral/window_manager_tools.h 2017-03-02 10:25:41 +0000
16@@ -193,6 +193,15 @@
17 void remove_tree_from_workspace(Window const& window, std::shared_ptr<Workspace> const& workspace);
18
19 /**
20+ * Moves all the content from one workspace to another
21+ * @param from_workspace the workspace to move the windows from;
22+ * @param to_workspace the workspace to move the windows to;
23+ */
24+ void move_workspace_content_to_workspace(
25+ std::shared_ptr<Workspace> const& to_workspace,
26+ std::shared_ptr<Workspace> const& from_workspace);
27+
28+ /**
29 * invoke callback with each workspace containing window
30 * \warning it is unsafe to add or remove windows from workspaces from the callback during enumeration
31 * @param window
32
33=== modified file 'miral/basic_window_manager.cpp'
34--- miral/basic_window_manager.cpp 2017-02-21 15:02:23 +0000
35+++ miral/basic_window_manager.cpp 2017-03-02 10:25:41 +0000
36@@ -1951,6 +1951,39 @@
37 workspace_policy->advise_removing_from_workspace(workspace, windows_removed);
38 }
39
40+void miral::BasicWindowManager::move_workspace_content_to_workspace(
41+ std::shared_ptr<Workspace> const& to_workspace, std::shared_ptr<Workspace> const& from_workspace)
42+{
43+ std::vector<Window> windows_removed;
44+
45+ auto const iter_pair_from = workspaces_to_windows.left.equal_range(from_workspace);
46+ for (auto kv = iter_pair_from.first; kv != iter_pair_from.second;)
47+ {
48+ auto const current = kv++;
49+ windows_removed.push_back(current->second);
50+ workspaces_to_windows.left.erase(current);
51+ }
52+
53+ if (!windows_removed.empty())
54+ workspace_policy->advise_removing_from_workspace(from_workspace, windows_removed);
55+
56+ std::vector<Window> windows_added;
57+
58+ auto const iter_pair_to = workspaces_to_windows.left.equal_range(to_workspace);
59+ for (auto& w : windows_removed)
60+ {
61+ if (!std::count_if(iter_pair_to.first, iter_pair_to.second,
62+ [&w](wwbimap_t::left_value_type const& kv) { return kv.second == w; }))
63+ {
64+ workspaces_to_windows.left.insert(wwbimap_t::left_value_type{to_workspace, w});
65+ windows_added.push_back(w);
66+ }
67+ }
68+
69+ if (!windows_added.empty())
70+ workspace_policy->advise_adding_to_workspace(to_workspace, windows_added);
71+}
72+
73 void miral::BasicWindowManager::for_each_workspace_containing(
74 miral::Window const& window, std::function<void(std::shared_ptr<miral::Workspace> const&)> const& callback)
75 {
76
77=== modified file 'miral/basic_window_manager.h'
78--- miral/basic_window_manager.h 2017-02-27 12:38:27 +0000
79+++ miral/basic_window_manager.h 2017-03-02 10:25:41 +0000
80@@ -107,6 +107,10 @@
81
82 void remove_tree_from_workspace(Window const& window, std::shared_ptr<Workspace> const& workspace) override;
83
84+ void move_workspace_content_to_workspace(
85+ std::shared_ptr<Workspace> const& to_workspace,
86+ std::shared_ptr<Workspace> const& from_workspace);
87+
88 void for_each_workspace_containing(
89 Window const& window,
90 std::function<void(std::shared_ptr<Workspace> const& workspace)> const& callback) override;
91
92=== modified file 'miral/symbols.map'
93--- miral/symbols.map 2017-02-15 17:32:34 +0000
94+++ miral/symbols.map 2017-03-02 10:25:41 +0000
95@@ -376,6 +376,7 @@
96 miral::WindowManagerTools::for_each_window_in_workspace*;
97 miral::WindowManagerTools::for_each_workspace_containing*;
98 miral::WindowManagerTools::remove_tree_from_workspace*;
99+ miral::WindowManagerTools::move_workspace_content_to_workspace*;
100 miral::WorkspacePolicy::?WorkspacePolicy*;
101 miral::WorkspacePolicy::WorkspacePolicy*;
102 miral::WorkspacePolicy::advise_adding_to_workspace*;
103
104=== modified file 'miral/window_management_trace.cpp'
105--- miral/window_management_trace.cpp 2017-02-17 15:36:54 +0000
106+++ miral/window_management_trace.cpp 2017-03-02 10:25:41 +0000
107@@ -555,6 +555,14 @@
108 }
109 MIRAL_TRACE_EXCEPTION
110
111+void miral::WindowManagementTrace::move_workspace_content_to_workspace(
112+ std::shared_ptr<Workspace> const& to_workspace, std::shared_ptr<Workspace> const& from_workspace)
113+try {
114+ mir::log_info("%s to_workspace=%p, from_workspace=%p", __func__, to_workspace.get(), from_workspace.get());
115+ wrapped.move_workspace_content_to_workspace(to_workspace, from_workspace);
116+}
117+MIRAL_TRACE_EXCEPTION
118+
119 void miral::WindowManagementTrace::for_each_workspace_containing(
120 miral::Window const& window, std::function<void(std::shared_ptr<miral::Workspace> const&)> const& callback)
121 try {
122
123=== modified file 'miral/window_management_trace.h'
124--- miral/window_management_trace.h 2017-02-03 17:49:34 +0000
125+++ miral/window_management_trace.h 2017-03-02 10:25:41 +0000
126@@ -96,6 +96,10 @@
127
128 void remove_tree_from_workspace(Window const& window, std::shared_ptr<Workspace> const& workspace) override;
129
130+ void move_workspace_content_to_workspace(
131+ std::shared_ptr<Workspace> const& to_workspace,
132+ std::shared_ptr<Workspace> const& from_workspace) override;
133+
134 void for_each_workspace_containing(
135 Window const& window,
136 std::function<void(std::shared_ptr<Workspace> const& workspace)> const& callback) override;
137
138=== modified file 'miral/window_manager_tools.cpp'
139--- miral/window_manager_tools.cpp 2017-02-03 17:49:34 +0000
140+++ miral/window_manager_tools.cpp 2017-03-02 10:25:41 +0000
141@@ -112,6 +112,11 @@
142 std::shared_ptr<miral::Workspace> const& workspace)
143 { tools->remove_tree_from_workspace(window, workspace); }
144
145+void miral::WindowManagerTools::move_workspace_content_to_workspace(
146+ std::shared_ptr<Workspace> const& to_workspace,
147+ std::shared_ptr<Workspace> const& from_workspace)
148+{ tools->move_workspace_content_to_workspace(to_workspace, from_workspace); }
149+
150 void miral::WindowManagerTools::for_each_workspace_containing(
151 miral::Window const& window,
152 std::function<void(std::shared_ptr<miral::Workspace> const&)> const& callback)
153
154=== modified file 'miral/window_manager_tools_implementation.h'
155--- miral/window_manager_tools_implementation.h 2017-02-03 17:49:34 +0000
156+++ miral/window_manager_tools_implementation.h 2017-03-02 10:25:41 +0000
157@@ -73,6 +73,9 @@
158 virtual auto create_workspace() -> std::shared_ptr<Workspace> = 0;
159 virtual void add_tree_to_workspace(Window const& window, std::shared_ptr<Workspace> const& workspace) = 0;
160 virtual void remove_tree_from_workspace(Window const& window, std::shared_ptr<Workspace> const& workspace) = 0;
161+ virtual void move_workspace_content_to_workspace(
162+ std::shared_ptr<Workspace> const& to_workspace,
163+ std::shared_ptr<Workspace> const& from_workspace) = 0;
164 virtual void for_each_workspace_containing(
165 Window const& window,
166 std::function<void(std::shared_ptr<Workspace> const& workspace)> const& callback) = 0;
167
168=== modified file 'test/workspaces.cpp'
169--- test/workspaces.cpp 2017-02-14 17:11:07 +0000
170+++ test/workspaces.cpp 2017-03-02 10:25:41 +0000
171@@ -601,3 +601,69 @@
172 << "server_window(a_window): " << tools.info_for(server_window(a_window)).name();
173 });
174 }
175+
176+TEST_F(Workspaces, move_windows_from_one_workspace_to_another)
177+{
178+ auto const pre_workspace = create_workspace();
179+ auto const from_workspace = create_workspace();
180+ auto const to_workspace = create_workspace();
181+ auto const post_workspace = create_workspace();
182+
183+ create_window(a_window);
184+ create_window(another_window);
185+
186+ invoke_tools([&, this](WindowManagerTools& tools)
187+ {
188+ tools.add_tree_to_workspace(server_window(a_window), pre_workspace);
189+ tools.add_tree_to_workspace(server_window(top_level), from_workspace);
190+ tools.add_tree_to_workspace(server_window(another_window), post_workspace);
191+
192+ tools.move_workspace_content_to_workspace(to_workspace, from_workspace);
193+ });
194+
195+ EXPECT_THAT(windows_in_workspace(from_workspace).size(), Eq(0u));
196+
197+ EXPECT_THAT(workspaces_containing_window(server_window(a_window)), ElementsAre(pre_workspace));
198+ EXPECT_THAT(workspaces_containing_window(server_window(top_level)), ElementsAre(to_workspace));
199+ EXPECT_THAT(workspaces_containing_window(server_window(dialog)), ElementsAre(to_workspace));
200+ EXPECT_THAT(workspaces_containing_window(server_window(tip)), ElementsAre(to_workspace));
201+ EXPECT_THAT(workspaces_containing_window(server_window(another_window)), ElementsAre(post_workspace));
202+}
203+
204+TEST_F(Workspaces, when_moving_windows_from_one_workspace_to_another_windows_only_appear_once_in_target_workspace)
205+{
206+ auto const from_workspace = create_workspace();
207+ auto const to_workspace = create_workspace();
208+
209+ create_window(a_window);
210+ create_window(another_window);
211+
212+ invoke_tools([&, this](WindowManagerTools& tools)
213+ {
214+ tools.add_tree_to_workspace(server_window(a_window), from_workspace);
215+ tools.add_tree_to_workspace(server_window(another_window), from_workspace);
216+ tools.add_tree_to_workspace(server_window(a_window), to_workspace);
217+
218+ tools.move_workspace_content_to_workspace(to_workspace, from_workspace);
219+ });
220+
221+ EXPECT_THAT(windows_in_workspace(to_workspace), ElementsAre(server_window(a_window), server_window(another_window)));
222+}
223+
224+TEST_F(Workspaces, when_workspace_content_is_moved_the_policy_is_notified)
225+{
226+ auto const from_workspace = create_workspace();
227+ auto const to_workspace = create_workspace();
228+
229+ EXPECT_CALL(policy(), advise_removing_from_workspace(from_workspace,
230+ ElementsAre(server_window(top_level), server_window(dialog), server_window(tip))));
231+
232+ EXPECT_CALL(policy(), advise_adding_to_workspace(to_workspace,
233+ ElementsAre(server_window(top_level), server_window(dialog), server_window(tip))));
234+
235+ invoke_tools([&, this](WindowManagerTools& tools)
236+ {
237+ tools.add_tree_to_workspace(server_window(dialog), from_workspace);
238+ tools.move_workspace_content_to_workspace(to_workspace, from_workspace);
239+ });
240+}

Subscribers

People subscribed via source and target branches

to all changes: