From 4b623d1c1bf68bf9340888bcb2290ed7ccd86c37 Mon Sep 17 00:00:00 2001 From: Mikkel Kamstrup Erlandsen Date: Tue, 1 Feb 2011 11:36:36 +0100 Subject: Implement support for quicklists in the Launcher DBus API (bzr r798.5.6) --- src/LauncherEntryRemote.cpp | 146 ++++++++++++++++++++++++++++++++++++++- src/LauncherEntryRemote.h | 21 ++++-- src/LauncherEntryRemoteModel.cpp | 11 ++- 3 files changed, 169 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/LauncherEntryRemote.cpp b/src/LauncherEntryRemote.cpp index 2d545e2b8..2db9cc877 100644 --- a/src/LauncherEntryRemote.cpp +++ b/src/LauncherEntryRemote.cpp @@ -21,22 +21,28 @@ /** * Create a new LauncherEntryRemote parsed from the raw DBus wire format - * of the com.canonical.Unity.LauncherEntry.Update signal '(sa{sv})'. + * of the com.canonical.Unity.LauncherEntry.Update signal '(sa{sv})'. The + * dbus_name argument should be the unique bus name of the process owning + * the launcher entry. * * You don't normally need to use this constructor yourself. The * LauncherEntryRemoteModel will do that for you when needed. */ -LauncherEntryRemote::LauncherEntryRemote(GVariant *val) +LauncherEntryRemote::LauncherEntryRemote(const gchar *dbus_name, GVariant *val) { gchar *app_uri, *prop_key; GVariantIter *prop_iter; GVariant *prop_value; + g_return_if_fail (dbus_name != NULL); g_return_if_fail (val != NULL); + _dbus_name = g_strdup (dbus_name); + _emblem = NULL; _count = G_GINT64_CONSTANT (0); _progress = 0.0; + _quicklist = NULL; _emblem_visible = FALSE; _count_visible = FALSE; @@ -61,6 +67,12 @@ LauncherEntryRemote::LauncherEntryRemote(GVariant *val) _count_visible = g_variant_get_boolean (prop_value); else if (g_str_equal ("progress-visible", prop_key)) _progress_visible = g_variant_get_boolean (prop_value); + else if (g_str_equal ("quicklist", prop_key)) + { + const gchar *ql_path; + ql_path = g_variant_get_string (prop_value, NULL); + _quicklist = dbusmenu_client_new (_dbus_name, ql_path); + } } g_variant_iter_free (prop_iter); @@ -69,6 +81,12 @@ LauncherEntryRemote::LauncherEntryRemote(GVariant *val) LauncherEntryRemote::~LauncherEntryRemote() { + if (_dbus_name) + { + g_free (_dbus_name); + _dbus_name = NULL; + } + if (_app_uri) { g_free (_app_uri); @@ -80,14 +98,37 @@ LauncherEntryRemote::~LauncherEntryRemote() g_free (_emblem); _emblem = NULL; } + + if (_quicklist) + { + g_object_unref (_quicklist); + _quicklist = NULL; + } } +/** + * The appuri property is on the form application://$desktop_file_id and is + * used within the LauncherEntryRemoteModel to uniquely identify the various + * applications. + * + * Note that a desktop file id is defined to be the base name of the desktop + * file including the extension. Eg. gedit.desktop. Thus a full appuri could be + * application://gedit.desktop. + */ const gchar* LauncherEntryRemote::AppUri() { return _app_uri; } +/** + * Return the unique DBus name for the remote party owning this launcher entry. + */ +const gchar* +LauncherEntryRemote::DBusName() +{ + return _dbus_name; +} const gchar* LauncherEntryRemote::Emblem() @@ -107,6 +148,18 @@ LauncherEntryRemote::Progress() return _progress; } +/** + * Return a pointer to the current quicklist of the launcher entry; NULL if + * it's unset. + * + * The returned object should not be freed. + */ +DbusmenuClient* +LauncherEntryRemote::Quicklist() +{ + return _quicklist; +} + gboolean LauncherEntryRemote::EmblemVisible() { @@ -158,6 +211,86 @@ LauncherEntryRemote::SetProgress(gdouble progress) progress_changed.emit (); } +/** + * Set the quicklist of this entry to be the Dbusmenu on the given path. + * If entry already has a quicklist with the same path this call is a no-op. + * + * To unset the quicklist pass in a NULL path. + */ +void +LauncherEntryRemote::SetQuicklistPath(const gchar *dbus_path) +{ + /* Check if existing quicklist have exact same path + * and ignore the change in that case */ + if (_quicklist) + { + gchar *ql_path; + g_object_get (_quicklist, DBUSMENU_CLIENT_PROP_DBUS_OBJECT, &ql_path, NULL); + if (g_strcmp0 (dbus_path, ql_path) == 0) + { + g_free (ql_path); + return; + } + + /* Prepare for a new quicklist */ + g_free (ql_path); + g_object_unref (_quicklist); + } + else if (_quicklist == NULL && dbus_path == NULL) + return; + + if (dbus_path != NULL) + _quicklist = dbusmenu_client_new (_dbus_name, dbus_path); + else + _quicklist = NULL; + + quicklist_changed.emit (); +} + +/** + * Set the quicklist of this entry to a given DbusmenuClient. + * If entry already has a quicklist with the same path this call is a no-op. + * + * To unset the quicklist for this entry pass in NULL as the quicklist to set. + */ +void +LauncherEntryRemote::SetQuicklist(DbusmenuClient *quicklist) +{ + /* Check if existing quicklist have exact same path as the new one + * and ignore the change in that case */ + if (_quicklist) + { + gchar *ql_path, *new_ql_path; + g_object_get (_quicklist, DBUSMENU_CLIENT_PROP_DBUS_OBJECT, &ql_path, NULL); + + if (quicklist == NULL) + new_ql_path = NULL; + else + g_object_get (quicklist, DBUSMENU_CLIENT_PROP_DBUS_OBJECT, &new_ql_path, NULL); + + if (g_strcmp0 (new_ql_path, ql_path) == 0) + { + g_free (ql_path); + g_free (new_ql_path); + return; + } + + /* Prepare for a new quicklist */ + g_free (ql_path); + g_free (new_ql_path); + g_object_unref (_quicklist); + } + else if (_quicklist == NULL && quicklist == NULL) + return; + + if (quicklist == NULL) + _quicklist = NULL; + else + _quicklist = (DbusmenuClient *) g_object_ref (quicklist); + + quicklist_changed.emit (); +} + void LauncherEntryRemote::SetEmblemVisible(gboolean visible) { @@ -194,9 +327,18 @@ LauncherEntryRemote::SetProgressVisible(gboolean visible) void LauncherEntryRemote::Update(LauncherEntryRemote *other) { + if (g_strcmp0 (DBusName(), other->DBusName()) != 0) + { + g_critical ("You can only call LauncherEntryRemote::Update() on entries" + " with the same unique DBus name. Saw %s and %s.", + DBusName(), other->DBusName()); + return; + } + SetEmblem (other->Emblem ()); SetCount (other->Count ()); SetProgress (other->Progress ()); + SetQuicklist (other->Quicklist()); SetEmblemVisible (other->EmblemVisible ()); SetCountVisible(other->CountVisible ()); diff --git a/src/LauncherEntryRemote.h b/src/LauncherEntryRemote.h index 1d2c36f69..411f589ab 100644 --- a/src/LauncherEntryRemote.h +++ b/src/LauncherEntryRemote.h @@ -23,6 +23,8 @@ #include #include #include +#include +#include /** * Instances of this class mirrors the remote metadata for a laucnher entry @@ -38,13 +40,15 @@ class LauncherEntryRemote : public nux::InitiallyUnownedObject, public sigc::tra public: - LauncherEntryRemote(GVariant *val); + LauncherEntryRemote(const gchar *dbus_name, GVariant *val); ~LauncherEntryRemote(); - const gchar* AppUri(); - const gchar* Emblem(); - gint64 Count(); - gdouble Progress(); + const gchar* AppUri(); + const gchar* DBusName(); + const gchar* Emblem(); + gint64 Count(); + gdouble Progress(); + DbusmenuClient* Quicklist (); gboolean EmblemVisible(); gboolean CountVisible(); @@ -53,6 +57,7 @@ public: sigc::signal emblem_changed; sigc::signal count_changed; sigc::signal progress_changed; + sigc::signal quicklist_changed; sigc::signal emblem_visible_changed; sigc::signal count_visible_changed; @@ -65,6 +70,10 @@ private: gint64 _count; gdouble _progress; + gchar *_dbus_name; + gchar *_quicklist_dbus_path; + DbusmenuClient *_quicklist; + gboolean _emblem_visible; gboolean _count_visible; gboolean _progress_visible; @@ -72,6 +81,8 @@ private: void SetEmblem (const gchar *emblem); void SetCount (gint64 count); void SetProgress (gdouble progress); + void SetQuicklistPath (const gchar *dbus_path); + void SetQuicklist (DbusmenuClient *quicklist); void SetEmblemVisible (gboolean visible); void SetCountVisible (gboolean visible); diff --git a/src/LauncherEntryRemoteModel.cpp b/src/LauncherEntryRemoteModel.cpp index f8eb41df7..df014f82f 100644 --- a/src/LauncherEntryRemoteModel.cpp +++ b/src/LauncherEntryRemoteModel.cpp @@ -204,7 +204,6 @@ on_launcher_entry_signal_received (GDBusConnection *connection, LauncherEntryRemoteModel *self; LauncherEntryRemote *entry; - self = static_cast (user_data); if (parameters == NULL) @@ -224,7 +223,15 @@ on_launcher_entry_signal_received (GDBusConnection *connection, return; } - entry = new LauncherEntryRemote (parameters); + if (sender_name == NULL) + { + g_critical ("Received 'com.canonical.Unity.LauncherEntry.Update' from" + " an undefined sender. This may happen if you are trying " + "to run Unity on a p2p DBus connection."); + return; + } + + entry = new LauncherEntryRemote (sender_name, parameters); self->AddEntry (entry); // consumes floating ref on entry } else -- cgit v1.2.3