Merge lp:~3v1n0/unity/launcher-filemanager-integration into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Andrea Azzarone
Approved revision: no longer in the source branch.
Merged at revision: 4069
Proposed branch: lp:~3v1n0/unity/launcher-filemanager-integration
Merge into: lp:unity
Prerequisite: lp:~3v1n0/unity/switcher-dynamic-model
Diff against target: 5139 lines (+2020/-1214)
47 files modified
UnityCore/DesktopUtilities.cpp (+5/-0)
UnityCore/DesktopUtilities.h (+1/-0)
UnityCore/GLibDBusProxy.cpp (+3/-3)
debian/control (+1/-0)
launcher/AbstractLauncherIcon.h (+11/-7)
launcher/ApplicationLauncherIcon.cpp (+118/-685)
launcher/ApplicationLauncherIcon.h (+51/-94)
launcher/CMakeLists.txt (+3/-0)
launcher/DesktopLauncherIcon.cpp (+5/-0)
launcher/DesktopLauncherIcon.h (+1/-0)
launcher/DeviceLauncherSection.h (+4/-0)
launcher/FileManagerLauncherIcon.cpp (+128/-0)
launcher/FileManagerLauncherIcon.h (+52/-0)
launcher/Launcher.cpp (+2/-9)
launcher/LauncherController.cpp (+24/-7)
launcher/LauncherControllerPrivate.h (+2/-1)
launcher/LauncherIcon.cpp (+12/-2)
launcher/LauncherIcon.h (+14/-10)
launcher/MockLauncherIcon.h (+38/-28)
launcher/SoftwareCenterLauncherIcon.cpp (+2/-1)
launcher/StorageLauncherIcon.cpp (+119/-0)
launcher/StorageLauncherIcon.h (+55/-0)
launcher/SwitcherController.cpp (+4/-7)
launcher/SwitcherModel.cpp (+2/-11)
launcher/SwitcherView.cpp (+1/-1)
launcher/TrashLauncherIcon.cpp (+49/-21)
launcher/TrashLauncherIcon.h (+5/-7)
launcher/VolumeLauncherIcon.cpp (+101/-63)
launcher/VolumeLauncherIcon.h (+7/-5)
launcher/WindowedLauncherIcon.cpp (+618/-0)
launcher/WindowedLauncherIcon.h (+100/-0)
tests/CMakeLists.txt (+1/-0)
tests/mock-application.h (+12/-2)
tests/test_application_launcher_icon.cpp (+15/-30)
tests/test_launcher_controller.cpp (+53/-48)
tests/test_mock_filemanager.h (+8/-5)
tests/test_software_center_launcher_icon.cpp (+3/-2)
tests/test_switcher_controller.h (+6/-16)
tests/test_switcher_controller_class.cpp (+9/-18)
tests/test_trash_launcher_icon.cpp (+72/-2)
tests/test_volume_launcher_icon.cpp (+169/-27)
unity-shared/ApplicationManager.h (+3/-0)
unity-shared/BamfApplicationManager.cpp (+8/-4)
unity-shared/BamfApplicationManager.h (+3/-1)
unity-shared/FileManager.h (+5/-6)
unity-shared/GnomeFileManager.cpp (+113/-86)
unity-shared/GnomeFileManager.h (+2/-5)
To merge this branch: bzr merge lp:~3v1n0/unity/launcher-filemanager-integration
Reviewer Review Type Date Requested Status
Andrea Azzarone (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+279812@code.launchpad.net

Commit message

Launcher: add FileManager, Trash and Volume icons integration

Now the launcher will link each nautilus window to the related volume or trash
icon, while the Nautilus launcher icon will only be active if the file manager is
browsing other locations.
It's now possible to manage sub-windows from the parent icon like it happens for
every other application (so even spreading them or select from QL)

The windows management logic has been moved to WindowedLauncherIcon which is a
base class of ApplicationLauncherIcon, and StorageLauncherIcon.
VolumeLauncherIcon and TrashLauncherIcon are now based on StorageLauncherIcon
which connects to the FileManager to get the windows for a given location.

FileManagerLauncherIcon is now special and is both an ApplicationLauncherIcon
and a StorageLauncherIcon, and uses the parent application only for some tasks.

Lots of random code cleanup included too.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Andrea Azzarone (azzar1) wrote :

+1. Code looks good and I tested it in the last two weeks and everything works fine.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'UnityCore/DesktopUtilities.cpp'
--- UnityCore/DesktopUtilities.cpp 2014-09-23 23:35:43 +0000
+++ UnityCore/DesktopUtilities.cpp 2016-02-09 10:44:04 +0000
@@ -90,6 +90,11 @@
90 return "";90 return "";
91}91}
9292
93std::string DesktopUtilities::GetUserTrashDirectory()
94{
95 return GetUserDataDirectory().append(G_DIR_SEPARATOR_S "Trash" G_DIR_SEPARATOR_S "files" G_DIR_SEPARATOR_S);
96}
97
93std::vector<std::string> DesktopUtilities::GetSystemDataDirectories()98std::vector<std::string> DesktopUtilities::GetSystemDataDirectories()
94{99{
95 const char* const* system_dirs = g_get_system_data_dirs();100 const char* const* system_dirs = g_get_system_data_dirs();
96101
=== modified file 'UnityCore/DesktopUtilities.h'
--- UnityCore/DesktopUtilities.h 2014-08-26 22:59:57 +0000
+++ UnityCore/DesktopUtilities.h 2016-02-09 10:44:04 +0000
@@ -33,6 +33,7 @@
33 static std::string GetUserCacheDirectory();33 static std::string GetUserCacheDirectory();
34 static std::string GetUserRuntimeDirectory();34 static std::string GetUserRuntimeDirectory();
35 static std::string GetUserConfigDirectory();35 static std::string GetUserConfigDirectory();
36 static std::string GetUserTrashDirectory();
36 static std::vector<std::string> GetSystemDataDirectories();37 static std::vector<std::string> GetSystemDataDirectories();
37 static std::vector<std::string> GetDataDirectories();38 static std::vector<std::string> GetDataDirectories();
3839
3940
=== modified file 'UnityCore/GLibDBusProxy.cpp'
--- UnityCore/GLibDBusProxy.cpp 2015-09-30 16:32:38 +0000
+++ UnityCore/GLibDBusProxy.cpp 2016-02-09 10:44:04 +0000
@@ -301,7 +301,7 @@
301 }301 }
302 }302 }
303303
304 g_variant_iter_free (iter);304 g_variant_iter_free(iter);
305 }305 }
306306
307 for (const gchar *property_name = *invalidated; property_name; property_name = *(++invalidated))307 for (const gchar *property_name = *invalidated; property_name; property_name = *(++invalidated))
@@ -624,7 +624,7 @@
624 [] (GObject *source, GAsyncResult *res, gpointer user_data) {624 [] (GObject *source, GAsyncResult *res, gpointer user_data) {
625 glib::Error err;625 glib::Error err;
626 std::unique_ptr<ReplyCallback> callback(static_cast<ReplyCallback*>(user_data));626 std::unique_ptr<ReplyCallback> callback(static_cast<ReplyCallback*>(user_data));
627 Variant result(g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), res, &err));627 Variant result(g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), res, &err), StealRef());
628628
629 if (err)629 if (err)
630 {630 {
@@ -660,7 +660,7 @@
660 nullptr, G_DBUS_CALL_FLAGS_NONE, -1, pimpl->cancellable_,660 nullptr, G_DBUS_CALL_FLAGS_NONE, -1, pimpl->cancellable_,
661 [] (GObject *source, GAsyncResult *res, gpointer user_data) {661 [] (GObject *source, GAsyncResult *res, gpointer user_data) {
662 glib::Error err;662 glib::Error err;
663 Variant result(g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), res, &err));663 Variant result(g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), res, &err), StealRef());
664 if (err)664 if (err)
665 {665 {
666 LOG_ERROR(logger) << "Impossible to set property: " << err;666 LOG_ERROR(logger) << "Impossible to set property: " << err;
667667
=== modified file 'debian/control'
--- debian/control 2016-02-08 20:34:08 +0000
+++ debian/control 2016-02-09 10:44:04 +0000
@@ -83,6 +83,7 @@
83Provides: indicator-renderer83Provides: indicator-renderer
84Recommends: unity-control-center,84Recommends: unity-control-center,
85 ${unity-default-masterscopes}85 ${unity-default-masterscopes}
86 nautilus,
86 indicator-appmenu (>= 15.02.0),87 indicator-appmenu (>= 15.02.0),
87 indicator-application,88 indicator-application,
88 indicator-sound,89 indicator-sound,
8990
=== modified file 'launcher/AbstractLauncherIcon.h'
--- launcher/AbstractLauncherIcon.h 2015-11-02 18:08:08 +0000
+++ launcher/AbstractLauncherIcon.h 2016-02-09 10:44:04 +0000
@@ -174,13 +174,17 @@
174174
175 virtual WindowList Windows() = 0;175 virtual WindowList Windows() = 0;
176176
177 virtual std::vector<Window> WindowsForMonitor(int monitor) = 0;177 virtual WindowList WindowsForMonitor(int monitor) = 0;
178178
179 virtual std::vector<Window> WindowsOnViewport() = 0;179 virtual WindowList WindowsOnViewport() = 0;
180180
181 virtual const bool WindowVisibleOnMonitor(int monitor) = 0;181 virtual bool WindowVisibleOnMonitor(int monitor) const = 0;
182182
183 virtual const bool WindowVisibleOnViewport() = 0;183 virtual bool WindowVisibleOnViewport() const = 0;
184
185 virtual size_t WindowsVisibleOnMonitor(int monitor) const = 0;
186
187 virtual size_t WindowsVisibleOnViewport() const = 0;
184188
185 virtual float PresentUrgency() = 0;189 virtual float PresentUrgency() = 0;
186190
187191
=== modified file 'launcher/ApplicationLauncherIcon.cpp'
--- launcher/ApplicationLauncherIcon.cpp 2015-12-11 12:45:28 +0000
+++ launcher/ApplicationLauncherIcon.cpp 2016-02-09 10:44:04 +0000
@@ -1,6 +1,6 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*2/*
3 * Copyright (C) 2010-2012 Canonical Ltd3 * Copyright (C) 2010-2015 Canonical Ltd
4 *4 *
5 * This program is free software: you can redistribute it and/or modify5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as6 * it under the terms of the GNU General Public License version 3 as
@@ -19,10 +19,8 @@
19 */19 */
2020
21#include "config.h"21#include "config.h"
22#include <boost/algorithm/string.hpp>
2322
24#include <Nux/Nux.h>23#include <Nux/Nux.h>
25#include <Nux/BaseWindow.h>
26#include <NuxCore/Logger.h>24#include <NuxCore/Logger.h>
2725
28#include <UnityCore/GLibWrapper.h>26#include <UnityCore/GLibWrapper.h>
@@ -30,12 +28,7 @@
3028
31#include "ApplicationLauncherIcon.h"29#include "ApplicationLauncherIcon.h"
32#include "FavoriteStore.h"30#include "FavoriteStore.h"
33#include "MultiMonitor.h"
34#include "unity-shared/DesktopApplicationManager.h"31#include "unity-shared/DesktopApplicationManager.h"
35#include "unity-shared/GnomeFileManager.h"
36#include "unity-shared/UBusWrapper.h"
37#include "unity-shared/UBusMessages.h"
38#include "unity-shared/UScreen.h"
3932
40#include <glib/gi18n-lib.h>33#include <glib/gi18n-lib.h>
41#include <gio/gdesktopappinfo.h>34#include <gio/gdesktopappinfo.h>
@@ -44,15 +37,13 @@
44{37{
45namespace launcher38namespace launcher
46{39{
40namespace
41{
47DECLARE_LOGGER(logger, "unity.launcher.icon.application");42DECLARE_LOGGER(logger, "unity.launcher.icon.application");
48namespace43
49{44// We use the "application-" prefix since the manager is protected, to avoid name clash
50// We use the "bamf-" prefix since the manager is protected, to avoid name clash45const std::string ICON_REMOVE_TIMEOUT = "application-icon-remove";
51const std::string ICON_REMOVE_TIMEOUT = "bamf-icon-remove";
52const std::string ICON_DND_OVER_TIMEOUT = "bamf-icon-dnd-over";
53const std::string DEFAULT_ICON = "application-default-icon";46const std::string DEFAULT_ICON = "application-default-icon";
54const int MAXIMUM_QUICKLIST_WIDTH = 300;
55const int COMPIZ_SCALE_DND_SPREAD = 1 << 7;
5647
57enum MenuItemType48enum MenuItemType
58{49{
@@ -67,10 +58,8 @@
67NUX_IMPLEMENT_OBJECT_TYPE(ApplicationLauncherIcon);58NUX_IMPLEMENT_OBJECT_TYPE(ApplicationLauncherIcon);
6859
69ApplicationLauncherIcon::ApplicationLauncherIcon(ApplicationPtr const& app)60ApplicationLauncherIcon::ApplicationLauncherIcon(ApplicationPtr const& app)
70 : SimpleLauncherIcon(IconType::APPLICATION)61 : WindowedLauncherIcon(IconType::APPLICATION)
71 , _startup_notification_timestamp(0)62 , startup_notification_timestamp_(0)
72 , _last_scroll_timestamp(0)
73 , _progressive_scroll(0)
74 , use_custom_bg_color_(false)63 , use_custom_bg_color_(false)
75 , bg_color_(nux::color::White)64 , bg_color_(nux::color::White)
76{65{
@@ -83,13 +72,6 @@
83 << ", running: " << (app->running() ? "yes" : "no");72 << ", running: " << (app->running() ? "yes" : "no");
8473
85 SetApplication(app);74 SetApplication(app);
86
87 WindowManager& wm = WindowManager::Default();
88 wm.window_minimized.connect(sigc::mem_fun(this, &ApplicationLauncherIcon::OnWindowMinimized));
89 wm.screen_viewport_switch_ended.connect(sigc::mem_fun(this, &ApplicationLauncherIcon::EnsureWindowState));
90 wm.terminate_expo.connect(sigc::mem_fun(this, &ApplicationLauncherIcon::EnsureWindowState));
91 UScreen::GetDefault()->changed.connect(sigc::hide(sigc::hide(sigc::mem_fun(this, &ApplicationLauncherIcon::EnsureWindowsLocation))));
92
93 EnsureWindowsLocation();75 EnsureWindowsLocation();
94}76}
9577
@@ -157,23 +139,19 @@
157 signals_conn_.Add(app_->window_opened.connect([this](ApplicationWindowPtr const& win) {139 signals_conn_.Add(app_->window_opened.connect([this](ApplicationWindowPtr const& win) {
158 signals_conn_.Add(win->monitor.changed.connect([this] (int) { EnsureWindowsLocation(); }));140 signals_conn_.Add(win->monitor.changed.connect([this] (int) { EnsureWindowsLocation(); }));
159 EnsureWindowsLocation();141 EnsureWindowsLocation();
160
161 if (WindowManager::Default().IsScaleActiveForGroup() && IsActive())
162 Spread(true, 0, false);
163 }));142 }));
164143
165 auto ensure_win_location_cb = sigc::hide(sigc::mem_fun(this, &ApplicationLauncherIcon::EnsureWindowsLocation));144 signals_conn_.Add(app_->window_closed.connect([this] (ApplicationWindowPtr const&) { EnsureWindowsLocation(); }));
166 signals_conn_.Add(app_->window_closed.connect(ensure_win_location_cb));
167145
168 for (auto& win : app_->GetWindows())146 for (auto& win : app_->GetWindows())
169 signals_conn_.Add(win->monitor.changed.connect(ensure_win_location_cb));147 signals_conn_.Add(win->monitor.changed.connect([this] (int) { EnsureWindowsLocation(); }));
170148
171 signals_conn_.Add(app_->urgent.changed.connect([this](bool const& urgent) {149 signals_conn_.Add(app_->urgent.changed.connect([this](bool urgent) {
172 LOG_DEBUG(logger) << tooltip_text() << " urgent now " << (urgent ? "true" : "false");150 LOG_DEBUG(logger) << tooltip_text() << " urgent now " << (urgent ? "true" : "false");
173 SetQuirk(Quirk::URGENT, urgent);151 SetQuirk(Quirk::URGENT, urgent);
174 }));152 }));
175153
176 signals_conn_.Add(app_->active.changed.connect([this](bool const& active) {154 signals_conn_.Add(app_->active.changed.connect([this](bool active) {
177 LOG_DEBUG(logger) << tooltip_text() << " active now " << (active ? "true" : "false");155 LOG_DEBUG(logger) << tooltip_text() << " active now " << (active ? "true" : "false");
178 SetQuirk(Quirk::ACTIVE, active);156 SetQuirk(Quirk::ACTIVE, active);
179 }));157 }));
@@ -185,8 +163,8 @@
185163
186 signals_conn_.Add(app_->title.changed.connect([this](std::string const& name) {164 signals_conn_.Add(app_->title.changed.connect([this](std::string const& name) {
187 LOG_DEBUG(logger) << tooltip_text() << " name now " << name;165 LOG_DEBUG(logger) << tooltip_text() << " name now " << name;
188 if (_menu_items.size() == MenuItemType::SIZE)166 if (menu_items_.size() == MenuItemType::SIZE)
189 _menu_items[MenuItemType::APP_NAME] = nullptr;167 menu_items_[MenuItemType::APP_NAME] = nullptr;
190 tooltip_text = name;168 tooltip_text = name;
191 }));169 }));
192170
@@ -195,7 +173,7 @@
195 icon_name = (icon.empty() ? DEFAULT_ICON : icon);173 icon_name = (icon.empty() ? DEFAULT_ICON : icon);
196 }));174 }));
197175
198 signals_conn_.Add(app_->running.changed.connect([this](bool const& running) {176 signals_conn_.Add(app_->running.changed.connect([this](bool running) {
199 LOG_DEBUG(logger) << tooltip_text() << " running now " << (running ? "true" : "false");177 LOG_DEBUG(logger) << tooltip_text() << " running now " << (running ? "true" : "false");
200 SetQuirk(Quirk::RUNNING, running);178 SetQuirk(Quirk::RUNNING, running);
201179
@@ -208,35 +186,47 @@
208 }186 }
209 }));187 }));
210188
211 signals_conn_.Add(app_->visible.changed.connect([this](bool const& visible) {189 signals_conn_.Add(app_->visible.changed.connect([this](bool visible) {
212 SetQuirk(Quirk::VISIBLE, IsSticky() ? true : visible);190 SetQuirk(Quirk::VISIBLE, IsSticky() ? true : visible);
213 }));191 }));
214192
215 signals_conn_.Add(app_->closed.connect([this]() {193 signals_conn_.Add(app_->closed.connect([this] {
216 if (!IsSticky())194 LOG_DEBUG(logger) << tooltip_text() << " closed";
217 {195 OnApplicationClosed();
218 SetQuirk(Quirk::VISIBLE, false);
219 HideTooltip();
220
221 /* Use a timeout to remove the icon, this avoids
222 * that we remove an application that is going
223 * to be reopened soon. So applications that
224 * have a splash screen won't be removed from
225 * the launcher while the splash is closed and
226 * a new window is opened. */
227 _source_manager.AddTimeoutSeconds(1, [this] {
228 Remove();
229 return false;
230 }, ICON_REMOVE_TIMEOUT);
231 }
232 }));196 }));
233}197}
234198
199WindowList ApplicationLauncherIcon::GetManagedWindows() const
200{
201 return app_ ? app_->GetWindows() : WindowList();
202}
203
204void ApplicationLauncherIcon::OnApplicationClosed()
205{
206 if (IsSticky())
207 return;
208
209 SetQuirk(Quirk::VISIBLE, false);
210 HideTooltip();
211
212 /* Use a timeout to remove the icon, this avoids
213 * that we remove an application that is going
214 * to be reopened soon. So applications that
215 * have a splash screen won't be removed from
216 * the launcher while the splash is closed and
217 * a new window is opened. */
218 _source_manager.AddTimeoutSeconds(1, [this] {
219 Remove();
220 return false;
221 }, ICON_REMOVE_TIMEOUT);
222}
223
224// Move to WindowedLauncherIcon?!
235bool ApplicationLauncherIcon::GetQuirk(AbstractLauncherIcon::Quirk quirk, int monitor) const225bool ApplicationLauncherIcon::GetQuirk(AbstractLauncherIcon::Quirk quirk, int monitor) const
236{226{
237 if (quirk == Quirk::ACTIVE)227 if (quirk == Quirk::ACTIVE)
238 {228 {
239 if (!SimpleLauncherIcon::GetQuirk(Quirk::ACTIVE, monitor))229 if (!WindowedLauncherIcon::GetQuirk(Quirk::ACTIVE, monitor))
240 return false;230 return false;
241231
242 if (app_->type() == AppType::WEBAPP)232 if (app_->type() == AppType::WEBAPP)
@@ -248,304 +238,35 @@
248 return app_->OwnsWindow(WindowManager::Default().GetActiveWindow());238 return app_->OwnsWindow(WindowManager::Default().GetActiveWindow());
249 }239 }
250240
251 return SimpleLauncherIcon::GetQuirk(quirk, monitor);241 return WindowedLauncherIcon::GetQuirk(quirk, monitor);
252}242}
253243
254void ApplicationLauncherIcon::Remove()244void ApplicationLauncherIcon::Remove()
255{245{
256 LogUnityEvent(ApplicationEventType::LEAVE);246 LogUnityEvent(ApplicationEventType::LEAVE);
257 UnsetApplication();247 UnsetApplication();
258 SimpleLauncherIcon::Remove();248 WindowedLauncherIcon::Remove();
259}249}
260250
261bool ApplicationLauncherIcon::IsSticky() const251bool ApplicationLauncherIcon::IsSticky() const
262{252{
263 if (app_)253 if (app_)
264 return app_->sticky() && SimpleLauncherIcon::IsSticky();254 return app_->sticky() && WindowedLauncherIcon::IsSticky();
265255
266 return false;256 return false;
267}257}
268258
269bool ApplicationLauncherIcon::IsActive() const259bool ApplicationLauncherIcon::IsUserVisible() const
270{260{
271 return GetQuirk(Quirk::ACTIVE);261 return app_ ? app_->visible() : false;
272}
273
274bool ApplicationLauncherIcon::IsRunning() const
275{
276 return GetQuirk(Quirk::RUNNING);
277}
278
279bool ApplicationLauncherIcon::IsUrgent() const
280{
281 return GetQuirk(Quirk::URGENT);
282}
283
284void ApplicationLauncherIcon::ActivateLauncherIcon(ActionArg arg)
285{
286 SimpleLauncherIcon::ActivateLauncherIcon(arg);
287 WindowManager& wm = WindowManager::Default();
288
289 // This is a little awkward as the target is only set from the switcher.
290 if (arg.target)
291 {
292 // thumper: should we Raise too? should the WM raise?
293 wm.Activate(arg.target);
294 return;
295 }
296
297 bool scale_was_active = wm.IsScaleActive();
298 bool active = IsActive();
299 bool user_visible = IsRunning();
300 /* We should check each child to see if there is
301 * an unmapped (!= minimized) window around and
302 * if so force "Focus" behaviour */
303
304 if (arg.source != ActionArg::Source::SWITCHER)
305 {
306 user_visible = app_->visible();
307
308 if (active)
309 {
310 bool any_visible = false;
311 bool any_mapped = false;
312 bool any_on_top = false;
313 bool any_on_monitor = (arg.monitor < 0);
314 int active_monitor = arg.monitor;
315
316 for (auto const& window : app_->GetWindows())
317 {
318 Window xid = window->window_id();
319
320 if (!any_visible && wm.IsWindowOnCurrentDesktop(xid))
321 {
322 any_visible = true;
323 }
324
325 if (!any_mapped && wm.IsWindowMapped(xid))
326 {
327 any_mapped = true;
328 }
329
330 if (!any_on_top && wm.IsWindowOnTop(xid))
331 {
332 any_on_top = true;
333 }
334
335 if (!any_on_monitor && window->monitor() == arg.monitor &&
336 wm.IsWindowMapped(xid) && wm.IsWindowVisible(xid))
337 {
338 any_on_monitor = true;
339 }
340
341 if (window->active())
342 {
343 active_monitor = window->monitor();
344 }
345 }
346
347 if (!any_visible || !any_mapped || !any_on_top)
348 active = false;
349
350 if (any_on_monitor && arg.monitor >= 0 && active_monitor != arg.monitor)
351 active = false;
352 }
353
354 if (user_visible && IsSticky() && IsFileManager())
355 {
356 // See bug #753938
357 unsigned minimum_windows = 0;
358 auto const& file_manager = GnomeFileManager::Get();
359
360 if (file_manager->IsTrashOpened())
361 ++minimum_windows;
362
363 if (file_manager->IsDeviceOpened())
364 ++minimum_windows;
365
366 if (minimum_windows > 0)
367 {
368 if (file_manager->OpenedLocations().size() == minimum_windows &&
369 GetWindows(WindowFilter::USER_VISIBLE|WindowFilter::MAPPED).size() == minimum_windows)
370 {
371 user_visible = false;
372 }
373 }
374 }
375 }
376
377 /* Behaviour:
378 * 1) Nothing running, or nothing visible -> launch application
379 * 2) Running and active -> spread application
380 * 3) Running and not active -> focus application
381 * 4) Spread is active and different icon pressed -> change spread
382 * 5) Spread is active -> Spread de-activated, and fall through
383 */
384
385 if (!IsRunning() || (IsRunning() && !user_visible)) // #1 above
386 {
387 if (GetQuirk(Quirk::STARTING, arg.monitor))
388 return;
389
390 wm.TerminateScale();
391 SetQuirk(Quirk::STARTING, true, arg.monitor);
392 OpenInstanceLauncherIcon(arg.timestamp);
393 }
394 else // app is running
395 {
396 if (active)
397 {
398 if (scale_was_active) // #5 above
399 {
400 wm.TerminateScale();
401
402 if (minimize_window_on_click())
403 {
404 for (auto const& win : GetWindows(WindowFilter::ON_CURRENT_DESKTOP))
405 wm.Minimize(win->window_id());
406 }
407 else
408 {
409 Focus(arg);
410 }
411 }
412 else // #2 above
413 {
414 if (arg.source != ActionArg::Source::SWITCHER)
415 {
416 bool minimized = false;
417
418 if (minimize_window_on_click())
419 {
420 WindowList const& windows = GetWindows(WindowFilter::ON_CURRENT_DESKTOP);
421
422 if (windows.size() == 1)
423 {
424 wm.Minimize(windows[0]->window_id());
425 minimized = true;
426 }
427 }
428
429 if (!minimized)
430 {
431 Spread(true, 0, false);
432 }
433 }
434 }
435 }
436 else
437 {
438 if (scale_was_active) // #4 above
439 {
440 if (GetWindows(WindowFilter::ON_CURRENT_DESKTOP).size() <= 1)
441 wm.TerminateScale();
442
443 Focus(arg);
444
445 if (arg.source != ActionArg::Source::SWITCHER)
446 Spread(true, 0, false);
447 }
448 else // #3 above
449 {
450 Focus(arg);
451 }
452 }
453 }
454}
455
456WindowList ApplicationLauncherIcon::GetWindows(WindowFilterMask filter, int monitor)
457{
458 WindowManager& wm = WindowManager::Default();
459 WindowList results;
460
461 monitor = (filter & WindowFilter::ON_ALL_MONITORS) ? -1 : monitor;
462 bool mapped = (filter & WindowFilter::MAPPED);
463 bool user_visible = (filter & WindowFilter::USER_VISIBLE);
464 bool current_desktop = (filter & WindowFilter::ON_CURRENT_DESKTOP);
465
466 for (auto& window : app_->GetWindows())
467 {
468 if ((monitor >= 0 && window->monitor() == monitor) || monitor < 0)
469 {
470 if ((user_visible && window->visible()) || !user_visible)
471 {
472 Window xid = window->window_id();
473
474 if ((mapped && wm.IsWindowMapped(xid)) || !mapped)
475 {
476 if ((current_desktop && wm.IsWindowOnCurrentDesktop(xid)) || !current_desktop)
477 {
478 results.push_back(window);
479 }
480 }
481 }
482 }
483 }
484
485 return results;
486}
487
488WindowList ApplicationLauncherIcon::Windows()
489{
490 return GetWindows(WindowFilter::MAPPED|WindowFilter::ON_ALL_MONITORS);
491}
492
493std::vector<Window> ApplicationLauncherIcon::WindowsOnViewport()
494{
495 WindowFilterMask filter = 0;
496 filter |= WindowFilter::MAPPED;
497 filter |= WindowFilter::USER_VISIBLE;
498 filter |= WindowFilter::ON_CURRENT_DESKTOP;
499 filter |= WindowFilter::ON_ALL_MONITORS;
500
501 std::vector<Window> windows;
502 for (auto& window : GetWindows(filter))
503 {
504 windows.push_back(window->window_id());
505 }
506 return windows;
507}
508
509std::vector<Window> ApplicationLauncherIcon::WindowsForMonitor(int monitor)
510{
511 WindowFilterMask filter = 0;
512 filter |= WindowFilter::MAPPED;
513 filter |= WindowFilter::USER_VISIBLE;
514 filter |= WindowFilter::ON_CURRENT_DESKTOP;
515
516 std::vector<Window> windows;
517 for (auto& window : GetWindows(filter, monitor))
518 {
519 windows.push_back(window->window_id());
520 }
521 return windows;
522}
523
524void ApplicationLauncherIcon::OnWindowMinimized(guint32 xid)
525{
526 for (auto const& window: app_->GetWindows())
527 {
528 if (xid == window->window_id())
529 {
530 int monitor = GetCenterForMonitor(window->monitor()).first;
531
532 if (monitor >= 0)
533 {
534 Present(0.5f, 600, monitor);
535 FullyAnimateQuirkDelayed(300, Quirk::SHIMMER, monitor);
536 }
537
538 break;
539 }
540 }
541}262}
542263
543void ApplicationLauncherIcon::UpdateDesktopFile()264void ApplicationLauncherIcon::UpdateDesktopFile()
544{265{
545 std::string const& filename = app_->desktop_file();266 std::string const& filename = app_->desktop_file();
546267
547 if (_desktop_file_monitor)268 if (desktop_file_monitor_)
548 _gsignals.Disconnect(_desktop_file_monitor, "changed");269 glib_signals_.Disconnect(desktop_file_monitor_, "changed");
549270
550 auto old_uri = RemoteUri();271 auto old_uri = RemoteUri();
551 UpdateRemoteUri();272 UpdateRemoteUri();
@@ -559,11 +280,11 @@
559 // we can remove ourself from the launcher and when it's changed280 // we can remove ourself from the launcher and when it's changed
560 // we can update the quicklist.281 // we can update the quicklist.
561 glib::Object<GFile> desktop_file(g_file_new_for_path(filename.c_str()));282 glib::Object<GFile> desktop_file(g_file_new_for_path(filename.c_str()));
562 _desktop_file_monitor = g_file_monitor_file(desktop_file, G_FILE_MONITOR_NONE,283 desktop_file_monitor_ = g_file_monitor_file(desktop_file, G_FILE_MONITOR_NONE,
563 nullptr, nullptr);284 nullptr, nullptr);
564 g_file_monitor_set_rate_limit(_desktop_file_monitor, 2000);285 g_file_monitor_set_rate_limit(desktop_file_monitor_, 2000);
565286
566 _gsignals.Add<void, GFileMonitor*, GFile*, GFile*, GFileMonitorEvent>(_desktop_file_monitor, "changed",287 glib_signals_.Add<void, GFileMonitor*, GFile*, GFile*, GFileMonitorEvent>(desktop_file_monitor_, "changed",
567 [this, desktop_file] (GFileMonitor*, GFile*, GFile*, GFileMonitorEvent event_type) {288 [this, desktop_file] (GFileMonitor*, GFile*, GFile*, GFileMonitorEvent event_type) {
568 switch (event_type)289 switch (event_type)
569 {290 {
@@ -600,7 +321,7 @@
600 bool update_saved_uri = (!filename.empty() && app_->sticky());321 bool update_saved_uri = (!filename.empty() && app_->sticky());
601322
602 if (update_saved_uri)323 if (update_saved_uri)
603 SimpleLauncherIcon::UnStick();324 WindowedLauncherIcon::UnStick();
604325
605 uri_changed.emit(new_uri);326 uri_changed.emit(new_uri);
606327
@@ -614,22 +335,6 @@
614 return app_->desktop_file();335 return app_->desktop_file();
615}336}
616337
617void ApplicationLauncherIcon::AddProperties(debug::IntrospectionData& introspection)
618{
619 SimpleLauncherIcon::AddProperties(introspection);
620
621 std::vector<Window> xids;
622 for (auto const& window : GetWindows())
623 xids.push_back(window->window_id());
624
625 introspection
626 .add("desktop_file", DesktopFile())
627 .add("desktop_id", app_->desktop_id())
628 .add("xids", glib::Variant::FromVector(xids))
629 .add("sticky", IsSticky())
630 .add("startup_notification_timestamp", _startup_notification_timestamp);
631}
632
633void ApplicationLauncherIcon::OpenInstanceWithUris(std::set<std::string> const& uris, Time timestamp)338void ApplicationLauncherIcon::OpenInstanceWithUris(std::set<std::string> const& uris, Time timestamp)
634{339{
635 glib::Error error;340 glib::Error error;
@@ -639,9 +344,9 @@
639 GdkDisplay* display = gdk_display_get_default();344 GdkDisplay* display = gdk_display_get_default();
640 glib::Object<GdkAppLaunchContext> app_launch_context(gdk_display_get_app_launch_context(display));345 glib::Object<GdkAppLaunchContext> app_launch_context(gdk_display_get_app_launch_context(display));
641346
642 _startup_notification_timestamp = timestamp;347 startup_notification_timestamp_ = timestamp;
643 if (_startup_notification_timestamp > 0)348 if (startup_notification_timestamp_ > 0)
644 gdk_app_launch_context_set_timestamp(app_launch_context, _startup_notification_timestamp);349 gdk_app_launch_context_set_timestamp(app_launch_context, startup_notification_timestamp_);
645350
646 if (g_app_info_supports_uris(appInfo))351 if (g_app_info_supports_uris(appInfo))
647 {352 {
@@ -705,83 +410,40 @@
705 app_->Focus(show_only_visible, arg.monitor);410 app_->Focus(show_only_visible, arg.monitor);
706}411}
707412
708bool ApplicationLauncherIcon::Spread(bool current_desktop, int state, bool force)
709{
710 std::vector<Window> windows;
711 for (auto& window : GetWindows(current_desktop ? WindowFilter::ON_CURRENT_DESKTOP : 0))
712 windows.push_back(window->window_id());
713
714 return WindowManager::Default().ScaleWindowGroup(windows, state, force);
715}
716
717void ApplicationLauncherIcon::EnsureWindowState()
718{
719 std::vector<int> number_of_windows_on_monitor(monitors::MAX);
720
721 for (auto& window: app_->GetWindows())
722 {
723 int monitor = window->monitor();
724 Window window_id = window->window_id();
725
726 if (WindowManager::Default().IsWindowOnCurrentDesktop(window_id))
727 {
728 // If monitor is -1 (or negative), show on all monitors.
729 if (monitor < 0)
730 {
731 for (unsigned j; j < monitors::MAX; ++j)
732 ++number_of_windows_on_monitor[j];
733 }
734 else
735 {
736 ++number_of_windows_on_monitor[monitor];
737 }
738 }
739 }
740
741 for (unsigned i = 0; i < monitors::MAX; ++i)
742 SetNumberOfWindowsVisibleOnMonitor(number_of_windows_on_monitor[i], i);
743}
744
745void ApplicationLauncherIcon::EnsureWindowsLocation()
746{
747 EnsureWindowState();
748 UpdateIconGeometries(GetCenters());
749}
750
751void ApplicationLauncherIcon::UpdateDesktopQuickList()413void ApplicationLauncherIcon::UpdateDesktopQuickList()
752{414{
753 std::string const& desktop_file = DesktopFile();415 std::string const& desktop_file = DesktopFile();
754416
755 if (_menu_desktop_shortcuts)417 if (menu_desktop_shortcuts_)
756 {418 {
757 for (GList *l = dbusmenu_menuitem_get_children(_menu_desktop_shortcuts); l; l = l->next)419 for (GList *l = dbusmenu_menuitem_get_children(menu_desktop_shortcuts_); l; l = l->next)
758 {420 {
759 _gsignals.Disconnect(l->data, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED);421 glib_signals_.Disconnect(l->data, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED);
760 }422 }
761423
762 _menu_desktop_shortcuts = nullptr;424 menu_desktop_shortcuts_ = nullptr;
763 }425 }
764426
765 if (desktop_file.empty())427 if (desktop_file.empty())
766 return;428 return;
767429
768 _menu_desktop_shortcuts = dbusmenu_menuitem_new();430 menu_desktop_shortcuts_ = dbusmenu_menuitem_new();
769 dbusmenu_menuitem_set_root(_menu_desktop_shortcuts, TRUE);431 dbusmenu_menuitem_set_root(menu_desktop_shortcuts_, TRUE);
770432
771 // Build a desktop shortcuts object and tell it that our433 // Build a desktop shortcuts object and tell it that our
772 // environment is Unity to handle the filtering434 // environment is Unity to handle the filtering
773 _desktop_shortcuts = indicator_desktop_shortcuts_new(desktop_file.c_str(), "Unity");435 desktop_shortcuts_ = indicator_desktop_shortcuts_new(desktop_file.c_str(), "Unity");
774 // This will get us a list of the nicks available, it should436 // This will get us a list of the nicks available, it should
775 // always be at least one entry of NULL if there either aren't437 // always be at least one entry of NULL if there either aren't
776 // any or they're filtered for the environment we're in438 // any or they're filtered for the environment we're in
777 const gchar** nicks = indicator_desktop_shortcuts_get_nicks(_desktop_shortcuts);439 const gchar** nicks = indicator_desktop_shortcuts_get_nicks(desktop_shortcuts_);
778440
779 for (int index = 0; nicks[index]; ++index)441 for (int index = 0; nicks[index]; ++index)
780 {442 {
781 // Build a dbusmenu item for each nick that is the desktop443 // Build a dbusmenu item for each nick that is the desktop
782 // file that is built from it's name and includes a callback444 // file that is built from it's name and includes a callback
783 // to the desktop shortcuts object to execute the nick445 // to the desktop shortcuts object to execute the nick
784 glib::String name(indicator_desktop_shortcuts_nick_get_name(_desktop_shortcuts,446 glib::String name(indicator_desktop_shortcuts_nick_get_name(desktop_shortcuts_,
785 nicks[index]));447 nicks[index]));
786 glib::Object<DbusmenuMenuitem> item(dbusmenu_menuitem_new());448 glib::Object<DbusmenuMenuitem> item(dbusmenu_menuitem_new());
787 dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_LABEL, name);449 dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_LABEL, name);
@@ -789,16 +451,16 @@
789 dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);451 dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
790 auto nick = glib::gchar_to_string(nicks[index]);452 auto nick = glib::gchar_to_string(nicks[index]);
791453
792 _gsignals.Add<void, DbusmenuMenuitem*, gint>(item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,454 glib_signals_.Add<void, DbusmenuMenuitem*, gint>(item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
793 [this, nick] (DbusmenuMenuitem* item, unsigned timestamp) {455 [this, nick] (DbusmenuMenuitem* item, unsigned timestamp) {
794 GdkDisplay* display = gdk_display_get_default();456 GdkDisplay* display = gdk_display_get_default();
795 glib::Object<GdkAppLaunchContext> context(gdk_display_get_app_launch_context(display));457 glib::Object<GdkAppLaunchContext> context(gdk_display_get_app_launch_context(display));
796 gdk_app_launch_context_set_timestamp(context, timestamp);458 gdk_app_launch_context_set_timestamp(context, timestamp);
797 auto gcontext = glib::object_cast<GAppLaunchContext>(context);459 auto gcontext = glib::object_cast<GAppLaunchContext>(context);
798 indicator_desktop_shortcuts_nick_exec_with_context(_desktop_shortcuts, nick.c_str(), gcontext);460 indicator_desktop_shortcuts_nick_exec_with_context(desktop_shortcuts_, nick.c_str(), gcontext);
799 });461 });
800462
801 dbusmenu_menuitem_child_append(_menu_desktop_shortcuts, item);463 dbusmenu_menuitem_child_append(menu_desktop_shortcuts_, item);
802 }464 }
803}465}
804466
@@ -821,60 +483,16 @@
821 }483 }
822}484}
823485
824void ApplicationLauncherIcon::EnsureMenuItemsWindowsReady()
825{
826 // delete all menu items for windows
827 _menu_items_windows.clear();
828
829 auto const& windows = Windows();
830
831 // We only add quicklist menu-items for windows if we have more than one window
832 if (windows.size() < 2)
833 return;
834
835 // add menu items for all open windows
836 for (auto const& w : windows)
837 {
838 auto const& title = w->title();
839
840 if (title.empty())
841 continue;
842
843 glib::Object<DbusmenuMenuitem> menu_item(dbusmenu_menuitem_new());
844 dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, title.c_str());
845 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
846 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
847 dbusmenu_menuitem_property_set_bool(menu_item, QuicklistMenuItem::MARKUP_ACCEL_DISABLED_PROPERTY, true);
848 dbusmenu_menuitem_property_set_int(menu_item, QuicklistMenuItem::MAXIMUM_LABEL_WIDTH_PROPERTY, MAXIMUM_QUICKLIST_WIDTH);
849
850 Window xid = w->window_id();
851 _gsignals.Add<void, DbusmenuMenuitem*, unsigned>(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
852 [xid] (DbusmenuMenuitem*, unsigned) {
853 WindowManager& wm = WindowManager::Default();
854 wm.Activate(xid);
855 wm.Raise(xid);
856 });
857
858 if (w->active())
859 {
860 dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE, DBUSMENU_MENUITEM_TOGGLE_RADIO);
861 dbusmenu_menuitem_property_set_int(menu_item, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED);
862 }
863
864 _menu_items_windows.push_back(menu_item);
865 }
866}
867
868void ApplicationLauncherIcon::EnsureMenuItemsStaticQuicklist()486void ApplicationLauncherIcon::EnsureMenuItemsStaticQuicklist()
869{487{
870 // make a client for desktop file actions488 // make a client for desktop file actions
871 if (!_menu_desktop_shortcuts.IsType(DBUSMENU_TYPE_MENUITEM))489 if (!menu_desktop_shortcuts_.IsType(DBUSMENU_TYPE_MENUITEM))
872 {490 {
873 UpdateDesktopQuickList();491 UpdateDesktopQuickList();
874 }492 }
875}493}
876494
877void ApplicationLauncherIcon::Quit()495void ApplicationLauncherIcon::Quit() const
878{496{
879 app_->Quit();497 app_->Quit();
880}498}
@@ -899,7 +517,7 @@
899 }517 }
900 else518 else
901 {519 {
902 SimpleLauncherIcon::Stick(save);520 WindowedLauncherIcon::Stick(save);
903521
904 if (save)522 if (save)
905 LogUnityEvent(ApplicationEventType::ACCESS);523 LogUnityEvent(ApplicationEventType::ACCESS);
@@ -912,11 +530,11 @@
912 return;530 return;
913531
914 LogUnityEvent(ApplicationEventType::ACCESS);532 LogUnityEvent(ApplicationEventType::ACCESS);
915 SimpleLauncherIcon::UnStick();533 WindowedLauncherIcon::UnStick();
916 SetQuirk(Quirk::VISIBLE, app_->visible());534 SetQuirk(Quirk::VISIBLE, app_->visible());
917 app_->sticky = false;535 app_->sticky = false;
918536
919 if (!app_->running())537 if (!IsRunning())
920 Remove();538 Remove();
921}539}
922540
@@ -956,10 +574,10 @@
956574
957void ApplicationLauncherIcon::EnsureMenuItemsDefaultReady()575void ApplicationLauncherIcon::EnsureMenuItemsDefaultReady()
958{576{
959 if (_menu_items.size() == MenuItemType::SIZE)577 if (menu_items_.size() == MenuItemType::SIZE)
960 return;578 return;
961579
962 _menu_items.resize(MenuItemType::SIZE);580 menu_items_.resize(MenuItemType::SIZE);
963581
964 /* (Un)Stick to Launcher */582 /* (Un)Stick to Launcher */
965 glib::Object<DbusmenuMenuitem> menu_item(dbusmenu_menuitem_new());583 glib::Object<DbusmenuMenuitem> menu_item(dbusmenu_menuitem_new());
@@ -968,12 +586,12 @@
968 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);586 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
969 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);587 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
970588
971 _gsignals.Add<void, DbusmenuMenuitem*, unsigned>(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,589 glib_signals_.Add<void, DbusmenuMenuitem*, unsigned>(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
972 [this] (DbusmenuMenuitem*, unsigned) {590 [this] (DbusmenuMenuitem*, unsigned) {
973 ToggleSticky();591 ToggleSticky();
974 });592 });
975593
976 _menu_items[MenuItemType::STICK] = menu_item;594 menu_items_[MenuItemType::STICK] = menu_item;
977595
978 /* Quit */596 /* Quit */
979 menu_item = dbusmenu_menuitem_new();597 menu_item = dbusmenu_menuitem_new();
@@ -981,17 +599,17 @@
981 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);599 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
982 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);600 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
983601
984 _gsignals.Add<void, DbusmenuMenuitem*, unsigned>(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,602 glib_signals_.Add<void, DbusmenuMenuitem*, unsigned>(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
985 [this] (DbusmenuMenuitem*, unsigned) {603 [this] (DbusmenuMenuitem*, unsigned) {
986 Quit();604 Quit();
987 });605 });
988606
989 _menu_items[MenuItemType::QUIT] = menu_item;607 menu_items_[MenuItemType::QUIT] = menu_item;
990608
991 /* Separator */609 /* Separator */
992 menu_item = dbusmenu_menuitem_new();610 menu_item = dbusmenu_menuitem_new();
993 dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);611 dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
994 _menu_items[MenuItemType::SEPARATOR] = menu_item;612 menu_items_[MenuItemType::SEPARATOR] = menu_item;
995}613}
996614
997AbstractLauncherIcon::MenuItemsVector ApplicationLauncherIcon::GetMenus()615AbstractLauncherIcon::MenuItemsVector ApplicationLauncherIcon::GetMenus()
@@ -1003,7 +621,7 @@
1003 EnsureMenuItemsDefaultReady();621 EnsureMenuItemsDefaultReady();
1004 EnsureMenuItemsStaticQuicklist();622 EnsureMenuItemsStaticQuicklist();
1005623
1006 for (auto const& menus : {GetRemoteMenus(), _menu_desktop_shortcuts})624 for (auto const& menus : {GetRemoteMenus(), menu_desktop_shortcuts_})
1007 {625 {
1008 if (!menus.IsType(DBUSMENU_TYPE_MENUITEM))626 if (!menus.IsType(DBUSMENU_TYPE_MENUITEM))
1009 continue;627 continue;
@@ -1049,11 +667,11 @@
1049667
1050 if (separator_needed)668 if (separator_needed)
1051 {669 {
1052 result.push_back(_menu_items[MenuItemType::SEPARATOR]);670 result.push_back(menu_items_[MenuItemType::SEPARATOR]);
1053 separator_needed = false;671 separator_needed = false;
1054 }672 }
1055673
1056 if (!_menu_items[MenuItemType::APP_NAME])674 if (!menu_items_[MenuItemType::APP_NAME])
1057 {675 {
1058 glib::String app_name(g_markup_escape_text(app_->title().c_str(), -1));676 glib::String app_name(g_markup_escape_text(app_->title().c_str(), -1));
1059 std::string bold_app_name("<b>"+app_name.Str()+"</b>");677 std::string bold_app_name("<b>"+app_name.Str()+"</b>");
@@ -1064,7 +682,7 @@
1064 dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);682 dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE);
1065 dbusmenu_menuitem_property_set_bool(item, QuicklistMenuItem::MARKUP_ENABLED_PROPERTY, TRUE);683 dbusmenu_menuitem_property_set_bool(item, QuicklistMenuItem::MARKUP_ENABLED_PROPERTY, TRUE);
1066684
1067 _gsignals.Add<void, DbusmenuMenuitem*, unsigned>(item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,685 glib_signals_.Add<void, DbusmenuMenuitem*, unsigned>(item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
1068 [this] (DbusmenuMenuitem*, unsigned timestamp) {686 [this] (DbusmenuMenuitem*, unsigned timestamp) {
1069 _source_manager.AddIdle([this, timestamp] {687 _source_manager.AddIdle([this, timestamp] {
1070 ActivateLauncherIcon(ActionArg(ActionArg::Source::LAUNCHER, 0, timestamp));688 ActivateLauncherIcon(ActionArg(ActionArg::Source::LAUNCHER, 0, timestamp));
@@ -1072,25 +690,23 @@
1072 });690 });
1073 });691 });
1074692
1075 _menu_items[MenuItemType::APP_NAME] = item;693 menu_items_[MenuItemType::APP_NAME] = item;
1076 }694 }
1077695
1078 result.push_back(_menu_items[MenuItemType::APP_NAME]);696 result.push_back(menu_items_[MenuItemType::APP_NAME]);
1079 result.push_back(_menu_items[MenuItemType::SEPARATOR]);697 result.push_back(menu_items_[MenuItemType::SEPARATOR]);
1080698
1081 EnsureMenuItemsWindowsReady();699 auto const& windows_menu_items = GetWindowsMenuItems();
1082700
1083 if (!_menu_items_windows.empty())701 if (!windows_menu_items.empty())
1084 {702 {
1085 for (auto const& it : _menu_items_windows)703 result.insert(end(result), begin(windows_menu_items), end(windows_menu_items));
1086 result.push_back(it);704 result.push_back(menu_items_[MenuItemType::SEPARATOR]);
1087
1088 result.push_back(_menu_items[MenuItemType::SEPARATOR]);
1089 }705 }
1090706
1091 const char* label = !IsSticky() ? _("Lock to Launcher") : _("Unlock from Launcher");707 const char* label = !IsSticky() ? _("Lock to Launcher") : _("Unlock from Launcher");
1092 dbusmenu_menuitem_property_set(_menu_items[MenuItemType::STICK], DBUSMENU_MENUITEM_PROP_LABEL, label);708 dbusmenu_menuitem_property_set(menu_items_[MenuItemType::STICK], DBUSMENU_MENUITEM_PROP_LABEL, label);
1093 result.push_back(_menu_items[MenuItemType::STICK]);709 result.push_back(menu_items_[MenuItemType::STICK]);
1094710
1095 if (IsRunning())711 if (IsRunning())
1096 {712 {
@@ -1102,7 +718,7 @@
1102 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);718 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
1103 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);719 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
1104720
1105 _gsignals.Add<void, DbusmenuMenuitem*, unsigned>(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,721 glib_signals_.Add<void, DbusmenuMenuitem*, unsigned>(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
1106 [this] (DbusmenuMenuitem*, unsigned) {722 [this] (DbusmenuMenuitem*, unsigned) {
1107 app_->CreateLocalDesktopFile();723 app_->CreateLocalDesktopFile();
1108 });724 });
@@ -1111,7 +727,7 @@
1111 }727 }
1112728
1113 if (!quit_item)729 if (!quit_item)
1114 quit_item = _menu_items[MenuItemType::QUIT];730 quit_item = menu_items_[MenuItemType::QUIT];
1115731
1116 dbusmenu_menuitem_property_set(quit_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Quit"));732 dbusmenu_menuitem_property_set(quit_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Quit"));
1117 result.push_back(quit_item);733 result.push_back(quit_item);
@@ -1125,28 +741,7 @@
1125 if (app_->type() == AppType::WEBAPP)741 if (app_->type() == AppType::WEBAPP)
1126 return;742 return;
1127743
1128 nux::Geometry geo(0, 0, icon_size, icon_size);744 return WindowedLauncherIcon::UpdateIconGeometries(centers);
1129
1130 for (auto& window : app_->GetWindows())
1131 {
1132 Window xid = window->window_id();
1133 int monitor = GetCenterForMonitor(window->monitor()).first;
1134
1135 if (monitor < 0)
1136 {
1137 WindowManager::Default().SetWindowIconGeometry(xid, nux::Geometry());
1138 continue;
1139 }
1140
1141 geo.x = centers[monitor].x - icon_size / 2;
1142 geo.y = centers[monitor].y - icon_size / 2;
1143 WindowManager::Default().SetWindowIconGeometry(xid, geo);
1144 }
1145}
1146
1147void ApplicationLauncherIcon::OnCenterStabilized(std::vector<nux::Point3> const& centers)
1148{
1149 UpdateIconGeometries(centers);
1150}745}
1151746
1152void ApplicationLauncherIcon::UpdateRemoteUri()747void ApplicationLauncherIcon::UpdateRemoteUri()
@@ -1155,69 +750,21 @@
1155750
1156 if (!desktop_id.empty())751 if (!desktop_id.empty())
1157 {752 {
1158 _remote_uri = FavoriteStore::URI_PREFIX_APP + desktop_id;753 remote_uri_ = FavoriteStore::URI_PREFIX_APP + desktop_id;
1159 }754 }
1160 else755 else
1161 {756 {
1162 _remote_uri.clear();757 remote_uri_.clear();
1163 }758 }
1164}759}
1165760
1166std::string ApplicationLauncherIcon::GetRemoteUri() const761std::string ApplicationLauncherIcon::GetRemoteUri() const
1167{762{
1168 return _remote_uri;763 return remote_uri_;
1169}
1170
1171void ApplicationLauncherIcon::OnDndEnter()
1172{
1173 auto timestamp = nux::GetGraphicsDisplay()->GetCurrentEvent().x11_timestamp;
1174
1175 _source_manager.AddTimeout(1000, [this, timestamp] {
1176 bool to_spread = GetWindows(WindowFilter::ON_CURRENT_DESKTOP).size() > 1;
1177
1178 if (!to_spread)
1179 WindowManager::Default().TerminateScale();
1180
1181 if (!IsRunning())
1182 return false;
1183
1184 UBusManager::SendMessage(UBUS_OVERLAY_CLOSE_REQUEST);
1185 Focus(ActionArg(ActionArg::Source::LAUNCHER, 1, timestamp));
1186
1187 if (to_spread)
1188 Spread(true, COMPIZ_SCALE_DND_SPREAD, false);
1189
1190 return false;
1191 }, ICON_DND_OVER_TIMEOUT);
1192}
1193
1194void ApplicationLauncherIcon::OnDndLeave()
1195{
1196 _source_manager.Remove(ICON_DND_OVER_TIMEOUT);
1197}
1198
1199bool ApplicationLauncherIcon::IsFileManager()
1200{
1201 auto const& desktop_file = DesktopFile();
1202
1203 return boost::algorithm::ends_with(desktop_file, "org.gnome.Nautilus.desktop") ||
1204 boost::algorithm::ends_with(desktop_file, "nautilus.desktop") ||
1205 boost::algorithm::ends_with(desktop_file, "nautilus-folder-handler.desktop") ||
1206 boost::algorithm::ends_with(desktop_file, "nautilus-home.desktop");
1207}764}
1208765
1209bool ApplicationLauncherIcon::OnShouldHighlightOnDrag(DndData const& dnd_data)766bool ApplicationLauncherIcon::OnShouldHighlightOnDrag(DndData const& dnd_data)
1210{767{
1211 if (IsFileManager())
1212 {
1213 for (auto const& uri : dnd_data.Uris())
1214 {
1215 if (boost::algorithm::starts_with(uri, "file://"))
1216 return true;
1217 }
1218 return false;
1219 }
1220
1221 for (auto type : dnd_data.Types())768 for (auto type : dnd_data.Types())
1222 {769 {
1223 for (auto supported_type : GetSupportedTypes())770 for (auto supported_type : GetSupportedTypes())
@@ -1248,28 +795,6 @@
1248 OpenInstanceWithUris(dnd_data.Uris(), timestamp);795 OpenInstanceWithUris(dnd_data.Uris(), timestamp);
1249}796}
1250797
1251bool ApplicationLauncherIcon::ShowInSwitcher(bool current)
1252{
1253 if (!removed() && IsRunning() && IsVisible())
1254 {
1255 // If current is true, we only want to show the current workspace.
1256 if (!current)
1257 {
1258 return true;
1259 }
1260 else
1261 {
1262 for (unsigned i = 0; i < monitors::MAX; ++i)
1263 {
1264 if (WindowVisibleOnMonitor(i))
1265 return true;
1266 }
1267 }
1268 }
1269
1270 return false;
1271}
1272
1273bool ApplicationLauncherIcon::AllowDetailViewInSwitcher() const798bool ApplicationLauncherIcon::AllowDetailViewInSwitcher() const
1274{799{
1275 return app_->type() != AppType::WEBAPP;800 return app_->type() != AppType::WEBAPP;
@@ -1277,18 +802,11 @@
1277802
1278uint64_t ApplicationLauncherIcon::SwitcherPriority()803uint64_t ApplicationLauncherIcon::SwitcherPriority()
1279{804{
1280 uint64_t result = 0;
1281 // Webapps always go at the back.805 // Webapps always go at the back.
1282 if (app_->type() == AppType::WEBAPP)806 if (app_->type() == AppType::WEBAPP)
1283 return result;807 return 0;
1284808
1285 for (auto& window : app_->GetWindows())809 return WindowedLauncherIcon::SwitcherPriority();
1286 {
1287 Window xid = window->window_id();
1288 result = std::max(result, WindowManager::Default().GetWindowActiveNumber(xid));
1289 }
1290
1291 return result;
1292}810}
1293811
1294nux::Color ApplicationLauncherIcon::BackgroundColor() const812nux::Color ApplicationLauncherIcon::BackgroundColor() const
@@ -1296,7 +814,7 @@
1296 if (use_custom_bg_color_)814 if (use_custom_bg_color_)
1297 return bg_color_;815 return bg_color_;
1298816
1299 return SimpleLauncherIcon::BackgroundColor();817 return WindowedLauncherIcon::BackgroundColor();
1300}818}
1301819
1302const std::set<std::string> ApplicationLauncherIcon::GetSupportedTypes()820const std::set<std::string> ApplicationLauncherIcon::GetSupportedTypes()
@@ -1312,103 +830,18 @@
1312 return supported_types;830 return supported_types;
1313}831}
1314832
1315void PerformScrollUp(WindowList const& windows, unsigned int progressive_scroll)
1316{
1317 if (progressive_scroll == windows.size() - 1)
1318 {
1319 //RestackAbove to preserve Global Stacking Order
1320 WindowManager::Default().RestackBelow(windows.at(0)->window_id(), windows.at(1)->window_id());
1321 WindowManager::Default().RestackBelow(windows.at(1)->window_id(), windows.at(0)->window_id());
1322 windows.back()->Focus();
1323 return;
1324 }
1325
1326 WindowManager::Default().RestackBelow(windows.at(0)->window_id(), windows.at(progressive_scroll + 1)->window_id());
1327 windows.at(progressive_scroll + 1)->Focus();
1328}
1329
1330void PerformScrollDown(WindowList const& windows, unsigned int progressive_scroll)
1331{
1332 if (!progressive_scroll)
1333 {
1334 WindowManager::Default().RestackBelow(windows.at(0)->window_id(), windows.back()->window_id());
1335 windows.at(1)->Focus();
1336 return;
1337 }
1338
1339 WindowManager::Default().RestackBelow(windows.at(0)->window_id(), windows.at(progressive_scroll)->window_id());
1340 windows.at(progressive_scroll)->Focus();
1341}
1342
1343void ApplicationLauncherIcon::PerformScroll(ScrollDirection direction, Time timestamp)
1344{
1345 if (timestamp - _last_scroll_timestamp < 150)
1346 return;
1347 else if (timestamp - _last_scroll_timestamp > 1500)
1348 _progressive_scroll = 0;
1349
1350 _last_scroll_timestamp = timestamp;
1351
1352 auto const& windows = GetWindowsOnCurrentDesktopInStackingOrder();
1353
1354 if (windows.empty())
1355 return;
1356
1357 if (scroll_inactive_icons && !IsActive())
1358 {
1359 windows.at(0)->Focus();
1360 return;
1361 }
1362
1363 if (!scroll_inactive_icons && !IsActive())
1364 return;
1365
1366 if (windows.size() <= 1)
1367 return;
1368
1369 if (direction == ScrollDirection::DOWN)
1370 ++_progressive_scroll;
1371 else
1372 //--_progressive_scroll; but roll to the top of windows
1373 _progressive_scroll += windows.size() - 1;
1374 _progressive_scroll %= windows.size();
1375
1376 switch(direction)
1377 {
1378 case ScrollDirection::UP:
1379 PerformScrollUp(windows, _progressive_scroll);
1380 break;
1381 case ScrollDirection::DOWN:
1382 PerformScrollDown(windows, _progressive_scroll);
1383 break;
1384 }
1385}
1386
1387WindowList ApplicationLauncherIcon::GetWindowsOnCurrentDesktopInStackingOrder()
1388{
1389 auto windows = GetWindows(WindowFilter::ON_CURRENT_DESKTOP | WindowFilter::ON_ALL_MONITORS);
1390 auto sorted_windows = WindowManager::Default().GetWindowsInStackingOrder();
1391
1392 // Order the windows
1393 std::sort(windows.begin(), windows.end(), [&sorted_windows] (ApplicationWindowPtr const& win1, ApplicationWindowPtr const& win2) {
1394 for (auto const& window : sorted_windows)
1395 {
1396 if (window == win1->window_id())
1397 return false;
1398 else if (window == win2->window_id())
1399 return true;
1400 }
1401
1402 return true;
1403 });
1404
1405 return windows;
1406}
1407
1408std::string ApplicationLauncherIcon::GetName() const833std::string ApplicationLauncherIcon::GetName() const
1409{834{
1410 return "ApplicationLauncherIcon";835 return "ApplicationLauncherIcon";
1411}836}
1412837
838void ApplicationLauncherIcon::AddProperties(debug::IntrospectionData& introspection)
839{
840 WindowedLauncherIcon::AddProperties(introspection);
841
842 introspection.add("desktop_file", DesktopFile())
843 .add("desktop_id", app_->desktop_id());
844}
845
1413} // namespace launcher846} // namespace launcher
1414} // namespace unity847} // namespace unity
1415848
=== modified file 'launcher/ApplicationLauncherIcon.h'
--- launcher/ApplicationLauncherIcon.h 2015-11-18 15:25:31 +0000
+++ launcher/ApplicationLauncherIcon.h 2016-02-09 10:44:04 +0000
@@ -1,6 +1,6 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*2/*
3 * Copyright (C) 2010-2012 Canonical Ltd3 * Copyright (C) 2010-2015 Canonical Ltd
4 *4 *
5 * This program is free software: you can redistribute it and/or modify5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as6 * it under the terms of the GNU General Public License version 3 as
@@ -18,17 +18,15 @@
18 * Marco Trevisan (Treviño) <3v1n0@ubuntu.com>18 * Marco Trevisan (Treviño) <3v1n0@ubuntu.com>
19 */19 */
2020
21#ifndef APPLICATIONLAUNCHERICON_H21#ifndef APPLICATION_LAUNCHER_ICON_H
22#define APPLICATIONLAUNCHERICON_H22#define APPLICATION_LAUNCHER_ICON_H
2323
24#include <UnityCore/GLibSignal.h>
25#include <UnityCore/GLibWrapper.h>
26#include <UnityCore/ConnectionManager.h>24#include <UnityCore/ConnectionManager.h>
27#include <UnityCore/Variant.h>25#include <UnityCore/Variant.h>
2826
29#include <libindicator/indicator-desktop-shortcuts.h>27#include <libindicator/indicator-desktop-shortcuts.h>
3028
31#include "SimpleLauncherIcon.h"29#include "WindowedLauncherIcon.h"
3230
33namespace unity31namespace unity
34{32{
@@ -37,115 +35,74 @@
3735
38class Launcher;36class Launcher;
3937
40class ApplicationLauncherIcon : public SimpleLauncherIcon38class ApplicationLauncherIcon : public virtual WindowedLauncherIcon
41{39{
42 NUX_DECLARE_OBJECT_TYPE(ApplicationLauncherIcon, SimpleLauncherIcon);40 NUX_DECLARE_OBJECT_TYPE(ApplicationLauncherIcon, WindowedLauncherIcon);
43public:41public:
44 ApplicationLauncherIcon(ApplicationPtr const& app);42 ApplicationLauncherIcon(ApplicationPtr const&);
45 virtual ~ApplicationLauncherIcon();43 virtual ~ApplicationLauncherIcon();
4644
47 virtual void ActivateLauncherIcon(ActionArg arg);
48
49 std::string DesktopFile() const;45 std::string DesktopFile() const;
5046
51 bool IsSticky() const;47 bool IsSticky() const override;
52 bool IsActive() const;48 bool IsUserVisible() const override;
53 bool IsRunning() const;49 bool GetQuirk(Quirk quirk, int monitor = 0) const override;
54 bool IsUrgent() const;50
5551 void Quit() const override;
56 virtual bool GetQuirk(Quirk quirk, int monitor = 0) const override;52
5753 void Stick(bool save = true) override;
58 virtual void Quit();54 void UnStick() override;
59 virtual void AboutToRemove();
60
61 virtual void Stick(bool save = true);
62 virtual void UnStick();
63
64 virtual bool ShowInSwitcher(bool current);
65 virtual bool AllowDetailViewInSwitcher() const override;
66 virtual uint64_t SwitcherPriority();
67
68 virtual nux::Color BackgroundColor() const;
69
70 WindowList Windows();
71 std::vector<Window> WindowsOnViewport();
72 std::vector<Window> WindowsForMonitor(int monitor);
73
74 void PerformScroll(ScrollDirection direction, Time timestamp) override;
7555
76protected:56protected:
77 void SetApplication(ApplicationPtr const& app);57 void SetApplication(ApplicationPtr const& app);
78 ApplicationPtr GetApplication() const;58 ApplicationPtr GetApplication() const;
7959
60 WindowList GetManagedWindows() const override;
61
62 void LogUnityEvent(ApplicationEventType);
80 void Remove();63 void Remove();
81 void UpdateIconGeometries(std::vector<nux::Point3> const& centers);64
82 void OnCenterStabilized(std::vector<nux::Point3> const& centers);65 void AboutToRemove() override;
83 void AddProperties(debug::IntrospectionData&);66 bool AllowDetailViewInSwitcher() const override;
84 void OnAcceptDrop(DndData const& dnd_data);67 uint64_t SwitcherPriority() override;
85 void OnDndEnter();68 void UpdateIconGeometries(std::vector<nux::Point3> const& centers) override;
86 void OnDndLeave();69 nux::Color BackgroundColor() const override;
70 MenuItemsVector GetMenus() override;
71 std::string GetRemoteUri() const override;
72
87 void OpenInstanceLauncherIcon(Time timestamp) override;73 void OpenInstanceLauncherIcon(Time timestamp) override;
88 void ToggleSticky();74 void OpenInstanceWithUris(std::set<std::string> const& uris, Time timestamp);
89 void LogUnityEvent(ApplicationEventType);75 void Focus(ActionArg arg) override;
90 bool IsFileManager();76
9177 void OnAcceptDrop(DndData const&) override;
92 bool OnShouldHighlightOnDrag(DndData const& dnd_data);78 bool OnShouldHighlightOnDrag(DndData const&) override;
93 nux::DndAction OnQueryAcceptDrop(DndData const& dnd_data);79 nux::DndAction OnQueryAcceptDrop(DndData const&) override;
9480
95 MenuItemsVector GetMenus();81 std::string GetName() const override;
9682 void AddProperties(debug::IntrospectionData&) override;
97 std::string GetRemoteUri() const;
98
99 bool HandlesSpread() { return true; }
100 std::string GetName() const;
101
102 void UpdateDesktopFile();
103 void UpdateRemoteUri();
104 std::string _desktop_file;
105
106private:
107 typedef unsigned long int WindowFilterMask;
108 enum WindowFilter
109 {
110 MAPPED = (1 << 0),
111 USER_VISIBLE = (1 << 1),
112 ON_CURRENT_DESKTOP = (1 << 2),
113 ON_ALL_MONITORS = (1 << 3),
114 };
11583
116 void UnsetApplication();84 void UnsetApplication();
117 void SetupApplicationSignalsConnections();85 void SetupApplicationSignalsConnections();
118 void EnsureWindowState();
119 void EnsureWindowsLocation();
120 void EnsureMenuItemsWindowsReady();
121 void EnsureMenuItemsDefaultReady();86 void EnsureMenuItemsDefaultReady();
122 void EnsureMenuItemsStaticQuicklist();87 void EnsureMenuItemsStaticQuicklist();
123 void UpdateBackgroundColor();88 void UpdateBackgroundColor();
124 void UpdateDesktopQuickList();89 void UpdateDesktopQuickList();
12590 void UpdateDesktopFile();
126 void OpenInstanceWithUris(std::set<std::string> const& uris, Time timestamp);91 void UpdateRemoteUri();
127 void Focus(ActionArg arg);92 void ToggleSticky();
128 bool Spread(bool current_desktop, int state, bool force);93 void OnApplicationClosed();
12994
130 void OnWindowMinimized(guint32 xid);
131
132 WindowList GetWindows(WindowFilterMask filter = 0, int monitor = -1);
133 const std::set<std::string> GetSupportedTypes();95 const std::set<std::string> GetSupportedTypes();
134 WindowList GetWindowsOnCurrentDesktopInStackingOrder();
135 ApplicationSubjectPtr GetSubject();96 ApplicationSubjectPtr GetSubject();
13697
137 ApplicationPtr app_;98 ApplicationPtr app_;
138 std::string _remote_uri;99 std::string remote_uri_;
139 Time _startup_notification_timestamp;100 Time startup_notification_timestamp_;
140 Time _last_scroll_timestamp;101 std::set<std::string> supported_types_;
141 unsigned int _progressive_scroll;102 MenuItemsVector menu_items_;
142 std::set<std::string> _supported_types;103 glib::Object<IndicatorDesktopShortcuts> desktop_shortcuts_;
143 std::vector<glib::Object<DbusmenuMenuitem>> _menu_items;104 glib::Object<DbusmenuMenuitem> menu_desktop_shortcuts_;
144 std::vector<glib::Object<DbusmenuMenuitem>> _menu_items_windows;105 glib::Object<GFileMonitor> desktop_file_monitor_;
145 glib::Object<IndicatorDesktopShortcuts> _desktop_shortcuts;
146 glib::Object<DbusmenuMenuitem> _menu_desktop_shortcuts;
147 glib::Object<GFileMonitor> _desktop_file_monitor;
148 glib::SignalManager _gsignals;
149106
150 bool use_custom_bg_color_;107 bool use_custom_bg_color_;
151 nux::Color bg_color_;108 nux::Color bg_color_;
@@ -153,7 +110,7 @@
153 connection::Manager signals_conn_;110 connection::Manager signals_conn_;
154};111};
155112
156}113} // namespace launcher
157}114} // namespace unity
158115
159#endif // BAMFLAUNCHERICON_H116#endif // APPLICATION_LAUNCHER_ICON_H
160117
=== modified file 'launcher/CMakeLists.txt'
--- launcher/CMakeLists.txt 2013-09-11 18:39:27 +0000
+++ launcher/CMakeLists.txt 2016-02-09 10:44:04 +0000
@@ -32,6 +32,7 @@
32 FavoriteStore.cpp32 FavoriteStore.cpp
33 FavoriteStoreGSettings.cpp33 FavoriteStoreGSettings.cpp
34 FavoriteStorePrivate.cpp34 FavoriteStorePrivate.cpp
35 FileManagerLauncherIcon.cpp
35 HudLauncherIcon.cpp36 HudLauncherIcon.cpp
36 Launcher.cpp37 Launcher.cpp
37 LauncherController.cpp38 LauncherController.cpp
@@ -55,12 +56,14 @@
55 SingleMonitorLauncherIcon.cpp56 SingleMonitorLauncherIcon.cpp
56 SoftwareCenterLauncherIcon.cpp57 SoftwareCenterLauncherIcon.cpp
57 SpacerLauncherIcon.cpp58 SpacerLauncherIcon.cpp
59 StorageLauncherIcon.cpp
58 Tooltip.cpp60 Tooltip.cpp
59 TooltipManager.cpp61 TooltipManager.cpp
60 TrashLauncherIcon.cpp62 TrashLauncherIcon.cpp
61 VolumeImp.cpp63 VolumeImp.cpp
62 VolumeLauncherIcon.cpp64 VolumeLauncherIcon.cpp
63 VolumeMonitorWrapper.cpp65 VolumeMonitorWrapper.cpp
66 WindowedLauncherIcon.cpp
64 XdndCollectionWindowImp.cpp67 XdndCollectionWindowImp.cpp
65 XdndManagerImp.cpp68 XdndManagerImp.cpp
66 XdndStartStopNotifier.cpp69 XdndStartStopNotifier.cpp
6770
=== modified file 'launcher/DesktopLauncherIcon.cpp'
--- launcher/DesktopLauncherIcon.cpp 2014-08-13 23:32:39 +0000
+++ launcher/DesktopLauncherIcon.cpp 2016-02-09 10:44:04 +0000
@@ -77,5 +77,10 @@
77 return show_in_switcher_;77 return show_in_switcher_;
78}78}
7979
80uint64_t DesktopLauncherIcon::SwitcherPriority()
81{
82 return std::numeric_limits<uint64_t>::max();
83}
84
80} // namespace launcher85} // namespace launcher
81} // namespace unity86} // namespace unity
8287
=== modified file 'launcher/DesktopLauncherIcon.h'
--- launcher/DesktopLauncherIcon.h 2014-08-13 23:32:39 +0000
+++ launcher/DesktopLauncherIcon.h 2016-02-09 10:44:04 +0000
@@ -37,6 +37,7 @@
3737
38protected:38protected:
39 void ActivateLauncherIcon(ActionArg arg);39 void ActivateLauncherIcon(ActionArg arg);
40 uint64_t SwitcherPriority() override;
40 std::string GetName() const;41 std::string GetName() const;
41 std::string GetRemoteUri() const;42 std::string GetRemoteUri() const;
4243
4344
=== modified file 'launcher/DeviceLauncherSection.h'
--- launcher/DeviceLauncherSection.h 2013-10-07 14:13:45 +0000
+++ launcher/DeviceLauncherSection.h 2016-02-09 10:44:04 +0000
@@ -37,10 +37,14 @@
37class DeviceLauncherSection : public sigc::trackable37class DeviceLauncherSection : public sigc::trackable
38{38{
39public:39public:
40 typedef std::shared_ptr<DeviceLauncherSection> Ptr;
41
40 DeviceLauncherSection(AbstractVolumeMonitorWrapper::Ptr const& volume_monitor = nullptr,42 DeviceLauncherSection(AbstractVolumeMonitorWrapper::Ptr const& volume_monitor = nullptr,
41 DevicesSettings::Ptr const& devices_settings = nullptr,43 DevicesSettings::Ptr const& devices_settings = nullptr,
42 DeviceNotificationDisplay::Ptr const& notifications = nullptr);44 DeviceNotificationDisplay::Ptr const& notifications = nullptr);
4345
46 virtual ~DeviceLauncherSection() = default;
47
44 std::vector<VolumeLauncherIcon::Ptr> GetIcons() const;48 std::vector<VolumeLauncherIcon::Ptr> GetIcons() const;
4549
46 sigc::signal<void, AbstractLauncherIcon::Ptr const&> icon_added;50 sigc::signal<void, AbstractLauncherIcon::Ptr const&> icon_added;
4751
=== added file 'launcher/FileManagerLauncherIcon.cpp'
--- launcher/FileManagerLauncherIcon.cpp 1970-01-01 00:00:00 +0000
+++ launcher/FileManagerLauncherIcon.cpp 2016-02-09 10:44:04 +0000
@@ -0,0 +1,128 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*
3 * Copyright (C) 2015 Canonical Ltd
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by: Marco Trevisan <marco.trevisan@canonical.com>
18 */
19
20#include "FileManagerLauncherIcon.h"
21
22#include <boost/algorithm/string.hpp>
23#include <NuxCore/Logger.h>
24#include <UnityCore/DesktopUtilities.h>
25
26#include "unity-shared/GnomeFileManager.h"
27
28namespace unity
29{
30namespace launcher
31{
32namespace
33{
34DECLARE_LOGGER(logger, "unity.launcher.icon.filemanager");
35const std::string TRASH_URI = "trash:";
36const std::string TRASH_PATH = "file://" + DesktopUtilities::GetUserTrashDirectory();
37const std::string DEFAULT_ICON = "system-file-manager";
38}
39
40FileManagerLauncherIcon::FileManagerLauncherIcon(ApplicationPtr const& app, DeviceLauncherSection::Ptr const& dev, FileManager::Ptr const& fm)
41 : WindowedLauncherIcon(IconType::APPLICATION)
42 , ApplicationLauncherIcon(app)
43 , StorageLauncherIcon(GetIconType(), fm ? fm : GnomeFileManager::Get())
44 , devices_(dev)
45{
46 // We disconnect from ApplicationLauncherIcon app signals, as we manage them manually
47 signals_conn_.Clear();
48
49 signals_conn_.Add(app_->desktop_file.changed.connect([this](std::string const& desktop_file) {
50 LOG_DEBUG(logger) << tooltip_text() << " desktop_file now " << desktop_file;
51 UpdateDesktopFile();
52 }));
53
54 signals_conn_.Add(app_->closed.connect([this] {
55 LOG_DEBUG(logger) << tooltip_text() << " closed";
56 OnApplicationClosed();
57 }));
58
59 signals_conn_.Add(app_->title.changed.connect([this](std::string const& name) {
60 LOG_DEBUG(logger) << tooltip_text() << " name now " << name;
61 menu_items_.clear();
62 tooltip_text = name;
63 }));
64
65 signals_conn_.Add(app_->icon.changed.connect([this](std::string const& icon) {
66 LOG_DEBUG(logger) << tooltip_text() << " icon now " << icon;
67 icon_name = (icon.empty() ? DEFAULT_ICON : icon);
68 }));
69
70 UpdateStorageWindows();
71}
72
73void FileManagerLauncherIcon::Focus(ActionArg arg)
74{
75 WindowedLauncherIcon::Focus(arg);
76}
77
78void FileManagerLauncherIcon::Quit() const
79{
80 WindowedLauncherIcon::Quit();
81}
82
83bool FileManagerLauncherIcon::IsLocationManaged(std::string const& location) const
84{
85 if (location.empty())
86 return true;
87
88 if (boost::algorithm::starts_with(location, TRASH_URI))
89 return false;
90
91 if (boost::algorithm::starts_with(location, TRASH_PATH))
92 return false;
93
94 for (auto const& volume_icon : devices_->GetIcons())
95 {
96 auto const& volume_uri = volume_icon->GetVolumeUri();
97 if (!volume_uri.empty() && boost::algorithm::starts_with(location, volume_uri))
98 return false;
99 }
100
101 return true;
102}
103
104WindowList FileManagerLauncherIcon::GetManagedWindows() const
105{
106 return StorageLauncherIcon::GetManagedWindows();
107}
108
109WindowList FileManagerLauncherIcon::GetStorageWindows() const
110{
111 WindowList fm_windows;
112
113 for (auto const& app_win : ApplicationLauncherIcon::GetManagedWindows())
114 {
115 if (IsLocationManaged(file_manager_->LocationForWindow(app_win)))
116 fm_windows.push_back(app_win);
117 }
118
119 return fm_windows;
120}
121
122bool FileManagerLauncherIcon::OnShouldHighlightOnDrag(DndData const& dnd_data)
123{
124 return StorageLauncherIcon::OnShouldHighlightOnDrag(dnd_data);
125}
126
127} // namespace launcher
128} // namespace unity
0129
=== added file 'launcher/FileManagerLauncherIcon.h'
--- launcher/FileManagerLauncherIcon.h 1970-01-01 00:00:00 +0000
+++ launcher/FileManagerLauncherIcon.h 2016-02-09 10:44:04 +0000
@@ -0,0 +1,52 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*
3 * Copyright (C) 2015 Canonical Ltd
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by: Marco Trevisan <marco.trevisan@canonical.com>
18 */
19
20#ifndef FILEMANAGER_LAUNCHER_ICON_H
21#define FILEMANAGER_LAUNCHER_ICON_H
22
23#include "ApplicationLauncherIcon.h"
24#include "StorageLauncherIcon.h"
25#include "DeviceLauncherSection.h"
26
27namespace unity
28{
29namespace launcher
30{
31
32class FileManagerLauncherIcon : public ApplicationLauncherIcon, public StorageLauncherIcon
33{
34public:
35 FileManagerLauncherIcon(ApplicationPtr const&, DeviceLauncherSection::Ptr const&, FileManager::Ptr const& = nullptr);
36
37private:
38 WindowList GetManagedWindows() const override;
39 WindowList GetStorageWindows() const override;
40 void Focus(ActionArg arg) override;
41 void Quit() const override;
42 bool OnShouldHighlightOnDrag(DndData const& dnd_data) override;
43
44 bool IsLocationManaged(std::string const&) const;
45
46 DeviceLauncherSection::Ptr devices_;
47};
48
49} // namespace launcher
50} // namespace unity
51
52#endif // FILEMANAGER_LAUNCHER_ICON_H
053
=== modified file 'launcher/Launcher.cpp'
--- launcher/Launcher.cpp 2015-07-07 16:54:46 +0000
+++ launcher/Launcher.cpp 2016-02-09 10:44:04 +0000
@@ -578,16 +578,9 @@
578 else578 else
579 {579 {
580 if (options()->show_for_all)580 if (options()->show_for_all)
581 arg.window_indicators = std::max<int> (icon->WindowsOnViewport().size(), 1);581 arg.window_indicators = std::max<int>(icon->WindowsVisibleOnViewport(), 1);
582 else582 else
583 arg.window_indicators = std::max<int> (icon->WindowsForMonitor(monitor).size(), 1);583 arg.window_indicators = std::max<int>(icon->WindowsVisibleOnMonitor(monitor), 1);
584
585 if (icon->GetIconType() == AbstractLauncherIcon::IconType::TRASH ||
586 icon->GetIconType() == AbstractLauncherIcon::IconType::DEVICE)
587 {
588 // TODO: also these icons should respect the actual windows they have
589 arg.window_indicators = 0;
590 }
591 }584 }
592585
593 arg.backlight_intensity = IconBackgroundIntensity(icon);586 arg.backlight_intensity = IconBackgroundIntensity(icon);
594587
=== modified file 'launcher/LauncherController.cpp'
--- launcher/LauncherController.cpp 2015-12-11 12:44:27 +0000
+++ launcher/LauncherController.cpp 2016-02-09 10:44:04 +0000
@@ -21,6 +21,7 @@
2121
22#include "config.h"22#include "config.h"
23#include <glib/gi18n-lib.h>23#include <glib/gi18n-lib.h>
24#include <boost/algorithm/string.hpp>
2425
25#include <Nux/Nux.h>26#include <Nux/Nux.h>
26#include <Nux/HLayout.h>27#include <Nux/HLayout.h>
@@ -32,6 +33,7 @@
32#include "DesktopLauncherIcon.h"33#include "DesktopLauncherIcon.h"
33#include "VolumeLauncherIcon.h"34#include "VolumeLauncherIcon.h"
34#include "FavoriteStore.h"35#include "FavoriteStore.h"
36#include "FileManagerLauncherIcon.h"
35#include "HudLauncherIcon.h"37#include "HudLauncherIcon.h"
36#include "LauncherController.h"38#include "LauncherController.h"
37#include "LauncherControllerPrivate.h"39#include "LauncherControllerPrivate.h"
@@ -102,13 +104,13 @@
102104
103 return FavoriteStore::URI_PREFIX_APP + DesktopUtilities::GetDesktopID(desktop_path);105 return FavoriteStore::URI_PREFIX_APP + DesktopUtilities::GetDesktopID(desktop_path);
104}106}
105
106}107}
107108
108Controller::Impl::Impl(Controller* parent, XdndManager::Ptr const& xdnd_manager, ui::EdgeBarrierController::Ptr const& edge_barriers)109Controller::Impl::Impl(Controller* parent, XdndManager::Ptr const& xdnd_manager, ui::EdgeBarrierController::Ptr const& edge_barriers)
109 : parent_(parent)110 : parent_(parent)
110 , model_(std::make_shared<LauncherModel>())111 , model_(std::make_shared<LauncherModel>())
111 , xdnd_manager_(xdnd_manager)112 , xdnd_manager_(xdnd_manager)
113 , device_section_(std::make_shared<DeviceLauncherSection>())
112 , expo_icon_(new ExpoLauncherIcon())114 , expo_icon_(new ExpoLauncherIcon())
113 , desktop_icon_(new DesktopLauncherIcon())115 , desktop_icon_(new DesktopLauncherIcon())
114 , edge_barriers_(edge_barriers)116 , edge_barriers_(edge_barriers)
@@ -342,6 +344,21 @@
342 return launcher;344 return launcher;
343}345}
344346
347ApplicationLauncherIcon* Controller::Impl::CreateAppLauncherIcon(ApplicationPtr const& app)
348{
349 auto const& desktop_file = app->desktop_file();
350
351 if (boost::algorithm::ends_with(desktop_file, "org.gnome.Nautilus.desktop") ||
352 boost::algorithm::ends_with(desktop_file, "nautilus.desktop") ||
353 boost::algorithm::ends_with(desktop_file, "nautilus-folder-handler.desktop") ||
354 boost::algorithm::ends_with(desktop_file, "nautilus-home.desktop"))
355 {
356 return new FileManagerLauncherIcon(app, device_section_);
357 }
358
359 return new ApplicationLauncherIcon(app);
360}
361
345void Controller::Impl::OnLauncherAddRequest(std::string const& icon_uri, AbstractLauncherIcon::Ptr const& icon_before)362void Controller::Impl::OnLauncherAddRequest(std::string const& icon_uri, AbstractLauncherIcon::Ptr const& icon_before)
346{363{
347 std::string app_uri;364 std::string app_uri;
@@ -838,7 +855,7 @@
838 if (app->sticky() || app->seen())855 if (app->sticky() || app->seen())
839 return;856 return;
840857
841 AbstractLauncherIcon::Ptr icon(new ApplicationLauncherIcon(app));858 AbstractLauncherIcon::Ptr icon(CreateAppLauncherIcon(app));
842 RegisterIcon(icon, GetLastIconPriority<ApplicationLauncherIcon>(local::RUNNING_APPS_URI));859 RegisterIcon(icon, GetLastIconPriority<ApplicationLauncherIcon>(local::RUNNING_APPS_URI));
843}860}
844861
@@ -875,11 +892,11 @@
875 if (!app || app->seen())892 if (!app || app->seen())
876 return result;893 return result;
877894
878 result = AbstractLauncherIcon::Ptr(new ApplicationLauncherIcon(app));895 result = AbstractLauncherIcon::Ptr(CreateAppLauncherIcon(app));
879 }896 }
880 else if (icon_uri.find(FavoriteStore::URI_PREFIX_DEVICE) == 0)897 else if (icon_uri.find(FavoriteStore::URI_PREFIX_DEVICE) == 0)
881 {898 {
882 auto const& devices = device_section_.GetIcons();899 auto const& devices = device_section_->GetIcons();
883 auto const& icon = std::find_if(devices.begin(), devices.end(),900 auto const& icon = std::find_if(devices.begin(), devices.end(),
884 [&icon_uri](AbstractLauncherIcon::Ptr const& i) { return (i->RemoteUri() == icon_uri); });901 [&icon_uri](AbstractLauncherIcon::Ptr const& i) { return (i->RemoteUri() == icon_uri); });
885902
@@ -954,7 +971,7 @@
954 << (app->seen() ? "yes" : "no");971 << (app->seen() ? "yes" : "no");
955 if (!app->seen())972 if (!app->seen())
956 {973 {
957 AbstractLauncherIcon::Ptr icon(new ApplicationLauncherIcon(app));974 AbstractLauncherIcon::Ptr icon(CreateAppLauncherIcon(app));
958 icon->SkipQuirkAnimation(AbstractLauncherIcon::Quirk::VISIBLE);975 icon->SkipQuirkAnimation(AbstractLauncherIcon::Quirk::VISIBLE);
959 RegisterIcon(icon, ++sort_priority_);976 RegisterIcon(icon, ++sort_priority_);
960 }977 }
@@ -964,7 +981,7 @@
964void Controller::Impl::AddDevices()981void Controller::Impl::AddDevices()
965{982{
966 auto& fav_store = FavoriteStore::Instance();983 auto& fav_store = FavoriteStore::Instance();
967 for (auto const& icon : device_section_.GetIcons())984 for (auto const& icon : device_section_->GetIcons())
968 {985 {
969 if (!icon->IsSticky() && !fav_store.IsFavorite(icon->RemoteUri()))986 if (!icon->IsSticky() && !fav_store.IsFavorite(icon->RemoteUri()))
970 {987 {
@@ -1044,7 +1061,7 @@
1044 ApplicationManager::Default().application_started1061 ApplicationManager::Default().application_started
1045 .connect(sigc::mem_fun(this, &Impl::OnApplicationStarted));1062 .connect(sigc::mem_fun(this, &Impl::OnApplicationStarted));
10461063
1047 device_section_.icon_added.connect(sigc::mem_fun(this, &Impl::OnDeviceIconAdded));1064 device_section_->icon_added.connect(sigc::mem_fun(this, &Impl::OnDeviceIconAdded));
1048 favorite_store.favorite_added.connect(sigc::mem_fun(this, &Impl::OnFavoriteStoreFavoriteAdded));1065 favorite_store.favorite_added.connect(sigc::mem_fun(this, &Impl::OnFavoriteStoreFavoriteAdded));
1049 favorite_store.favorite_removed.connect(sigc::mem_fun(this, &Impl::OnFavoriteStoreFavoriteRemoved));1066 favorite_store.favorite_removed.connect(sigc::mem_fun(this, &Impl::OnFavoriteStoreFavoriteRemoved));
1050 favorite_store.reordered.connect(sigc::mem_fun(this, &Impl::ResetIconPriorities));1067 favorite_store.reordered.connect(sigc::mem_fun(this, &Impl::ResetIconPriorities));
10511068
=== modified file 'launcher/LauncherControllerPrivate.h'
--- launcher/LauncherControllerPrivate.h 2015-04-16 14:38:54 +0000
+++ launcher/LauncherControllerPrivate.h 2016-02-09 10:44:04 +0000
@@ -87,6 +87,7 @@
8787
88 void RegisterIcon(AbstractLauncherIcon::Ptr const& icon, int priority = std::numeric_limits<int>::min());88 void RegisterIcon(AbstractLauncherIcon::Ptr const& icon, int priority = std::numeric_limits<int>::min());
8989
90 ApplicationLauncherIcon* CreateAppLauncherIcon(ApplicationPtr const&);
90 AbstractLauncherIcon::Ptr CreateFavoriteIcon(std::string const& icon_uri, bool emit_signal = false);91 AbstractLauncherIcon::Ptr CreateFavoriteIcon(std::string const& icon_uri, bool emit_signal = false);
91 AbstractLauncherIcon::Ptr GetIconByUri(std::string const& icon_uri);92 AbstractLauncherIcon::Ptr GetIconByUri(std::string const& icon_uri);
92 SoftwareCenterLauncherIcon::Ptr CreateSCLauncherIcon(std::string const& file_path, std::string const& aptdaemon_trans_id, std::string const& icon_path);93 SoftwareCenterLauncherIcon::Ptr CreateSCLauncherIcon(std::string const& file_path, std::string const& aptdaemon_trans_id, std::string const& icon_path);
@@ -122,7 +123,7 @@
122 nux::ObjectPtr<Launcher> launcher_;123 nux::ObjectPtr<Launcher> launcher_;
123 nux::ObjectPtr<Launcher> keyboard_launcher_;124 nux::ObjectPtr<Launcher> keyboard_launcher_;
124 XdndManager::Ptr xdnd_manager_;125 XdndManager::Ptr xdnd_manager_;
125 DeviceLauncherSection device_section_;126 DeviceLauncherSection::Ptr device_section_;
126 LauncherEntryRemoteModel remote_model_;127 LauncherEntryRemoteModel remote_model_;
127 AbstractLauncherIcon::Ptr expo_icon_;128 AbstractLauncherIcon::Ptr expo_icon_;
128 AbstractLauncherIcon::Ptr desktop_icon_;129 AbstractLauncherIcon::Ptr desktop_icon_;
129130
=== modified file 'launcher/LauncherIcon.cpp'
--- launcher/LauncherIcon.cpp 2015-11-02 18:08:08 +0000
+++ launcher/LauncherIcon.cpp 2016-02-09 10:44:04 +0000
@@ -150,16 +150,26 @@
150 QuicklistManager::Default()->RegisterQuicklist(_quicklist);150 QuicklistManager::Default()->RegisterQuicklist(_quicklist);
151}151}
152152
153const bool LauncherIcon::WindowVisibleOnMonitor(int monitor)153bool LauncherIcon::WindowVisibleOnMonitor(int monitor) const
154{154{
155 return _has_visible_window[monitor];155 return _has_visible_window[monitor];
156}156}
157157
158const bool LauncherIcon::WindowVisibleOnViewport()158bool LauncherIcon::WindowVisibleOnViewport() const
159{159{
160 return _has_visible_window.any();160 return _has_visible_window.any();
161}161}
162162
163size_t LauncherIcon::WindowsVisibleOnMonitor(int monitor) const
164{
165 return _number_of_visible_windows[monitor];
166}
167
168size_t LauncherIcon::WindowsVisibleOnViewport() const
169{
170 return std::accumulate(begin(_number_of_visible_windows), end(_number_of_visible_windows), 0);
171}
172
163std::string173std::string
164LauncherIcon::GetName() const174LauncherIcon::GetName() const
165{175{
166176
=== modified file 'launcher/LauncherIcon.h'
--- launcher/LauncherIcon.h 2015-11-02 18:08:08 +0000
+++ launcher/LauncherIcon.h 2016-02-09 10:44:04 +0000
@@ -82,7 +82,7 @@
8282
83 nux::Point3 GetCenter(int monitor);83 nux::Point3 GetCenter(int monitor);
8484
85 virtual void Activate(ActionArg arg);85 void Activate(ActionArg arg);
8686
87 void OpenInstance(ActionArg arg);87 void OpenInstance(ActionArg arg);
8888
@@ -94,15 +94,19 @@
9494
95 void SetOrder(int order);95 void SetOrder(int order);
9696
97 virtual WindowList Windows() { return WindowList(); }97 WindowList Windows() { return WindowList(); }
9898
99 virtual std::vector<Window> WindowsOnViewport() { return std::vector<Window> (); }99 WindowList WindowsOnViewport() { return WindowList(); }
100100
101 virtual std::vector<Window> WindowsForMonitor(int monitor) { return std::vector<Window> (); }101 WindowList WindowsForMonitor(int monitor) { return WindowList(); }
102102
103 const bool WindowVisibleOnMonitor(int monitor);103 bool WindowVisibleOnMonitor(int monitor) const;
104104
105 const bool WindowVisibleOnViewport();105 bool WindowVisibleOnViewport() const;
106
107 size_t WindowsVisibleOnMonitor(int monitor) const;
108
109 size_t WindowsVisibleOnViewport() const;
106110
107 float PresentUrgency();111 float PresentUrgency();
108112
109113
=== modified file 'launcher/MockLauncherIcon.h'
--- launcher/MockLauncherIcon.h 2015-10-05 16:52:24 +0000
+++ launcher/MockLauncherIcon.h 2016-02-09 10:44:04 +0000
@@ -112,34 +112,34 @@
112 return result;112 return result;
113 }113 }
114114
115 std::vector<Window> WindowsOnViewport ()115 WindowList WindowsOnViewport()
116 {116 {
117 std::vector<Window> result;117 WindowList result;
118118
119 result.push_back ((100 << 16) + 200);119 result.push_back(std::make_shared<MockApplicationWindow>((100 << 16) + 200));
120 result.push_back ((500 << 16) + 200);120 result.push_back(std::make_shared<MockApplicationWindow>((500 << 16) + 200));
121 result.push_back ((300 << 16) + 200);121 result.push_back(std::make_shared<MockApplicationWindow>((300 << 16) + 200));
122 result.push_back ((200 << 16) + 200);122 result.push_back(std::make_shared<MockApplicationWindow>((200 << 16) + 200));
123 result.push_back ((300 << 16) + 200);123 result.push_back(std::make_shared<MockApplicationWindow>((300 << 16) + 200));
124 result.push_back ((100 << 16) + 200);124 result.push_back(std::make_shared<MockApplicationWindow>((100 << 16) + 200));
125 result.push_back ((300 << 16) + 200);125 result.push_back(std::make_shared<MockApplicationWindow>((300 << 16) + 200));
126 result.push_back ((600 << 16) + 200);126 result.push_back(std::make_shared<MockApplicationWindow>((600 << 16) + 200));
127127
128 return result;128 return result;
129 }129 }
130130
131 std::vector<Window> WindowsForMonitor (int monitor)131 WindowList WindowsForMonitor(int monitor)
132 {132 {
133 std::vector<Window> result;133 WindowList result;
134134
135 result.push_back ((100 << 16) + 200);135 result.push_back(std::make_shared<MockApplicationWindow>((100 << 16) + 200));
136 result.push_back ((500 << 16) + 200);136 result.push_back(std::make_shared<MockApplicationWindow>((500 << 16) + 200));
137 result.push_back ((300 << 16) + 200);137 result.push_back(std::make_shared<MockApplicationWindow>((300 << 16) + 200));
138 result.push_back ((200 << 16) + 200);138 result.push_back(std::make_shared<MockApplicationWindow>((200 << 16) + 200));
139 result.push_back ((300 << 16) + 200);139 result.push_back(std::make_shared<MockApplicationWindow>((300 << 16) + 200));
140 result.push_back ((100 << 16) + 200);140 result.push_back(std::make_shared<MockApplicationWindow>((100 << 16) + 200));
141 result.push_back ((300 << 16) + 200);141 result.push_back(std::make_shared<MockApplicationWindow>((300 << 16) + 200));
142 result.push_back ((600 << 16) + 200);142 result.push_back(std::make_shared<MockApplicationWindow>((600 << 16) + 200));
143143
144 return result;144 return result;
145 }145 }
@@ -194,14 +194,24 @@
194 return 7;194 return 7;
195 }195 }
196196
197 const bool WindowVisibleOnViewport()197 bool WindowVisibleOnViewport() const
198 {198 {
199 return false;199 return false;
200 }200 }
201201
202 const bool WindowVisibleOnMonitor(int monitor)202 bool WindowVisibleOnMonitor(int monitor) const
203 {203 {
204 return false;204 return false;
205 }
206
207 size_t WindowsVisibleOnMonitor(int monitor) const
208 {
209 return 0;
210 }
211
212 size_t WindowsVisibleOnViewport() const
213 {
214 return 0;
205 }215 }
206216
207 void SetVisibleOnMonitor(int monitor, bool visible) {}217 void SetVisibleOnMonitor(int monitor, bool visible) {}
208218
=== modified file 'launcher/SoftwareCenterLauncherIcon.cpp'
--- launcher/SoftwareCenterLauncherIcon.cpp 2013-10-29 22:33:02 +0000
+++ launcher/SoftwareCenterLauncherIcon.cpp 2016-02-09 10:44:04 +0000
@@ -46,7 +46,8 @@
46SoftwareCenterLauncherIcon::SoftwareCenterLauncherIcon(ApplicationPtr const& app,46SoftwareCenterLauncherIcon::SoftwareCenterLauncherIcon(ApplicationPtr const& app,
47 std::string const& aptdaemon_trans_id,47 std::string const& aptdaemon_trans_id,
48 std::string const& icon_path)48 std::string const& icon_path)
49 : ApplicationLauncherIcon(app)49 : WindowedLauncherIcon(IconType::APPLICATION)
50 , ApplicationLauncherIcon(app)
50 , aptdaemon_trans_(std::make_shared<glib::DBusProxy>("org.debian.apt",51 , aptdaemon_trans_(std::make_shared<glib::DBusProxy>("org.debian.apt",
51 aptdaemon_trans_id,52 aptdaemon_trans_id,
52 "org.debian.apt.transaction",53 "org.debian.apt.transaction",
5354
=== added file 'launcher/StorageLauncherIcon.cpp'
--- launcher/StorageLauncherIcon.cpp 1970-01-01 00:00:00 +0000
+++ launcher/StorageLauncherIcon.cpp 2016-02-09 10:44:04 +0000
@@ -0,0 +1,119 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*
3 * Copyright (C) 2015 Canonical Ltd
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by: Marco Trevisan <marco.trevisan@canonical.com>
18 */
19
20#include "StorageLauncherIcon.h"
21
22namespace unity
23{
24namespace launcher
25{
26
27StorageLauncherIcon::StorageLauncherIcon(AbstractLauncherIcon::IconType icon_type, FileManager::Ptr const& fm)
28 : WindowedLauncherIcon(icon_type)
29 , file_manager_(fm)
30{
31 file_manager_->locations_changed.connect(sigc::mem_fun(this, &StorageLauncherIcon::UpdateStorageWindows));
32}
33
34void StorageLauncherIcon::UpdateStorageWindows()
35{
36 bool active = false;
37 bool urgent = false;
38 bool check_visibility = (GetIconType() == IconType::APPLICATION);
39 bool visible = IsSticky();
40
41 managed_windows_ = GetStorageWindows();
42 windows_connections_.Clear();
43
44 for (auto const& win : managed_windows_)
45 {
46 windows_connections_.Add(win->monitor.changed.connect([this] (int) { EnsureWindowsLocation(); }));
47 windows_connections_.Add(win->urgent.changed.connect([this] (bool) { OnWindowStateChanged(); }));
48 windows_connections_.Add(win->active.changed.connect([this] (bool) { OnWindowStateChanged(); }));
49 windows_connections_.Add(win->closed.connect([this] { UpdateStorageWindows(); }));
50
51 if (!active && win->active())
52 active = true;
53
54 if (!urgent && win->urgent())
55 urgent = true;
56
57 if (check_visibility)
58 {
59 windows_connections_.Add(win->visible.changed.connect([this] (bool) { OnWindowStateChanged(); }));
60
61 if (!visible && win->visible())
62 visible = true;
63 }
64 }
65
66 SetQuirk(Quirk::RUNNING, !managed_windows_.empty());
67 SetQuirk(Quirk::ACTIVE, active);
68 SetQuirk(Quirk::URGENT, urgent);
69
70 if (check_visibility)
71 SetQuirk(Quirk::VISIBLE, visible);
72
73 EnsureWindowsLocation();
74}
75
76WindowList StorageLauncherIcon::GetManagedWindows() const
77{
78 return managed_windows_;
79}
80
81void StorageLauncherIcon::OnWindowStateChanged()
82{
83 bool active = false;
84 bool urgent = false;
85 bool check_visibility = (GetIconType() == IconType::APPLICATION);
86 bool visible = IsSticky();
87
88 for (auto const& win : managed_windows_)
89 {
90 if (!active && win->active())
91 active = true;
92
93 if (!urgent && win->urgent())
94 urgent = true;
95
96 if (check_visibility && !visible && win->visible())
97 visible = true;
98 }
99
100 SetQuirk(Quirk::ACTIVE, active);
101 SetQuirk(Quirk::URGENT, urgent);
102
103 if (check_visibility)
104 SetQuirk(Quirk::VISIBLE, visible);
105}
106
107bool StorageLauncherIcon::OnShouldHighlightOnDrag(DndData const& dnd_data)
108{
109 for (auto const& uri : dnd_data.Uris())
110 {
111 if (uri.find("file://") == 0)
112 return true;
113 }
114
115 return false;
116}
117
118} // namespace launcher
119} // namespace unity
0120
=== added file 'launcher/StorageLauncherIcon.h'
--- launcher/StorageLauncherIcon.h 1970-01-01 00:00:00 +0000
+++ launcher/StorageLauncherIcon.h 2016-02-09 10:44:04 +0000
@@ -0,0 +1,55 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*
3 * Copyright (C) 2015 Canonical Ltd
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by: Marco Trevisan <marco.trevisan@canonical.com>
18 */
19
20#ifndef STORAGE_LAUNCHER_ICON_H
21#define STORAGE_LAUNCHER_ICON_H
22
23#include "WindowedLauncherIcon.h"
24#include "unity-shared/FileManager.h"
25
26namespace unity
27{
28namespace launcher
29{
30
31class StorageLauncherIcon : public virtual WindowedLauncherIcon
32{
33public:
34 StorageLauncherIcon(AbstractLauncherIcon::IconType, FileManager::Ptr const&);
35
36protected:
37 void UpdateStorageWindows();
38 WindowList GetManagedWindows() const override;
39 virtual WindowList GetStorageWindows() const = 0;
40
41 bool OnShouldHighlightOnDrag(DndData const& dnd_data) override;
42
43private:
44 void OnWindowStateChanged();
45
46protected:
47 FileManager::Ptr file_manager_;
48 WindowList managed_windows_;
49 connection::Manager windows_connections_;
50};
51
52} // namespace launcher
53} // namespace unity
54
55#endif // STORAGE_LAUNCHER_ICON_H
056
=== modified file 'launcher/SwitcherController.cpp'
--- launcher/SwitcherController.cpp 2015-12-16 02:16:57 +0000
+++ launcher/SwitcherController.cpp 2016-02-09 10:44:04 +0000
@@ -720,14 +720,11 @@
720 uint64_t second_first = 0; // second icons first highest active720 uint64_t second_first = 0; // second icons first highest active
721721
722 WindowManager& wm = WindowManager::Default();722 WindowManager& wm = WindowManager::Default();
723 for (auto& window : first->Windows())723 auto const& windows = (model_->only_apps_on_viewport) ? first->WindowsOnViewport() : first->Windows();
724
725 for (auto& window : windows)
724 {726 {
725 Window xid = window->window_id();727 uint64_t num = wm.GetWindowActiveNumber(window->window_id());
726
727 if (model_->only_apps_on_viewport && !wm.IsWindowOnCurrentDesktop(xid))
728 continue;
729
730 uint64_t num = wm.GetWindowActiveNumber(xid);
731728
732 if (num > first_highest)729 if (num > first_highest)
733 {730 {
734731
=== modified file 'launcher/SwitcherModel.cpp'
--- launcher/SwitcherModel.cpp 2015-12-16 02:16:57 +0000
+++ launcher/SwitcherModel.cpp 2016-02-09 10:44:04 +0000
@@ -37,16 +37,7 @@
37bool CompareSwitcherItemsPriority(AbstractLauncherIcon::Ptr const& first,37bool CompareSwitcherItemsPriority(AbstractLauncherIcon::Ptr const& first,
38 AbstractLauncherIcon::Ptr const& second)38 AbstractLauncherIcon::Ptr const& second)
39{39{
40 if (first->GetIconType() == second->GetIconType())40 return first->SwitcherPriority() > second->SwitcherPriority();
41 return first->SwitcherPriority() > second->SwitcherPriority();
42
43 if (first->GetIconType() == AbstractLauncherIcon::IconType::DESKTOP)
44 return true;
45
46 if (second->GetIconType() == AbstractLauncherIcon::IconType::DESKTOP)
47 return false;
48
49 return first->GetIconType() < second->GetIconType();
50}41}
51}42}
5243
@@ -174,7 +165,7 @@
174165
175void SwitcherModel::AddIcon(AbstractLauncherIcon::Ptr const& icon)166void SwitcherModel::AddIcon(AbstractLauncherIcon::Ptr const& icon)
176{167{
177 if (!icon || icon->GetIconType() != AbstractLauncherIcon::IconType::APPLICATION)168 if (!icon)
178 return;169 return;
179170
180 if (icon->ShowInSwitcher(only_apps_on_viewport))171 if (icon->ShowInSwitcher(only_apps_on_viewport))
181172
=== modified file 'launcher/SwitcherView.cpp'
--- launcher/SwitcherView.cpp 2015-12-15 16:11:09 +0000
+++ launcher/SwitcherView.cpp 2016-02-09 10:44:04 +0000
@@ -538,7 +538,7 @@
538 // tells the renderer to render arrows by number538 // tells the renderer to render arrows by number
539 arg.running_on_viewport = true;539 arg.running_on_viewport = true;
540540
541 arg.window_indicators = icon->WindowsForMonitor(monitor).size();541 arg.window_indicators = icon->WindowsVisibleOnMonitor(monitor);
542 if (arg.window_indicators > 1)542 if (arg.window_indicators > 1)
543 arg.running_arrow = true;543 arg.running_arrow = true;
544 else544 else
545545
=== modified file 'launcher/TrashLauncherIcon.cpp'
--- launcher/TrashLauncherIcon.cpp 2014-04-16 01:24:47 +0000
+++ launcher/TrashLauncherIcon.cpp 2016-02-09 10:44:04 +0000
@@ -1,6 +1,6 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*2/*
3 * Copyright (C) 2010-2013 Canonical Ltd3 * Copyright (C) 2010-2015 Canonical Ltd
4 *4 *
5 * This program is free software: you can redistribute it and/or modify5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as6 * it under the terms of the GNU General Public License version 3 as
@@ -24,6 +24,7 @@
24#include "config.h"24#include "config.h"
25#include <glib/gi18n-lib.h>25#include <glib/gi18n-lib.h>
26#include <NuxCore/Logger.h>26#include <NuxCore/Logger.h>
27#include <UnityCore/DesktopUtilities.h>
27#include <zeitgeist.h>28#include <zeitgeist.h>
2829
29#include "QuicklistMenuItemLabel.h"30#include "QuicklistMenuItemLabel.h"
@@ -39,20 +40,19 @@
39 DECLARE_LOGGER(logger, "unity.launcher.icon.trash");40 DECLARE_LOGGER(logger, "unity.launcher.icon.trash");
40 const std::string ZEITGEIST_UNITY_ACTOR = "application://compiz.desktop";41 const std::string ZEITGEIST_UNITY_ACTOR = "application://compiz.desktop";
41 const std::string TRASH_URI = "trash:";42 const std::string TRASH_URI = "trash:";
43 const std::string TRASH_PATH = "file://" + DesktopUtilities::GetUserTrashDirectory();
42}44}
4345
44TrashLauncherIcon::TrashLauncherIcon(FileManager::Ptr const& fmo)46TrashLauncherIcon::TrashLauncherIcon(FileManager::Ptr const& fm)
45 : SimpleLauncherIcon(IconType::TRASH)47 : WindowedLauncherIcon(IconType::TRASH)
48 , StorageLauncherIcon(GetIconType(), fm ? fm : GnomeFileManager::Get())
46 , empty_(true)49 , empty_(true)
47 , file_manager_(fmo ? fmo : GnomeFileManager::Get())
48{50{
49 tooltip_text = _("Trash");51 tooltip_text = _("Trash");
50 icon_name = "user-trash";52 icon_name = "user-trash";
51 position = Position::END;53 position = Position::END;
52 SetQuirk(Quirk::VISIBLE, true);54 SetQuirk(Quirk::VISIBLE, true);
53 SkipQuirkAnimation(Quirk::VISIBLE);55 SkipQuirkAnimation(Quirk::VISIBLE);
54
55 SetQuirk(Quirk::RUNNING, file_manager_->IsTrashOpened());
56 SetShortcut('t');56 SetShortcut('t');
5757
58 glib::Object<GFile> location(g_file_new_for_uri(TRASH_URI.c_str()));58 glib::Object<GFile> location(g_file_new_for_uri(TRASH_URI.c_str()));
@@ -67,20 +67,27 @@
67 }67 }
68 else68 else
69 {69 {
70 trash_changed_signal_.Connect(trash_monitor_, "changed",70 glib_signals_.Add<void, GFileMonitor*, GFile*, GFile*, GFileMonitorEvent>(trash_monitor_, "changed",
71 [this] (GFileMonitor*, GFile*, GFile*, GFileMonitorEvent) {71 [this] (GFileMonitor*, GFile*, GFile*, GFileMonitorEvent) {
72 UpdateTrashIcon();72 UpdateTrashIcon();
73 });73 });
74 }74 }
7575
76 file_manager_->locations_changed.connect(sigc::mem_fun(this, &TrashLauncherIcon::OnOpenedLocationsChanged));
77
78 UpdateTrashIcon();76 UpdateTrashIcon();
79}77 UpdateStorageWindows();
8078}
81void TrashLauncherIcon::OnOpenedLocationsChanged()79
82{80WindowList TrashLauncherIcon::GetStorageWindows() const
83 SetQuirk(Quirk::RUNNING, file_manager_->IsTrashOpened());81{
82 auto windows = file_manager_->WindowsForLocation(TRASH_URI);
83 auto const& path_wins = file_manager_->WindowsForLocation(TRASH_PATH);
84 windows.insert(end(windows), begin(path_wins), end(path_wins));
85 return windows;
86}
87
88void TrashLauncherIcon::OpenInstanceLauncherIcon(Time timestamp)
89{
90 file_manager_->OpenTrash(timestamp);
84}91}
8592
86AbstractLauncherIcon::MenuItemsVector TrashLauncherIcon::GetMenus()93AbstractLauncherIcon::MenuItemsVector TrashLauncherIcon::GetMenus()
@@ -92,22 +99,43 @@
92 dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Empty Trash…"));99 dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Empty Trash…"));
93 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, !empty_);100 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, !empty_);
94 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);101 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
95 empty_activated_signal_.Connect(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,102 glib_signals_.Add<void, DbusmenuMenuitem*, unsigned>(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
96 [this] (DbusmenuMenuitem*, unsigned timestamp) {103 [this] (DbusmenuMenuitem*, unsigned timestamp) {
97 file_manager_->EmptyTrash(timestamp);104 file_manager_->EmptyTrash(timestamp);
98 });105 });
99106
100 result.push_back(menu_item);107 result.push_back(menu_item);
101108
109 if (IsRunning())
110 {
111 auto const& windows_items = GetWindowsMenuItems();
112 if (!windows_items.empty())
113 {
114 menu_item = dbusmenu_menuitem_new();
115 dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
116 result.push_back(menu_item);
117
118 result.insert(end(result), begin(windows_items), end(windows_items));
119 }
120
121 menu_item = dbusmenu_menuitem_new();
122 dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
123 result.push_back(menu_item);
124
125 menu_item = dbusmenu_menuitem_new();
126 dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Quit"));
127 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
128 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
129 result.push_back(menu_item);
130
131 glib_signals_.Add<void, DbusmenuMenuitem*, unsigned>(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, [this] (DbusmenuMenuitem*, int) {
132 Quit();
133 });
134 }
135
102 return result;136 return result;
103}137}
104138
105void TrashLauncherIcon::ActivateLauncherIcon(ActionArg arg)
106{
107 SimpleLauncherIcon::ActivateLauncherIcon(arg);
108 file_manager_->OpenTrash(arg.timestamp);
109}
110
111void TrashLauncherIcon::UpdateTrashIcon()139void TrashLauncherIcon::UpdateTrashIcon()
112{140{
113 glib::Object<GFile> location(g_file_new_for_uri(TRASH_URI.c_str()));141 glib::Object<GFile> location(g_file_new_for_uri(TRASH_URI.c_str()));
114142
=== modified file 'launcher/TrashLauncherIcon.h'
--- launcher/TrashLauncherIcon.h 2013-04-03 20:45:58 +0000
+++ launcher/TrashLauncherIcon.h 2016-02-09 10:44:04 +0000
@@ -23,9 +23,10 @@
23#include <gio/gio.h>23#include <gio/gio.h>
24#include <UnityCore/GLibWrapper.h>24#include <UnityCore/GLibWrapper.h>
25#include <UnityCore/GLibSignal.h>25#include <UnityCore/GLibSignal.h>
26#include <UnityCore/ConnectionManager.h>
2627
27#include "DndData.h"28#include "DndData.h"
28#include "SimpleLauncherIcon.h"29#include "StorageLauncherIcon.h"
29#include "unity-shared/FileManager.h"30#include "unity-shared/FileManager.h"
3031
31namespace unity32namespace unity
@@ -33,7 +34,7 @@
33namespace launcher34namespace launcher
34{35{
3536
36class TrashLauncherIcon : public SimpleLauncherIcon37class TrashLauncherIcon : public StorageLauncherIcon
37{38{
38public:39public:
39 TrashLauncherIcon(FileManager::Ptr const& = nullptr);40 TrashLauncherIcon(FileManager::Ptr const& = nullptr);
@@ -45,21 +46,18 @@
45 bool OnShouldHighlightOnDrag(DndData const& dnd_data);46 bool OnShouldHighlightOnDrag(DndData const& dnd_data);
46 void OnAcceptDrop(DndData const& dnd_data);47 void OnAcceptDrop(DndData const& dnd_data);
4748
49 WindowList GetStorageWindows() const override;
48 std::string GetName() const;50 std::string GetName() const;
4951
50private:52private:
51 void ActivateLauncherIcon(ActionArg arg);53 void OpenInstanceLauncherIcon(Time timestamp) override;
52 void OnOpenedLocationsChanged();
53 MenuItemsVector GetMenus();54 MenuItemsVector GetMenus();
5455
55 static void UpdateTrashIconCb(GObject* source, GAsyncResult* res, gpointer data);56 static void UpdateTrashIconCb(GObject* source, GAsyncResult* res, gpointer data);
5657
57 bool empty_;58 bool empty_;
58 FileManager::Ptr file_manager_;
59 glib::Cancellable cancellable_;59 glib::Cancellable cancellable_;
60 glib::Object<GFileMonitor> trash_monitor_;60 glib::Object<GFileMonitor> trash_monitor_;
61 glib::Signal<void, GFileMonitor*, GFile*, GFile*, GFileMonitorEvent> trash_changed_signal_;
62 glib::Signal<void, DbusmenuMenuitem*, unsigned> empty_activated_signal_;
63};61};
6462
65}63}
6664
=== modified file 'launcher/VolumeLauncherIcon.cpp'
--- launcher/VolumeLauncherIcon.cpp 2015-01-22 15:05:34 +0000
+++ launcher/VolumeLauncherIcon.cpp 2016-02-09 10:44:04 +0000
@@ -49,7 +49,7 @@
49 , volume_(volume)49 , volume_(volume)
50 , devices_settings_(devices_settings)50 , devices_settings_(devices_settings)
51 , notification_(notification)51 , notification_(notification)
52 , file_manager_(fm)52 , file_manager_(parent_->file_manager_)
53 {53 {
54 UpdateIcon();54 UpdateIcon();
55 UpdateVisibility();55 UpdateVisibility();
@@ -60,48 +60,41 @@
60 {60 {
61 parent_->tooltip_text = volume_->GetName();61 parent_->tooltip_text = volume_->GetName();
62 parent_->icon_name = volume_->GetIconName();62 parent_->icon_name = volume_->GetIconName();
63 parent_->SetQuirk(Quirk::RUNNING, file_manager_->IsPrefixOpened(volume_->GetUri()));
64 }63 }
6564
66 void UpdateVisibility()65 void UpdateVisibility()
67 {66 {
68 UpdateKeepInLauncher();67 parent_->SetQuirk(Quirk::VISIBLE, IsVisible());
69 parent_->SetQuirk(Quirk::VISIBLE, keep_in_launcher_);68 }
70 }69
7170 bool IsBlackListed()
72 void UpdateKeepInLauncher()71 {
73 {72 return devices_settings_->IsABlacklistedDevice(volume_->GetIdentifier());
74 auto const& identifier = volume_->GetIdentifier();73 }
75 keep_in_launcher_ = !devices_settings_->IsABlacklistedDevice(identifier);74
75 bool IsVisible()
76 {
77 if (IsBlackListed() && parent_->GetManagedWindows().empty())
78 return false;
79
80 return true;
76 }81 }
7782
78 void ConnectSignals()83 void ConnectSignals()
79 {84 {
80 connections_.Add(volume_->changed.connect(sigc::mem_fun(this, &Impl::OnVolumeChanged)));85 connections_.Add(volume_->changed.connect([this] { UpdateIcon(); }));
81 connections_.Add(volume_->removed.connect(sigc::mem_fun(this, &Impl::OnVolumeRemoved)));86 connections_.Add(volume_->removed.connect(sigc::mem_fun(this, &Impl::OnVolumeRemoved)));
82 connections_.Add(devices_settings_->changed.connect(sigc::mem_fun(this, &Impl::OnSettingsChanged)));87 connections_.Add(devices_settings_->changed.connect([this] { UpdateVisibility(); }));
83 connections_.Add(file_manager_->locations_changed.connect(sigc::mem_fun(this, &Impl::UpdateIcon)));88 connections_.Add(parent_->windows_changed.connect([this] (int) { UpdateVisibility(); }));
84 }
85
86 void OnVolumeChanged()
87 {
88 UpdateIcon();
89 }89 }
9090
91 void OnVolumeRemoved()91 void OnVolumeRemoved()
92 {92 {
93 if (devices_settings_->IsABlacklistedDevice(volume_->GetIdentifier()))93 devices_settings_->TryToUnblacklist(volume_->GetIdentifier());
94 devices_settings_->TryToUnblacklist(volume_->GetIdentifier());
95
96 parent_->UnStick();94 parent_->UnStick();
97 parent_->Remove();95 parent_->Remove();
98 }96 }
9997
100 void OnSettingsChanged()
101 {
102 UpdateVisibility();
103 }
104
105 bool CanEject() const98 bool CanEject() const
106 {99 {
107 return volume_->CanBeEjected();100 return volume_->CanBeEjected();
@@ -152,7 +145,7 @@
152 void OpenInFileManager(uint64_t timestamp)145 void OpenInFileManager(uint64_t timestamp)
153 {146 {
154 DoActionWhenMounted([this, timestamp] {147 DoActionWhenMounted([this, timestamp] {
155 file_manager_->OpenActiveChild(volume_->GetUri(), timestamp);148 file_manager_->Open(volume_->GetUri(), timestamp);
156 });149 });
157 }150 }
158151
@@ -171,29 +164,38 @@
171 AppendSeparatorItem(result);164 AppendSeparatorItem(result);
172 AppendNameItem(result);165 AppendNameItem(result);
173 AppendSeparatorItem(result);166 AppendSeparatorItem(result);
174 AppendUnlockFromLauncherItem(result);167 AppendWindowsItems(result);
168 AppendToggleLockFromLauncherItem(result);
175 AppendEjectItem(result);169 AppendEjectItem(result);
176 AppendSafelyRemoveItem(result);170 AppendSafelyRemoveItem(result);
177 AppendUnmountItem(result);171 AppendUnmountItem(result);
172 AppendQuitItem(result);
178173
179 return result;174 return result;
180 }175 }
181176
182 void AppendUnlockFromLauncherItem(MenuItemsVector& menu)177 void AppendToggleLockFromLauncherItem(MenuItemsVector& menu)
183 {178 {
184 if (volume_->GetIdentifier().empty())179 if (volume_->GetIdentifier().empty())
185 return;180 return;
186181
187 glib::Object<DbusmenuMenuitem> menu_item(dbusmenu_menuitem_new());182 glib::Object<DbusmenuMenuitem> menu_item(dbusmenu_menuitem_new());
188183
189 dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Unlock from Launcher"));184 const char* label = IsBlackListed() ? _("Lock to Launcher") : _("Unlock from Launcher");
185 dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, label);
190 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);186 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
191 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);187 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
192188
193 gsignals_.Add(new ItemSignal(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, [this] (DbusmenuMenuitem*, int) {189 parent_->glib_signals_.Add(new ItemSignal(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, [this] (DbusmenuMenuitem*, int) {
194 auto const& identifier = volume_->GetIdentifier();190 if (!IsBlackListed())
195 parent_->UnStick();191 {
196 devices_settings_->TryToBlacklist(identifier);192 parent_->UnStick();
193 devices_settings_->TryToBlacklist(volume_->GetIdentifier());
194 }
195 else
196 {
197 devices_settings_->TryToUnblacklist(volume_->GetIdentifier());
198 }
197 }));199 }));
198200
199 menu.push_back(menu_item);201 menu.push_back(menu_item);
@@ -220,13 +222,26 @@
220 dbusmenu_menuitem_property_set_bool(menu_item, QuicklistMenuItem::MARKUP_ENABLED_PROPERTY, true);222 dbusmenu_menuitem_property_set_bool(menu_item, QuicklistMenuItem::MARKUP_ENABLED_PROPERTY, true);
221 dbusmenu_menuitem_property_set_bool(menu_item, QuicklistMenuItem::MARKUP_ACCEL_DISABLED_PROPERTY, true);223 dbusmenu_menuitem_property_set_bool(menu_item, QuicklistMenuItem::MARKUP_ACCEL_DISABLED_PROPERTY, true);
222224
223 gsignals_.Add(new ItemSignal(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, [this] (DbusmenuMenuitem*, unsigned timestamp) {225 parent_->glib_signals_.Add(new ItemSignal(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, [this] (DbusmenuMenuitem*, unsigned timestamp) {
224 OpenInFileManager(timestamp);226 OpenInFileManager(timestamp);
225 }));227 }));
226228
227 menu.push_back(menu_item);229 menu.push_back(menu_item);
228 }230 }
229231
232 void AppendWindowsItems(MenuItemsVector& menu)
233 {
234 if (!parent_->IsRunning())
235 return;
236
237 auto const& windows_items = parent_->GetWindowsMenuItems();
238 if (!windows_items.empty())
239 {
240 menu.insert(end(menu), begin(windows_items), end(windows_items));
241 AppendSeparatorItem(menu);
242 }
243 }
244
230 void AppendOpenItem(MenuItemsVector& menu)245 void AppendOpenItem(MenuItemsVector& menu)
231 {246 {
232 glib::Object<DbusmenuMenuitem> menu_item(dbusmenu_menuitem_new());247 glib::Object<DbusmenuMenuitem> menu_item(dbusmenu_menuitem_new());
@@ -235,7 +250,7 @@
235 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);250 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
236 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);251 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
237252
238 gsignals_.Add(new ItemSignal(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, [this] (DbusmenuMenuitem*, unsigned timestamp) {253 parent_->glib_signals_.Add(new ItemSignal(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, [this] (DbusmenuMenuitem*, unsigned timestamp) {
239 OpenInFileManager(timestamp);254 OpenInFileManager(timestamp);
240 }));255 }));
241256
@@ -253,7 +268,8 @@
253 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);268 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
254 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);269 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
255270
256 gsignals_.Add(new ItemSignal(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, [this] (DbusmenuMenuitem*, int) {271 parent_->glib_signals_.Add(new ItemSignal(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, [this] (DbusmenuMenuitem*, int) {
272 parent_->Quit();
257 EjectAndShowNotification();273 EjectAndShowNotification();
258 }));274 }));
259275
@@ -271,8 +287,9 @@
271 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);287 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
272 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);288 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
273289
274 gsignals_.Add(new ItemSignal(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, [this] (DbusmenuMenuitem*, int) {290 parent_->glib_signals_.Add(new ItemSignal(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, [this] (DbusmenuMenuitem*, int) {
275 volume_->StopDrive();291 parent_->Quit();
292 volume_->StopDrive();
276 }));293 }));
277294
278 menu.push_back(menu_item);295 menu.push_back(menu_item);
@@ -289,8 +306,29 @@
289 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);306 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
290 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);307 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
291308
292 gsignals_.Add(new ItemSignal(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, [this] (DbusmenuMenuitem*, int) {309 parent_->glib_signals_.Add(new ItemSignal(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, [this] (DbusmenuMenuitem*, int) {
293 volume_->Unmount();310 volume_->Unmount();
311 }));
312
313 menu.push_back(menu_item);
314 }
315
316 void AppendQuitItem(MenuItemsVector& menu)
317 {
318 if (!parent_->IsRunning())
319 return;
320
321 if (!menu.empty())
322 AppendSeparatorItem(menu);
323
324 glib::Object<DbusmenuMenuitem> menu_item(dbusmenu_menuitem_new());
325
326 dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Quit"));
327 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
328 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
329
330 parent_->glib_signals_.Add(new ItemSignal(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, [this] (DbusmenuMenuitem*, int) {
331 parent_->Quit();
294 }));332 }));
295333
296 menu.push_back(menu_item);334 menu.push_back(menu_item);
@@ -307,13 +345,10 @@
307 }345 }
308346
309 VolumeLauncherIcon* parent_;347 VolumeLauncherIcon* parent_;
310 bool keep_in_launcher_;
311 Volume::Ptr volume_;348 Volume::Ptr volume_;
312 DevicesSettings::Ptr devices_settings_;349 DevicesSettings::Ptr devices_settings_;
313 DeviceNotificationDisplay::Ptr notification_;350 DeviceNotificationDisplay::Ptr notification_;
314 FileManager::Ptr file_manager_;351 FileManager::Ptr file_manager_;
315
316 glib::SignalManager gsignals_;
317 connection::Manager connections_;352 connection::Manager connections_;
318};353};
319354
@@ -325,15 +360,20 @@
325 DevicesSettings::Ptr const& devices_settings,360 DevicesSettings::Ptr const& devices_settings,
326 DeviceNotificationDisplay::Ptr const& notification,361 DeviceNotificationDisplay::Ptr const& notification,
327 FileManager::Ptr const& fm)362 FileManager::Ptr const& fm)
328 : SimpleLauncherIcon(IconType::DEVICE)363 : WindowedLauncherIcon(IconType::DEVICE)
364 , StorageLauncherIcon(GetIconType(), fm)
329 , pimpl_(new Impl(volume, devices_settings, notification, fm, this))365 , pimpl_(new Impl(volume, devices_settings, notification, fm, this))
330{}366{
367 UpdateStorageWindows();
368}
331369
332VolumeLauncherIcon::~VolumeLauncherIcon()370VolumeLauncherIcon::~VolumeLauncherIcon()
333{}371{}
334372
335void VolumeLauncherIcon::AboutToRemove()373void VolumeLauncherIcon::AboutToRemove()
336{374{
375 StorageLauncherIcon::AboutToRemove();
376
337 if (CanEject())377 if (CanEject())
338 EjectAndShowNotification();378 EjectAndShowNotification();
339 else if (CanStop())379 else if (CanStop())
@@ -360,12 +400,6 @@
360 return pimpl_->StopDrive();400 return pimpl_->StopDrive();
361}401}
362402
363void VolumeLauncherIcon::ActivateLauncherIcon(ActionArg arg)
364{
365 SimpleLauncherIcon::ActivateLauncherIcon(arg);
366 pimpl_->OpenInFileManager(arg.timestamp);
367}
368
369AbstractLauncherIcon::MenuItemsVector VolumeLauncherIcon::GetMenus()403AbstractLauncherIcon::MenuItemsVector VolumeLauncherIcon::GetMenus()
370{404{
371 return pimpl_->GetMenus();405 return pimpl_->GetMenus();
@@ -388,17 +422,6 @@
388 SetQuirk(Quirk::VISIBLE, true);422 SetQuirk(Quirk::VISIBLE, true);
389}423}
390424
391bool VolumeLauncherIcon::OnShouldHighlightOnDrag(DndData const& dnd_data)
392{
393 for (auto const& uri : dnd_data.Uris())
394 {
395 if (uri.find("file://") == 0)
396 return true;
397 }
398
399 return false;
400}
401
402nux::DndAction VolumeLauncherIcon::OnQueryAcceptDrop(DndData const& dnd_data)425nux::DndAction VolumeLauncherIcon::OnQueryAcceptDrop(DndData const& dnd_data)
403{426{
404 return dnd_data.Uris().empty() ? nux::DNDACTION_NONE : nux::DNDACTION_COPY;427 return dnd_data.Uris().empty() ? nux::DNDACTION_NONE : nux::DNDACTION_COPY;
@@ -412,6 +435,21 @@
412 FullyAnimateQuirkDelayed(100, LauncherIcon::Quirk::SHIMMER);435 FullyAnimateQuirkDelayed(100, LauncherIcon::Quirk::SHIMMER);
413}436}
414437
438std::string VolumeLauncherIcon::GetVolumeUri() const
439{
440 return pimpl_->volume_->GetUri();
441}
442
443WindowList VolumeLauncherIcon::GetStorageWindows() const
444{
445 return file_manager_->WindowsForLocation(GetVolumeUri());
446}
447
448void VolumeLauncherIcon::OpenInstanceLauncherIcon(Time timestamp)
449{
450 pimpl_->OpenInFileManager(timestamp);
451}
452
415//453//
416// Introspection454// Introspection
417//455//
418456
=== modified file 'launcher/VolumeLauncherIcon.h'
--- launcher/VolumeLauncherIcon.h 2013-10-07 18:33:47 +0000
+++ launcher/VolumeLauncherIcon.h 2016-02-09 10:44:04 +0000
@@ -24,7 +24,7 @@
24#include "Volume.h"24#include "Volume.h"
25#include "DevicesSettings.h"25#include "DevicesSettings.h"
26#include "DeviceNotificationDisplay.h"26#include "DeviceNotificationDisplay.h"
27#include "SimpleLauncherIcon.h"27#include "StorageLauncherIcon.h"
28#include "unity-shared/FileManager.h"28#include "unity-shared/FileManager.h"
2929
30namespace unity30namespace unity
@@ -32,7 +32,7 @@
32namespace launcher32namespace launcher
33{33{
3434
35class VolumeLauncherIcon : public SimpleLauncherIcon35class VolumeLauncherIcon : public StorageLauncherIcon
36{36{
37public:37public:
38 typedef nux::ObjectPtr<VolumeLauncherIcon> Ptr;38 typedef nux::ObjectPtr<VolumeLauncherIcon> Ptr;
@@ -41,7 +41,7 @@
41 DeviceNotificationDisplay::Ptr const&, FileManager::Ptr const&);41 DeviceNotificationDisplay::Ptr const&, FileManager::Ptr const&);
42 virtual ~VolumeLauncherIcon();42 virtual ~VolumeLauncherIcon();
4343
44 virtual void AboutToRemove();44 void AboutToRemove() override;
4545
46 bool CanEject() const; // TODO: rename to public virtual bool IsTrashable();46 bool CanEject() const; // TODO: rename to public virtual bool IsTrashable();
47 void EjectAndShowNotification(); // TODO: rename to private virtual void DoDropToTrash();47 void EjectAndShowNotification(); // TODO: rename to private virtual void DoDropToTrash();
@@ -49,14 +49,16 @@
49 void StopDrive();49 void StopDrive();
50 void Stick(bool save = true);50 void Stick(bool save = true);
51 void UnStick();51 void UnStick();
52
52 MenuItemsVector GetMenus();53 MenuItemsVector GetMenus();
53 std::string GetRemoteUri() const;54 std::string GetRemoteUri() const;
55 std::string GetVolumeUri() const;
5456
55protected:57protected:
56 void ActivateLauncherIcon(ActionArg arg);
57 bool OnShouldHighlightOnDrag(DndData const&);
58 void OnAcceptDrop(DndData const&);58 void OnAcceptDrop(DndData const&);
59 nux::DndAction OnQueryAcceptDrop(DndData const&);59 nux::DndAction OnQueryAcceptDrop(DndData const&);
60 WindowList GetStorageWindows() const override;
61 void OpenInstanceLauncherIcon(Time timestamp) override;
6062
61 // Introspection63 // Introspection
62 virtual std::string GetName() const;64 virtual std::string GetName() const;
6365
=== added file 'launcher/WindowedLauncherIcon.cpp'
--- launcher/WindowedLauncherIcon.cpp 1970-01-01 00:00:00 +0000
+++ launcher/WindowedLauncherIcon.cpp 2016-02-09 10:44:04 +0000
@@ -0,0 +1,618 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*
3 * Copyright (C) 2015 Canonical Ltd
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by: Marco Trevisan <marco.trevisan@canonical.com>
18 */
19
20#include <Nux/Nux.h>
21
22#include "WindowedLauncherIcon.h"
23#include "MultiMonitor.h"
24#include "unity-shared/UBusWrapper.h"
25#include "unity-shared/UBusMessages.h"
26#include "unity-shared/UScreen.h"
27
28namespace unity
29{
30namespace launcher
31{
32namespace
33{
34const std::string ICON_DND_OVER_TIMEOUT = "windowed-icon-dnd-over";
35const int COMPIZ_SCALE_DND_SPREAD = 1 << 7;
36const int MAXIMUM_QUICKLIST_WIDTH = 300;
37}
38
39NUX_IMPLEMENT_OBJECT_TYPE(WindowedLauncherIcon);
40
41WindowedLauncherIcon::WindowedLauncherIcon(AbstractLauncherIcon::IconType icon_type)
42 : SimpleLauncherIcon(icon_type)
43 , last_scroll_timestamp_(0)
44 , progressive_scroll_(0)
45{
46 WindowManager& wm = WindowManager::Default();
47 wm.window_minimized.connect(sigc::mem_fun(this, &WindowedLauncherIcon::OnWindowMinimized));
48 wm.screen_viewport_switch_ended.connect(sigc::mem_fun(this, &WindowedLauncherIcon::EnsureWindowState));
49 wm.terminate_expo.connect(sigc::mem_fun(this, &WindowedLauncherIcon::EnsureWindowState));
50 UScreen::GetDefault()->changed.connect(sigc::hide(sigc::hide(sigc::mem_fun(this, &WindowedLauncherIcon::EnsureWindowsLocation))));
51
52 windows_changed.connect([this] (int) {
53 if (WindowManager::Default().IsScaleActiveForGroup() && IsActive())
54 Spread(true, 0, false);
55 });
56}
57
58bool WindowedLauncherIcon::IsActive() const
59{
60 return GetQuirk(Quirk::ACTIVE);
61}
62
63bool WindowedLauncherIcon::IsRunning() const
64{
65 return GetQuirk(Quirk::RUNNING);
66}
67
68bool WindowedLauncherIcon::IsUrgent() const
69{
70 return GetQuirk(Quirk::URGENT);
71}
72
73bool WindowedLauncherIcon::IsUserVisible() const
74{
75 return IsRunning();
76}
77
78void WindowedLauncherIcon::ActivateLauncherIcon(ActionArg arg)
79{
80 SimpleLauncherIcon::ActivateLauncherIcon(arg);
81 WindowManager& wm = WindowManager::Default();
82
83 // This is a little awkward as the target is only set from the switcher.
84 if (arg.target)
85 {
86 // thumper: should we Raise too? should the WM raise?
87 wm.Activate(arg.target);
88 return;
89 }
90
91 bool scale_was_active = wm.IsScaleActive();
92 bool active = IsActive();
93 bool user_visible = IsRunning();
94 /* We should check each child to see if there is
95 * an unmapped (!= minimized) window around and
96 * if so force "Focus" behaviour */
97
98 if (arg.source != ActionArg::Source::SWITCHER)
99 {
100 user_visible = IsUserVisible();
101
102 if (active)
103 {
104 bool any_visible = false;
105 bool any_mapped = false;
106 bool any_on_top = false;
107 bool any_on_monitor = (arg.monitor < 0);
108 int active_monitor = arg.monitor;
109
110 for (auto const& window : GetManagedWindows())
111 {
112 Window xid = window->window_id();
113
114 if (!any_visible && wm.IsWindowOnCurrentDesktop(xid))
115 {
116 any_visible = true;
117 }
118
119 if (!any_mapped && wm.IsWindowMapped(xid))
120 {
121 any_mapped = true;
122 }
123
124 if (!any_on_top && wm.IsWindowOnTop(xid))
125 {
126 any_on_top = true;
127 }
128
129 if (!any_on_monitor && window->monitor() == arg.monitor &&
130 wm.IsWindowMapped(xid) && wm.IsWindowVisible(xid))
131 {
132 any_on_monitor = true;
133 }
134
135 if (window->active())
136 {
137 active_monitor = window->monitor();
138 }
139 }
140
141 if (!any_visible || !any_mapped || !any_on_top)
142 active = false;
143
144 if (any_on_monitor && arg.monitor >= 0 && active_monitor != arg.monitor)
145 active = false;
146 }
147 }
148
149 /* Behaviour:
150 * 1) Nothing running, or nothing visible -> launch application
151 * 2) Running and active -> spread application
152 * 3) Running and not active -> focus application
153 * 4) Spread is active and different icon pressed -> change spread
154 * 5) Spread is active -> Spread de-activated, and fall through
155 */
156
157 if (!IsRunning() || (IsRunning() && !user_visible)) // #1 above
158 {
159 if (GetQuirk(Quirk::STARTING, arg.monitor))
160 return;
161
162 wm.TerminateScale();
163 SetQuirk(Quirk::STARTING, true, arg.monitor);
164 OpenInstanceLauncherIcon(arg.timestamp);
165 }
166 else // container is running
167 {
168 if (active)
169 {
170 if (scale_was_active) // #5 above
171 {
172 wm.TerminateScale();
173
174 if (minimize_window_on_click())
175 {
176 for (auto const& win : GetWindows(WindowFilter::ON_CURRENT_DESKTOP))
177 wm.Minimize(win->window_id());
178 }
179 else
180 {
181 Focus(arg);
182 }
183 }
184 else // #2 above
185 {
186 if (arg.source != ActionArg::Source::SWITCHER)
187 {
188 bool minimized = false;
189
190 if (minimize_window_on_click())
191 {
192 WindowList const& windows = GetWindows(WindowFilter::ON_CURRENT_DESKTOP);
193
194 if (windows.size() == 1)
195 {
196 wm.Minimize(windows[0]->window_id());
197 minimized = true;
198 }
199 }
200
201 if (!minimized)
202 {
203 Spread(true, 0, false);
204 }
205 }
206 }
207 }
208 else
209 {
210 if (scale_was_active) // #4 above
211 {
212 if (GetWindows(WindowFilter::ON_CURRENT_DESKTOP).size() <= 1)
213 wm.TerminateScale();
214
215 Focus(arg);
216
217 if (arg.source != ActionArg::Source::SWITCHER)
218 Spread(true, 0, false);
219 }
220 else // #3 above
221 {
222 Focus(arg);
223 }
224 }
225 }
226}
227
228WindowList WindowedLauncherIcon::GetWindows(WindowFilterMask filter, int monitor)
229{
230 if ((!filter && monitor < 0) || (filter == WindowFilter::ON_ALL_MONITORS))
231 return GetManagedWindows();
232
233 WindowManager& wm = WindowManager::Default();
234 WindowList results;
235
236 monitor = (filter & WindowFilter::ON_ALL_MONITORS) ? -1 : monitor;
237 bool mapped = (filter & WindowFilter::MAPPED);
238 bool user_visible = (filter & WindowFilter::USER_VISIBLE);
239 bool current_desktop = (filter & WindowFilter::ON_CURRENT_DESKTOP);
240
241 for (auto& window : GetManagedWindows())
242 {
243 if ((monitor >= 0 && window->monitor() == monitor) || monitor < 0)
244 {
245 if ((user_visible && window->visible()) || !user_visible)
246 {
247 Window xid = window->window_id();
248
249 if ((mapped && wm.IsWindowMapped(xid)) || !mapped)
250 {
251 if ((current_desktop && wm.IsWindowOnCurrentDesktop(xid)) || !current_desktop)
252 {
253 results.push_back(window);
254 }
255 }
256 }
257 }
258 }
259
260 return results;
261}
262
263WindowList WindowedLauncherIcon::Windows()
264{
265 return GetWindows(WindowFilter::MAPPED|WindowFilter::ON_ALL_MONITORS);
266}
267
268WindowList WindowedLauncherIcon::WindowsOnViewport()
269{
270 WindowFilterMask filter = 0;
271 filter |= WindowFilter::MAPPED;
272 filter |= WindowFilter::USER_VISIBLE;
273 filter |= WindowFilter::ON_CURRENT_DESKTOP;
274 filter |= WindowFilter::ON_ALL_MONITORS;
275
276 return GetWindows(filter);
277}
278
279WindowList WindowedLauncherIcon::WindowsForMonitor(int monitor)
280{
281 WindowFilterMask filter = 0;
282 filter |= WindowFilter::MAPPED;
283 filter |= WindowFilter::USER_VISIBLE;
284 filter |= WindowFilter::ON_CURRENT_DESKTOP;
285
286 return GetWindows(filter, monitor);
287}
288
289void WindowedLauncherIcon::OnWindowMinimized(Window xid)
290{
291 for (auto const& window : GetManagedWindows())
292 {
293 if (xid == window->window_id())
294 {
295 int monitor = GetCenterForMonitor(window->monitor()).first;
296
297 if (monitor >= 0)
298 {
299 Present(0.5f, 600, monitor);
300 FullyAnimateQuirkDelayed(300, Quirk::SHIMMER, monitor);
301 }
302
303 break;
304 }
305 }
306}
307
308void WindowedLauncherIcon::Focus(ActionArg arg)
309{
310 bool show_only_visible = (arg.source == ActionArg::Source::SWITCHER);
311 ApplicationManager::Default().FocusWindowGroup(GetManagedWindows(), show_only_visible, arg.monitor);
312}
313
314bool WindowedLauncherIcon::Spread(bool current_desktop, int state, bool force)
315{
316 std::vector<Window> windows;
317 for (auto& window : GetWindows(current_desktop ? WindowFilter::ON_CURRENT_DESKTOP : 0))
318 windows.push_back(window->window_id());
319
320 return WindowManager::Default().ScaleWindowGroup(windows, state, force);
321}
322
323void WindowedLauncherIcon::EnsureWindowState()
324{
325 std::vector<int> number_of_windows_on_monitor(monitors::MAX);
326
327 for (auto const& window : WindowsOnViewport())
328 {
329 int monitor = window->monitor();
330
331 // If monitor is -1 (or negative), show on all monitors.
332 if (monitor < 0)
333 {
334 for (unsigned j; j < monitors::MAX; ++j)
335 ++number_of_windows_on_monitor[j];
336 }
337 else
338 {
339 ++number_of_windows_on_monitor[monitor];
340 }
341 }
342
343 for (unsigned i = 0; i < monitors::MAX; ++i)
344 SetNumberOfWindowsVisibleOnMonitor(number_of_windows_on_monitor[i], i);
345}
346
347void WindowedLauncherIcon::EnsureWindowsLocation()
348{
349 EnsureWindowState();
350 UpdateIconGeometries(GetCenters());
351}
352
353void WindowedLauncherIcon::UpdateIconGeometries(std::vector<nux::Point3> const& centers)
354{
355 nux::Geometry geo(0, 0, icon_size, icon_size);
356
357 for (auto& window : GetManagedWindows())
358 {
359 Window xid = window->window_id();
360 int monitor = GetCenterForMonitor(window->monitor()).first;
361
362 if (monitor < 0)
363 {
364 WindowManager::Default().SetWindowIconGeometry(xid, nux::Geometry());
365 continue;
366 }
367
368 geo.x = centers[monitor].x - icon_size / 2;
369 geo.y = centers[monitor].y - icon_size / 2;
370 WindowManager::Default().SetWindowIconGeometry(xid, geo);
371 }
372}
373
374void WindowedLauncherIcon::OnCenterStabilized(std::vector<nux::Point3> const& centers)
375{
376 UpdateIconGeometries(centers);
377}
378
379void WindowedLauncherIcon::OnDndEnter()
380{
381 auto timestamp = nux::GetGraphicsDisplay()->GetCurrentEvent().x11_timestamp;
382
383 _source_manager.AddTimeout(1000, [this, timestamp] {
384 bool to_spread = GetWindows(WindowFilter::ON_CURRENT_DESKTOP).size() > 1;
385
386 if (!to_spread)
387 WindowManager::Default().TerminateScale();
388
389 if (!IsRunning())
390 return false;
391
392 UBusManager::SendMessage(UBUS_OVERLAY_CLOSE_REQUEST);
393 Focus(ActionArg(ActionArg::Source::LAUNCHER, 1, timestamp));
394
395 if (to_spread)
396 Spread(true, COMPIZ_SCALE_DND_SPREAD, false);
397
398 return false;
399 }, ICON_DND_OVER_TIMEOUT);
400}
401
402void WindowedLauncherIcon::OnDndLeave()
403{
404 _source_manager.Remove(ICON_DND_OVER_TIMEOUT);
405}
406
407bool WindowedLauncherIcon::HandlesSpread()
408{
409 return true;
410}
411
412bool WindowedLauncherIcon::ShowInSwitcher(bool current)
413{
414 if (!removed() && IsRunning() && IsVisible())
415 {
416 // If current is true, we only want to show the current workspace.
417 if (!current)
418 {
419 return true;
420 }
421 else
422 {
423 for (unsigned i = 0; i < monitors::MAX; ++i)
424 {
425 if (WindowVisibleOnMonitor(i))
426 return true;
427 }
428 }
429 }
430
431 return false;
432}
433
434bool WindowedLauncherIcon::AllowDetailViewInSwitcher() const
435{
436 return true;
437}
438
439uint64_t WindowedLauncherIcon::SwitcherPriority()
440{
441 uint64_t result = 0;
442
443 for (auto& window : GetManagedWindows())
444 {
445 Window xid = window->window_id();
446 result = std::max(result, WindowManager::Default().GetWindowActiveNumber(xid));
447 }
448
449 return result;
450}
451
452void PerformScrollUp(WindowList const& windows, unsigned int progressive_scroll)
453{
454 if (progressive_scroll == windows.size() - 1)
455 {
456 //RestackAbove to preserve Global Stacking Order
457 WindowManager::Default().RestackBelow(windows.at(0)->window_id(), windows.at(1)->window_id());
458 WindowManager::Default().RestackBelow(windows.at(1)->window_id(), windows.at(0)->window_id());
459 windows.back()->Focus();
460 return;
461 }
462
463 WindowManager::Default().RestackBelow(windows.at(0)->window_id(), windows.at(progressive_scroll + 1)->window_id());
464 windows.at(progressive_scroll + 1)->Focus();
465}
466
467void PerformScrollDown(WindowList const& windows, unsigned int progressive_scroll)
468{
469 if (!progressive_scroll)
470 {
471 WindowManager::Default().RestackBelow(windows.at(0)->window_id(), windows.back()->window_id());
472 windows.at(1)->Focus();
473 return;
474 }
475
476 WindowManager::Default().RestackBelow(windows.at(0)->window_id(), windows.at(progressive_scroll)->window_id());
477 windows.at(progressive_scroll)->Focus();
478}
479
480void WindowedLauncherIcon::PerformScroll(ScrollDirection direction, Time timestamp)
481{
482 if (timestamp - last_scroll_timestamp_ < 150)
483 return;
484 else if (timestamp - last_scroll_timestamp_ > 1500)
485 progressive_scroll_ = 0;
486
487 last_scroll_timestamp_ = timestamp;
488
489 auto const& windows = GetWindowsOnCurrentDesktopInStackingOrder();
490
491 if (windows.empty())
492 return;
493
494 if (scroll_inactive_icons && !IsActive())
495 {
496 windows.at(0)->Focus();
497 return;
498 }
499
500 if (!scroll_inactive_icons && !IsActive())
501 return;
502
503 if (windows.size() <= 1)
504 return;
505
506 if (direction == ScrollDirection::DOWN)
507 ++progressive_scroll_;
508 else
509 //--progressive_scroll_; but roll to the top of windows
510 progressive_scroll_ += windows.size() - 1;
511 progressive_scroll_ %= windows.size();
512
513 switch(direction)
514 {
515 case ScrollDirection::UP:
516 PerformScrollUp(windows, progressive_scroll_);
517 break;
518 case ScrollDirection::DOWN:
519 PerformScrollDown(windows, progressive_scroll_);
520 break;
521 }
522}
523
524WindowList WindowedLauncherIcon::GetWindowsOnCurrentDesktopInStackingOrder()
525{
526 auto windows = GetWindows(WindowFilter::ON_CURRENT_DESKTOP | WindowFilter::ON_ALL_MONITORS);
527 auto sorted_windows = WindowManager::Default().GetWindowsInStackingOrder();
528
529 // Order the windows
530 std::sort(windows.begin(), windows.end(), [&sorted_windows] (ApplicationWindowPtr const& win1, ApplicationWindowPtr const& win2) {
531 for (auto const& window : sorted_windows)
532 {
533 if (window == win1->window_id())
534 return false;
535 else if (window == win2->window_id())
536 return true;
537 }
538
539 return true;
540 });
541
542 return windows;
543}
544
545void WindowedLauncherIcon::Quit() const
546{
547 for (auto& window : GetManagedWindows())
548 window->Quit();
549}
550
551void WindowedLauncherIcon::AboutToRemove()
552{
553 Quit();
554}
555
556AbstractLauncherIcon::MenuItemsVector WindowedLauncherIcon::GetWindowsMenuItems()
557{
558 auto const& windows = Windows();
559 MenuItemsVector menu_items;
560
561 // We only add quicklist menu-items for windows if we have more than one window
562 if (windows.size() < 2)
563 return menu_items;
564
565 // add menu items for all open windows
566 for (auto const& w : windows)
567 {
568 auto const& title = w->title();
569
570 if (title.empty())
571 continue;
572
573 glib::Object<DbusmenuMenuitem> menu_item(dbusmenu_menuitem_new());
574 dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, title.c_str());
575 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
576 dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
577 dbusmenu_menuitem_property_set_bool(menu_item, QuicklistMenuItem::MARKUP_ACCEL_DISABLED_PROPERTY, true);
578 dbusmenu_menuitem_property_set_int(menu_item, QuicklistMenuItem::MAXIMUM_LABEL_WIDTH_PROPERTY, MAXIMUM_QUICKLIST_WIDTH);
579
580 Window xid = w->window_id();
581 glib_signals_.Add<void, DbusmenuMenuitem*, unsigned>(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
582 [xid] (DbusmenuMenuitem*, unsigned) {
583 WindowManager& wm = WindowManager::Default();
584 wm.Activate(xid);
585 wm.Raise(xid);
586 });
587
588 if (w->active())
589 {
590 dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE, DBUSMENU_MENUITEM_TOGGLE_RADIO);
591 dbusmenu_menuitem_property_set_int(menu_item, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED);
592 }
593
594 menu_items.push_back(menu_item);
595 }
596
597 return menu_items;
598}
599
600std::string WindowedLauncherIcon::GetName() const
601{
602 return "WindowedLauncherIcon";
603}
604
605void WindowedLauncherIcon::AddProperties(debug::IntrospectionData& introspection)
606{
607 SimpleLauncherIcon::AddProperties(introspection);
608
609 std::vector<Window> xids;
610 for (auto const& window : GetManagedWindows())
611 xids.push_back(window->window_id());
612
613 introspection.add("xids", glib::Variant::FromVector(xids))
614 .add("sticky", IsSticky());
615}
616
617} // namespace launcher
618} // namespace unity
0619
=== added file 'launcher/WindowedLauncherIcon.h'
--- launcher/WindowedLauncherIcon.h 1970-01-01 00:00:00 +0000
+++ launcher/WindowedLauncherIcon.h 2016-02-09 10:44:04 +0000
@@ -0,0 +1,100 @@
1// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
2/*
3 * Copyright (C) 2015 Canonical Ltd
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authored by: Marco Trevisan <marco.trevisan@canonical.com>
18 */
19
20#ifndef WINDOWED_LAUNCHER_ICON_H
21#define WINDOWED_LAUNCHER_ICON_H
22
23#include <UnityCore/GLibSignal.h>
24
25#include "SimpleLauncherIcon.h"
26
27namespace unity
28{
29namespace launcher
30{
31
32class WindowedLauncherIcon : public SimpleLauncherIcon
33{
34 NUX_DECLARE_OBJECT_TYPE(WindowedLauncherIcon, SimpleLauncherIcon);
35public:
36 WindowedLauncherIcon(AbstractLauncherIcon::IconType);
37
38 WindowList Windows() override;
39 WindowList WindowsOnViewport() override;
40 WindowList WindowsForMonitor(int monitor) override;
41
42 virtual bool IsActive() const;
43 virtual bool IsRunning() const;
44 virtual bool IsUrgent() const;
45 virtual bool IsUserVisible() const;
46
47 virtual void Quit() const;
48
49protected:
50 virtual WindowList GetManagedWindows() const = 0;
51 void EnsureWindowState();
52 void EnsureWindowsLocation();
53
54 virtual void UpdateIconGeometries(std::vector<nux::Point3> const& centers);
55
56 std::string GetName() const override;
57 void AddProperties(debug::IntrospectionData&) override;
58
59 bool HandlesSpread() override;
60 bool ShowInSwitcher(bool current) override;
61 bool AllowDetailViewInSwitcher() const override;
62 uint64_t SwitcherPriority() override;
63 void AboutToRemove() override;
64
65 void ActivateLauncherIcon(ActionArg arg) override;
66 void PerformScroll(ScrollDirection direction, Time timestamp) override;
67 virtual void Focus(ActionArg arg);
68 virtual bool Spread(bool current_desktop, int state, bool force);
69
70 typedef unsigned long int WindowFilterMask;
71 enum WindowFilter
72 {
73 MAPPED = (1 << 0),
74 USER_VISIBLE = (1 << 1),
75 ON_CURRENT_DESKTOP = (1 << 2),
76 ON_ALL_MONITORS = (1 << 3),
77 };
78
79 WindowList GetWindows(WindowFilterMask filter = 0, int monitor = -1);
80 WindowList GetWindowsOnCurrentDesktopInStackingOrder();
81
82 MenuItemsVector GetWindowsMenuItems();
83
84private:
85 void OnCenterStabilized(std::vector<nux::Point3> const& centers) override;
86 void OnWindowMinimized(Window);
87 void OnDndEnter();
88 void OnDndLeave();
89
90 Time last_scroll_timestamp_;
91 unsigned int progressive_scroll_;
92
93protected:
94 glib::SignalManager glib_signals_;
95};
96
97} // namespace launcher
98} // namespace unity
99
100#endif // WINDOWED_LAUNCHER_ICON_H
0101
=== modified file 'tests/CMakeLists.txt'
--- tests/CMakeLists.txt 2015-12-11 12:45:49 +0000
+++ tests/CMakeLists.txt 2016-02-09 10:44:04 +0000
@@ -80,6 +80,7 @@
80 set (GTEST_SLOW_SOURCES80 set (GTEST_SLOW_SOURCES
81 test_main.cpp81 test_main.cpp
82 logger_helper.cpp82 logger_helper.cpp
83 mock-application.cpp
83 test_switcher_controller_slow.cpp84 test_switcher_controller_slow.cpp
84 test_switcher_controller_class.cpp85 test_switcher_controller_class.cpp
85 test_tooltip_manager.cpp86 test_tooltip_manager.cpp
8687
=== modified file 'tests/mock-application.h'
--- tests/mock-application.h 2015-07-09 17:11:53 +0000
+++ tests/mock-application.h 2016-02-09 10:44:04 +0000
@@ -91,7 +91,7 @@
91 return;91 return;
9292
93 title_ = new_title;93 title_ = new_title;
94 title.changed(title_);94 title.changed.emit(title_);
95 }95 }
9696
97 void SetIcon(std::string const& new_icon)97 void SetIcon(std::string const& new_icon)
@@ -100,7 +100,16 @@
100 return;100 return;
101101
102 icon_ = new_icon;102 icon_ = new_icon;
103 icon.changed(icon_);103 icon.changed.emit(icon_);
104 }
105
106 void SetMonitor(int new_monitor)
107 {
108 if (monitor_ == new_monitor)
109 return;
110
111 monitor_ = new_monitor;
112 monitor.changed.emit(monitor_);
104 }113 }
105};114};
106115
@@ -329,6 +338,7 @@
329 MOCK_CONST_METHOD0(GetActiveApplication, unity::ApplicationPtr());338 MOCK_CONST_METHOD0(GetActiveApplication, unity::ApplicationPtr());
330 MOCK_CONST_METHOD1(GetWindowsForMonitor, unity::WindowList(int));339 MOCK_CONST_METHOD1(GetWindowsForMonitor, unity::WindowList(int));
331 MOCK_CONST_METHOD1(GetWindowForId, unity::ApplicationWindowPtr(Window));340 MOCK_CONST_METHOD1(GetWindowForId, unity::ApplicationWindowPtr(Window));
341 MOCK_CONST_METHOD3(FocusWindowGroup, void(unity::WindowList const&, bool, int));
332342
333 unity::ApplicationPtr LocalGetApplicationForDesktopFile(std::string const& desktop_file)343 unity::ApplicationPtr LocalGetApplicationForDesktopFile(std::string const& desktop_file)
334 {344 {
335345
=== modified file 'tests/test_application_launcher_icon.cpp'
--- tests/test_application_launcher_icon.cpp 2015-05-22 16:04:12 +0000
+++ tests/test_application_launcher_icon.cpp 2016-02-09 10:44:04 +0000
@@ -50,7 +50,8 @@
50 typedef nux::ObjectPtr<MockApplicationLauncherIcon> Ptr;50 typedef nux::ObjectPtr<MockApplicationLauncherIcon> Ptr;
5151
52 MockApplicationLauncherIcon(ApplicationPtr const& app)52 MockApplicationLauncherIcon(ApplicationPtr const& app)
53 : ApplicationLauncherIcon(app)53 : WindowedLauncherIcon(IconType::APPLICATION)
54 , ApplicationLauncherIcon(app)
54 {55 {
55 ON_CALL(*this, Stick(_)).WillByDefault(Invoke([this] (bool save) { ApplicationLauncherIcon::Stick(save); }));56 ON_CALL(*this, Stick(_)).WillByDefault(Invoke([this] (bool save) { ApplicationLauncherIcon::Stick(save); }));
56 ON_CALL(*this, Stick()).WillByDefault(Invoke([this] { ApplicationLauncherIcon::Stick(); }));57 ON_CALL(*this, Stick()).WillByDefault(Invoke([this] { ApplicationLauncherIcon::Stick(); }));
@@ -67,11 +68,14 @@
67 bool LauncherIconIsSticky() const { return LauncherIcon::IsSticky(); }68 bool LauncherIconIsSticky() const { return LauncherIcon::IsSticky(); }
68 void LocalActivate(ActionArg a) { ApplicationLauncherIcon::ActivateLauncherIcon(a); }69 void LocalActivate(ActionArg a) { ApplicationLauncherIcon::ActivateLauncherIcon(a); }
6970
70 using ApplicationLauncherIcon::IsFileManager;
71 using ApplicationLauncherIcon::LogUnityEvent;71 using ApplicationLauncherIcon::LogUnityEvent;
72 using ApplicationLauncherIcon::Remove;72 using ApplicationLauncherIcon::Remove;
73 using ApplicationLauncherIcon::SetApplication;73 using ApplicationLauncherIcon::SetApplication;
74 using ApplicationLauncherIcon::GetApplication;74 using ApplicationLauncherIcon::GetApplication;
75 using ApplicationLauncherIcon::PerformScroll;
76 using LauncherIcon::BackgroundColor;
77 using LauncherIcon::GetRemoteUri;
78 using LauncherIcon::AllowDetailViewInSwitcher;
75};79};
7680
77MATCHER_P(AreArgsEqual, a, "")81MATCHER_P(AreArgsEqual, a, "")
@@ -90,15 +94,15 @@
90 virtual void SetUp() override94 virtual void SetUp() override
91 {95 {
92 usc_app = std::make_shared<MockApplication::Nice>(USC_DESKTOP, "softwarecenter");96 usc_app = std::make_shared<MockApplication::Nice>(USC_DESKTOP, "softwarecenter");
93 usc_icon = new NiceMock<MockApplicationLauncherIcon>(usc_app);97 usc_icon = new MockApplicationLauncherIcon(usc_app);
94 ASSERT_EQ(usc_icon->DesktopFile(), USC_DESKTOP);98 ASSERT_EQ(usc_icon->DesktopFile(), USC_DESKTOP);
9599
96 empty_app = std::make_shared<MockApplication::Nice>(NO_ICON_DESKTOP);100 empty_app = std::make_shared<MockApplication::Nice>(NO_ICON_DESKTOP);
97 empty_icon = new NiceMock<MockApplicationLauncherIcon>(empty_app);101 empty_icon = new MockApplicationLauncherIcon(empty_app);
98 ASSERT_EQ(empty_icon->DesktopFile(), NO_ICON_DESKTOP);102 ASSERT_EQ(empty_icon->DesktopFile(), NO_ICON_DESKTOP);
99103
100 mock_app = std::make_shared<MockApplication::Nice>();104 mock_app = std::make_shared<MockApplication::Nice>();
101 mock_icon = new NiceMock<MockApplicationLauncherIcon>(mock_app);105 mock_icon = new MockApplicationLauncherIcon(mock_app);
102 ASSERT_TRUE(mock_icon->DesktopFile().empty());106 ASSERT_TRUE(mock_icon->DesktopFile().empty());
103 }107 }
104108
@@ -173,7 +177,7 @@
173{177{
174 std::shared_ptr<MockApplication> app = std::make_shared<MockApplication::Nice>(USC_DESKTOP);178 std::shared_ptr<MockApplication> app = std::make_shared<MockApplication::Nice>(USC_DESKTOP);
175 {179 {
176 MockApplicationLauncherIcon::Ptr icon(new NiceMock<MockApplicationLauncherIcon>(app));180 MockApplicationLauncherIcon::Ptr icon(new MockApplicationLauncherIcon(app));
177 EXPECT_FALSE(app->closed.empty());181 EXPECT_FALSE(app->closed.empty());
178 }182 }
179183
@@ -266,7 +270,7 @@
266 auto app = std::make_shared<MockApplication::Nice>(USC_DESKTOP);270 auto app = std::make_shared<MockApplication::Nice>(USC_DESKTOP);
267 app->sticky = true;271 app->sticky = true;
268 app->desktop_file_ = UM_DESKTOP;272 app->desktop_file_ = UM_DESKTOP;
269 MockApplicationLauncherIcon::Ptr icon(new NiceMock<MockApplicationLauncherIcon>(app));273 MockApplicationLauncherIcon::Ptr icon(new MockApplicationLauncherIcon(app));
270 ASSERT_TRUE(icon->IsSticky());274 ASSERT_TRUE(icon->IsSticky());
271 EXPECT_TRUE(icon->LauncherIconIsSticky());275 EXPECT_TRUE(icon->LauncherIconIsSticky());
272}276}
@@ -275,7 +279,7 @@
275{279{
276 auto app = std::make_shared<MockApplication::Nice>();280 auto app = std::make_shared<MockApplication::Nice>();
277 app->sticky = true;281 app->sticky = true;
278 MockApplicationLauncherIcon::Ptr icon(new NiceMock<MockApplicationLauncherIcon>(app));282 MockApplicationLauncherIcon::Ptr icon(new MockApplicationLauncherIcon(app));
279 ASSERT_FALSE(icon->IsSticky());283 ASSERT_FALSE(icon->IsSticky());
280 EXPECT_FALSE(icon->LauncherIconIsSticky());284 EXPECT_FALSE(icon->LauncherIconIsSticky());
281}285}
@@ -291,7 +295,7 @@
291TEST_F(TestApplicationLauncherIcon, StickAndSaveDesktopLessAppCreatesNewDesktop)295TEST_F(TestApplicationLauncherIcon, StickAndSaveDesktopLessAppCreatesNewDesktop)
292{296{
293 auto app = std::make_shared<MockApplication::Nice>();297 auto app = std::make_shared<MockApplication::Nice>();
294 MockApplicationLauncherIcon::Ptr icon(new NiceMock<MockApplicationLauncherIcon>(app));298 MockApplicationLauncherIcon::Ptr icon(new MockApplicationLauncherIcon(app));
295299
296 EXPECT_CALL(*app, CreateLocalDesktopFile());300 EXPECT_CALL(*app, CreateLocalDesktopFile());
297 icon->Stick(true);301 icon->Stick(true);
@@ -354,7 +358,7 @@
354TEST_F(TestApplicationLauncherIcon, UnstickDesktopLessAppLogEvent)358TEST_F(TestApplicationLauncherIcon, UnstickDesktopLessAppLogEvent)
355{359{
356 auto app = std::make_shared<MockApplication::Nice>();360 auto app = std::make_shared<MockApplication::Nice>();
357 MockApplicationLauncherIcon::Ptr icon(new NiceMock<MockApplicationLauncherIcon>(app));361 MockApplicationLauncherIcon::Ptr icon(new MockApplicationLauncherIcon(app));
358362
359 EXPECT_CALL(*unity_app_, LogEvent(ApplicationEventType::ACCESS, _)).Times(0);363 EXPECT_CALL(*unity_app_, LogEvent(ApplicationEventType::ACCESS, _)).Times(0);
360 icon->UnStick();364 icon->UnStick();
@@ -1103,25 +1107,6 @@
1103 dbusmenu_menuitem_handle_event(item, DBUSMENU_MENUITEM_EVENT_ACTIVATED, nullptr, 0);1107 dbusmenu_menuitem_handle_event(item, DBUSMENU_MENUITEM_EVENT_ACTIVATED, nullptr, 0);
1104}1108}
11051109
1106TEST_F(TestApplicationLauncherIcon, IsFileManager)
1107{
1108 EXPECT_FALSE(usc_icon->IsFileManager());
1109 EXPECT_FALSE(empty_icon->IsFileManager());
1110 EXPECT_FALSE(mock_icon->IsFileManager());
1111
1112 auto app = std::make_shared<MockApplication::Nice>("/any/path/org.gnome.Nautilus.desktop", "Nautilus");
1113 MockApplicationLauncherIcon::Ptr icon(new NiceMock<MockApplicationLauncherIcon>(app));
1114 EXPECT_TRUE(icon->IsFileManager());
1115
1116 app = std::make_shared<MockApplication::Nice>("/any/path/nautilus-folder-handler.desktop", "Nautilus");
1117 icon = new NiceMock<MockApplicationLauncherIcon>(app);
1118 EXPECT_TRUE(icon->IsFileManager());
1119
1120 app = std::make_shared<MockApplication::Nice>("/any/path/nautilus-home.desktop", "Nautilus");
1121 icon = new NiceMock<MockApplicationLauncherIcon>(app);
1122 EXPECT_TRUE(icon->IsFileManager());
1123}
1124
1125TEST_F(TestApplicationLauncherIcon, AllowDetailViewInSwitcher)1110TEST_F(TestApplicationLauncherIcon, AllowDetailViewInSwitcher)
1126{1111{
1127 mock_app->type_ = AppType::NORMAL;1112 mock_app->type_ = AppType::NORMAL;
@@ -1232,7 +1217,7 @@
1232 mock_icon->Remove();1217 mock_icon->Remove();
1233 ASSERT_FALSE(mock_app->seen);1218 ASSERT_FALSE(mock_app->seen);
12341219
1235 MockApplicationLauncherIcon::Ptr new_icon(new NiceMock<MockApplicationLauncherIcon>(mock_app));1220 MockApplicationLauncherIcon::Ptr new_icon(new MockApplicationLauncherIcon(mock_app));
1236 mock_icon = nullptr;1221 mock_icon = nullptr;
12371222
1238 EXPECT_TRUE(mock_app->seen);1223 EXPECT_TRUE(mock_app->seen);
12391224
=== modified file 'tests/test_launcher_controller.cpp'
--- tests/test_launcher_controller.cpp 2015-04-16 14:38:54 +0000
+++ tests/test_launcher_controller.cpp 2016-02-09 10:44:04 +0000
@@ -136,8 +136,10 @@
136136
137struct MockApplicationLauncherIcon : ApplicationLauncherIcon137struct MockApplicationLauncherIcon : ApplicationLauncherIcon
138{138{
139 typedef NiceMock<MockApplicationLauncherIcon> Nice;139 // NiceMock doesn't work well with Virtual Inheritance, so we need to disable it
140 typedef nux::ObjectPtr<MockApplicationLauncherIcon::Nice> Ptr;140 //typedef NiceMock<MockApplicationLauncherIcon> Nice;
141 typedef MockApplicationLauncherIcon Nice;
142 typedef nux::ObjectPtr<MockApplicationLauncherIcon> Ptr;
141 typedef bool Fake;143 typedef bool Fake;
142144
143 MockApplicationLauncherIcon(Fake = true, std::string const& remote_uri = "")145 MockApplicationLauncherIcon(Fake = true, std::string const& remote_uri = "")
@@ -154,7 +156,8 @@
154 }156 }
155157
156 explicit MockApplicationLauncherIcon(ApplicationPtr const& app)158 explicit MockApplicationLauncherIcon(ApplicationPtr const& app)
157 : ApplicationLauncherIcon(app)159 : WindowedLauncherIcon(IconType::APPLICATION)
160 , ApplicationLauncherIcon(app)
158 {161 {
159 ON_CALL(*this, Stick(_)).WillByDefault(Invoke([this] (bool save) { ApplicationLauncherIcon::Stick(save); }));162 ON_CALL(*this, Stick(_)).WillByDefault(Invoke([this] (bool save) { ApplicationLauncherIcon::Stick(save); }));
160 ON_CALL(*this, UnStick()).WillByDefault(Invoke([this] { ApplicationLauncherIcon::UnStick(); }));163 ON_CALL(*this, UnStick()).WillByDefault(Invoke([this] { ApplicationLauncherIcon::UnStick(); }));
@@ -170,15 +173,18 @@
170 MOCK_CONST_METHOD0(GetRemoteUri, std::string());173 MOCK_CONST_METHOD0(GetRemoteUri, std::string());
171 MOCK_METHOD1(Stick, void(bool));174 MOCK_METHOD1(Stick, void(bool));
172 MOCK_METHOD0(UnStick, void());175 MOCK_METHOD0(UnStick, void());
173 MOCK_METHOD0(Quit, void());176 MOCK_CONST_METHOD0(Quit, void());
174};177};
175178
176struct MockVolumeLauncherIcon : public VolumeLauncherIcon179struct MockVolumeLauncherIcon : public VolumeLauncherIcon
177{180{
178 typedef nux::ObjectPtr<MockVolumeLauncherIcon> Ptr;181 typedef nux::ObjectPtr<MockVolumeLauncherIcon> Ptr;
182 // typedef NiceMock<MockVolumeLauncherIcon> Nice;
183 typedef MockVolumeLauncherIcon Nice;
179184
180 MockVolumeLauncherIcon()185 MockVolumeLauncherIcon()
181 : VolumeLauncherIcon(Volume::Ptr(volume_ = new NiceMock<MockVolume>()),186 : WindowedLauncherIcon(IconType::DEVICE)
187 , VolumeLauncherIcon(Volume::Ptr(volume_ = new NiceMock<MockVolume>()),
182 std::make_shared<MockDevicesSettings::Nice>(),188 std::make_shared<MockDevicesSettings::Nice>(),
183 std::make_shared<MockDeviceNotificationDisplay::Nice>(),189 std::make_shared<MockDeviceNotificationDisplay::Nice>(),
184 std::make_shared<MockFileManager::Nice>())190 std::make_shared<MockFileManager::Nice>())
@@ -269,7 +275,7 @@
269 void DisconnectSignals()275 void DisconnectSignals()
270 {276 {
271 ApplicationManager::Default().application_started.clear();277 ApplicationManager::Default().application_started.clear();
272 Impl()->device_section_.icon_added.clear();278 Impl()->device_section_->icon_added.clear();
273 Impl()->model_->icon_removed.clear();279 Impl()->model_->icon_removed.clear();
274 Impl()->model_->saved.clear();280 Impl()->model_->saved.clear();
275 Impl()->model_->order_changed.clear();281 Impl()->model_->order_changed.clear();
@@ -640,8 +646,8 @@
640646
641TEST_F(TestLauncherController, CreateFavoriteDevice)647TEST_F(TestLauncherController, CreateFavoriteDevice)
642{648{
643 lc.Impl()->device_section_ = MockDeviceLauncherSection();649 lc.Impl()->device_section_ = std::make_shared<MockDeviceLauncherSection>();
644 auto const& icons = lc.Impl()->device_section_.GetIcons();650 auto const& icons = lc.Impl()->device_section_->GetIcons();
645 auto const& device_icon = icons.front();651 auto const& device_icon = icons.front();
646652
647 ASSERT_TRUE(device_icon.IsValid());653 ASSERT_TRUE(device_icon.IsValid());
@@ -903,8 +909,8 @@
903{909{
904 lc.ClearModel();910 lc.ClearModel();
905 lc.DisconnectSignals();911 lc.DisconnectSignals();
906 lc.Impl()->device_section_ = MockDeviceLauncherSection();912 lc.Impl()->device_section_ = std::make_shared<MockDeviceLauncherSection>();
907 auto const& icons = lc.Impl()->device_section_.GetIcons();913 auto const& icons = lc.Impl()->device_section_->GetIcons();
908 auto const& device_icon1 = icons.front();914 auto const& device_icon1 = icons.front();
909 auto const& device_icon2 = *(std::next(icons.begin()));915 auto const& device_icon2 = *(std::next(icons.begin()));
910916
@@ -949,7 +955,7 @@
949TEST_F(TestLauncherController, SetupIcons)955TEST_F(TestLauncherController, SetupIcons)
950{956{
951 lc.ClearModel();957 lc.ClearModel();
952 lc.Impl()->device_section_ = MockDeviceLauncherSection();958 lc.Impl()->device_section_ = std::make_shared<MockDeviceLauncherSection>();
953 lc.Impl()->expo_icon_->UnStick();959 lc.Impl()->expo_icon_->UnStick();
954 lc.Impl()->desktop_icon_->UnStick();960 lc.Impl()->desktop_icon_->UnStick();
955 auto const& model = lc.Impl()->model_;961 auto const& model = lc.Impl()->model_;
@@ -970,7 +976,7 @@
970 fav = lc.Impl()->GetIconByUri(FavoriteStore::URI_PREFIX_APP + app::SW_CENTER);976 fav = lc.Impl()->GetIconByUri(FavoriteStore::URI_PREFIX_APP + app::SW_CENTER);
971 EXPECT_EQ(model->IconIndex(fav), ++icon_index);977 EXPECT_EQ(model->IconIndex(fav), ++icon_index);
972978
973 for (auto const& device : lc.Impl()->device_section_.GetIcons())979 for (auto const& device : lc.Impl()->device_section_->GetIcons())
974 ASSERT_EQ(model->IconIndex(device), ++icon_index);980 ASSERT_EQ(model->IconIndex(device), ++icon_index);
975981
976 fav = lc.Impl()->GetIconByUri(FavoriteStore::URI_PREFIX_APP + app::UPDATE_MANAGER);982 fav = lc.Impl()->GetIconByUri(FavoriteStore::URI_PREFIX_APP + app::UPDATE_MANAGER);
@@ -995,7 +1001,7 @@
995TEST_F(TestLauncherController, ResetIconPriorities)1001TEST_F(TestLauncherController, ResetIconPriorities)
996{1002{
997 lc.ClearModel();1003 lc.ClearModel();
998 lc.Impl()->device_section_ = MockDeviceLauncherSection();1004 lc.Impl()->device_section_ = std::make_shared<MockDeviceLauncherSection>();
999 auto const& model = lc.Impl()->model_;1005 auto const& model = lc.Impl()->model_;
10001006
1001 favorite_store.AddFavorite(places::APPS_URI, -1);1007 favorite_store.AddFavorite(places::APPS_URI, -1);
@@ -1012,7 +1018,7 @@
10121018
1013 int icon_index = -1;1019 int icon_index = -1;
10141020
1015 for (auto const& device : lc.Impl()->device_section_.GetIcons())1021 for (auto const& device : lc.Impl()->device_section_->GetIcons())
1016 ASSERT_EQ(model->IconIndex(device), ++icon_index);1022 ASSERT_EQ(model->IconIndex(device), ++icon_index);
10171023
1018 auto fav = lc.Impl()->GetIconByUri(FavoriteStore::URI_PREFIX_APP + app::SW_CENTER);1024 auto fav = lc.Impl()->GetIconByUri(FavoriteStore::URI_PREFIX_APP + app::SW_CENTER);
@@ -1043,8 +1049,8 @@
1043TEST_F(TestLauncherController, GetLastIconPriorityUnSticky)1049TEST_F(TestLauncherController, GetLastIconPriorityUnSticky)
1044{1050{
1045 lc.ClearModel();1051 lc.ClearModel();
1046 lc.Impl()->device_section_ = MockDeviceLauncherSection(3);1052 lc.Impl()->device_section_ = std::make_shared<MockDeviceLauncherSection>(3);
1047 auto const& device_icons = lc.Impl()->device_section_.GetIcons();1053 auto const& device_icons = lc.Impl()->device_section_->GetIcons();
1048 auto const& last_device = device_icons.back();1054 auto const& last_device = device_icons.back();
10491055
1050 favorite_store.SetFavorites({ places::DEVICES_URI,1056 favorite_store.SetFavorites({ places::DEVICES_URI,
@@ -1060,8 +1066,8 @@
1060TEST_F(TestLauncherController, GetLastIconPriorityUnStickyWithAllStickyIcons)1066TEST_F(TestLauncherController, GetLastIconPriorityUnStickyWithAllStickyIcons)
1061{1067{
1062 lc.ClearModel();1068 lc.ClearModel();
1063 lc.Impl()->device_section_ = MockDeviceLauncherSection(3);1069 lc.Impl()->device_section_ = std::make_shared<MockDeviceLauncherSection>(3);
1064 auto const& device_icons = lc.Impl()->device_section_.GetIcons();1070 auto const& device_icons = lc.Impl()->device_section_->GetIcons();
1065 auto const& last_device = device_icons.back();1071 auto const& last_device = device_icons.back();
10661072
1067 favorite_store.SetFavorites({ places::DEVICES_URI,1073 favorite_store.SetFavorites({ places::DEVICES_URI,
@@ -1080,8 +1086,8 @@
1080TEST_F(TestLauncherController, GetLastIconPriorityUnStickyWithSomeStickyIcons)1086TEST_F(TestLauncherController, GetLastIconPriorityUnStickyWithSomeStickyIcons)
1081{1087{
1082 lc.ClearModel();1088 lc.ClearModel();
1083 lc.Impl()->device_section_ = MockDeviceLauncherSection(3);1089 lc.Impl()->device_section_ = std::make_shared<MockDeviceLauncherSection>(3);
1084 auto const& device_icons = lc.Impl()->device_section_.GetIcons();1090 auto const& device_icons = lc.Impl()->device_section_->GetIcons();
1085 auto const& first_device = *(std::next(device_icons.rbegin()));1091 auto const& first_device = *(std::next(device_icons.rbegin()));
1086 auto const& last_device = device_icons.back();1092 auto const& last_device = device_icons.back();
10871093
@@ -1100,7 +1106,7 @@
1100TEST_F(TestLauncherController, GetLastIconPriorityUnStickyWithNoIcons)1106TEST_F(TestLauncherController, GetLastIconPriorityUnStickyWithNoIcons)
1101{1107{
1102 lc.ClearModel();1108 lc.ClearModel();
1103 lc.Impl()->device_section_ = MockDeviceLauncherSection(0);1109 lc.Impl()->device_section_ = std::make_shared<MockDeviceLauncherSection>(0);
1104 lc.Impl()->SetupIcons();1110 lc.Impl()->SetupIcons();
1105 lc.DisconnectSignals();1111 lc.DisconnectSignals();
11061112
@@ -1111,7 +1117,7 @@
1111TEST_F(TestLauncherController, GetLastIconPriorityUnStickyWithNoIconsAndUri)1117TEST_F(TestLauncherController, GetLastIconPriorityUnStickyWithNoIconsAndUri)
1112{1118{
1113 lc.ClearModel();1119 lc.ClearModel();
1114 lc.Impl()->device_section_ = MockDeviceLauncherSection(0);1120 lc.Impl()->device_section_ = std::make_shared<MockDeviceLauncherSection>(0);
11151121
1116 favorite_store.SetFavorites({ places::DEVICES_URI,1122 favorite_store.SetFavorites({ places::DEVICES_URI,
1117 FavoriteStore::URI_PREFIX_APP + app::SW_CENTER });1123 FavoriteStore::URI_PREFIX_APP + app::SW_CENTER });
@@ -1136,11 +1142,11 @@
1136TEST_F(TestLauncherController, GetLastIconPrioritySticky)1142TEST_F(TestLauncherController, GetLastIconPrioritySticky)
1137{1143{
1138 lc.ClearModel();1144 lc.ClearModel();
1139 lc.Impl()->device_section_ = MockDeviceLauncherSection(3);1145 lc.Impl()->device_section_ = std::make_shared<MockDeviceLauncherSection>(3);
1140 lc.Impl()->SetupIcons();1146 lc.Impl()->SetupIcons();
1141 lc.DisconnectSignals();1147 lc.DisconnectSignals();
11421148
1143 auto const& device_icons = lc.Impl()->device_section_.GetIcons();1149 auto const& device_icons = lc.Impl()->device_section_->GetIcons();
1144 auto const& first_device = device_icons.front();1150 auto const& first_device = device_icons.front();
11451151
1146 int last_priority = lc.Impl()->GetLastIconPriority<VolumeLauncherIcon>("", true);1152 int last_priority = lc.Impl()->GetLastIconPriority<VolumeLauncherIcon>("", true);
@@ -1150,8 +1156,8 @@
1150TEST_F(TestLauncherController, GetLastIconPriorityStickyWithAllStickyIcons)1156TEST_F(TestLauncherController, GetLastIconPriorityStickyWithAllStickyIcons)
1151{1157{
1152 lc.ClearModel();1158 lc.ClearModel();
1153 lc.Impl()->device_section_ = MockDeviceLauncherSection(3);1159 lc.Impl()->device_section_ = std::make_shared<MockDeviceLauncherSection>(3);
1154 auto const& device_icons = lc.Impl()->device_section_.GetIcons();1160 auto const& device_icons = lc.Impl()->device_section_->GetIcons();
1155 auto const& last_device = device_icons.back();1161 auto const& last_device = device_icons.back();
11561162
1157 favorite_store.SetFavorites({ places::DEVICES_URI,1163 favorite_store.SetFavorites({ places::DEVICES_URI,
@@ -1170,8 +1176,8 @@
1170TEST_F(TestLauncherController, GetLastIconPriorityStickyWithSomeStickyIcons)1176TEST_F(TestLauncherController, GetLastIconPriorityStickyWithSomeStickyIcons)
1171{1177{
1172 lc.ClearModel();1178 lc.ClearModel();
1173 lc.Impl()->device_section_ = MockDeviceLauncherSection(3);1179 lc.Impl()->device_section_ = std::make_shared<MockDeviceLauncherSection>(3);
1174 auto const& device_icons = lc.Impl()->device_section_.GetIcons();1180 auto const& device_icons = lc.Impl()->device_section_->GetIcons();
1175 auto const& first_device = *(std::next(device_icons.rbegin()));1181 auto const& first_device = *(std::next(device_icons.rbegin()));
11761182
1177 favorite_store.SetFavorites({ places::DEVICES_URI,1183 favorite_store.SetFavorites({ places::DEVICES_URI,
@@ -1189,7 +1195,7 @@
1189TEST_F(TestLauncherController, GetLastIconPriorityStickyWithNoIcons)1195TEST_F(TestLauncherController, GetLastIconPriorityStickyWithNoIcons)
1190{1196{
1191 lc.ClearModel();1197 lc.ClearModel();
1192 lc.Impl()->device_section_ = MockDeviceLauncherSection(0);1198 lc.Impl()->device_section_ = std::make_shared<MockDeviceLauncherSection>(0);
1193 lc.Impl()->SetupIcons();1199 lc.Impl()->SetupIcons();
1194 lc.DisconnectSignals();1200 lc.DisconnectSignals();
11951201
@@ -1240,8 +1246,8 @@
1240TEST_F(TestLauncherController, LauncherAddRequestDeviceAdd)1246TEST_F(TestLauncherController, LauncherAddRequestDeviceAdd)
1241{1247{
1242 auto const& model = lc.Impl()->model_;1248 auto const& model = lc.Impl()->model_;
1243 lc.Impl()->device_section_ = MockDeviceLauncherSection();1249 lc.Impl()->device_section_ = std::make_shared<MockDeviceLauncherSection>();
1244 auto const& icons = lc.Impl()->device_section_.GetIcons();1250 auto const& icons = lc.Impl()->device_section_->GetIcons();
1245 auto const& device_icon = icons.front();1251 auto const& device_icon = icons.front();
1246 auto const& icon_uri = device_icon->RemoteUri();1252 auto const& icon_uri = device_icon->RemoteUri();
12471253
@@ -1262,7 +1268,7 @@
1262TEST_F(TestLauncherController, LauncherAddRequestDeviceStick)1268TEST_F(TestLauncherController, LauncherAddRequestDeviceStick)
1263{1269{
1264 auto const& model = lc.Impl()->model_;1270 auto const& model = lc.Impl()->model_;
1265 MockVolumeLauncherIcon::Ptr device_icon(new NiceMock<MockVolumeLauncherIcon>());1271 MockVolumeLauncherIcon::Ptr device_icon(new MockVolumeLauncherIcon::Nice());
1266 lc.Impl()->RegisterIcon(device_icon, std::numeric_limits<int>::max());1272 lc.Impl()->RegisterIcon(device_icon, std::numeric_limits<int>::max());
12671273
1268 auto app_icons = model->GetSublist<ApplicationLauncherIcon>();1274 auto app_icons = model->GetSublist<ApplicationLauncherIcon>();
@@ -1287,7 +1293,7 @@
12871293
1288TEST_F(TestLauncherController, LauncherRemoveRequestDeviceEjects)1294TEST_F(TestLauncherController, LauncherRemoveRequestDeviceEjects)
1289{1295{
1290 MockVolumeLauncherIcon::Ptr device_icon(new NiceMock<MockVolumeLauncherIcon>());1296 MockVolumeLauncherIcon::Ptr device_icon(new MockVolumeLauncherIcon::Nice());
12911297
1292 EXPECT_CALL(*(device_icon->volume_), CanBeEjected())1298 EXPECT_CALL(*(device_icon->volume_), CanBeEjected())
1293 .WillRepeatedly(Return(true));1299 .WillRepeatedly(Return(true));
@@ -1302,7 +1308,7 @@
13021308
1303TEST_F(TestLauncherController, LauncherRemoveRequestDeviceStops)1309TEST_F(TestLauncherController, LauncherRemoveRequestDeviceStops)
1304{1310{
1305 MockVolumeLauncherIcon::Ptr device_icon(new NiceMock<MockVolumeLauncherIcon>());1311 MockVolumeLauncherIcon::Ptr device_icon(new MockVolumeLauncherIcon::Nice());
13061312
1307 EXPECT_CALL(*(device_icon->volume_), CanBeEjected())1313 EXPECT_CALL(*(device_icon->volume_), CanBeEjected())
1308 .WillRepeatedly(Return(false));1314 .WillRepeatedly(Return(false));
@@ -1362,7 +1368,7 @@
1362 invisible_app->SetQuirk(AbstractLauncherIcon::Quirk::VISIBLE, false);1368 invisible_app->SetQuirk(AbstractLauncherIcon::Quirk::VISIBLE, false);
1363 lc.Impl()->RegisterIcon(invisible_app, ++priority);1369 lc.Impl()->RegisterIcon(invisible_app, ++priority);
13641370
1365 MockVolumeLauncherIcon::Ptr sticky_device(new NiceMock<MockVolumeLauncherIcon>());1371 MockVolumeLauncherIcon::Ptr sticky_device(new MockVolumeLauncherIcon::Nice());
1366 sticky_device->Stick(false);1372 sticky_device->Stick(false);
1367 lc.Impl()->RegisterIcon(sticky_device, ++priority);1373 lc.Impl()->RegisterIcon(sticky_device, ++priority);
13681374
@@ -1393,7 +1399,7 @@
1393 sticky_app->Stick(false);1399 sticky_app->Stick(false);
1394 lc.Impl()->RegisterIcon(sticky_app, ++priority);1400 lc.Impl()->RegisterIcon(sticky_app, ++priority);
13951401
1396 MockVolumeLauncherIcon::Ptr sticky_device(new NiceMock<MockVolumeLauncherIcon>());1402 MockVolumeLauncherIcon::Ptr sticky_device(new MockVolumeLauncherIcon::Nice());
1397 sticky_device->Stick(false);1403 sticky_device->Stick(false);
1398 lc.Impl()->RegisterIcon(sticky_device, ++priority);1404 lc.Impl()->RegisterIcon(sticky_device, ++priority);
13991405
@@ -1422,7 +1428,7 @@
1422 sticky_app->Stick(false);1428 sticky_app->Stick(false);
1423 lc.Impl()->RegisterIcon(sticky_app, ++priority);1429 lc.Impl()->RegisterIcon(sticky_app, ++priority);
14241430
1425 MockVolumeLauncherIcon::Ptr sticky_device(new NiceMock<MockVolumeLauncherIcon>());1431 MockVolumeLauncherIcon::Ptr sticky_device(new MockVolumeLauncherIcon::Nice());
1426 sticky_device->Stick(false);1432 sticky_device->Stick(false);
1427 lc.Impl()->RegisterIcon(sticky_device, ++priority);1433 lc.Impl()->RegisterIcon(sticky_device, ++priority);
14281434
@@ -1447,7 +1453,7 @@
1447 sticky_app->Stick(false);1453 sticky_app->Stick(false);
1448 lc.Impl()->RegisterIcon(sticky_app, ++priority);1454 lc.Impl()->RegisterIcon(sticky_app, ++priority);
14491455
1450 MockVolumeLauncherIcon::Ptr sticky_device(new NiceMock<MockVolumeLauncherIcon>());1456 MockVolumeLauncherIcon::Ptr sticky_device(new MockVolumeLauncherIcon::Nice());
1451 sticky_device->Stick(false);1457 sticky_device->Stick(false);
1452 lc.Impl()->RegisterIcon(sticky_device, ++priority);1458 lc.Impl()->RegisterIcon(sticky_device, ++priority);
14531459
@@ -1597,9 +1603,9 @@
1597TEST_F(TestLauncherController, OnFavoriteStoreFavoriteAddedDeviceSection)1603TEST_F(TestLauncherController, OnFavoriteStoreFavoriteAddedDeviceSection)
1598{1604{
1599 lc.ClearModel();1605 lc.ClearModel();
1600 lc.Impl()->device_section_ = MockDeviceLauncherSection();1606 lc.Impl()->device_section_ = std::make_shared<MockDeviceLauncherSection>();
1601 auto const& model = lc.Impl()->model_;1607 auto const& model = lc.Impl()->model_;
1602 auto const& icons = lc.Impl()->device_section_.GetIcons();1608 auto const& icons = lc.Impl()->device_section_->GetIcons();
1603 auto const& device_icon1(icons.front());1609 auto const& device_icon1(icons.front());
1604 auto const& device_icon2(*(std::next(icons.begin())));1610 auto const& device_icon2(*(std::next(icons.begin())));
16051611
@@ -1634,10 +1640,10 @@
1634TEST_F(TestLauncherController, OnFavoriteStoreFavoriteRemovedDevice)1640TEST_F(TestLauncherController, OnFavoriteStoreFavoriteRemovedDevice)
1635{1641{
1636 lc.ClearModel();1642 lc.ClearModel();
1637 lc.Impl()->device_section_ = MockDeviceLauncherSection();1643 lc.Impl()->device_section_ = std::make_shared<MockDeviceLauncherSection>();
1638 auto const& model = lc.Impl()->model_;1644 auto const& model = lc.Impl()->model_;
16391645
1640 auto const& icons = lc.Impl()->device_section_.GetIcons();1646 auto const& icons = lc.Impl()->device_section_->GetIcons();
1641 auto const& device_icon(icons.front());1647 auto const& device_icon(icons.front());
16421648
1643 favorite_store.SetFavorites({ lc.Impl()->expo_icon_->RemoteUri(),1649 favorite_store.SetFavorites({ lc.Impl()->expo_icon_->RemoteUri(),
@@ -1660,10 +1666,10 @@
1660TEST_F(TestLauncherController, OnFavoriteStoreFavoriteRemovedDeviceSection)1666TEST_F(TestLauncherController, OnFavoriteStoreFavoriteRemovedDeviceSection)
1661{1667{
1662 lc.ClearModel();1668 lc.ClearModel();
1663 lc.Impl()->device_section_ = MockDeviceLauncherSection();1669 lc.Impl()->device_section_ = std::make_shared<MockDeviceLauncherSection>();
1664 auto const& model = lc.Impl()->model_;1670 auto const& model = lc.Impl()->model_;
16651671
1666 auto const& icons = lc.Impl()->device_section_.GetIcons();1672 auto const& icons = lc.Impl()->device_section_->GetIcons();
1667 auto const& device_icon1(icons.front());1673 auto const& device_icon1(icons.front());
1668 auto const& device_icon2(*(std::next(icons.begin())));1674 auto const& device_icon2(*(std::next(icons.begin())));
16691675
@@ -1958,10 +1964,9 @@
1958 unity::glib::Object<BamfMockApplication> bamf_mock_application(bamf_mock_application_new());1964 unity::glib::Object<BamfMockApplication> bamf_mock_application(bamf_mock_application_new());
1959 ApplicationPtr app(new unity::bamf::Application(mock_manager, unity::glib::object_cast<BamfApplication>(bamf_mock_application)));1965 ApplicationPtr app(new unity::bamf::Application(mock_manager, unity::glib::object_cast<BamfApplication>(bamf_mock_application)));
19601966
1961 MockApplicationLauncherIcon::Ptr our_icon;1967 AbstractLauncherIcon::Ptr our_icon;
1962
1963 mock_manager.Default().application_started.emit(app);1968 mock_manager.Default().application_started.emit(app);
1964 1969
1965 app->title.changed.emit("Hello");1970 app->title.changed.emit("Hello");
1966 auto app_icons = lc.Impl()->model_->GetSublist<ApplicationLauncherIcon>();1971 auto app_icons = lc.Impl()->model_->GetSublist<ApplicationLauncherIcon>();
19671972
@@ -1971,7 +1976,7 @@
1971 {1976 {
1972 our_icon = icon;1977 our_icon = icon;
1973 break;1978 break;
1974 } 1979 }
1975 }1980 }
1976 ASSERT_TRUE(our_icon);1981 ASSERT_TRUE(our_icon);
1977 EXPECT_FALSE(our_icon->removed);1982 EXPECT_FALSE(our_icon->removed);
19781983
=== modified file 'tests/test_mock_filemanager.h'
--- tests/test_mock_filemanager.h 2013-10-07 18:10:17 +0000
+++ tests/test_mock_filemanager.h 2016-02-09 10:44:04 +0000
@@ -32,15 +32,18 @@
32 typedef testing::NiceMock<MockFileManager> Nice;32 typedef testing::NiceMock<MockFileManager> Nice;
3333
34 MOCK_METHOD2(Open, void(std::string const& uri, uint64_t time));34 MOCK_METHOD2(Open, void(std::string const& uri, uint64_t time));
35 MOCK_METHOD2(OpenActiveChild, void(std::string const& uri, uint64_t time));
36 MOCK_METHOD1(OpenTrash, void(uint64_t time));35 MOCK_METHOD1(OpenTrash, void(uint64_t time));
37 MOCK_METHOD1(TrashFile, bool(std::string const& uri));36 MOCK_METHOD1(TrashFile, bool(std::string const& uri));
38 MOCK_METHOD1(EmptyTrash, void(uint64_t time));37 MOCK_METHOD1(EmptyTrash, void(uint64_t time));
39 MOCK_METHOD3(CopyFiles, void(std::set<std::string> const& files, std::string const& dest, uint64_t time));38 MOCK_METHOD3(CopyFiles, void(std::set<std::string> const& files, std::string const& dest, uint64_t time));
40 MOCK_CONST_METHOD0(OpenedLocations, std::vector<std::string>());39 MOCK_CONST_METHOD1(WindowsForLocation, WindowList(std::string const&));
41 MOCK_CONST_METHOD1(IsPrefixOpened, bool(std::string const& uri));40 MOCK_CONST_METHOD1(LocationForWindow, std::string(ApplicationWindowPtr const&));
42 MOCK_CONST_METHOD0(IsTrashOpened, bool());41
43 MOCK_CONST_METHOD0(IsDeviceOpened, bool());42 MockFileManager()
43 {
44 using namespace testing;
45 ON_CALL(*this, WindowsForLocation(_)).WillByDefault(Return(WindowList()));
46 }
44};47};
4548
46}49}
4750
=== modified file 'tests/test_software_center_launcher_icon.cpp'
--- tests/test_software_center_launcher_icon.cpp 2015-03-13 13:49:16 +0000
+++ tests/test_software_center_launcher_icon.cpp 2016-02-09 10:44:04 +0000
@@ -62,16 +62,17 @@
62 MockSoftwareCenterLauncherIcon(ApplicationPtr const& app,62 MockSoftwareCenterLauncherIcon(ApplicationPtr const& app,
63 std::string const& aptdaemon_trans_id,63 std::string const& aptdaemon_trans_id,
64 std::string const& icon_path)64 std::string const& icon_path)
65 : SoftwareCenterLauncherIcon(app, aptdaemon_trans_id, icon_path)65 : WindowedLauncherIcon(IconType::APPLICATION)
66 , SoftwareCenterLauncherIcon(app, aptdaemon_trans_id, icon_path)
66 {}67 {}
6768
68 void LauncherIconUnstick() { LauncherIcon::UnStick(); }69 void LauncherIconUnstick() { LauncherIcon::UnStick(); }
6970
70 using SoftwareCenterLauncherIcon::GetActualDesktopFileAfterInstall;71 using SoftwareCenterLauncherIcon::GetActualDesktopFileAfterInstall;
71 using SoftwareCenterLauncherIcon::GetRemoteUri;
72 using SoftwareCenterLauncherIcon::OnFinished;72 using SoftwareCenterLauncherIcon::OnFinished;
73 using SoftwareCenterLauncherIcon::OnPropertyChanged;73 using SoftwareCenterLauncherIcon::OnPropertyChanged;
74 using SoftwareCenterLauncherIcon::drag_window_;74 using SoftwareCenterLauncherIcon::drag_window_;
75 using LauncherIcon::GetRemoteUri;
75 };76 };
7677
77 nux::ObjectPtr<Launcher> CreateLauncher()78 nux::ObjectPtr<Launcher> CreateLauncher()
7879
=== modified file 'tests/test_switcher_controller.h'
--- tests/test_switcher_controller.h 2015-11-04 09:42:55 +0000
+++ tests/test_switcher_controller.h 2016-02-09 10:44:04 +0000
@@ -27,10 +27,11 @@
2727
28#include "test_utils.h"28#include "test_utils.h"
29#include "DesktopLauncherIcon.h"29#include "DesktopLauncherIcon.h"
30#include "SimpleLauncherIcon.h"30#include "WindowedLauncherIcon.h"
31#include "SwitcherController.h"31#include "SwitcherController.h"
32#include "SwitcherView.h"32#include "SwitcherView.h"
33#include "TimeUtil.h"33#include "TimeUtil.h"
34#include "mock-application.h"
34#include "mock-base-window.h"35#include "mock-base-window.h"
35#include "test_standalone_wm.h"36#include "test_standalone_wm.h"
3637
@@ -48,35 +49,24 @@
48/**49/**
49 * A fake ApplicationWindow for verifying selection of the switcher.50 * A fake ApplicationWindow for verifying selection of the switcher.
50 */51 */
51class FakeApplicationWindow : public unity::ApplicationWindow52struct FakeApplicationWindow : public ::testmocks::MockApplicationWindow::Nice
52{53{
53public:54 typedef NiceMock<FakeApplicationWindow> Nice;
54 FakeApplicationWindow(Window xid, uint64_t active_number = 0);55 FakeApplicationWindow(Window xid, uint64_t active_number = 0);
55 ~FakeApplicationWindow();56 ~FakeApplicationWindow();
56
57 virtual WindowType type() const;
58
59 virtual Window window_id() const;
60 virtual int monitor() const;
61 virtual unity::ApplicationPtr application() const;
62 virtual bool Focus() const;
63 virtual void Quit() const;
64
65private:
66 Window xid_;
67};57};
6858
69/**59/**
70 * A fake LauncherIcon for verifying selection operations of the switcher.60 * A fake LauncherIcon for verifying selection operations of the switcher.
71 */61 */
72struct FakeLauncherIcon : unity::launcher::SimpleLauncherIcon62struct FakeLauncherIcon : unity::launcher::WindowedLauncherIcon
73{63{
74 FakeLauncherIcon(std::string const& app_name, bool allow_detail_view, uint64_t priority);64 FakeLauncherIcon(std::string const& app_name, bool allow_detail_view, uint64_t priority);
7565
76 unity::WindowList Windows() override;
77 bool AllowDetailViewInSwitcher() const override;66 bool AllowDetailViewInSwitcher() const override;
78 bool ShowInSwitcher(bool) override;67 bool ShowInSwitcher(bool) override;
79 uint64_t SwitcherPriority() override;68 uint64_t SwitcherPriority() override;
69 WindowList GetManagedWindows() const override;
8070
81 bool allow_detail_view_;71 bool allow_detail_view_;
82 uint64_t priority_;72 uint64_t priority_;
8373
=== modified file 'tests/test_switcher_controller_class.cpp'
--- tests/test_switcher_controller_class.cpp 2015-11-04 09:42:55 +0000
+++ tests/test_switcher_controller_class.cpp 2016-02-09 10:44:04 +0000
@@ -26,14 +26,13 @@
26using namespace std::chrono;26using namespace std::chrono;
2727
28FakeApplicationWindow::FakeApplicationWindow(Window xid, uint64_t active_number)28FakeApplicationWindow::FakeApplicationWindow(Window xid, uint64_t active_number)
29 : xid_(xid)29 : MockApplicationWindow::Nice(xid)
30{30{
31 auto standalone_window = std::make_shared<StandaloneWindow>(xid_);31 SetMonitor(-1);
32 auto standalone_window = std::make_shared<StandaloneWindow>(window_id());
32 standalone_window->active_number = active_number;33 standalone_window->active_number = active_number;
33 testwrapper::StandaloneWM::Get()->AddStandaloneWindow(standalone_window);34 testwrapper::StandaloneWM::Get()->AddStandaloneWindow(standalone_window);
3435 ON_CALL(*this, Quit()).WillByDefault(Invoke([this] { WindowManager::Default().Close(window_id()); }));
35 title.SetGetterFunction([this] { return "FakeApplicationWindow"; });
36 icon.SetGetterFunction([this] { return ""; });
37}36}
3837
39FakeApplicationWindow::~FakeApplicationWindow()38FakeApplicationWindow::~FakeApplicationWindow()
@@ -41,25 +40,17 @@
41 testwrapper::StandaloneWM::Get()->Close(xid_);40 testwrapper::StandaloneWM::Get()->Close(xid_);
42}41}
4342
44WindowType FakeApplicationWindow::type() const { return WindowType::MOCK; }
45
46Window FakeApplicationWindow::window_id() const { return xid_; }
47int FakeApplicationWindow::monitor() const { return -1; }
48ApplicationPtr FakeApplicationWindow::application() const { return ApplicationPtr(); }
49bool FakeApplicationWindow::Focus() const { return false; }
50void FakeApplicationWindow::Quit() const { WindowManager::Default().Close(xid_); }
51
52FakeLauncherIcon::FakeLauncherIcon(std::string const& app_name, bool allow_detail_view, uint64_t priority)43FakeLauncherIcon::FakeLauncherIcon(std::string const& app_name, bool allow_detail_view, uint64_t priority)
53 : launcher::SimpleLauncherIcon(IconType::APPLICATION)44 : launcher::WindowedLauncherIcon(IconType::APPLICATION)
54 , allow_detail_view_(allow_detail_view)45 , allow_detail_view_(allow_detail_view)
55 , priority_(priority)46 , priority_(priority)
56 , window_list{ std::make_shared<FakeApplicationWindow>(priority_ | 0x0001, SwitcherPriority()),47 , window_list{ std::make_shared<FakeApplicationWindow::Nice>(priority_ | 0x0001, SwitcherPriority()),
57 std::make_shared<FakeApplicationWindow>(priority_ | 0x0002, priority_) }48 std::make_shared<FakeApplicationWindow::Nice>(priority_ | 0x0002, priority_) }
58{49{
59 tooltip_text = app_name;50 tooltip_text = app_name;
60}51}
6152
62WindowList FakeLauncherIcon::Windows()53WindowList FakeLauncherIcon::GetManagedWindows() const
63{54{
64 return window_list;55 return window_list;
65}56}
@@ -85,7 +76,7 @@
85//class TestSwitcherController : public testing::Test76//class TestSwitcherController : public testing::Test
86TestSwitcherController::TestSwitcherController()77TestSwitcherController::TestSwitcherController()
87 : animation_controller_(tick_source_)78 : animation_controller_(tick_source_)
88 , mock_window_(new NiceMock<testmocks::MockBaseWindow>())79 , mock_window_(new NiceMock<unity::testmocks::MockBaseWindow>())
89 , controller_(std::make_shared<Controller>([this] { return mock_window_; }))80 , controller_(std::make_shared<Controller>([this] { return mock_window_; }))
90{81{
91 controller_->timeout_length = 0;82 controller_->timeout_length = 0;
9283
=== modified file 'tests/test_trash_launcher_icon.cpp'
--- tests/test_trash_launcher_icon.cpp 2014-02-28 05:48:21 +0000
+++ tests/test_trash_launcher_icon.cpp 2016-02-09 10:44:04 +0000
@@ -27,9 +27,11 @@
27using namespace unity;27using namespace unity;
28using namespace unity::launcher;28using namespace unity::launcher;
29using namespace testing;29using namespace testing;
30using namespace testmocks;
3031
31namespace32namespace
32{33{
34const std::string TRASH_URI = "trash:";
3335
34struct TestTrashLauncherIcon : testmocks::TestUnityAppBase36struct TestTrashLauncherIcon : testmocks::TestUnityAppBase
35{37{
@@ -42,6 +44,12 @@
42 TrashLauncherIcon icon;44 TrashLauncherIcon icon;
43};45};
4446
47TEST_F(TestTrashLauncherIcon, InitState)
48{
49 EXPECT_FALSE(icon.GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));
50 EXPECT_FALSE(icon.GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE));
51}
52
45TEST_F(TestTrashLauncherIcon, Position)53TEST_F(TestTrashLauncherIcon, Position)
46{54{
47 EXPECT_EQ(icon.position(), AbstractLauncherIcon::Position::END);55 EXPECT_EQ(icon.position(), AbstractLauncherIcon::Position::END);
@@ -74,15 +82,77 @@
7482
75TEST_F(TestTrashLauncherIcon, RunningState)83TEST_F(TestTrashLauncherIcon, RunningState)
76{84{
77 EXPECT_CALL(*fm_, IsTrashOpened()).WillRepeatedly(Return(true));85 auto win1 = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
86 auto win2 = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
87
88 ON_CALL(*fm_, WindowsForLocation(TRASH_URI)).WillByDefault(Return(WindowList({win1, win2})));
78 fm_->locations_changed.emit();89 fm_->locations_changed.emit();
79 EXPECT_TRUE(icon.GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));90 EXPECT_TRUE(icon.GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));
8091
81 EXPECT_CALL(*fm_, IsTrashOpened()).WillRepeatedly(Return(false));92 ON_CALL(*fm_, WindowsForLocation(TRASH_URI)).WillByDefault(Return(WindowList()));
82 fm_->locations_changed.emit();93 fm_->locations_changed.emit();
83 EXPECT_FALSE(icon.GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));94 EXPECT_FALSE(icon.GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));
84}95}
8596
97TEST_F(TestTrashLauncherIcon, ActiveState)
98{
99 auto win1 = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
100 auto win2 = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
101
102 ON_CALL(*fm_, WindowsForLocation(TRASH_URI)).WillByDefault(Return(WindowList({win1, win2})));
103 fm_->locations_changed.emit();
104 ASSERT_FALSE(icon.GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE));
105
106 win2->LocalFocus();
107 EXPECT_TRUE(icon.GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE));
108
109 ON_CALL(*fm_, WindowsForLocation(TRASH_URI)).WillByDefault(Return(WindowList()));
110 fm_->locations_changed.emit();
111 EXPECT_FALSE(icon.GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE));
112}
113
114TEST_F(TestTrashLauncherIcon, WindowsCount)
115{
116 WindowList windows((g_random_int() % 10) + 5);
117 for (unsigned i = 0; i < windows.capacity(); ++i)
118 windows[i] = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
119
120 ON_CALL(*fm_, WindowsForLocation(TRASH_URI)).WillByDefault(Return(windows));
121 fm_->locations_changed.emit();
122 EXPECT_EQ(icon.Windows().size(), windows.size());
123}
124
125TEST_F(TestTrashLauncherIcon, WindowsPerMonitor)
126{
127 WindowList windows((g_random_int() % 10) + 5);
128 for (unsigned i = 0; i < windows.capacity(); ++i)
129 {
130 auto win = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
131 win->monitor_ = i % 2;
132 windows[i] = win;
133 }
134
135 ON_CALL(*fm_, WindowsForLocation(TRASH_URI)).WillByDefault(Return(windows));
136 fm_->locations_changed.emit();
137
138 EXPECT_EQ(icon.WindowsVisibleOnMonitor(0), (windows.size() / 2) + (windows.size() % 2));
139 EXPECT_EQ(icon.WindowsVisibleOnMonitor(1), windows.size() / 2);
140}
141
142TEST_F(TestTrashLauncherIcon, WindowsOnMonitorChanges)
143{
144 auto win = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
145 ON_CALL(*fm_, WindowsForLocation(TRASH_URI)).WillByDefault(Return(WindowList({win})));
146 fm_->locations_changed.emit();
147
148 EXPECT_EQ(icon.WindowsVisibleOnMonitor(0), 1);
149 EXPECT_EQ(icon.WindowsVisibleOnMonitor(1), 0);
150
151 win->SetMonitor(1);
152 EXPECT_EQ(icon.WindowsVisibleOnMonitor(0), 0);
153 EXPECT_EQ(icon.WindowsVisibleOnMonitor(1), 1);
154}
155
86TEST_F(TestTrashLauncherIcon, FilemanagerSignalDisconnection)156TEST_F(TestTrashLauncherIcon, FilemanagerSignalDisconnection)
87{157{
88 auto file_manager = std::make_shared<NiceMock<MockFileManager>>();158 auto file_manager = std::make_shared<NiceMock<MockFileManager>>();
89159
=== modified file 'tests/test_volume_launcher_icon.cpp'
--- tests/test_volume_launcher_icon.cpp 2015-01-22 15:05:34 +0000
+++ tests/test_volume_launcher_icon.cpp 2016-02-09 10:44:04 +0000
@@ -27,8 +27,11 @@
27#include "test_utils.h"27#include "test_utils.h"
28#include "test_mock_devices.h"28#include "test_mock_devices.h"
29#include "test_mock_filemanager.h"29#include "test_mock_filemanager.h"
30#include "mock-application.h"
31
30using namespace unity;32using namespace unity;
31using namespace unity::launcher;33using namespace unity::launcher;
34using namespace testmocks;
3235
33namespace36namespace
34{37{
@@ -43,7 +46,7 @@
43 {46 {
44 SetupVolumeDefaultBehavior();47 SetupVolumeDefaultBehavior();
45 SetupSettingsDefaultBehavior();48 SetupSettingsDefaultBehavior();
46 icon_ = new NiceMock<VolumeLauncherIcon>(volume_, settings_, notifications_, file_manager_);49 icon_ = new VolumeLauncherIcon(volume_, settings_, notifications_, file_manager_);
47 }50 }
4851
49 void SetupSettingsDefaultBehavior()52 void SetupSettingsDefaultBehavior()
@@ -94,7 +97,7 @@
9497
95 void CreateIcon()98 void CreateIcon()
96 {99 {
97 icon_ = new NiceMock<VolumeLauncherIcon>(volume_, settings_, notifications_, file_manager_);100 icon_ = new VolumeLauncherIcon(volume_, settings_, notifications_, file_manager_);
98 }101 }
99};102};
100103
@@ -105,7 +108,7 @@
105108
106TEST_F(TestVolumeLauncherIconDelayedConstruction, TestRunningOnClosed)109TEST_F(TestVolumeLauncherIconDelayedConstruction, TestRunningOnClosed)
107{110{
108 ON_CALL(*file_manager_, IsPrefixOpened(volume_->GetUri())).WillByDefault(Return(false));111 ON_CALL(*file_manager_, WindowsForLocation(_)).WillByDefault(Return(WindowList()));
109 CreateIcon();112 CreateIcon();
110113
111 EXPECT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));114 EXPECT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));
@@ -113,7 +116,8 @@
113116
114TEST_F(TestVolumeLauncherIconDelayedConstruction, TestRunningOnOpened)117TEST_F(TestVolumeLauncherIconDelayedConstruction, TestRunningOnOpened)
115{118{
116 ON_CALL(*file_manager_, IsPrefixOpened(volume_->GetUri())).WillByDefault(Return(true));119 auto win = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
120 ON_CALL(*file_manager_, WindowsForLocation(volume_->GetUri())).WillByDefault(Return(WindowList({win})));
117 CreateIcon();121 CreateIcon();
118122
119 EXPECT_TRUE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));123 EXPECT_TRUE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));
@@ -128,16 +132,91 @@
128132
129TEST_F(TestVolumeLauncherIcon, TestRunningStateOnLocationChangedClosed)133TEST_F(TestVolumeLauncherIcon, TestRunningStateOnLocationChangedClosed)
130{134{
131 ON_CALL(*file_manager_, IsPrefixOpened(volume_->GetUri())).WillByDefault(Return(false));135 ON_CALL(*file_manager_, WindowsForLocation(volume_->GetUri())).WillByDefault(Return(WindowList()));
132 file_manager_->locations_changed.emit();136 file_manager_->locations_changed.emit();
133 EXPECT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));137 EXPECT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));
134}138}
135139
136TEST_F(TestVolumeLauncherIcon, TestRunningStateOnLocationChangedOpened)140TEST_F(TestVolumeLauncherIcon, TestRunningStateOnLocationChangedOpened)
137{141{
138 ON_CALL(*file_manager_, IsPrefixOpened(volume_->GetUri())).WillByDefault(Return(true));142 auto win1 = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
139 file_manager_->locations_changed.emit();143 auto win2 = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
140 EXPECT_TRUE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));144 ON_CALL(*file_manager_, WindowsForLocation(volume_->GetUri())).WillByDefault(Return(WindowList({win1, win2})));
145 file_manager_->locations_changed.emit();
146 EXPECT_TRUE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));
147}
148
149TEST_F(TestVolumeLauncherIcon, RunningState)
150{
151 auto win1 = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
152 auto win2 = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
153
154 ON_CALL(*file_manager_, WindowsForLocation(volume_->GetUri())).WillByDefault(Return(WindowList({win1, win2})));
155 file_manager_->locations_changed.emit();
156 EXPECT_TRUE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));
157
158 ON_CALL(*file_manager_, WindowsForLocation(volume_->GetUri())).WillByDefault(Return(WindowList()));
159 file_manager_->locations_changed.emit();
160 EXPECT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::RUNNING));
161}
162
163TEST_F(TestVolumeLauncherIcon, ActiveState)
164{
165 auto win1 = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
166 auto win2 = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
167
168 ON_CALL(*file_manager_, WindowsForLocation(volume_->GetUri())).WillByDefault(Return(WindowList({win1, win2})));
169 file_manager_->locations_changed.emit();
170 ASSERT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE));
171
172 win2->LocalFocus();
173 EXPECT_TRUE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE));
174
175 ON_CALL(*file_manager_, WindowsForLocation(volume_->GetUri())).WillByDefault(Return(WindowList()));
176 file_manager_->locations_changed.emit();
177 EXPECT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::ACTIVE));
178}
179
180TEST_F(TestVolumeLauncherIcon, WindowsCount)
181{
182 WindowList windows((g_random_int() % 10) + 5);
183 for (unsigned i = 0; i < windows.capacity(); ++i)
184 windows[i] = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
185
186 ON_CALL(*file_manager_, WindowsForLocation(volume_->GetUri())).WillByDefault(Return(windows));
187 file_manager_->locations_changed.emit();
188 EXPECT_EQ(icon_->Windows().size(), windows.size());
189}
190
191TEST_F(TestVolumeLauncherIcon, WindowsPerMonitor)
192{
193 WindowList windows((g_random_int() % 10) + 5);
194 for (unsigned i = 0; i < windows.capacity(); ++i)
195 {
196 auto win = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
197 win->monitor_ = i % 2;
198 windows[i] = win;
199 }
200
201 ON_CALL(*file_manager_, WindowsForLocation(volume_->GetUri())).WillByDefault(Return(windows));
202 file_manager_->locations_changed.emit();
203
204 EXPECT_EQ(icon_->WindowsVisibleOnMonitor(0), (windows.size() / 2) + (windows.size() % 2));
205 EXPECT_EQ(icon_->WindowsVisibleOnMonitor(1), windows.size() / 2);
206}
207
208TEST_F(TestVolumeLauncherIcon, WindowsOnMonitorChanges)
209{
210 auto win = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
211 ON_CALL(*file_manager_, WindowsForLocation(volume_->GetUri())).WillByDefault(Return(WindowList({win})));
212 file_manager_->locations_changed.emit();
213
214 EXPECT_EQ(icon_->WindowsVisibleOnMonitor(0), 1);
215 EXPECT_EQ(icon_->WindowsVisibleOnMonitor(1), 0);
216
217 win->SetMonitor(1);
218 EXPECT_EQ(icon_->WindowsVisibleOnMonitor(0), 0);
219 EXPECT_EQ(icon_->WindowsVisibleOnMonitor(1), 1);
141}220}
142221
143TEST_F(TestVolumeLauncherIcon, TestPosition)222TEST_F(TestVolumeLauncherIcon, TestPosition)
@@ -240,6 +319,32 @@
240 EXPECT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE));319 EXPECT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE));
241}320}
242321
322TEST_F(TestVolumeLauncherIcon, TestVisibilityWithWindows)
323{
324 ON_CALL(*settings_, IsABlacklistedDevice(volume_->GetIdentifier())).WillByDefault(Return(false));
325 settings_->changed.emit();
326 ASSERT_TRUE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE));
327
328 auto win = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
329 ON_CALL(*file_manager_, WindowsForLocation(volume_->GetUri())).WillByDefault(Return(WindowList({win})));
330 file_manager_->locations_changed.emit();
331
332 EXPECT_TRUE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE));
333}
334
335TEST_F(TestVolumeLauncherIcon, TestVisibilityWithWindows_Blacklisted)
336{
337 ON_CALL(*settings_, IsABlacklistedDevice(volume_->GetIdentifier())).WillByDefault(Return(true));
338 settings_->changed.emit();
339 ASSERT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE));
340
341 auto win = std::make_shared<MockApplicationWindow::Nice>(g_random_int());
342 ON_CALL(*file_manager_, WindowsForLocation(volume_->GetUri())).WillByDefault(Return(WindowList({win})));
343 file_manager_->locations_changed.emit();
344
345 EXPECT_TRUE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE));
346}
347
243TEST_F(TestVolumeLauncherIcon, TestUnlockFromLauncherMenuItem_VolumeWithoutIdentifier)348TEST_F(TestVolumeLauncherIcon, TestUnlockFromLauncherMenuItem_VolumeWithoutIdentifier)
244{349{
245 EXPECT_CALL(*volume_, GetIdentifier())350 EXPECT_CALL(*volume_, GetIdentifier())
@@ -251,22 +356,22 @@
251356
252TEST_F(TestVolumeLauncherIcon, TestUnlockFromLauncherMenuItem_Success)357TEST_F(TestVolumeLauncherIcon, TestUnlockFromLauncherMenuItem_Success)
253{358{
359 ON_CALL(*settings_, IsABlacklistedDevice(volume_->GetIdentifier())).WillByDefault(Return(false));
360 settings_->changed.emit();
361 ASSERT_TRUE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE));
254 auto menuitem = GetMenuItemAtIndex(4);362 auto menuitem = GetMenuItemAtIndex(4);
255363
256 ASSERT_STREQ(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Unlock from Launcher");364 ASSERT_STREQ(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Unlock from Launcher");
257 EXPECT_TRUE(dbusmenu_menuitem_property_get_bool(menuitem, DBUSMENU_MENUITEM_PROP_VISIBLE));365 EXPECT_TRUE(dbusmenu_menuitem_property_get_bool(menuitem, DBUSMENU_MENUITEM_PROP_VISIBLE));
258 EXPECT_TRUE(dbusmenu_menuitem_property_get_bool(menuitem, DBUSMENU_MENUITEM_PROP_ENABLED));366 EXPECT_TRUE(dbusmenu_menuitem_property_get_bool(menuitem, DBUSMENU_MENUITEM_PROP_ENABLED));
259367
260 EXPECT_CALL(*settings_, TryToBlacklist(_))368 EXPECT_CALL(*settings_, TryToBlacklist(volume_->GetIdentifier())).Times(1);
261 .Times(1);
262
263 EXPECT_CALL(*settings_, IsABlacklistedDevice(_))
264 .WillRepeatedly(Return(true));
265
266 dbusmenu_menuitem_handle_event(menuitem, DBUSMENU_MENUITEM_EVENT_ACTIVATED, nullptr, 0);369 dbusmenu_menuitem_handle_event(menuitem, DBUSMENU_MENUITEM_EVENT_ACTIVATED, nullptr, 0);
370
371 EXPECT_CALL(*settings_, IsABlacklistedDevice(volume_->GetIdentifier())).WillRepeatedly(Return(true));
267 settings_->changed.emit(); // TryToBlacklist() works if DevicesSettings emits a changed signal.372 settings_->changed.emit(); // TryToBlacklist() works if DevicesSettings emits a changed signal.
268373
269 ASSERT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE));374 EXPECT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE));
270}375}
271376
272TEST_F(TestVolumeLauncherIcon, TestUnlockFromLauncherMenuItem_Failure)377TEST_F(TestVolumeLauncherIcon, TestUnlockFromLauncherMenuItem_Failure)
@@ -277,12 +382,49 @@
277 EXPECT_TRUE(dbusmenu_menuitem_property_get_bool(menuitem, DBUSMENU_MENUITEM_PROP_VISIBLE));382 EXPECT_TRUE(dbusmenu_menuitem_property_get_bool(menuitem, DBUSMENU_MENUITEM_PROP_VISIBLE));
278 EXPECT_TRUE(dbusmenu_menuitem_property_get_bool(menuitem, DBUSMENU_MENUITEM_PROP_ENABLED));383 EXPECT_TRUE(dbusmenu_menuitem_property_get_bool(menuitem, DBUSMENU_MENUITEM_PROP_ENABLED));
279384
280 EXPECT_CALL(*settings_, TryToBlacklist(_))385 EXPECT_CALL(*settings_, TryToBlacklist(volume_->GetIdentifier())).Times(1);
281 .Times(1);386 dbusmenu_menuitem_handle_event(menuitem, DBUSMENU_MENUITEM_EVENT_ACTIVATED, nullptr, 0);
282387
283 dbusmenu_menuitem_handle_event(menuitem, DBUSMENU_MENUITEM_EVENT_ACTIVATED, nullptr, 0);388 EXPECT_TRUE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE));
284389}
285 ASSERT_TRUE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE));390
391TEST_F(TestVolumeLauncherIcon, TestLockToLauncherMenuItem_Success)
392{
393 ON_CALL(*settings_, IsABlacklistedDevice(volume_->GetIdentifier())).WillByDefault(Return(true));
394 settings_->changed.emit();
395 ASSERT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE));
396
397 auto menuitem = GetMenuItemAtIndex(4);
398
399 ASSERT_STREQ(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Lock to Launcher");
400 EXPECT_TRUE(dbusmenu_menuitem_property_get_bool(menuitem, DBUSMENU_MENUITEM_PROP_VISIBLE));
401 EXPECT_TRUE(dbusmenu_menuitem_property_get_bool(menuitem, DBUSMENU_MENUITEM_PROP_ENABLED));
402
403 EXPECT_CALL(*settings_, TryToUnblacklist(volume_->GetIdentifier())).Times(1);
404 dbusmenu_menuitem_handle_event(menuitem, DBUSMENU_MENUITEM_EVENT_ACTIVATED, nullptr, 0);
405
406 EXPECT_CALL(*settings_, IsABlacklistedDevice(_)).WillRepeatedly(Return(false));
407 settings_->changed.emit(); // TryToBlacklist() works if DevicesSettings emits a changed signal.
408
409 EXPECT_TRUE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE));
410}
411
412TEST_F(TestVolumeLauncherIcon, TestLockToLauncherMenuItem_Failure)
413{
414 ON_CALL(*settings_, IsABlacklistedDevice(volume_->GetIdentifier())).WillByDefault(Return(true));
415 settings_->changed.emit();
416 ASSERT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE));
417
418 auto menuitem = GetMenuItemAtIndex(4);
419
420 ASSERT_STREQ(dbusmenu_menuitem_property_get(menuitem, DBUSMENU_MENUITEM_PROP_LABEL), "Lock to Launcher");
421 EXPECT_TRUE(dbusmenu_menuitem_property_get_bool(menuitem, DBUSMENU_MENUITEM_PROP_VISIBLE));
422 EXPECT_TRUE(dbusmenu_menuitem_property_get_bool(menuitem, DBUSMENU_MENUITEM_PROP_ENABLED));
423
424 EXPECT_CALL(*settings_, TryToUnblacklist(volume_->GetIdentifier())).Times(1);
425 dbusmenu_menuitem_handle_event(menuitem, DBUSMENU_MENUITEM_EVENT_ACTIVATED, nullptr, 0);
426
427 EXPECT_FALSE(icon_->GetQuirk(AbstractLauncherIcon::Quirk::VISIBLE));
286}428}
287429
288TEST_F(TestVolumeLauncherIcon, TestOpenMenuItem)430TEST_F(TestVolumeLauncherIcon, TestOpenMenuItem)
@@ -298,7 +440,7 @@
298440
299 InSequence seq;441 InSequence seq;
300 EXPECT_CALL(*volume_, Mount());442 EXPECT_CALL(*volume_, Mount());
301 EXPECT_CALL(*file_manager_, OpenActiveChild(volume_->GetUri(), time));443 EXPECT_CALL(*file_manager_, Open(volume_->GetUri(), time));
302444
303 dbusmenu_menuitem_handle_event(menuitem, DBUSMENU_MENUITEM_EVENT_ACTIVATED, nullptr, time);445 dbusmenu_menuitem_handle_event(menuitem, DBUSMENU_MENUITEM_EVENT_ACTIVATED, nullptr, time);
304}446}
@@ -318,7 +460,7 @@
318460
319 InSequence seq;461 InSequence seq;
320 EXPECT_CALL(*volume_, Mount());462 EXPECT_CALL(*volume_, Mount());
321 EXPECT_CALL(*file_manager_, OpenActiveChild(volume_->GetUri(), time));463 EXPECT_CALL(*file_manager_, Open(volume_->GetUri(), time));
322464
323 dbusmenu_menuitem_handle_event(menuitem, DBUSMENU_MENUITEM_EVENT_ACTIVATED, nullptr, time);465 dbusmenu_menuitem_handle_event(menuitem, DBUSMENU_MENUITEM_EVENT_ACTIVATED, nullptr, time);
324}466}
@@ -438,7 +580,7 @@
438 EXPECT_CALL(*settings_, TryToBlacklist(_))580 EXPECT_CALL(*settings_, TryToBlacklist(_))
439 .Times(0);581 .Times(0);
440 EXPECT_CALL(*settings_, TryToUnblacklist(_))582 EXPECT_CALL(*settings_, TryToUnblacklist(_))
441 .Times(0);583 .Times(1);
442584
443 volume_->removed.emit();585 volume_->removed.emit();
444}586}
@@ -451,7 +593,7 @@
451 EXPECT_CALL(*settings_, TryToBlacklist(_))593 EXPECT_CALL(*settings_, TryToBlacklist(_))
452 .Times(0);594 .Times(0);
453 EXPECT_CALL(*settings_, TryToUnblacklist(_))595 EXPECT_CALL(*settings_, TryToUnblacklist(_))
454 .Times(0);596 .Times(1);
455597
456 volume_->removed.emit();598 volume_->removed.emit();
457}599}
@@ -516,7 +658,7 @@
516 uint64_t time = g_random_int();658 uint64_t time = g_random_int();
517 InSequence seq;659 InSequence seq;
518 EXPECT_CALL(*volume_, Mount()).Times(0);660 EXPECT_CALL(*volume_, Mount()).Times(0);
519 EXPECT_CALL(*file_manager_, OpenActiveChild(volume_->GetUri(), time));661 EXPECT_CALL(*file_manager_, Open(volume_->GetUri(), time));
520 icon_->Activate(ActionArg(ActionArg::Source::LAUNCHER, 0, time));662 icon_->Activate(ActionArg(ActionArg::Source::LAUNCHER, 0, time));
521}663}
522664
@@ -526,7 +668,7 @@
526 ON_CALL(*volume_, IsMounted()).WillByDefault(Return(false));668 ON_CALL(*volume_, IsMounted()).WillByDefault(Return(false));
527 InSequence seq;669 InSequence seq;
528 EXPECT_CALL(*volume_, Mount());670 EXPECT_CALL(*volume_, Mount());
529 EXPECT_CALL(*file_manager_, OpenActiveChild(volume_->GetUri(), time));671 EXPECT_CALL(*file_manager_, Open(volume_->GetUri(), time));
530 icon_->Activate(ActionArg(ActionArg::Source::LAUNCHER, 0, time));672 icon_->Activate(ActionArg(ActionArg::Source::LAUNCHER, 0, time));
531}673}
532674
533675
=== modified file 'unity-shared/ApplicationManager.h'
--- unity-shared/ApplicationManager.h 2015-07-09 16:32:54 +0000
+++ unity-shared/ApplicationManager.h 2016-02-09 10:44:04 +0000
@@ -109,6 +109,8 @@
109 nux::ROProperty<bool> active;109 nux::ROProperty<bool> active;
110 nux::ROProperty<bool> urgent;110 nux::ROProperty<bool> urgent;
111 nux::ROProperty<bool> maximized;111 nux::ROProperty<bool> maximized;
112
113 sigc::signal<void> closed;
112};114};
113115
114116
@@ -219,6 +221,7 @@
219 virtual WindowList GetWindowsForMonitor(int monitor = -1) const = 0;221 virtual WindowList GetWindowsForMonitor(int monitor = -1) const = 0;
220 virtual ApplicationPtr GetApplicationForWindow(Window xid) const = 0;222 virtual ApplicationPtr GetApplicationForWindow(Window xid) const = 0;
221 virtual ApplicationWindowPtr GetWindowForId(Window xid) const = 0;223 virtual ApplicationWindowPtr GetWindowForId(Window xid) const = 0;
224 virtual void FocusWindowGroup(WindowList const&, bool show_on_visible, int monitor) const = 0;
222225
223 sigc::signal<void, ApplicationPtr const&> application_started;226 sigc::signal<void, ApplicationPtr const&> application_started;
224 sigc::signal<void, ApplicationPtr const&> application_stopped;227 sigc::signal<void, ApplicationPtr const&> application_stopped;
225228
=== modified file 'unity-shared/BamfApplicationManager.cpp'
--- unity-shared/BamfApplicationManager.cpp 2015-10-28 15:41:17 +0000
+++ unity-shared/BamfApplicationManager.cpp 2016-02-09 10:44:04 +0000
@@ -147,6 +147,7 @@
147 });147 });
148 signals_.Add<void, BamfView*>(bamf_view_, "closed",148 signals_.Add<void, BamfView*>(bamf_view_, "closed",
149 [this] (BamfView* view) {149 [this] (BamfView* view) {
150 this->closed.emit();
150 pool::wins_.erase(view);151 pool::wins_.erase(view);
151 });152 });
152}153}
@@ -473,7 +474,7 @@
473 return pool::EnsureWindow(manager_, bamf_application_get_focusable_child(bamf_app_));474 return pool::EnsureWindow(manager_, bamf_application_get_focusable_child(bamf_app_));
474}475}
475476
476void Application::Focus(bool show_only_visible, int monitor) const477void Manager::FocusWindowGroup(WindowList const& wins, bool show_only_visible, int monitor) const
477{478{
478 WindowManager& wm = WindowManager::Default();479 WindowManager& wm = WindowManager::Default();
479 std::vector<Window> urgent_windows;480 std::vector<Window> urgent_windows;
@@ -481,7 +482,7 @@
481 std::vector<Window> non_visible_windows;482 std::vector<Window> non_visible_windows;
482 bool any_visible = false;483 bool any_visible = false;
483484
484 for (auto& window : GetWindows())485 for (auto& window : wins)
485 {486 {
486 Window window_id = window->window_id();487 Window window_id = window->window_id();
487 if (window->urgent())488 if (window->urgent())
@@ -526,12 +527,15 @@
526 }527 }
527}528}
528529
530void Application::Focus(bool show_only_visible, int monitor) const
531{
532 manager_.FocusWindowGroup(GetWindows(), show_only_visible, monitor);
533}
534
529void Application::Quit() const535void Application::Quit() const
530{536{
531 for (auto& window : GetWindows())537 for (auto& window : GetWindows())
532 {
533 window->Quit();538 window->Quit();
534 }
535}539}
536540
537bool Application::CreateLocalDesktopFile() const541bool Application::CreateLocalDesktopFile() const
538542
=== modified file 'unity-shared/BamfApplicationManager.h'
--- unity-shared/BamfApplicationManager.h 2015-07-09 16:32:54 +0000
+++ unity-shared/BamfApplicationManager.h 2016-02-09 10:44:04 +0000
@@ -64,7 +64,7 @@
6464
65 bool operator==(unity::ApplicationWindow const& other) const override65 bool operator==(unity::ApplicationWindow const& other) const override
66 {66 {
67 return static_cast<WindowBase const*>(this)->bamf_view_ == static_cast<WindowBase const&>(other).bamf_view_;67 return static_cast<WindowBase const*>(this)->bamf_view_ == static_cast<WindowBase const&>(other).bamf_view_;
68 }68 }
69 bool operator!=(unity::ApplicationWindow const& other) const override { return !(operator==(other)); }69 bool operator!=(unity::ApplicationWindow const& other) const override { return !(operator==(other)); }
70};70};
@@ -175,6 +175,8 @@
175 ApplicationPtr EnsureApplication(BamfView*) const;175 ApplicationPtr EnsureApplication(BamfView*) const;
176 ApplicationWindowPtr EnsureWindow(BamfView*) const;176 ApplicationWindowPtr EnsureWindow(BamfView*) const;
177177
178 void FocusWindowGroup(WindowList const&, bool show_on_visible, int monitor) const;
179
178private:180private:
179 void OnViewOpened(BamfMatcher* matcher, BamfView* view);181 void OnViewOpened(BamfMatcher* matcher, BamfView* view);
180 void OnViewClosed(BamfMatcher* matcher, BamfView* view);182 void OnViewClosed(BamfMatcher* matcher, BamfView* view);
181183
=== modified file 'unity-shared/FileManager.h'
--- unity-shared/FileManager.h 2013-10-07 18:10:17 +0000
+++ unity-shared/FileManager.h 2016-02-09 10:44:04 +0000
@@ -27,6 +27,8 @@
27#include <vector>27#include <vector>
28#include <set>28#include <set>
29#include <sigc++/sigc++.h>29#include <sigc++/sigc++.h>
30#include "ApplicationManager.h"
31
3032
31namespace unity33namespace unity
32{34{
@@ -40,15 +42,12 @@
40 virtual ~FileManager() = default;42 virtual ~FileManager() = default;
4143
42 virtual void Open(std::string const& uri, uint64_t timestamp = 0) = 0;44 virtual void Open(std::string const& uri, uint64_t timestamp = 0) = 0;
43 virtual void OpenActiveChild(std::string const& uri, uint64_t timestamp = 0) = 0;
44 virtual void OpenTrash(uint64_t timestamp) = 0;45 virtual void OpenTrash(uint64_t timestamp) = 0;
45 virtual std::vector<std::string> OpenedLocations() const = 0;
46 virtual bool IsPrefixOpened(std::string const& uri) const = 0;
47 virtual bool IsTrashOpened() const = 0;
48 virtual bool IsDeviceOpened() const = 0;
49 virtual void CopyFiles(std::set<std::string> const& uris, std::string const& dest, uint64_t timestamp = 0) = 0;46 virtual void CopyFiles(std::set<std::string> const& uris, std::string const& dest, uint64_t timestamp = 0) = 0;
50 virtual bool TrashFile(std::string const& uri) = 0;47 virtual bool TrashFile(std::string const& uri) = 0;
51 virtual void EmptyTrash(uint64_t timestamp = 0) = 0;48 virtual void EmptyTrash(uint64_t timestamp = 0) = 0;
49 virtual WindowList WindowsForLocation(std::string const& location) const = 0;
50 virtual std::string LocationForWindow(ApplicationWindowPtr const&) const = 0;
5251
53 sigc::signal<void> locations_changed;52 sigc::signal<void> locations_changed;
5453
@@ -57,6 +56,6 @@
57 FileManager& operator=(FileManager const&) = delete;56 FileManager& operator=(FileManager const&) = delete;
58};57};
5958
60}59} // namespace unity
6160
62#endif61#endif
6362
=== modified file 'unity-shared/GnomeFileManager.cpp'
--- unity-shared/GnomeFileManager.cpp 2013-10-07 22:37:34 +0000
+++ unity-shared/GnomeFileManager.cpp 2016-02-09 10:44:04 +0000
@@ -21,8 +21,9 @@
21#include "GnomeFileManager.h"21#include "GnomeFileManager.h"
22#include <NuxCore/Logger.h>22#include <NuxCore/Logger.h>
23#include <UnityCore/DesktopUtilities.h>23#include <UnityCore/DesktopUtilities.h>
24#include <UnityCore/GLibSource.h>
25#include <UnityCore/GLibDBusProxy.h>
24#include <UnityCore/GLibWrapper.h>26#include <UnityCore/GLibWrapper.h>
25#include <UnityCore/GLibDBusProxy.h>
26#include <gdk/gdk.h>27#include <gdk/gdk.h>
27#include <gio/gio.h>28#include <gio/gio.h>
2829
@@ -33,10 +34,8 @@
33{34{
34DECLARE_LOGGER(logger, "unity.filemanager.gnome");35DECLARE_LOGGER(logger, "unity.filemanager.gnome");
3536
36const std::string TRASH_URI = "trash:";37const std::string TRASH_URI = "trash:///";
37const std::string FILE_SCHEMA = "file://";38const std::string FILE_SCHEMA = "file://";
38const std::string TRASH_PATH = FILE_SCHEMA + DesktopUtilities::GetUserDataDirectory() + "/Trash/files";
39const std::string DEVICES_PREFIX = FILE_SCHEMA + "/media/" + std::string(g_get_user_name());
4039
41const std::string NAUTILUS_NAME = "org.gnome.Nautilus";40const std::string NAUTILUS_NAME = "org.gnome.Nautilus";
42const std::string NAUTILUS_PATH = "/org/gnome/Nautilus";41const std::string NAUTILUS_PATH = "/org/gnome/Nautilus";
@@ -48,64 +47,83 @@
48 : parent_(parent)47 : parent_(parent)
49 , filemanager_proxy_("org.freedesktop.FileManager1", "/org/freedesktop/FileManager1", "org.freedesktop.FileManager1")48 , filemanager_proxy_("org.freedesktop.FileManager1", "/org/freedesktop/FileManager1", "org.freedesktop.FileManager1")
50 {49 {
51 auto callback = sigc::mem_fun(this, &Impl::OnOpenLocationsUpdated);50 auto callback = sigc::mem_fun(this, &Impl::OnOpenLocationsXidsUpdated);
52 filemanager_proxy_.GetProperty("OpenLocations", callback);51 filemanager_proxy_.GetProperty("XUbuntuOpenLocationsXids", callback);
53 filemanager_proxy_.ConnectProperty("OpenLocations", callback);52 filemanager_proxy_.ConnectProperty("XUbuntuOpenLocationsXids", callback);
54 }53 }
5554
56 void OnOpenLocationsUpdated(GVariant* value)55 glib::DBusProxy::Ptr NautilusOperationsProxy() const
57 {56 {
58 if (!g_variant_is_of_type(value, G_VARIANT_TYPE_STRING_ARRAY))57 return std::make_shared<glib::DBusProxy>(NAUTILUS_NAME, NAUTILUS_PATH,
58 "org.gnome.Nautilus.FileOperations");
59 }
60
61 void OnOpenLocationsXidsUpdated(GVariant* value)
62 {
63 opened_location_for_xid_.clear();
64
65 if (!value)
66 {
67 LOG_WARN(logger) << "Locations have been invalidated, maybe there's no filemanager around...";
68 parent_->locations_changed.emit();
69 return;
70 }
71
72 if (!g_variant_is_of_type(value, G_VARIANT_TYPE("a{uas}")))
59 {73 {
60 LOG_ERROR(logger) << "Locations value type is not matching the expected one!";74 LOG_ERROR(logger) << "Locations value type is not matching the expected one!";
75 parent_->locations_changed.emit();
61 return;76 return;
62 }77 }
6378
64 opened_locations_.clear();
65
66 GVariantIter iter;79 GVariantIter iter;
67 const char *str;80 GVariantIter *str_iter;
81 const char *loc;
82 guint32 xid;
6883
69 g_variant_iter_init(&iter, value);84 g_variant_iter_init(&iter, value);
7085
71 while (g_variant_iter_loop(&iter, "s", &str))86 while (g_variant_iter_loop(&iter, "{uas}", &xid, &str_iter))
72 {87 {
73 LOG_DEBUG(logger) << "Opened location " << str;88 while (g_variant_iter_loop(str_iter, "s", &loc))
74 opened_locations_.push_back(str);89 {
75 }90 /* We only care about the first mentioned location as per our "standard"
7691 * it's the active one */
77 parent_->locations_changed.emit();92 LOG_DEBUG(logger) << xid << ": Opened location " << loc;
78 }93 opened_location_for_xid_[xid] = loc;
7994 break;
80 std::string GetOpenedPrefix(std::string const& uri, bool allow_equal = true)95 }
81 {96 }
82 glib::Object<GFile> uri_file(g_file_new_for_uri(uri.c_str()));97
8398 // We must ensure that we emit the locations_changed signal only when all
84 for (auto const& loc : opened_locations_)99 // the parent windows have been registered on the app-manager
85 {100 auto app_manager_not_synced = [this]
86 bool equal = false;101 {
87102 auto& app_manager = ApplicationManager::Default();
88 glib::Object<GFile> loc_file(g_file_new_for_uri(loc.c_str()));103 bool synced = true;
89104
90 if (allow_equal && g_file_equal(loc_file, uri_file))105 for (auto const& pair : opened_location_for_xid_)
91 equal = true;106 {
92107 synced = (app_manager.GetWindowForId(pair.first) != nullptr);
93 if (equal || g_file_has_prefix(loc_file, uri_file))108
94 return loc;109 if (!synced)
95 }110 break;
96111 }
97 return "";
98 }
99
100 glib::DBusProxy::Ptr NautilusOperationsProxy() const
101 {
102 return std::make_shared<glib::DBusProxy>(NAUTILUS_NAME, NAUTILUS_PATH,
103 "org.gnome.Nautilus.FileOperations");
The diff has been truncated for viewing.