Merge lp:~alan-griffiths/miral/fix-1658085 into lp:miral

Proposed by Alan Griffiths
Status: Merged
Approved by: Daniel d'Andrada
Approved revision: 493
Merged at revision: 492
Proposed branch: lp:~alan-griffiths/miral/fix-1658085
Merge into: lp:miral
Diff against target: 169 lines (+105/-2)
5 files modified
debian/changelog (+1/-0)
miral/basic_window_manager.cpp (+6/-1)
test/CMakeLists.txt (+1/-0)
test/raise_tree.cpp (+95/-0)
test/test_window_manager_tools.h (+2/-1)
To merge this branch: bzr merge lp:~alan-griffiths/miral/fix-1658085
Reviewer Review Type Date Requested Status
Daniel d'Andrada (community) Approve
Review via email: mp+315232@code.launchpad.net

Commit message

[libmiral] top-level window is now raised along with its child (LP: #1658085)

To post a comment you must log in.
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

In the case described in the bug report, I get two raises:

- First one containing kate's top-level window and its "Open File" dialog.
- Then another containing juts the "Open File" dialog.

I should receive only the first raise notification. The second one is superfluous.

I suppose it should be easy for you to check if a window is already top level and thus avoid raising it?

review: Needs Fixing
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> In the case described in the bug report, I get two raises:
>
> - First one containing kate's top-level window and its "Open File" dialog.
> - Then another containing juts the "Open File" dialog.
>
> I should receive only the first raise notification. The second one is
> superfluous.
>
> I suppose it should be easy for you to check if a window is already top level
> and thus avoid raising it?

In this simple case, yes. But consider:

A parents B,C

Z order is DCBA

Click on B

I expect Z order to be: BCAD

Which transformation, AFAICS can only be expressed with multiple notifications (both to the Mir model and to the Qt model). Vis:

advise_raise (ABC)
advise_raise (B)

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

On 20/01/2017 15:53, Alan Griffiths wrote:
>> In the case described in the bug report, I get two raises:
>>
>> - First one containing kate's top-level window and its "Open File" dialog.
>> - Then another containing juts the "Open File" dialog.
>>
>> I should receive only the first raise notification. The second one is
>> superfluous.
>>
>> I suppose it should be easy for you to check if a window is already top level
>> and thus avoid raising it?
> In this simple case, yes. But consider:
>
> A parents B,C
>
> Z order is DCBA
>
> Click on B
>
> I expect Z order to be: BCAD
>
> Which transformation, AFAICS can only be expressed with multiple notifications (both to the Mir model and to the Qt model). Vis:
>
> advise_raise (ABC)
> advise_raise (B)

Indeed. But the question remains: Could you check if a raise is indeed
needed (ie, window in question not top-level) before issuing the raise?
A noop raise notification will bother the upper layers of the stack for
nothing.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

To do that I would need to change the Mir interface to determine if a "raise" is a NoOp. I don't have direct access to the model.

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

> To do that I would need to change the Mir interface to determine if a "raise"
> is a NoOp. I don't have direct access to the model.

Fair enough.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2017-01-20 11:17:36 +0000
3+++ debian/changelog 2017-01-20 15:10:26 +0000
4@@ -8,6 +8,7 @@
5 enums.
6 . Logging of exceptions added to --window-management-trace
7 - Bugs fixed:
8+ . top-level window is not raised along with its child (LP: #1658085)
9
10 -- Alan Griffiths <alan.griffiths@canonical.com> Wed, 14 Dec 2016 16:31:08 +0000
11
12
13=== modified file 'miral/basic_window_manager.cpp'
14--- miral/basic_window_manager.cpp 2017-01-20 11:17:36 +0000
15+++ miral/basic_window_manager.cpp 2017-01-20 15:10:26 +0000
16@@ -496,6 +496,11 @@
17
18 void miral::BasicWindowManager::raise_tree(Window const& root)
19 {
20+ auto const& info = info_for(root);
21+
22+ if (auto parent = info.parent())
23+ raise_tree(parent);
24+
25 std::vector<Window> windows;
26
27 std::function<void(WindowInfo const& info)> const add_children =
28@@ -509,7 +514,7 @@
29 };
30
31 windows.push_back(root);
32- add_children(info_for(root));
33+ add_children(info);
34
35 policy->advise_raise(windows);
36 focus_controller->raise({begin(windows), end(windows)});
37
38=== modified file 'test/CMakeLists.txt'
39--- test/CMakeLists.txt 2017-01-18 10:14:04 +0000
40+++ test/CMakeLists.txt 2017-01-20 15:10:26 +0000
41@@ -54,6 +54,7 @@
42 test_window_manager_tools.h
43 display_reconfiguration.cpp
44 active_window.cpp
45+ raise_tree.cpp
46 )
47
48 target_link_libraries(miral-test
49
50=== added file 'test/raise_tree.cpp'
51--- test/raise_tree.cpp 1970-01-01 00:00:00 +0000
52+++ test/raise_tree.cpp 2017-01-20 15:10:26 +0000
53@@ -0,0 +1,95 @@
54+/*
55+ * Copyright © 2017 Canonical Ltd.
56+ *
57+ * This program is free software: you can redistribute it and/or modify it
58+ * under the terms of the GNU General Public License version 3,
59+ * as published by the Free Software Foundation.
60+ *
61+ * This program is distributed in the hope that it will be useful,
62+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
63+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
64+ * GNU General Public License for more details.
65+ *
66+ * You should have received a copy of the GNU General Public License
67+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
68+ *
69+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
70+ */
71+
72+#include "test_window_manager_tools.h"
73+
74+using namespace miral;
75+using namespace testing;
76+namespace mt = mir::test;
77+
78+namespace
79+{
80+X const display_left{0};
81+Y const display_top{0};
82+Width const display_width{640};
83+Height const display_height{480};
84+
85+Rectangle const display_area{{display_left, display_top}, {display_width, display_height}};
86+
87+struct RaiseTree : TestWindowManagerTools
88+{
89+ Size const initial_parent_size{600, 400};
90+ Size const initial_child_size{300, 300};
91+ Rectangle const rectangle_away_from_rhs{{20, 20}, {20, 20}};
92+ Rectangle const rectangle_near_rhs{{590, 20}, {10, 20}};
93+ Rectangle const rectangle_away_from_bottom{{20, 20}, {20, 20}};
94+ Rectangle const rectangle_near_bottom{{20, 380}, {20, 20}};
95+ Rectangle const rectangle_near_both_sides{{0, 20}, {600, 20}};
96+ Rectangle const rectangle_near_both_sides_and_bottom{{0, 380}, {600, 20}};
97+ Rectangle const rectangle_near_all_sides{{0, 20}, {600, 380}};
98+ Rectangle const rectangle_near_both_bottom_right{{400, 380}, {200, 20}};
99+
100+ Window parent;
101+ Window child;
102+ Window another_window;
103+
104+ WindowSpecification modification;
105+
106+ void SetUp() override
107+ {
108+ basic_window_manager.add_display(display_area);
109+
110+ mir::scene::SurfaceCreationParameters creation_parameters;
111+ basic_window_manager.add_session(session);
112+
113+ EXPECT_CALL(*window_manager_policy, advise_new_window(_))
114+ .WillOnce(Invoke([this](WindowInfo const& window_info){ parent = window_info.window(); }))
115+ .WillOnce(Invoke([this](WindowInfo const& window_info){ child = window_info.window(); }))
116+ .WillOnce(Invoke([this](WindowInfo const& window_info){ another_window = window_info.window(); }));
117+
118+ creation_parameters.size = initial_parent_size;
119+ basic_window_manager.add_surface(session, creation_parameters, &create_surface);
120+
121+ creation_parameters.type = mir_window_type_menu;
122+ creation_parameters.parent = parent;
123+ creation_parameters.size = initial_child_size;
124+ basic_window_manager.add_surface(session, creation_parameters, &create_surface);
125+
126+ creation_parameters.type = mir_window_type_normal;
127+ creation_parameters.parent.reset();
128+ creation_parameters.size = display_area.size;
129+ basic_window_manager.add_surface(session, creation_parameters, &create_surface);
130+
131+ // Clear the expectations used to capture parent & child
132+ Mock::VerifyAndClearExpectations(window_manager_policy);
133+ }
134+};
135+}
136+
137+TEST_F(RaiseTree, when_parent_is_raised_child_is_raised)
138+{
139+ EXPECT_CALL(*window_manager_policy, advise_raise(ElementsAre(parent, child)));
140+ basic_window_manager.raise_tree(parent);
141+}
142+
143+TEST_F(RaiseTree, when_child_is_raised_parent_is_raised)
144+{
145+ EXPECT_CALL(*window_manager_policy, advise_raise(ElementsAre(parent, child)));
146+ EXPECT_CALL(*window_manager_policy, advise_raise(ElementsAre(child)));
147+ basic_window_manager.raise_tree(child);
148+}
149
150=== modified file 'test/test_window_manager_tools.h'
151--- test/test_window_manager_tools.h 2017-01-18 14:56:39 +0000
152+++ test/test_window_manager_tools.h 2017-01-20 15:10:26 +0000
153@@ -140,6 +140,7 @@
154 MOCK_METHOD1(advise_new_window, void (miral::WindowInfo const& window_info));
155 MOCK_METHOD2(advise_move_to, void(miral::WindowInfo const& window_info, mir::geometry::Point top_left));
156 MOCK_METHOD2(advise_resize, void(miral::WindowInfo const& window_info, mir::geometry::Size const& new_size));
157+ MOCK_METHOD1(advise_raise, void(std::vector<miral::Window> const&));
158 };
159
160 struct TestWindowManagerTools : testing::Test
161@@ -158,7 +159,7 @@
162 mir::test::fake_shared(persistent_surface_store),
163 [this](miral::WindowManagerTools const& tools) -> std::unique_ptr<miral::WindowManagementPolicy>
164 {
165- auto policy = std::make_unique<MockWindowManagerPolicy>(tools);
166+ auto policy = std::make_unique<testing::NiceMock<MockWindowManagerPolicy>>(tools);
167 window_manager_policy = policy.get();
168 window_manager_tools = tools;
169 return std::move(policy);

Subscribers

People subscribed via source and target branches