aboutsummaryrefslogtreecommitdiff
path: root/src/messages-service.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/messages-service.c')
-rw-r--r--src/messages-service.c253
1 files changed, 221 insertions, 32 deletions
diff --git a/src/messages-service.c b/src/messages-service.c
index ca9e799..0ebab0b 100644
--- a/src/messages-service.c
+++ b/src/messages-service.c
@@ -31,6 +31,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include <libdbusmenu-glib/client.h>
#include <libdbusmenu-glib/server.h>
+#include <libdbusmenu-glib/menuitem-proxy.h>
#include "im-menu-item.h"
#include "app-menu-item.h"
@@ -48,7 +49,10 @@ static GMainLoop * mainloop = NULL;
static MessageServiceDbus * dbus_interface = NULL;
+#define DESKTOP_FILE_GROUP "Messaging Menu"
+#define DESKTOP_FILE_KEY_DESKTOP "DesktopFile"
+static void server_shortcuts_changed (AppMenuItem * appitem, gpointer data);
static void server_count_changed (AppMenuItem * appitem, guint count, gpointer data);
static void server_name_changed (AppMenuItem * appitem, gchar * name, gpointer data);
static void im_time_changed (ImMenuItem * imitem, glong seconds, gpointer data);
@@ -57,9 +61,14 @@ static void indicator_removed (IndicateListener * listener, IndicateListenerServ
static void check_eclipses (AppMenuItem * ai);
static void remove_eclipses (AppMenuItem * ai);
static gboolean build_launcher (gpointer data);
+static gboolean build_launcher_keyfile (gpointer data);
+static void build_launcher_core (const gchar * desktop);
static gboolean build_launchers (gpointer data);
static gboolean blacklist_init (gpointer data);
static gboolean blacklist_add (gpointer data);
+static gchar * desktop_file_from_keyfile (const gchar * definition_file);
+static gboolean blacklist_keyfile_add (gpointer udata);
+static void blacklist_add_core (gchar * desktop, gchar * definition);
static gboolean blacklist_remove (gpointer data);
static void blacklist_dir_changed (GFileMonitor * monitor, GFile * file, GFile * other_file, GFileMonitorEvent event_type, gpointer user_data);
static void app_dir_changed (GFileMonitor * monitor, GFile * file, GFile * other_file, GFileMonitorEvent event_type, gpointer user_data);
@@ -241,7 +250,11 @@ blacklist_init (gpointer data)
while ((filename = g_dir_read_name(dir)) != NULL) {
g_debug("Found file: %s", filename);
gchar * path = g_build_filename(blacklistdir, filename, NULL);
- g_idle_add(blacklist_add, path);
+ if (g_str_has_suffix(path, "keyfile")) {
+ g_idle_add(blacklist_keyfile_add, path);
+ } else {
+ g_idle_add(blacklist_add, path);
+ }
}
g_dir_close(dir);
@@ -250,6 +263,53 @@ blacklist_init (gpointer data)
return FALSE;
}
+/* Parses through a keyfile to find the desktop file entry and
+ pushes them into the blacklist. */
+static gboolean
+blacklist_keyfile_add (gpointer udata)
+{
+ gchar * definition_file = (gchar *)udata;
+ gchar * desktopfile = desktop_file_from_keyfile(definition_file);
+ if (desktopfile != NULL) {
+ blacklist_add_core(desktopfile, definition_file);
+ g_free(desktopfile);
+ }
+ return FALSE;
+}
+
+/* Takes a keyfile and finds the desktop file in it for
+ us. With some error handling. */
+static gchar *
+desktop_file_from_keyfile (const gchar * definition_file)
+{
+ GKeyFile * keyfile = g_key_file_new();
+ GError * error = NULL;
+
+ if (!g_key_file_load_from_file(keyfile, definition_file, G_KEY_FILE_NONE, &error)) {
+ g_warning("Unable to load keyfile '%s' because: %s", definition_file, error == NULL ? "unknown" : error->message);
+ g_error_free(error);
+ g_key_file_free(keyfile);
+ return NULL;
+ }
+
+ if (!g_key_file_has_group(keyfile, DESKTOP_FILE_GROUP)) {
+ g_warning("Unable to use keyfile '%s' as it has no '" DESKTOP_FILE_GROUP "' group.", definition_file);
+ g_key_file_free(keyfile);
+ return NULL;
+ }
+
+ if (!g_key_file_has_key(keyfile, DESKTOP_FILE_GROUP, DESKTOP_FILE_KEY_DESKTOP, &error)) {
+ g_warning("Unable to use keyfile '%s' as there is no key '" DESKTOP_FILE_KEY_DESKTOP "' in the group '" DESKTOP_FILE_GROUP "' because: %s", definition_file, error == NULL ? "unknown" : error->message);
+ g_error_free(error);
+ g_key_file_free(keyfile);
+ return NULL;
+ }
+
+ gchar * desktopfile = g_key_file_get_string(keyfile, DESKTOP_FILE_GROUP, DESKTOP_FILE_KEY_DESKTOP, &error);
+ g_key_file_free(keyfile);
+ return desktopfile;
+}
+
/* Add a definition file into the black list and eclipse
and launchers that have the same file. */
static gboolean
@@ -268,38 +328,51 @@ blacklist_add (gpointer udata)
gchar * trimdesktop = pango_trim_string(desktop);
g_free(desktop);
+ blacklist_add_core(trimdesktop, definition_file);
+ g_free(trimdesktop);
+
+ return FALSE;
+}
+
+/* This takes a desktop file and tries to add it to the black
+ list for applications in the messaging menu. If it can,
+ then the launcher item gets marked as eclipsed and hidden
+ from the user. */
+static void
+blacklist_add_core (gchar * desktop, gchar * definition)
+{
/* Check for conflicts */
- gpointer data = g_hash_table_lookup(blacklist, trimdesktop);
+ gpointer data = g_hash_table_lookup(blacklist, desktop);
if (data != NULL) {
gchar * oldfile = (gchar *)data;
- if (!g_strcmp0(oldfile, definition_file)) {
+ if (!g_strcmp0(oldfile, definition)) {
g_warning("Already added file '%s'", oldfile);
} else {
- g_warning("Already have desktop file '%s' in blacklist file '%s' not adding from '%s'", trimdesktop, oldfile, definition_file);
+ g_warning("Already have desktop file '%s' in blacklist file '%s' not adding from '%s'", desktop, oldfile, definition);
}
- g_free(trimdesktop);
- g_free(definition_file);
- return FALSE;
+ return;
}
/* Actually blacklist this thing */
- g_hash_table_insert(blacklist, trimdesktop, definition_file);
- g_debug("Adding Blacklist item '%s' for desktop '%s'", definition_file, trimdesktop);
+ g_hash_table_insert(blacklist, desktop, definition);
+ g_debug("Adding Blacklist item '%s' for desktop '%s'", definition, desktop);
/* Go through and eclipse folks */
GList * launcher;
for (launcher = launcherList; launcher != NULL; launcher = launcher->next) {
launcherList_t * item = (launcherList_t *)launcher->data;
- if (!g_strcmp0(trimdesktop, launcher_menu_item_get_desktop(item->menuitem))) {
+ if (!g_strcmp0(desktop, launcher_menu_item_get_desktop(item->menuitem))) {
launcher_menu_item_set_eclipsed(item->menuitem, TRUE);
- dbusmenu_menuitem_property_set(item->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, "false");
+ dbusmenu_menuitem_property_set_bool(item->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
}
}
check_hidden();
+ /* Shouldn't need a resort here as hiding shouldn't cause things to
+ move other than this item disappearing. */
- return FALSE;
+ return;
}
/* Remove a black list item based on the definition file
@@ -340,7 +413,7 @@ blacklist_remove (gpointer data)
}
if (serveritem == NULL) {
launcher_menu_item_set_eclipsed(li->menuitem, FALSE);
- dbusmenu_menuitem_property_set(li->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, "true");
+ dbusmenu_menuitem_property_set_bool(li->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
}
}
}
@@ -506,11 +579,21 @@ server_added (IndicateListener * listener, IndicateListenerServer * server, gcha
/* Connect the signals up to the menu item */
g_signal_connect(G_OBJECT(menuitem), APP_MENU_ITEM_SIGNAL_COUNT_CHANGED, G_CALLBACK(server_count_changed), sl_item);
g_signal_connect(G_OBJECT(menuitem), APP_MENU_ITEM_SIGNAL_NAME_CHANGED, G_CALLBACK(server_name_changed), menushell);
+ g_signal_connect(G_OBJECT(menuitem), APP_MENU_ITEM_SIGNAL_SHORTCUTS_CHANGED, G_CALLBACK(server_shortcuts_changed), menushell);
/* Put our new menu item in, with the separator behind it.
resort_menu will take care of whether it should be hidden
or not. */
dbusmenu_menuitem_child_append(menushell, DBUSMENU_MENUITEM(menuitem));
+
+ GList * shortcuts = app_menu_item_get_items(sl_item->menuitem);
+ while (shortcuts != NULL) {
+ DbusmenuMenuitem * mi = DBUSMENU_MENUITEM(shortcuts->data);
+ g_debug("\tAdding shortcut: %s", dbusmenu_menuitem_property_get(mi, DBUSMENU_MENUITEM_PROP_LABEL));
+ dbusmenu_menuitem_child_append(menushell, mi);
+ shortcuts = g_list_next(shortcuts);
+ }
+
dbusmenu_menuitem_child_append(menushell, DBUSMENU_MENUITEM(sl_item->separator));
resort_menu(menushell);
@@ -519,6 +602,50 @@ server_added (IndicateListener * listener, IndicateListenerServer * server, gcha
return;
}
+/* The shortcuts have changed, let's just remove them and put
+ the back. */
+static void
+server_shortcuts_changed (AppMenuItem * appitem, gpointer data)
+{
+ g_debug("Application Shortcuts changed");
+ DbusmenuMenuitem * shell = DBUSMENU_MENUITEM(data);
+ gboolean appitemfound = FALSE;
+ GList * children = dbusmenu_menuitem_get_children(shell);
+ GList * removelist = NULL;
+
+ while (children != NULL) {
+ if (!appitemfound && children->data != appitem) {
+ children = g_list_next(children);
+ continue;
+ }
+ appitemfound = TRUE;
+
+ if (!DBUSMENU_IS_MENUITEM_PROXY(children->data)) {
+ break;
+ }
+
+ removelist = g_list_prepend(removelist, children->data);
+ }
+
+ GList * removeitem;
+ for (removeitem = removelist; removeitem != NULL; removeitem = g_list_next(removeitem)) {
+ dbusmenu_menuitem_child_delete(shell, DBUSMENU_MENUITEM(removeitem->data));
+ }
+ g_list_free(removeitem);
+
+ GList * shortcuts = app_menu_item_get_items(appitem);
+ while (shortcuts != NULL) {
+ DbusmenuMenuitem * mi = DBUSMENU_MENUITEM(shortcuts->data);
+ g_debug("\tAdding shortcut: %s", dbusmenu_menuitem_property_get(mi, DBUSMENU_MENUITEM_PROP_LABEL));
+ dbusmenu_menuitem_child_append(shell, mi);
+ shortcuts = g_list_next(shortcuts);
+ }
+
+ resort_menu(shell);
+
+ return;
+}
+
/* The name of a server has changed, we probably
need to reorder the menu to keep it in alphabetical
order. This happens often after we read the destkop
@@ -626,14 +753,14 @@ server_removed (IndicateListener * listener, IndicateListenerServer * server, gc
/* If there is a menu item, let's get rid of it. */
if (sltp->menuitem != NULL) {
- dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(sltp->menuitem), DBUSMENU_MENUITEM_PROP_VISIBLE, "false");
+ dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(sltp->menuitem), DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
dbusmenu_menuitem_child_delete(DBUSMENU_MENUITEM(data), DBUSMENU_MENUITEM(sltp->menuitem));
g_object_unref(G_OBJECT(sltp->menuitem));
}
/* If there is a separator, let's get rid of it. */
if (sltp->separator != NULL) {
- dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(sltp->separator), DBUSMENU_MENUITEM_PROP_VISIBLE, "false");
+ dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(sltp->separator), DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
dbusmenu_menuitem_child_delete(DBUSMENU_MENUITEM(data), DBUSMENU_MENUITEM(sltp->separator));
g_object_unref(G_OBJECT(sltp->separator));
}
@@ -724,12 +851,21 @@ resort_menu (DbusmenuMenuitem * menushell)
dbusmenu_menuitem_child_reorder(DBUSMENU_MENUITEM(menushell), DBUSMENU_MENUITEM(li->menuitem), position);
position++;
+ /* Inserting the shortcuts from the launcher */
+ GList * shortcuts = launcher_menu_item_get_items(li->menuitem);
+ while (shortcuts != NULL) {
+ g_debug("\t\tMoving shortcut to position %d", position);
+ dbusmenu_menuitem_child_reorder(DBUSMENU_MENUITEM(menushell), DBUSMENU_MENUITEM(shortcuts->data), position);
+ position++;
+ shortcuts = g_list_next(shortcuts);
+ }
+
/* Putting the launcher separator in */
g_debug("\tMoving launcher separator to position %d", position);
dbusmenu_menuitem_child_reorder(DBUSMENU_MENUITEM(menushell), DBUSMENU_MENUITEM(li->separator), position);
if (!launcher_menu_item_get_eclipsed(li->menuitem)) {
/* Only clear the visiblity if we're not eclipsed */
- dbusmenu_menuitem_property_set(li->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, "true");
+ dbusmenu_menuitem_property_set_bool(li->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
last_separator = li->separator;
}
position++;
@@ -746,6 +882,15 @@ resort_menu (DbusmenuMenuitem * menushell)
g_debug("\tMoving app %s to position %d", INDICATE_LISTENER_SERVER_DBUS_NAME(si->server), position);
dbusmenu_menuitem_child_reorder(DBUSMENU_MENUITEM(menushell), DBUSMENU_MENUITEM(si->menuitem), position);
position++;
+
+ /* Inserting the shortcuts from the launcher */
+ GList * shortcuts = app_menu_item_get_items(si->menuitem);
+ while (shortcuts != NULL) {
+ g_debug("\t\tMoving shortcut to position %d", position);
+ dbusmenu_menuitem_child_reorder(DBUSMENU_MENUITEM(menushell), DBUSMENU_MENUITEM(shortcuts->data), position);
+ position++;
+ shortcuts = g_list_next(shortcuts);
+ }
}
/* Putting all the indicators that are related to this application
@@ -765,7 +910,7 @@ resort_menu (DbusmenuMenuitem * menushell)
if (si->separator != NULL) {
g_debug("\tMoving app %s separator to position %d", INDICATE_LISTENER_SERVER_DBUS_NAME(si->server), position);
dbusmenu_menuitem_child_reorder(DBUSMENU_MENUITEM(menushell), DBUSMENU_MENUITEM(si->separator), position);
- dbusmenu_menuitem_property_set(si->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, "true");
+ dbusmenu_menuitem_property_set_bool(si->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
position++;
last_separator = si->separator;
}
@@ -780,12 +925,21 @@ resort_menu (DbusmenuMenuitem * menushell)
dbusmenu_menuitem_child_reorder(DBUSMENU_MENUITEM(menushell), DBUSMENU_MENUITEM(li->menuitem), position);
position++;
+ /* Inserting the shortcuts from the launcher */
+ GList * shortcuts = launcher_menu_item_get_items(li->menuitem);
+ while (shortcuts != NULL) {
+ g_debug("\t\tMoving shortcut to position %d", position);
+ dbusmenu_menuitem_child_reorder(DBUSMENU_MENUITEM(menushell), DBUSMENU_MENUITEM(shortcuts->data), position);
+ position++;
+ shortcuts = g_list_next(shortcuts);
+ }
+
/* Putting the launcher separator in */
g_debug("\tMoving launcher separator to position %d", position);
dbusmenu_menuitem_child_reorder(DBUSMENU_MENUITEM(menushell), DBUSMENU_MENUITEM(li->separator), position);
if (!launcher_menu_item_get_eclipsed(li->menuitem)) {
/* Only clear the visiblity if we're not eclipsed */
- dbusmenu_menuitem_property_set(li->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, "true");
+ dbusmenu_menuitem_property_set_bool(li->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
last_separator = li->separator;
}
position++;
@@ -794,7 +948,7 @@ resort_menu (DbusmenuMenuitem * menushell)
}
if (last_separator != NULL) {
- dbusmenu_menuitem_property_set(last_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, "false");
+ dbusmenu_menuitem_property_set_bool(last_separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
} else {
g_warning("No last separator on resort");
}
@@ -953,7 +1107,7 @@ indicator_removed (IndicateListener * listener, IndicateListenerServer * server,
/* Hide the item immediately, and then remove it
which might take a little longer. */
- dbusmenu_menuitem_property_set(menuitem, DBUSMENU_MENUITEM_PROP_VISIBLE, "false");
+ dbusmenu_menuitem_property_set_bool(menuitem, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
dbusmenu_menuitem_child_delete(DBUSMENU_MENUITEM(data), menuitem);
removed = TRUE;
}
@@ -981,7 +1135,11 @@ app_dir_changed (GFileMonitor * monitor, GFile * file, GFile * other_file, GFile
case G_FILE_MONITOR_EVENT_CREATED: {
gchar * path = g_file_get_path(file);
g_debug("\tCreate: %s", path);
- g_idle_add(build_launcher, path);
+ if (g_str_has_suffix(path, "keyfile")) {
+ g_idle_add(build_launcher_keyfile, path);
+ } else {
+ g_idle_add(build_launcher, path);
+ }
break;
}
default:
@@ -1010,7 +1168,7 @@ check_eclipses (AppMenuItem * ai)
if (!g_strcmp0(aidesktop, lidesktop)) {
launcher_menu_item_set_eclipsed(ll->menuitem, TRUE);
- dbusmenu_menuitem_property_set(ll->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, "false");
+ dbusmenu_menuitem_property_set_bool(ll->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
break;
}
}
@@ -1035,7 +1193,7 @@ remove_eclipses (AppMenuItem * ai)
if (!g_strcmp0(aidesktop, lidesktop)) {
launcher_menu_item_set_eclipsed(ll->menuitem, FALSE);
- dbusmenu_menuitem_property_set(ll->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, "true");
+ dbusmenu_menuitem_property_set_bool(ll->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE);
break;
}
}
@@ -1087,7 +1245,7 @@ destroy_launcher (gpointer data)
g_list_free(li->appdiritems);
if (li->menuitem != NULL) {
- dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(li->menuitem), DBUSMENU_MENUITEM_PROP_VISIBLE, "false");
+ dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(li->menuitem), DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
dbusmenu_menuitem_child_delete(root_menuitem, DBUSMENU_MENUITEM(li->menuitem));
g_object_unref(G_OBJECT(li->menuitem));
li->menuitem = NULL;
@@ -1119,11 +1277,34 @@ build_launcher (gpointer data)
g_free(desktop);
g_debug("\tcontents: %s", trimdesktop);
+ build_launcher_core(trimdesktop);
+ g_free(trimdesktop);
+ return FALSE;
+}
+
+/* Use a key file to find the desktop file. */
+static gboolean
+build_launcher_keyfile (gpointer data)
+{
+ gchar * path = (gchar *)data;
+ gchar * desktop = desktop_file_from_keyfile (path);
+ if (desktop != NULL) {
+ build_launcher_core(desktop);
+ g_free(desktop);
+ }
+ return FALSE;
+}
+
+/* The core action of dealing with a desktop file that should
+ be a launcher */
+static void
+build_launcher_core (const gchar * desktop)
+{
/* Check to see if we already have a launcher */
GList * listitem;
for (listitem = launcherList; listitem != NULL; listitem = listitem->next) {
launcherList_t * li = (launcherList_t *)listitem->data;
- if (!g_strcmp0(launcher_menu_item_get_desktop(li->menuitem), trimdesktop)) {
+ if (!g_strcmp0(launcher_menu_item_get_desktop(li->menuitem), desktop)) {
break;
}
}
@@ -1132,9 +1313,8 @@ build_launcher (gpointer data)
/* If not */
/* Build the item */
launcherList_t * ll = g_new0(launcherList_t, 1);
- ll->menuitem = launcher_menu_item_new(trimdesktop);
- g_free(trimdesktop);
- ll->appdiritems = g_list_append(NULL, path);
+ ll->menuitem = launcher_menu_item_new(desktop);
+ ll->appdiritems = g_list_append(NULL, g_strdup(desktop));
/* Build a separator */
ll->separator = dbusmenu_menuitem_new();
@@ -1145,6 +1325,11 @@ build_launcher (gpointer data)
/* Add it to the menu */
dbusmenu_menuitem_child_append(root_menuitem, DBUSMENU_MENUITEM(ll->menuitem));
+ GList * shortcuts = launcher_menu_item_get_items(ll->menuitem);
+ while (shortcuts != NULL) {
+ dbusmenu_menuitem_child_append(root_menuitem, DBUSMENU_MENUITEM(shortcuts->data));
+ shortcuts = g_list_next(shortcuts);
+ }
dbusmenu_menuitem_child_append(root_menuitem, DBUSMENU_MENUITEM(ll->separator));
/* If we're in the black list or we've gotten eclipsed
@@ -1152,7 +1337,7 @@ build_launcher (gpointer data)
if (blacklist_check(launcher_menu_item_get_desktop(ll->menuitem)) ||
launcher_menu_item_get_eclipsed(ll->menuitem)) {
launcher_menu_item_set_eclipsed(ll->menuitem, TRUE);
- dbusmenu_menuitem_property_set(ll->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, "false");
+ dbusmenu_menuitem_property_set_bool(ll->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
}
resort_menu(root_menuitem);
@@ -1160,10 +1345,10 @@ build_launcher (gpointer data)
} else {
/* If so add ourselves */
launcherList_t * ll = (launcherList_t *)listitem->data;
- ll->appdiritems = g_list_append(ll->appdiritems, path);
+ ll->appdiritems = g_list_append(ll->appdiritems, g_strdup(desktop));
}
- return FALSE;
+ return;
}
/* This function goes through all the launchers that we're
@@ -1197,7 +1382,11 @@ build_launchers (gpointer data)
while ((filename = g_dir_read_name(dir)) != NULL) {
g_debug("Found file: %s", filename);
gchar * path = g_build_filename(directory, filename, NULL);
- g_idle_add(build_launcher, path);
+ if (g_str_has_suffix(path, "keyfile")) {
+ g_idle_add(build_launcher_keyfile, path);
+ } else {
+ g_idle_add(build_launcher, path);
+ }
}
g_dir_close(dir);