summaryrefslogtreecommitdiff
diff options
authorThomi Richards <thomi.richards@canonical.com>2012-02-07 09:44:28 +1300
committerThomi Richards <thomi.richards@canonical.com>2012-02-07 09:44:28 +1300
commit8ca0b11e3aa9fc1f502bc7ee5b8b9135e4b0f2c4 (patch)
tree9160ba8bbb2f54b6e904d37757a041f52f315106
parent991e89b450d375c21e0b9693c7b93d57099caa6a (diff)
Refactor of launcher icon classes.
(bzr r1882.2.14)
-rw-r--r--plugins/unityshell/src/BFBLauncherIcon.cpp29
-rw-r--r--plugins/unityshell/src/BFBLauncherIcon.h3
-rw-r--r--plugins/unityshell/src/BamfLauncherIcon.cpp53
-rw-r--r--plugins/unityshell/src/BamfLauncherIcon.h4
-rw-r--r--plugins/unityshell/src/DesktopLauncherIcon.cpp5
-rw-r--r--plugins/unityshell/src/DesktopLauncherIcon.h1
-rw-r--r--plugins/unityshell/src/DeviceLauncherIcon.cpp65
-rw-r--r--plugins/unityshell/src/DeviceLauncherIcon.h1
-rw-r--r--plugins/unityshell/src/Introspectable.cpp12
-rw-r--r--plugins/unityshell/src/Introspectable.h2
-rw-r--r--plugins/unityshell/src/LauncherIcon.cpp6
-rw-r--r--plugins/unityshell/src/LauncherIcon.h4
-rw-r--r--plugins/unityshell/src/SimpleLauncherIcon.cpp9
-rw-r--r--plugins/unityshell/src/SimpleLauncherIcon.h3
-rw-r--r--plugins/unityshell/src/SpacerLauncherIcon.cpp4
-rw-r--r--plugins/unityshell/src/SpacerLauncherIcon.h2
-rw-r--r--plugins/unityshell/src/TrashLauncherIcon.cpp13
-rw-r--r--plugins/unityshell/src/TrashLauncherIcon.h1
-rw-r--r--plugins/unityshell/src/XPathQueryPart.cpp1
-rw-r--r--tests/autopilot/autopilot/emulators/unity.py218
-rw-r--r--tests/autopilot/autopilot/tests/test_invisible_windows.py24
21 files changed, 351 insertions, 109 deletions
diff --git a/plugins/unityshell/src/BFBLauncherIcon.cpp b/plugins/unityshell/src/BFBLauncherIcon.cpp
index c7d6f46ac..07f736a90 100644
--- a/plugins/unityshell/src/BFBLauncherIcon.cpp
+++ b/plugins/unityshell/src/BFBLauncherIcon.cpp
@@ -29,7 +29,7 @@ namespace unity
{
namespace launcher
{
-
+
UBusManager BFBLauncherIcon::ubus_manager_;
BFBLauncherIcon::BFBLauncherIcon()
@@ -40,9 +40,9 @@ BFBLauncherIcon::BFBLauncherIcon()
SetQuirk(QUIRK_VISIBLE, true);
SetQuirk(QUIRK_RUNNING, false);
SetIconType(TYPE_HOME);
-
+
background_color_ = nux::color::White;
-
+
mouse_enter.connect([&](int m) { ubus_manager_.SendMessage(UBUS_DASH_ABOUT_TO_SHOW, NULL); });
}
@@ -75,30 +75,30 @@ void BFBLauncherIcon::OnMenuitemActivated(DbusmenuMenuitem* item,
}
std::list<DbusmenuMenuitem*> BFBLauncherIcon::GetMenus()
-{
+{
std::list<DbusmenuMenuitem*> result;
DbusmenuMenuitem* menu_item;
-
+
// Home dash
menu_item = dbusmenu_menuitem_new();
-
+
dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Dash Home"));
dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
-
+
g_signal_connect(menu_item,
DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
(GCallback)&BFBLauncherIcon::OnMenuitemActivated,
g_strdup("home.lens"));
-
+
result.push_back(menu_item);
-
+
// Other lenses..
for (auto lens : lenses_.GetLenses())
{
if (!lens->visible())
continue;
-
+
menu_item = dbusmenu_menuitem_new();
dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, lens->name().c_str());
@@ -109,13 +109,18 @@ std::list<DbusmenuMenuitem*> BFBLauncherIcon::GetMenus()
DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
(GCallback)&BFBLauncherIcon::OnMenuitemActivated,
g_strdup(lens->id().c_str()));
-
+
result.push_back(menu_item);
}
-
+
return result;
}
+std::string BFBLauncherIcon::GetName() const
+{
+ return "BFBLauncherIcon";
+}
+
} // namespace launcher
} // namespace unity
diff --git a/plugins/unityshell/src/BFBLauncherIcon.h b/plugins/unityshell/src/BFBLauncherIcon.h
index 441448e73..1db9aeaa1 100644
--- a/plugins/unityshell/src/BFBLauncherIcon.h
+++ b/plugins/unityshell/src/BFBLauncherIcon.h
@@ -44,10 +44,11 @@ public:
protected:
std::list<DbusmenuMenuitem*> GetMenus();
+ std::string GetName() const;
private:
static void OnMenuitemActivated(DbusmenuMenuitem* item, int time, gchar* lens);
-
+
static unity::UBusManager ubus_manager_;
nux::Color background_color_;
dash::FilesystemLenses lenses_;
diff --git a/plugins/unityshell/src/BamfLauncherIcon.cpp b/plugins/unityshell/src/BamfLauncherIcon.cpp
index 10a330002..cd4a120e0 100644
--- a/plugins/unityshell/src/BamfLauncherIcon.cpp
+++ b/plugins/unityshell/src/BamfLauncherIcon.cpp
@@ -32,6 +32,7 @@
#include <libindicator/indicator-desktop-shortcuts.h>
#include <UnityCore/GLibWrapper.h>
+#include <UnityCore/Variant.h>
namespace unity
{
@@ -263,7 +264,7 @@ BamfLauncherIcon::~BamfLauncherIcon()
if (_fill_supported_types_id != 0)
g_source_remove(_fill_supported_types_id);
-
+
if (_window_moved_id != 0)
g_source_remove(_window_moved_id);
@@ -402,7 +403,7 @@ void BamfLauncherIcon::UpdateDesktopFile()
if (_on_desktop_file_changed_handler_id != 0)
g_signal_handler_disconnect(G_OBJECT(_desktop_file_monitor),
_on_desktop_file_changed_handler_id);
- g_object_unref(_desktop_file_monitor);
+ g_object_unref(_desktop_file_monitor);
}
GFile* desktop_file = g_file_new_for_path(DesktopFile());
@@ -439,9 +440,7 @@ const char* BamfLauncherIcon::BamfName()
void BamfLauncherIcon::AddProperties(GVariantBuilder* builder)
{
- LauncherIcon::AddProperties(builder);
-
- g_variant_builder_add(builder, "{sv}", "desktop-file", g_variant_new_string(DesktopFile()));
+ SimpleLauncherIcon::AddProperties(builder);
GList* children, *l;
BamfView* view;
@@ -460,7 +459,10 @@ void BamfLauncherIcon::AddProperties(GVariantBuilder* builder)
}
}
g_list_free(children);
- g_variant_builder_add(builder, "{sv}", "xids", g_variant_new_array(G_VARIANT_TYPE_UINT32, xids, i));
+ unity::variant::BuilderWrapper(builder)
+ .add("sticky", IsSticky())
+ .add("desktop-file",DesktopFile())
+ .add("xids", g_variant_new_array(G_VARIANT_TYPE_UINT32, xids, i));
}
bool BamfLauncherIcon::OwnsWindow(Window w)
@@ -513,7 +515,7 @@ void BamfLauncherIcon::OpenInstanceWithUris(std::set<std::string> uris)
else if (g_app_info_supports_files(G_APP_INFO(appInfo)))
{
GList* list = NULL, *l;
-
+
for (auto it : uris)
{
GFile* file = g_file_new_for_uri(it.c_str());
@@ -877,13 +879,13 @@ void BamfLauncherIcon::Quit()
void BamfLauncherIcon::Stick(bool save)
{
BamfView* view = BAMF_VIEW(m_App);
-
+
if (bamf_view_is_sticky(view))
return;
-
+
const gchar* desktop_file = DesktopFile();
bamf_view_set_sticky(view, true);
-
+
if (save && desktop_file && strlen(desktop_file) > 0)
FavoriteStore::GetDefault().AddFavorite(desktop_file, -1);
}
@@ -940,7 +942,7 @@ void BamfLauncherIcon::EnsureMenuItemsReady()
_menu_items["Pin"] = menu_item;
}
-
+
const char* label = !bamf_view_is_sticky(BAMF_VIEW(m_App)) ?
_("Lock to launcher") : _("Unlock from launcher");
@@ -1190,17 +1192,17 @@ std::set<std::string> BamfLauncherIcon::ValidateUrisForLaunch(unity::DndData& ur
{
for (auto k : uris.UrisByType(i))
result.insert(k);
-
+
break;
}
-
+
return result;
}
gboolean BamfLauncherIcon::OnDndHoveredTimeout(gpointer data)
{
BamfLauncherIcon* self = static_cast <BamfLauncherIcon*> (data);
-
+
// for now, let's not do this, it turns out to be quite buggy
//if (self->_dnd_hovered && bamf_view_is_running(BAMF_VIEW(self->m_App)))
// self->Spread(CompAction::StateInitEdgeDnd, true);
@@ -1311,7 +1313,7 @@ BamfLauncherIcon::GetSupportedTypes()
{
if (!_supported_types_filled)
FillSupportedTypes(this);
-
+
return _supported_types;
}
@@ -1319,24 +1321,24 @@ gboolean
BamfLauncherIcon::FillSupportedTypes(gpointer data)
{
BamfLauncherIcon* self = static_cast <BamfLauncherIcon*> (data);
-
+
if (self->_fill_supported_types_id)
{
g_source_remove(self->_fill_supported_types_id);
self->_fill_supported_types_id = 0;
}
-
+
if (!self->_supported_types_filled)
{
self->_supported_types_filled = true;
-
+
self->_supported_types.clear();
-
+
const char* desktop_file = self->DesktopFile();
if (!desktop_file || strlen(desktop_file) <= 1)
return false;
-
+
GKeyFile* key_file = g_key_file_new();
unity::glib::Error error;
@@ -1347,20 +1349,20 @@ BamfLauncherIcon::FillSupportedTypes(gpointer data)
g_key_file_free(key_file);
return false;
}
-
+
char** mimes = g_key_file_get_string_list(key_file, "Desktop Entry", "MimeType", NULL, NULL);
if (!mimes)
{
g_key_file_free(key_file);
return false;
}
-
+
for (int i=0; mimes[i]; i++)
{
unity::glib::String super_type(g_content_type_from_mime_type(mimes[i]));
self->_supported_types.insert(super_type.Str());
}
-
+
g_key_file_free(key_file);
g_strfreev(mimes);
}
@@ -1368,5 +1370,10 @@ BamfLauncherIcon::FillSupportedTypes(gpointer data)
return false;
}
+std::string BamfLauncherIcon::GetName() const
+{
+ return "BamfLauncherIcon";
+}
+
} // namespace launcher
} // namespace unity
diff --git a/plugins/unityshell/src/BamfLauncherIcon.h b/plugins/unityshell/src/BamfLauncherIcon.h
index 80409aa41..b3d35c7f4 100644
--- a/plugins/unityshell/src/BamfLauncherIcon.h
+++ b/plugins/unityshell/src/BamfLauncherIcon.h
@@ -59,8 +59,8 @@ public:
std::vector<Window> WindowsForMonitor(int monitor);
std::string NameForWindow (Window window);
-
protected:
+ std::string GetName() const;
std::list<DbusmenuMenuitem*> GetMenus();
void UpdateIconGeometries(std::vector<nux::Point3> center);
@@ -123,7 +123,7 @@ private:
void OnWindowMinimized(guint32 xid);
void OnWindowMoved(guint32 xid);
bool OwnsWindow(Window w);
-
+
const std::set<std::string>& GetSupportedTypes();
static void OnClosed(BamfView* view, gpointer data);
diff --git a/plugins/unityshell/src/DesktopLauncherIcon.cpp b/plugins/unityshell/src/DesktopLauncherIcon.cpp
index ae474aade..b974b7233 100644
--- a/plugins/unityshell/src/DesktopLauncherIcon.cpp
+++ b/plugins/unityshell/src/DesktopLauncherIcon.cpp
@@ -61,5 +61,10 @@ DesktopLauncherIcon::ActivateLauncherIcon(ActionArg arg)
WindowManager::Default()->ShowDesktop();
}
+std::string DesktopLauncherIcon::GetName() const
+{
+ return "DesktopLauncherIcon";
+}
+
} // namespace launcher
} // namespace unity
diff --git a/plugins/unityshell/src/DesktopLauncherIcon.h b/plugins/unityshell/src/DesktopLauncherIcon.h
index 05ad51f31..975faf12a 100644
--- a/plugins/unityshell/src/DesktopLauncherIcon.h
+++ b/plugins/unityshell/src/DesktopLauncherIcon.h
@@ -49,6 +49,7 @@ public:
protected:
void ActivateLauncherIcon(ActionArg arg);
+ std::string GetName() const;
private:
bool show_in_switcher_;
diff --git a/plugins/unityshell/src/DeviceLauncherIcon.cpp b/plugins/unityshell/src/DeviceLauncherIcon.cpp
index eca15f17a..59bac1d34 100644
--- a/plugins/unityshell/src/DeviceLauncherIcon.cpp
+++ b/plugins/unityshell/src/DeviceLauncherIcon.cpp
@@ -48,7 +48,7 @@ DeviceLauncherIcon::DeviceLauncherIcon(GVolume* volume)
, volume_(volume)
, device_file_(g_volume_get_identifier(volume_, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE))
, gdu_device_(get_device_for_device_file(device_file_))
-{
+{
DevicesSettings::GetDefault().changed.connect(sigc::mem_fun(this, &DeviceLauncherIcon::OnSettingsChanged));
// Checks if in favourites!
@@ -57,7 +57,7 @@ DeviceLauncherIcon::DeviceLauncherIcon(GVolume* volume)
DeviceList::iterator pos = std::find(favorites.begin(), favorites.end(), uuid.Str());
keep_in_launcher_ = pos != favorites.end();
-
+
UpdateDeviceIcon();
UpdateVisibility();
}
@@ -70,7 +70,7 @@ void DeviceLauncherIcon::UpdateDeviceIcon()
tooltip_text = name.Str();
icon_name = icon_string.Str();
-
+
SetIconType(TYPE_DEVICE);
SetQuirk(QUIRK_RUNNING, false);
}
@@ -106,13 +106,13 @@ std::list<DbusmenuMenuitem*> DeviceLauncherIcon::GetMenus()
dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, !keep_in_launcher_ ? _("Lock to launcher") : _("Unlock from launcher"));
dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
-
+
g_signal_connect(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
G_CALLBACK(&DeviceLauncherIcon::OnTogglePin), this);
result.push_back(menu_item);
}
-
+
// "Open" item
menu_item = dbusmenu_menuitem_new();
@@ -122,9 +122,9 @@ std::list<DbusmenuMenuitem*> DeviceLauncherIcon::GetMenus()
g_signal_connect(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
G_CALLBACK(&DeviceLauncherIcon::OnOpen), this);
-
+
result.push_back(menu_item);
-
+
// "Format" item
if (gdu_device_ && !gdu_device_is_optical_disc(gdu_device_))
{
@@ -136,15 +136,15 @@ std::list<DbusmenuMenuitem*> DeviceLauncherIcon::GetMenus()
g_signal_connect(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
G_CALLBACK(&DeviceLauncherIcon::OnFormat), this);
-
+
result.push_back(menu_item);
}
// "Eject" item
if (drive && g_drive_can_eject(drive))
- {
+ {
menu_item = dbusmenu_menuitem_new();
-
+
GList *list = g_drive_get_volumes(drive);
if (list != NULL)
{
@@ -152,10 +152,10 @@ std::list<DbusmenuMenuitem*> DeviceLauncherIcon::GetMenus()
dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Eject"));
else
dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Eject parent drive"));
-
+
g_list_free_full(list, g_object_unref);
}
-
+
dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
@@ -169,7 +169,7 @@ std::list<DbusmenuMenuitem*> DeviceLauncherIcon::GetMenus()
if (drive && g_drive_can_stop(drive))
{
menu_item = dbusmenu_menuitem_new();
-
+
GList *list = g_drive_get_volumes(drive);
if (list != NULL)
{
@@ -177,7 +177,7 @@ std::list<DbusmenuMenuitem*> DeviceLauncherIcon::GetMenus()
dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Safely remove"));
else
dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Safely remove parent drive"));
-
+
g_list_free_full(list, g_object_unref);
}
@@ -186,7 +186,7 @@ std::list<DbusmenuMenuitem*> DeviceLauncherIcon::GetMenus()
g_signal_connect(menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
G_CALLBACK(&DeviceLauncherIcon::OnDriveStop), this);
-
+
result.push_back(menu_item);
}
@@ -252,7 +252,7 @@ void DeviceLauncherIcon::ActivateLauncherIcon(ActionArg arg)
{
SimpleLauncherIcon::ActivateLauncherIcon(arg);
SetQuirk(QUIRK_STARTING, true);
-
+
glib::Object<GMount> mount(g_volume_get_mount(volume_));
if (G_IS_MOUNT(mount.RawPtr()))
@@ -292,29 +292,29 @@ void DeviceLauncherIcon::OnEjectReady(GObject* object,
DeviceLauncherIcon* self)
{
if (g_volume_eject_with_operation_finish(self->volume_, result, NULL))
- {
+ {
IconLoader::GetDefault().LoadFromGIconString(self->icon_name(), 48,
sigc::mem_fun(self, &DeviceLauncherIcon::ShowNotification));
}
}
-void DeviceLauncherIcon::ShowNotification(std::string const& icon_name,
+void DeviceLauncherIcon::ShowNotification(std::string const& icon_name,
unsigned size,
GdkPixbuf* pixbuf)
{
-
+
glib::String name(g_volume_get_name(volume_));
glib::Object<NotifyNotification> notification(notify_notification_new(name,
_("The drive has been successfully ejected"),
NULL));
-
+
notify_notification_set_hint(notification,
"x-canonical-private-synchronous",
g_variant_new_boolean(TRUE));
-
+
if(GDK_IS_PIXBUF(pixbuf))
notify_notification_set_image_from_pixbuf(notification, pixbuf);
-
+
notify_notification_show(notification, NULL);
}
@@ -335,7 +335,7 @@ void DeviceLauncherIcon::OnTogglePin(DbusmenuMenuitem* item,
DeviceLauncherIcon* self)
{
glib::String uuid(g_volume_get_identifier(self->volume_, G_VOLUME_IDENTIFIER_KIND_UUID));
-
+
self->keep_in_launcher_ = !self->keep_in_launcher_;
if (!self->keep_in_launcher_)
@@ -344,7 +344,7 @@ void DeviceLauncherIcon::OnTogglePin(DbusmenuMenuitem* item,
glib::Object<GMount> mount(g_volume_get_mount(self->volume_));
if (!mount)
- self->SetQuirk(QUIRK_VISIBLE, false);
+ self->SetQuirk(QUIRK_VISIBLE, false);
// Remove from favorites
if (!uuid.Str().empty())
@@ -369,12 +369,12 @@ void DeviceLauncherIcon::OnFormat(DbusmenuMenuitem* item,
DeviceLauncherIcon* self)
{
glib::Error error;
-
+
gchar const* args[] = { "/usr/lib/gnome-disk-utility/gdu-format-tool",
"--device-file",
self->device_file_.Value(),
NULL};
-
+
g_spawn_async(NULL, // working dir
const_cast<gchar **>(args),
NULL, // envp
@@ -383,7 +383,7 @@ void DeviceLauncherIcon::OnFormat(DbusmenuMenuitem* item,
NULL, // user_data
NULL, // GPid *child_pid
&error);
-
+
if (error)
{
LOG_WARNING(logger) << "Error launching " << args[0] << ": " << error;
@@ -408,7 +408,7 @@ void DeviceLauncherIcon::OnUnmountReady(GObject* object,
void DeviceLauncherIcon::Unmount()
{
glib::Object<GMount> mount(g_volume_get_mount(volume_));
-
+
if (mount)
{
glib::Object<GMountOperation> op(gtk_mount_operation_new(NULL));
@@ -469,11 +469,11 @@ void DeviceLauncherIcon::UpdateVisibility(int visibility)
else if (visibility < 0)
{
glib::Object<GMount> mount(g_volume_get_mount(volume_));
- SetQuirk(QUIRK_VISIBLE, mount.RawPtr() != NULL);
+ SetQuirk(QUIRK_VISIBLE, mount.RawPtr() != NULL);
}
else
{
- SetQuirk(QUIRK_VISIBLE, visibility);
+ SetQuirk(QUIRK_VISIBLE, visibility);
}
break;
case DevicesSettings::ALWAYS:
@@ -494,6 +494,11 @@ void DeviceLauncherIcon::OnSettingsChanged()
UpdateVisibility();
}
+std::string DeviceLauncherIcon::GetName() const
+{
+ return "DeviceLauncherIcon";
+}
+
namespace
{
diff --git a/plugins/unityshell/src/DeviceLauncherIcon.h b/plugins/unityshell/src/DeviceLauncherIcon.h
index 4c52b451b..e3ef262e4 100644
--- a/plugins/unityshell/src/DeviceLauncherIcon.h
+++ b/plugins/unityshell/src/DeviceLauncherIcon.h
@@ -48,6 +48,7 @@ public:
protected:
std::list<DbusmenuMenuitem*> GetMenus();
void UpdateDeviceIcon();
+ std::string GetName() const;
private:
void ActivateLauncherIcon(ActionArg arg);
diff --git a/plugins/unityshell/src/Introspectable.cpp b/plugins/unityshell/src/Introspectable.cpp
index a9f9a251e..59050a212 100644
--- a/plugins/unityshell/src/Introspectable.cpp
+++ b/plugins/unityshell/src/Introspectable.cpp
@@ -26,6 +26,8 @@ namespace debug
Introspectable::Introspectable()
{
+ static guint64 unique_id=0;
+ _id = unique_id++;
}
Introspectable::~Introspectable()
@@ -44,13 +46,12 @@ Introspectable::IntrospectableList const& Introspectable::GetIntrospectableChild
GVariant*
Introspectable::Introspect()
{
- static guint64 unique_id=0;
GVariantBuilder builder;
GVariantBuilder child_builder;
gint n_children = 0;
g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}"));
- g_variant_builder_add(&builder, "{sv}", "id", g_variant_new_uint64(unique_id++));
+ g_variant_builder_add(&builder, "{sv}", "id", g_variant_new_uint64(_id));
AddProperties(&builder);
@@ -92,5 +93,12 @@ Introspectable::GetChildsName() const
{
return "Children";
}
+
+guint64 Introspectable::GetIntrospectionId() const
+{
+ return _id;
+}
+
}
}
+
diff --git a/plugins/unityshell/src/Introspectable.h b/plugins/unityshell/src/Introspectable.h
index 5ceebd26a..e1d51b328 100644
--- a/plugins/unityshell/src/Introspectable.h
+++ b/plugins/unityshell/src/Introspectable.h
@@ -41,6 +41,7 @@ public:
void RemoveChild(Introspectable* child);
virtual void AddProperties(GVariantBuilder* builder) = 0;
virtual IntrospectableList const& GetIntrospectableChildren();
+ guint64 GetIntrospectionId() const;
protected:
/// Please don't override this unless you really need to. The only valid reason
@@ -60,6 +61,7 @@ protected:
private:
std::list<Introspectable*> _children;
std::list<Introspectable*> _parents;
+ guint64 _id;
};
}
}
diff --git a/plugins/unityshell/src/LauncherIcon.cpp b/plugins/unityshell/src/LauncherIcon.cpp
index 0addde9ce..108859c6a 100644
--- a/plugins/unityshell/src/LauncherIcon.cpp
+++ b/plugins/unityshell/src/LauncherIcon.cpp
@@ -576,7 +576,7 @@ bool LauncherIcon::OpenQuicklist(bool default_to_first_item, int monitor)
nux::Geometry geo = _parent_geo[monitor];
int tip_x = geo.x + geo.width + 1;
- int tip_y = geo.y + _center[monitor].y;
+ int tip_y = geo.y + _center[monitor].y;
auto win_manager = WindowManager::Default();
@@ -619,7 +619,7 @@ void LauncherIcon::RecvMouseClick(int button, int monitor)
{
ActionArg arg(ActionArg::LAUNCHER, button);
arg.monitor = monitor;
-
+
if (button == 1)
Activate(arg);
else if (button == 2)
@@ -793,7 +793,7 @@ LauncherIcon::SetQuirk(LauncherIcon::Quirk quirk, bool value)
{
if (_quirks[quirk] == value)
return;
-
+
_quirks[quirk] = value;
if (quirk == QUIRK_VISIBLE)
TimeUtil::SetTimeStruct(&(_quirk_times[quirk]), &(_quirk_times[quirk]), ANIM_DURATION_SHORT);
diff --git a/plugins/unityshell/src/LauncherIcon.h b/plugins/unityshell/src/LauncherIcon.h
index d6e95e435..e67241cc4 100644
--- a/plugins/unityshell/src/LauncherIcon.h
+++ b/plugins/unityshell/src/LauncherIcon.h
@@ -308,7 +308,7 @@ private:
int _last_monitor;
nux::Color _background_color;
nux::Color _glow_color;
-
+
gint64 _shortcut;
std::vector<nux::Point3> _center;
@@ -326,7 +326,7 @@ private:
std::list<LauncherEntryRemote*> _entry_list;
std::vector<std::map<TransformIndex, std::vector<nux::Vector4> > > transform_map;
-
+
};
}
diff --git a/plugins/unityshell/src/SimpleLauncherIcon.cpp b/plugins/unityshell/src/SimpleLauncherIcon.cpp
index 6d04ee58e..9d0a4ac9c 100644
--- a/plugins/unityshell/src/SimpleLauncherIcon.cpp
+++ b/plugins/unityshell/src/SimpleLauncherIcon.cpp
@@ -119,7 +119,7 @@ bool SimpleLauncherIcon::SetIconName(std::string& target, std::string const& val
target = value;
ReloadIcon();
-
+
return true;
}
@@ -142,7 +142,12 @@ void SimpleLauncherIcon::OnIconThemeChanged(GtkIconTheme* icon_theme, gpointer d
self->ReloadIcon();
}
+std::string SimpleLauncherIcon::GetName() const
+{
+ return "SimpleLauncherIcon";
+}
+
} // namespace launcher
} // namespace unity
-#endif \ No newline at end of file
+#endif
diff --git a/plugins/unityshell/src/SimpleLauncherIcon.h b/plugins/unityshell/src/SimpleLauncherIcon.h
index 15479ec4c..2d2a8faee 100644
--- a/plugins/unityshell/src/SimpleLauncherIcon.h
+++ b/plugins/unityshell/src/SimpleLauncherIcon.h
@@ -40,11 +40,12 @@ public:
// Properties
nux::Property<std::string> icon_name;
-
+
// Signals
sigc::signal<void> activate;
protected:
+ std::string GetName() const;
virtual void OnMouseDown(int button, int monitor);
virtual void OnMouseUp(int button, int monitor);
virtual void OnMouseClick(int button, int monitor);
diff --git a/plugins/unityshell/src/SpacerLauncherIcon.cpp b/plugins/unityshell/src/SpacerLauncherIcon.cpp
index 74d420ba2..180842e5c 100644
--- a/plugins/unityshell/src/SpacerLauncherIcon.cpp
+++ b/plugins/unityshell/src/SpacerLauncherIcon.cpp
@@ -37,6 +37,10 @@ SpacerLauncherIcon::SpacerLauncherIcon()
tooltip_text = _("Drop To Add Application");
}
+std::string SpacerLauncherIcon::GetName() const
+{
+ return "SpacerLauncherIcon";
+}
} // namespace launcher
} // namespace unity
diff --git a/plugins/unityshell/src/SpacerLauncherIcon.h b/plugins/unityshell/src/SpacerLauncherIcon.h
index a326357aa..87af8e872 100644
--- a/plugins/unityshell/src/SpacerLauncherIcon.h
+++ b/plugins/unityshell/src/SpacerLauncherIcon.h
@@ -36,6 +36,8 @@ public:
{
return true;
}
+protected:
+ std::string GetName() const;
};
}
diff --git a/plugins/unityshell/src/TrashLauncherIcon.cpp b/plugins/unityshell/src/TrashLauncherIcon.cpp
index 68d6c89fd..e12eee53f 100644
--- a/plugins/unityshell/src/TrashLauncherIcon.cpp
+++ b/plugins/unityshell/src/TrashLauncherIcon.cpp
@@ -42,7 +42,7 @@ TrashLauncherIcon::TrashLauncherIcon()
SetQuirk(QUIRK_RUNNING, false);
SetIconType(TYPE_TRASH);
SetShortcut('t');
-
+
glib::Object<GFile> location(g_file_new_for_uri("trash:///"));
trash_monitor_ = g_file_monitor_directory(location,
@@ -133,10 +133,10 @@ void TrashLauncherIcon::UpdateTrashIconCb(GObject* source,
glib::Object<GFileInfo> info(g_file_query_info_finish(G_FILE(source), res, NULL));
if (info)
- {
+ {
glib::Object<GIcon> icon(g_file_info_get_icon(info));
glib::String icon_string(g_icon_to_string(icon));
-
+
self->icon_name = icon_string.Str();
self->empty_ = (self->icon_name == "user-trash");
@@ -166,9 +166,14 @@ void TrashLauncherIcon::OnAcceptDrop(unity::DndData& dnd_data)
glib::Object<GFile> file(g_file_new_for_uri(it.c_str()));
g_file_trash(file, NULL, NULL);
}
-
+
SetQuirk(LauncherIcon::QUIRK_PULSE_ONCE, true);
}
+std::string TrashLauncherIcon::GetName() const
+{
+ return "TrashLauncherIcon";
+}
+
} // namespace launcher
} // namespace unity
diff --git a/plugins/unityshell/src/TrashLauncherIcon.h b/plugins/unityshell/src/TrashLauncherIcon.h
index f09319cc7..b693e5476 100644
--- a/plugins/unityshell/src/TrashLauncherIcon.h
+++ b/plugins/unityshell/src/TrashLauncherIcon.h
@@ -47,6 +47,7 @@ protected:
nux::DndAction OnQueryAcceptDrop(unity::DndData& dnd_data);
void OnAcceptDrop(unity::DndData& dnd_data);
+ std::string GetName() const;
private:
gulong on_trash_changed_handler_id_;
diff --git a/plugins/unityshell/src/XPathQueryPart.cpp b/plugins/unityshell/src/XPathQueryPart.cpp
index efa215669..cf3026733 100644
--- a/plugins/unityshell/src/XPathQueryPart.cpp
+++ b/plugins/unityshell/src/XPathQueryPart.cpp
@@ -77,6 +77,7 @@ bool XPathQueryPart::Matches(Introspectable* node) const
{
GVariantBuilder child_builder;
g_variant_builder_init(&child_builder, G_VARIANT_TYPE("a{sv}"));
+ g_variant_builder_add(&child_builder, "{sv}", "id", g_variant_new_uint64(node->GetIntrospectionId()));
node->AddProperties(&child_builder);
GVariant* prop_dict = g_variant_builder_end(&child_builder);
GVariant *prop_value = g_variant_lookup_value(prop_dict, param_name_.c_str(), NULL);
diff --git a/tests/autopilot/autopilot/emulators/unity.py b/tests/autopilot/autopilot/emulators/unity.py
index 784245a26..86d1ba957 100644
--- a/tests/autopilot/autopilot/emulators/unity.py
+++ b/tests/autopilot/autopilot/emulators/unity.py
@@ -50,6 +50,96 @@ class Unity(object):
return self._introspection_iface.GetState(piece)
+class SimpleLauncherIcon(Unity):
+ """Holds information about a simple launcher icon.
+
+ Do not instantiate an instance of this class yourself. Instead, use the
+ appropriate methods in the Launcher class instead.
+
+ """
+
+ def __init__(self, icon_dict):
+ super(SimpleLauncherIcon, self).__init__()
+ self._set_properties(icon_dict)
+
+ def refresh_state(self):
+ """Re-get the LauncherIcon's state from unity, updating it's public properties."""
+ state = self.get_state('//LauncherIcon[id=%d]' % (self.id))
+ self._set_properties(state[0])
+
+ def _set_properties(self, state_from_unity):
+ # please keep these in the same order as they are in unity:
+ self.urgent = state_from_unity['quirk-urgent']
+ self.presented = state_from_unity['quirk-presented']
+ self.visible = state_from_unity['quirk-visible']
+ self.sort_priority = state_from_unity['sort-priority']
+ self.running = state_from_unity['quirk-running']
+ self.active = state_from_unity['quirk-active']
+ self.icon_type = state_from_unity['icon-type']
+ self.related_windows = state_from_unity['related-windows']
+ self.y = state_from_unity['y']
+ self.x = state_from_unity['x']
+ self.z = state_from_unity['z']
+ self.id = state_from_unity['id']
+ self.tooltip_text = state_from_unity['tooltip-text']
+
+ def get_quicklist(self):
+ """Get the quicklist for this launcher icon.
+
+ This may return None, if there is no quicklist associated with this
+ launcher icon.
+
+ """
+ ql_state = self.get_state('//LauncherIcon[id=%d]/Quicklist' % (self.id))
+ if len(ql_state) > 0:
+ return Quicklist(ql_state[0])
+
+
+class BFBLauncherIcon(SimpleLauncherIcon):
+ """Represents the BFB button in the launcher."""
+
+
+class BamfLauncherIcon(SimpleLauncherIcon):
+ """Represents a launcher icon with BAMF integration."""
+
+ def _set_properties(self, state_from_unity):
+ super(BamfLauncherIcon, self)._set_properties(state_from_unity)
+ self.desktop_file = state_from_unity['desktop-file']
+ self.sticky = bool(state_from_unity['sticky'])
+
+
+class TrashLauncherIcon(SimpleLauncherIcon):
+ """Represents the trash launcher icon."""
+
+
+class DeviceLauncherIcon(SimpleLauncherIcon):
+ """Represents a device icon in the launcher."""
+
+
+class DesktopLauncherIcon(SimpleLauncherIcon):
+ """Represents an icon that may appear in the switcher."""
+
+
+_icon_type_registry = {
+ 'BamfLauncherIcon' : BamfLauncherIcon,
+ 'BFBLauncherIcon' : BFBLauncherIcon,
+ 'DesktopLauncherIcon' : DesktopLauncherIcon,
+ 'DeviceLauncherIcon' : DeviceLauncherIcon,
+ 'SimpleLauncherIcon' : SimpleLauncherIcon,
+ 'TrashLauncherIcon' : TrashLauncherIcon,
+ }
+
+
+def make_launcher_icon(dbus_tuple):
+ """Make a launcher icon instance of the appropriate type given the DBus child tuple."""
+ name,state = dbus_tuple
+ try:
+ class_type = _icon_type_registry[name]
+ return class_type(state)
+ except KeyError:
+ print name, "is not a valid icon type!"
+ return None
+
class Launcher(Unity):
"""Interact with the unity Launcher."""
@@ -79,7 +169,7 @@ class Launcher(Unity):
def reveal_launcher(self, monitor):
(x, y, w, h) = self.launcher_geometry(monitor)
- self._mouse.move(x - 1200, y + h / 2)
+ self._mouse.move(x - 920, y + h / 2, True, 5, .002)
sleep(self.show_timeout)
def keyboard_reveal_launcher(self):
@@ -179,7 +269,12 @@ class Launcher(Unity):
def get_launcher_icons(self):
"""Get a list of launcher icons in this launcher."""
model = self.get_state("/Unity/LauncherController/LauncherModel")[0]
- return [LauncherIcon(icon_dict[1]) for icon_dict in model['Children'] if icon_dict[0] == 'LauncherIcon']
+ icons = []
+ for child in model['Children']:
+ icon = make_launcher_icon(child)
+ if icon:
+ icons.append(icon)
+ return icons
def num_launcher_icons(self):
"""Get the number of icons in the launcher model."""
@@ -196,24 +291,111 @@ class Launcher(Unity):
self._mouse.click(button)
self.move_mouse_to_right_of_launcher(monitor)
-class LauncherIcon:
- """Holds information about a launcher icon.
+ def lock_to_launcher(self, icon):
+ """lock 'icon' to the launcher, if it's not already."""
+ if not isinstance(icon, BamfLauncherIcon):
+ raise TypeError("Can only lock instances of BamfLauncherIcon")
+ if icon.sticky:
+ return # nothing to do.
+
+ self.click_launcher_icon(icon, button=3) # right click
+ quicklist = icon.get_quicklist()
+ pin_item = quicklist.get_quicklist_item_by_text('Lock to launcher')
+ quicklist.click_item(pin_item)
+
+ def unlock_from_launcher(self, icon):
+ """lock 'icon' to the launcher, if it's not already."""
+ if not isinstance(icon, SimpleLauncherIcon):
+ raise TypeError("icon must be a LauncherIcon")
+ if icon.sticky:
+ return # nothing to do.
+
+ self.click_launcher_icon(icon, button=3) # right click
+ quicklist = icon.get_quicklist()
+ pin_item = quicklist.get_quicklist_item_by_text('Unlock from launcher')
+ quicklist.click_item(pin_item)
+
+
+class Quicklist(Unity):
+ """Represents a quicklist."""
+ def __init__(self, state_dict):
+ super(Quicklist, self).__init__()
+ self._set_properties(state_dict)
+
+ def _set_properties(self, state_dict):
+ self.id = state_dict['id']
+ self.x = state_dict['x']
+ self.y = state_dict['y']
+ self.width = state_dict['width']
+ self.height = state_dict['height']
+ self.active = state_dict['active']
+ self._children = state_dict['Children']
+
+ def refresh_state(self):
+ state = self.get_state('//Quicklist[id=%d]' % (self.id))
+ self._set_properties(state[0])
- Do not instantiate an instance of this class yourself. Instead, use the
- appropriate methods in the Launcher class instead.
+ @property
+ def items(self):
+ """Individual items in the quicklist."""
+ return [self.__make_quicklist_from_data(ctype, cdata) for ctype,cdata in self._children]
+
+ def get_quicklist_item_by_text(self, text):
+ """Returns a QuicklistMenuItemLabel object with the given text, or None."""
+ matches = []
+ for item in self.items:
+ if type(item) is QuicklistMenuItemLabel and item.text == text:
+ matches.append(item)
+ if len(matches) > 0:
+ return matches[0]
+
+ def __make_quicklist_from_data(self, quicklist_type, quicklist_data):
+ if quicklist_type == 'QuicklistMenuItemLabel':
+ return QuicklistMenuItemLabel(quicklist_data)
+ elif quicklist_type == 'QuicklistMenuItemSeparator':
+ return QuicklistMenuItemSeparator(quicklist_data)
+ else:
+ raise ValueError('Unknown quicklist item type "%s"' % (quicklist_type))
- """
+ def click_item(self, item):
+ """Click one of the quicklist items."""
+ if not isinstance(item, QuicklistMenuItem):
+ raise TypeError("Item must be a subclass of QuicklistMenuItem")
+ self._mouse.move(self.x + item.x + (item.width /2),
+ self.y + item.y + (item.height /2))
+ sleep(0.25)
+ self._mouse.click()
- def __init__(self, icon_dict):
- self.tooltip_text = icon_dict['tooltip-text']
- self.x = icon_dict['x']
- self.y = icon_dict['y']
- self.num_windows = icon_dict['related-windows']
- self.visible = icon_dict['quirk-visible']
- self.active = icon_dict['quirk-active']
- self.running = icon_dict['quirk-running']
- self.presented = icon_dict['quirk-presented']
- self.urgent = icon_dict['quirk-urgent']
+
+
+
+class QuicklistMenuItem(Unity):
+ """Represents a single item in a quicklist."""
+ def __init__(self, state_dict):
+ super(QuicklistMenuItem, self).__init__()
+ self._set_properties(state_dict)
+
+ def _set_properties(self, state_dict):
+ self.visible = state_dict['visible']
+ self.enabled = state_dict['enabled']
+ self.width = state_dict['width']
+ self.height = state_dict['height']
+ self.x = state_dict['x']
+ self.y = state_dict['y']
+ self.id = state_dict['id']
+ self.lit = state_dict['lit']
+
+
+class QuicklistMenuItemLabel(QuicklistMenuItem):
+ """Represents a text label inside a quicklist."""
+
+ def _set_properties(self, state_dict):
+ super(QuicklistMenuItemLabel, self)._set_properties(state_dict)
+ self.text = state_dict['text']
+ print "text = ", self.text
+
+class QuicklistMenuItemSeparator(QuicklistMenuItem):
+ """Represents a separator in a quicklist."""
class Switcher(Unity):
"""Interact with the Unity switcher."""
@@ -271,7 +453,7 @@ class Switcher(Unity):
model = self.__get_model()
sel_idx = self.get_selection_index()
try:
- return LauncherIcon(model['Children'][sel_idx][1])
+ return make_launcher_icon(model['Children'][sel_idx])
except KeyError:
return None
diff --git a/tests/autopilot/autopilot/tests/test_invisible_windows.py b/tests/autopilot/autopilot/tests/test_invisible_windows.py
index da2ec2c5c..307d765a4 100644
--- a/tests/autopilot/autopilot/tests/test_invisible_windows.py
+++ b/tests/autopilot/autopilot/tests/test_invisible_windows.py
@@ -17,6 +17,7 @@ from time import sleep
from autopilot.utilities import make_window_skip_taskbar
from autopilot.emulators.unity import Launcher, Switcher
from autopilot.emulators.bamf import Bamf
+from autopilot.emulators.X11 import Mouse
class InvisibleWindowTests(TestCase):
"""Test unity's handling of windows with the Skip-Tasklist flag set."""
@@ -68,16 +69,21 @@ class InvisibleWindowTests(TestCase):
self.addCleanup(call, ["killall", "gcalctool"])
# need to pin the app to the launcher - this could be tricky.
launcher = Launcher()
- launcher.grab_switcher()
+ launcher.reveal_launcher(0)
+ icons = launcher.get_launcher_icons()
+ # launcher.grab_switcher()
found = False
- current_icon = None
- for i in range(launcher.num_launcher_icons()):
- current_icon = launcher.get_currently_selected_icon()
- if current_icon.tooltip_text == 'Calculator':
+ # current_icon = None
+ for icon in icons:
+ if icon.tooltip_text == 'Calculator':
found = True
+ launcher.lock_to_launcher(icon)
+ self.addCleanup(launcher.unlock_from_launcher, icon)
break
- launcher.switcher_next()
+
self.assertTrue(found, "Could not find calculator in launcher.")
- launcher.switcher_enter_quicklist()
-
- launcher.end_switcher(cancel=True)
+ # launcher.switcher_enter_quicklist()
+ # quicklist = current_icon.get_quicklist()
+ # self.assertTrue(quicklist.active)
+
+ # launcher.end_switcher(cancel=True)