diff options
| author | Thomi Richards <thomi.richards@canonical.com> | 2012-02-07 09:44:28 +1300 |
|---|---|---|
| committer | Thomi Richards <thomi.richards@canonical.com> | 2012-02-07 09:44:28 +1300 |
| commit | 8ca0b11e3aa9fc1f502bc7ee5b8b9135e4b0f2c4 (patch) | |
| tree | 9160ba8bbb2f54b6e904d37757a041f52f315106 | |
| parent | 991e89b450d375c21e0b9693c7b93d57099caa6a (diff) | |
Refactor of launcher icon classes.
(bzr r1882.2.14)
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) |
