Merge lp:~azzar1/unity/properly-handle-copy-dialog into lp:unity

Proposed by Andrea Azzarone
Status: Merged
Approved by: Marco Trevisan (Treviño)
Approved revision: no longer in the source branch.
Merged at revision: 4202
Proposed branch: lp:~azzar1/unity/properly-handle-copy-dialog
Merge into: lp:unity
Prerequisite: lp:~azzar1/unity/fix-blinking-fm-icon
Diff against target: 351 lines (+248/-12)
5 files modified
launcher/FileManagerLauncherIcon.cpp (+30/-0)
launcher/FileManagerLauncherIcon.h (+8/-0)
launcher/StorageLauncherIcon.cpp (+7/-12)
tests/CMakeLists.txt (+1/-0)
tests/test_file_manager_launcher_icon.cpp (+202/-0)
To merge this branch: bzr merge lp:~azzar1/unity/properly-handle-copy-dialog
Reviewer Review Type Date Requested Status
Marco Trevisan (Treviño) Approve
PS Jenkins bot continuous-integration Pending
Review via email: mp+299301@code.launchpad.net

Commit message

Properly handle the file manager copy dialog in FileManagerLauncherIcon and in StorageLauncherIcon.

To post a comment you must log in.
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Sorry for being late, but... Yeah, although I'd like to get rid of that WindowManager::Default().IsWindowMapped(app_win->window_id()) check, I know that there are multiple races involved there, so we can't probably avoid it.

Just wondering if it could happen that the mapping would happen afterwards and we'd miss a window because there's no other signal catching that (and compiz might not signal us anything)...

But things work ok with this, so let's put it in production.

review: Approve
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Ouch, there are merging issues with trunk... Please fix this.

review: Needs Fixing
Revision history for this message
Andrea Azzarone (azzar1) wrote :

> Ouch, there are merging issues with trunk... Please fix this.

Done.

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

Ok, thanks!

review: Approve
Revision history for this message
Amr Ibrahim (amribrahim1987) wrote :

The related bugs were reported against Xenial but there were not fixed there. Please push this fix to Xenial. Users are still affected in 16.04. Have a look at bug #1399077 and its duplicates.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'launcher/FileManagerLauncherIcon.cpp'
2--- launcher/FileManagerLauncherIcon.cpp 2016-07-05 13:35:56 +0000
3+++ launcher/FileManagerLauncherIcon.cpp 2016-11-07 11:49:14 +0000
4@@ -49,6 +49,11 @@
5 SetQuirk(Quirk::VISIBLE, false);
6 SkipQuirkAnimation(Quirk::VISIBLE);
7
8+ signals_conn_.Add(app_->window_opened.connect([this](ApplicationWindowPtr const& win) {
9+ signals_conn_.Add(win->monitor.changed.connect([this] (int) { UpdateStorageWindows(); }));
10+ UpdateStorageWindows();
11+ }));
12+
13 signals_conn_.Add(app_->desktop_file.changed.connect([this](std::string const& desktop_file) {
14 LOG_DEBUG(logger) << tooltip_text() << " desktop_file now " << desktop_file;
15 UpdateDesktopFile();
16@@ -134,5 +139,30 @@
17 return StorageLauncherIcon::OnShouldHighlightOnDrag(dnd_data);
18 }
19
20+bool FileManagerLauncherIcon::IsUserVisible() const
21+{
22+ return ApplicationLauncherIcon::IsUserVisible();
23+}
24+
25+WindowList FileManagerLauncherIcon::WindowsOnViewport()
26+{
27+ WindowFilterMask filter = 0;
28+ filter |= WindowFilter::MAPPED;
29+ filter |= WindowFilter::ON_CURRENT_DESKTOP;
30+ filter |= WindowFilter::ON_ALL_MONITORS;
31+
32+ return WindowedLauncherIcon::GetWindows(filter);
33+}
34+
35+WindowList FileManagerLauncherIcon::WindowsForMonitor(int monitor)
36+{
37+ WindowFilterMask filter = 0;
38+ filter |= WindowFilter::MAPPED;
39+ filter |= WindowFilter::ON_CURRENT_DESKTOP;
40+
41+ return WindowedLauncherIcon::GetWindows(filter, monitor);
42+}
43+
44+
45 } // namespace launcher
46 } // namespace unity
47
48=== modified file 'launcher/FileManagerLauncherIcon.h'
49--- launcher/FileManagerLauncherIcon.h 2015-12-09 12:02:48 +0000
50+++ launcher/FileManagerLauncherIcon.h 2016-11-07 11:49:14 +0000
51@@ -32,8 +32,16 @@
52 class FileManagerLauncherIcon : public ApplicationLauncherIcon, public StorageLauncherIcon
53 {
54 public:
55+ typedef nux::ObjectPtr<FileManagerLauncherIcon> Ptr;
56+
57 FileManagerLauncherIcon(ApplicationPtr const&, DeviceLauncherSection::Ptr const&, FileManager::Ptr const& = nullptr);
58
59+ bool IsUserVisible() const override;
60+
61+protected:
62+ WindowList WindowsOnViewport() override;
63+ WindowList WindowsForMonitor(int monitor) override;
64+
65 private:
66 WindowList GetManagedWindows() const override;
67 WindowList GetStorageWindows() const override;
68
69=== modified file 'launcher/StorageLauncherIcon.cpp'
70--- launcher/StorageLauncherIcon.cpp 2015-12-08 14:31:30 +0000
71+++ launcher/StorageLauncherIcon.cpp 2016-11-07 11:49:14 +0000
72@@ -36,7 +36,7 @@
73 bool active = false;
74 bool urgent = false;
75 bool check_visibility = (GetIconType() == IconType::APPLICATION);
76- bool visible = IsSticky();
77+ bool visible = false;
78
79 managed_windows_ = GetStorageWindows();
80 windows_connections_.Clear();
81@@ -54,13 +54,8 @@
82 if (!urgent && win->urgent())
83 urgent = true;
84
85- if (check_visibility)
86- {
87- windows_connections_.Add(win->visible.changed.connect([this] (bool) { OnWindowStateChanged(); }));
88-
89- if (!visible && win->visible())
90- visible = true;
91- }
92+ if (check_visibility && !visible)
93+ visible = true;
94 }
95
96 SetQuirk(Quirk::RUNNING, !managed_windows_.empty());
97@@ -68,7 +63,7 @@
98 SetQuirk(Quirk::URGENT, urgent);
99
100 if (check_visibility)
101- SetQuirk(Quirk::VISIBLE, visible);
102+ SetQuirk(Quirk::VISIBLE, visible || IsSticky());
103
104 EnsureWindowsLocation();
105 }
106@@ -83,7 +78,7 @@
107 bool active = false;
108 bool urgent = false;
109 bool check_visibility = (GetIconType() == IconType::APPLICATION);
110- bool visible = IsSticky();
111+ bool visible = false;
112
113 for (auto const& win : managed_windows_)
114 {
115@@ -93,7 +88,7 @@
116 if (!urgent && win->urgent())
117 urgent = true;
118
119- if (check_visibility && !visible && win->visible())
120+ if (check_visibility && !visible)
121 visible = true;
122 }
123
124@@ -101,7 +96,7 @@
125 SetQuirk(Quirk::URGENT, urgent);
126
127 if (check_visibility)
128- SetQuirk(Quirk::VISIBLE, visible);
129+ SetQuirk(Quirk::VISIBLE, visible || IsSticky());
130 }
131
132 bool StorageLauncherIcon::OnShouldHighlightOnDrag(DndData const& dnd_data)
133
134=== modified file 'tests/CMakeLists.txt'
135--- tests/CMakeLists.txt 2016-10-27 08:40:57 +0000
136+++ tests/CMakeLists.txt 2016-11-07 11:49:14 +0000
137@@ -224,6 +224,7 @@
138 test_error_preview.cpp
139 test_edge_barrier_controller.cpp
140 test_expo_launcher_icon.cpp
141+ test_file_manager_launcher_icon.cpp
142 test_filter_widgets.cpp
143 test_glib_dbus_server.cpp
144 test_gnome_session_manager.cpp
145
146=== added file 'tests/test_file_manager_launcher_icon.cpp'
147--- tests/test_file_manager_launcher_icon.cpp 1970-01-01 00:00:00 +0000
148+++ tests/test_file_manager_launcher_icon.cpp 2016-11-07 11:49:14 +0000
149@@ -0,0 +1,202 @@
150+/*
151+ * Copyright 2016 Canonical Ltd.
152+ *
153+ * This program is free software: you can redistribute it and/or modify it
154+ * under the terms of the GNU General Public License version 3, as published
155+ * by the Free Software Foundation.
156+ *
157+ * This program is distributed in the hope that it will be useful, but
158+ * WITHOUT ANY WARRANTY; without even the implied warranties of
159+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
160+ * PURPOSE. See the GNU General Public License for more details.
161+ *
162+ * You should have received a copy of the GNU General Public License
163+ * version 3 along with this program. If not, see
164+ * <http://www.gnu.org/licenses/>
165+ *
166+ * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
167+ */
168+
169+#include <gmock/gmock.h>
170+using namespace testing;
171+
172+#include "FileManagerLauncherIcon.h"
173+#include "UnityCore/DesktopUtilities.h"
174+
175+#include "test_mock_devices.h"
176+#include "test_mock_filemanager.h"
177+#include "mock-application.h"
178+
179+using namespace unity;
180+using namespace unity::launcher;
181+using namespace testmocks;
182+
183+namespace
184+{
185+
186+const std::string TRASH_URI = "trash:";
187+const std::string TRASH_PATH = "file://" + DesktopUtilities::GetUserTrashDirectory();
188+
189+struct TestFileManagerLauncherIcon : public Test
190+{
191+ TestFileManagerLauncherIcon()
192+ : app_(std::make_shared<MockApplication::Nice>())
193+ , fm_(std::make_shared<MockFileManager::Nice>())
194+ , dev_ (std::make_shared<MockDeviceLauncherSection>(2))
195+ , icon_(new FileManagerLauncherIcon(app_, dev_, fm_))
196+ {
197+ }
198+
199+ MockApplication::Ptr app_;
200+ MockFileManager::Ptr fm_;
201+ DeviceLauncherSection::Ptr dev_;
202+ FileManagerLauncherIcon::Ptr icon_;
203+};
204+
205+TEST_F(TestFileManagerLauncherIcon, IconType)
206+{
207+ EXPECT_EQ(icon_->GetIconType(), AbstractLauncherIcon::IconType::APPLICATION);
208+}
209+
210+TEST_F(TestFileManagerLauncherIcon, NoWindow)
211+{
212+ EXPECT_FALSE(icon_->IsVisible());
213+}
214+
215+TEST_F(TestFileManagerLauncherIcon, NoManagedWindow_TrashUri)
216+{
217+ EXPECT_CALL(*fm_, LocationForWindow(_)).Times(1);
218+ ON_CALL(*fm_, LocationForWindow(_)).WillByDefault(Return(TRASH_URI));
219+
220+ auto win = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
221+ app_->windows_ = { win };
222+ app_->window_opened.emit(win);
223+
224+ EXPECT_FALSE(icon_->IsVisible());
225+ EXPECT_FALSE(icon_->IsRunning());
226+}
227+
228+TEST_F(TestFileManagerLauncherIcon, NoManagedWindow_TrashPath)
229+{
230+ EXPECT_CALL(*fm_, LocationForWindow(_)).Times(1);
231+ ON_CALL(*fm_, LocationForWindow(_)).WillByDefault(Return(TRASH_PATH));
232+
233+ auto win = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
234+ app_->windows_ = { win };
235+ app_->window_opened.emit(win);
236+
237+ EXPECT_FALSE(icon_->IsVisible());
238+ EXPECT_FALSE(icon_->IsRunning());
239+}
240+
241+TEST_F(TestFileManagerLauncherIcon, NoManagedWindow_Device)
242+{
243+ auto const& device_icons = dev_->GetIcons();
244+ ASSERT_EQ(2, device_icons.size());
245+
246+ device_icons.at(0)->Activate(ActionArg());
247+
248+ EXPECT_CALL(*fm_, LocationForWindow(_)).Times(1);
249+ ON_CALL(*fm_, LocationForWindow(_)).WillByDefault(Return(device_icons.at(0)->GetVolumeUri()));
250+
251+ auto win = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
252+ app_->windows_ = { win };
253+ app_->window_opened.emit(win);
254+
255+ EXPECT_FALSE(icon_->IsVisible());
256+ EXPECT_FALSE(icon_->IsRunning());
257+}
258+
259+TEST_F(TestFileManagerLauncherIcon, ManagedWindows)
260+{
261+ EXPECT_CALL(*fm_, LocationForWindow(_)).Times(1);
262+ ON_CALL(*fm_, LocationForWindow(_)).WillByDefault(Return("/usr/bin"));
263+
264+ auto win = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
265+ app_->windows_ = { win };
266+ app_->window_opened.emit(win);
267+
268+ EXPECT_TRUE(icon_->IsVisible());
269+ EXPECT_TRUE(icon_->IsRunning());
270+}
271+
272+TEST_F(TestFileManagerLauncherIcon, ManagedWindows_EmptyLocation)
273+{
274+ EXPECT_CALL(*fm_, LocationForWindow(_)).Times(1);
275+ ON_CALL(*fm_, LocationForWindow(_)).WillByDefault(Return(""));
276+
277+ auto win = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
278+ app_->windows_ = { win };
279+ app_->window_opened.emit(win);
280+
281+ EXPECT_TRUE(icon_->IsVisible());
282+ EXPECT_TRUE(icon_->IsRunning());
283+}
284+
285+TEST_F(TestFileManagerLauncherIcon, ManagedWindows_CopyDialog)
286+{
287+ EXPECT_CALL(*fm_, LocationForWindow(_)).Times(1);
288+ ON_CALL(*fm_, LocationForWindow(_)).WillByDefault(Return(""));
289+
290+ auto win = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
291+ win->visible_ = false;
292+ app_->windows_ = { win };
293+ app_->window_opened.emit(win);
294+
295+ EXPECT_TRUE(icon_->IsVisible());
296+ EXPECT_TRUE(icon_->IsRunning());
297+}
298+
299+
300+TEST_F(TestFileManagerLauncherIcon, ManagedWindows_CopyDialogAndManagedWindow)
301+{
302+ EXPECT_CALL(*fm_, LocationForWindow(_)).Times(3);
303+ ON_CALL(*fm_, LocationForWindow(_)).WillByDefault(Return(""));
304+
305+ auto win = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
306+ app_->windows_ = { win };
307+ app_->window_opened.emit(win);
308+
309+ win = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
310+ win->visible_ = false;
311+ app_->windows_.push_back(win);
312+ app_->window_opened.emit(win);
313+
314+ EXPECT_TRUE(icon_->IsVisible());
315+ EXPECT_TRUE(icon_->IsRunning());
316+ EXPECT_EQ(2, icon_->WindowsVisibleOnMonitor(0));
317+}
318+
319+TEST_F(TestFileManagerLauncherIcon, ManagedWindows_CopyDialogAndNoManagedWindow)
320+{
321+ {
322+ InSequence s;
323+
324+ EXPECT_CALL(*fm_, LocationForWindow(_))
325+ .Times(1)
326+ .WillOnce(Return(""));
327+
328+ EXPECT_CALL(*fm_, LocationForWindow(_))
329+ .Times(1)
330+ .WillOnce(Return(""));
331+
332+ EXPECT_CALL(*fm_, LocationForWindow(_))
333+ .Times(1)
334+ .WillOnce(Return(TRASH_PATH));
335+ }
336+
337+ auto win = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
338+ app_->windows_ = { win };
339+ app_->window_opened.emit(win);
340+
341+ win = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
342+ win->visible_ = false;
343+ app_->windows_.push_back(win);
344+ app_->window_opened.emit(win);
345+
346+ EXPECT_TRUE(icon_->IsVisible());
347+ EXPECT_TRUE(icon_->IsRunning());
348+ EXPECT_EQ(1, icon_->WindowsVisibleOnMonitor(0));
349+}
350+
351+}