ayatana-commits team mailing list archive
-
ayatana-commits team
-
Mailing list archive
-
Message #01543
[Merge] lp:~ted/indicator-appmenu/bamf-it into lp:indicator-appmenu
Ted Gould has proposed merging lp:~ted/indicator-appmenu/bamf-it into lp:indicator-appmenu.
Requested reviews:
Indicator Applet Developers (indicator-applet-developers)
Basic application switching support. Still doesn't detect applications leaving, but does switch between them. Also, breaks some Qt apps that send two menus for the same window ID. I think it's in a good place to end this branch though as it basically works.
--
https://code.launchpad.net/~ted/indicator-appmenu/bamf-it/+merge/26779
Your team ayatana-commits is subscribed to branch lp:indicator-appmenu.
=== modified file '.bzrignore'
--- .bzrignore 2010-06-02 14:05:45 +0000
+++ .bzrignore 2010-06-04 04:51:23 +0000
@@ -16,3 +16,4 @@
scripts/menu-pusher
src/application-menu-debug-client.h
src/application-menu-debug-server.h
+tools/current-menu-dump
=== modified file 'configure.ac'
--- configure.ac 2010-06-02 17:50:51 +0000
+++ configure.ac 2010-06-04 04:51:23 +0000
@@ -41,11 +41,13 @@
INDICATOR_REQUIRED_VERSION=0.3.5
DBUSMENUGTK_REQUIRED_VERSION=0.3.0
DBUS_GLIB_REQUIRED_VERSION=0.82
+BAMF_REQUIRED_VERSION=0.2
PKG_CHECK_MODULES(INDICATOR, gtk+-2.0 >= $GTK_REQUIRED_VERSION
indicator >= $INDICATOR_REQUIRED_VERSION
dbus-glib-1 >= $DBUS_GLIB_REQUIRED_VERSION
- dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION)
+ dbusmenu-gtk >= $DBUSMENUGTK_REQUIRED_VERSION
+ libbamf >= $BAMF_REQUIRED_VERSION)
AC_SUBST(INDICATOR_CFLAGS)
AC_SUBST(INDICATOR_LIBS)
=== modified file 'src/indicator-appmenu.c'
--- src/indicator-appmenu.c 2010-06-02 17:28:39 +0000
+++ src/indicator-appmenu.c 2010-06-04 04:51:23 +0000
@@ -30,6 +30,8 @@
#include <libindicator/indicator.h>
#include <libindicator/indicator-object.h>
+#include <libbamf/bamf-matcher.h>
+
#include "indicator-appmenu-marshal.h"
#include "window-menus.h"
#include "dbus-shared.h"
@@ -67,6 +69,8 @@
WindowMenus * default_app;
GHashTable * apps;
+ BamfMatcher * matcher;
+
gulong sig_entry_added;
gulong sig_entry_removed;
@@ -124,6 +128,10 @@
static void window_entry_removed (WindowMenus * mw,
IndicatorObjectEntry * entry,
gpointer user_data);
+static void active_window_changed (BamfMatcher * matcher,
+ BamfView * oldview,
+ BamfView * newview,
+ gpointer user_data);
static gboolean _application_menu_debug_server_current_menu (IndicatorAppmenuDebug * iappd,
guint * windowid,
gchar ** objectpath,
@@ -189,7 +197,18 @@
{
self->default_app = NULL;
self->debug = NULL;
- self->apps = g_hash_table_new_full(NULL, NULL, NULL, g_object_unref);
+ self->apps = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_object_unref);
+ self->matcher = NULL;
+
+ /* Get the default BAMF matcher */
+ self->matcher = bamf_matcher_get_default();
+ if (self->matcher == NULL) {
+ /* we don't want to exit out of Unity -- but this
+ should really never happen */
+ g_warning("Unable to get BAMF matcher, can not watch applications switch!");
+ } else {
+ g_signal_connect(G_OBJECT(self->matcher), "active-window-changed", G_CALLBACK(active_window_changed), self);
+ }
/* Register this object on DBus */
DBusGConnection * connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
@@ -222,6 +241,13 @@
{
IndicatorAppmenu * iapp = INDICATOR_APPMENU(object);
+ /* bring down the matcher before resetting to no menu so we don't
+ get match signals */
+ if (iapp->matcher != NULL) {
+ g_object_unref(iapp->matcher);
+ iapp->matcher = NULL;
+ }
+
/* No specific ref */
switch_default_app (iapp, NULL);
@@ -314,6 +340,16 @@
/* Remove old */
if (iapp->default_app != NULL) {
for (entries = window_menus_get_entries(iapp->default_app); entries != NULL; entries = g_list_next(entries)) {
+ IndicatorObjectEntry * entry = (IndicatorObjectEntry *)entries->data;
+
+ if (entry->label != NULL) {
+ gtk_widget_hide(GTK_WIDGET(entry->label));
+ }
+
+ if (entry->menu != NULL) {
+ gtk_menu_detach(entry->menu);
+ }
+
g_signal_emit(G_OBJECT(iapp), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED_ID, 0, entries->data, TRUE);
}
}
@@ -346,6 +382,12 @@
/* Add new */
if (iapp->default_app != NULL) {
for (entries = window_menus_get_entries(iapp->default_app); entries != NULL; entries = g_list_next(entries)) {
+ IndicatorObjectEntry * entry = (IndicatorObjectEntry *)entries->data;
+
+ if (entry->label != NULL) {
+ gtk_widget_show(GTK_WIDGET(entry->label));
+ }
+
g_signal_emit(G_OBJECT(iapp), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED_ID, 0, entries->data, TRUE);
}
}
@@ -353,20 +395,51 @@
return;
}
+/* Recieve the signal that the window being shown
+ has now changed. */
+static void
+active_window_changed (BamfMatcher * matcher, BamfView * oldview, BamfView * newview, gpointer user_data)
+{
+ if (!BAMF_IS_WINDOW(newview)) {
+ /* We're only dealing with windows currently */
+ return;
+ }
+ BamfWindow * window = BAMF_WINDOW(newview);
+
+ IndicatorAppmenu * appmenu = INDICATOR_APPMENU(user_data);
+
+ guint32 xid = bamf_window_get_xid(window);
+ g_debug("window changed to %d", xid);
+
+ WindowMenus * menus = g_hash_table_lookup(appmenu->apps, GINT_TO_POINTER(xid));
+
+ /* Note: This function can handle menus being NULL */
+ switch_default_app(appmenu, menus);
+
+ return;
+}
+
/* A new window wishes to register it's windows with us */
static gboolean
_application_menu_registrar_server_register_window (IndicatorAppmenu * iapp, guint windowid, const gchar * objectpath, DBusGMethodInvocation * method)
{
- if (TRUE || g_hash_table_lookup(iapp->apps, GUINT_TO_POINTER(windowid)) == NULL) {
+ g_debug("Registering window ID %d with path %s from %s", windowid, objectpath, dbus_g_method_get_sender(method));
+
+ if (g_hash_table_lookup(iapp->apps, GUINT_TO_POINTER(windowid)) == NULL) {
WindowMenus * wm = window_menus_new(windowid, dbus_g_method_get_sender(method), objectpath);
- //g_hash_table_insert(iapp->apps, GUINT_TO_POINTER(windowid), wm);
-
- /* TODO: Check to see if it's the visible window */
- switch_default_app(iapp, wm);
+ g_hash_table_insert(iapp->apps, GUINT_TO_POINTER(windowid), wm);
g_signal_emit(G_OBJECT(iapp), signals[WINDOW_REGISTERED], 0, windowid, objectpath, TRUE);
+
+ /* Node: Does not cause ref */
+ BamfWindow * win = bamf_matcher_get_active_window(iapp->matcher);
+ guint32 xid = bamf_window_get_xid(win);
+
+ if (xid == windowid) {
+ switch_default_app(iapp, wm);
+ }
} else {
- g_warning("Already have a menu for window ID %X with path %s from %s", windowid, objectpath, dbus_g_method_get_sender(method));
+ g_warning("Already have a menu for window ID %d with path %s from %s", windowid, objectpath, dbus_g_method_get_sender(method));
}
dbus_g_method_return(method);
=== modified file 'src/window-menus.c'
--- src/window-menus.c 2010-06-02 17:44:59 +0000
+++ src/window-menus.c 2010-06-04 04:51:23 +0000
@@ -128,6 +128,18 @@
WindowMenusPrivate * priv = WINDOW_MENUS_GET_PRIVATE(object);
if (priv->entries != NULL) {
+ int i;
+ for (i = 0; i < priv->entries->len; i++) {
+ IndicatorObjectEntry * entry;
+ entry = g_array_index(priv->entries, IndicatorObjectEntry *, i);
+
+ if (entry->label != NULL) {
+ g_object_unref(entry->label);
+ }
+ if (entry->menu != NULL) {
+ g_object_unref(entry->menu);
+ }
+ }
g_array_free(priv->entries, TRUE);
priv->entries = NULL;
}
@@ -300,10 +312,18 @@
IndicatorObjectEntry * entry = g_new0(IndicatorObjectEntry, 1);
entry->label = GTK_LABEL(gtk_label_new_with_mnemonic(dbusmenu_menuitem_property_get(newentry, DBUSMENU_MENUITEM_PROP_LABEL)));
+
+ if (entry->label != NULL) {
+ g_object_ref(entry->label);
+ }
+
entry->menu = dbusmenu_gtkclient_menuitem_get_submenu(priv->client, newentry);
if (entry->menu == NULL) {
g_debug("Submenu for %s is NULL", dbusmenu_menuitem_property_get(newentry, DBUSMENU_MENUITEM_PROP_LABEL));
+ } else {
+ g_object_ref(entry->menu);
+ gtk_menu_detach(entry->menu);
}
gtk_widget_show(GTK_WIDGET(entry->label));
Follow ups