ayatana-commits team mailing list archive
-
ayatana-commits team
-
Mailing list archive
-
Message #01614
[Merge] lp:~ted/indicator-appmenu/application-fallback into lp:indicator-appmenu
Ted Gould has proposed merging lp:~ted/indicator-appmenu/application-fallback into lp:indicator-appmenu.
Requested reviews:
Indicator Applet Developers (indicator-applet-developers)
Doesn't do anything super useful. But it puts blank menus in for application fallback and desktop fallback. Sets up all the framework for that.
--
https://code.launchpad.net/~ted/indicator-appmenu/application-fallback/+merge/27794
Your team ayatana-commits is subscribed to branch lp:indicator-appmenu.
=== modified file 'src/indicator-appmenu.c'
--- src/indicator-appmenu.c 2010-06-16 04:04:47 +0000
+++ src/indicator-appmenu.c 2010-06-17 04:59:22 +0000
@@ -70,10 +70,14 @@
GHashTable * apps;
BamfMatcher * matcher;
+ BamfWindow * active_window;
gulong sig_entry_added;
gulong sig_entry_removed;
+ GArray * window_menus;
+ GArray * desktop_menus;
+
IndicatorAppmenuDebug * debug;
};
@@ -109,11 +113,14 @@
static void indicator_appmenu_finalize (GObject *object);
static void indicator_appmenu_debug_class_init (IndicatorAppmenuDebugClass *klass);
static void indicator_appmenu_debug_init (IndicatorAppmenuDebug *self);
+static void build_window_menus (IndicatorAppmenu * iapp);
+static void build_desktop_menus (IndicatorAppmenu * iapp);
static GList * get_entries (IndicatorObject * io);
static guint get_location (IndicatorObject * io,
IndicatorObjectEntry * entry);
static void switch_default_app (IndicatorAppmenu * iapp,
- WindowMenus * newdef);
+ WindowMenus * newdef,
+ BamfWindow * active_window);
static gboolean _application_menu_registrar_server_register_window (IndicatorAppmenu * iapp,
guint windowid,
const gchar * objectpath,
@@ -199,6 +206,14 @@
self->debug = NULL;
self->apps = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_object_unref);
self->matcher = NULL;
+ self->active_window = NULL;
+
+ /* Setup the entries for the fallbacks */
+ self->window_menus = g_array_sized_new(FALSE, FALSE, sizeof(IndicatorObjectEntry), 2);
+ self->desktop_menus = g_array_sized_new(FALSE, FALSE, sizeof(IndicatorObjectEntry), 2);
+
+ build_window_menus(self);
+ build_desktop_menus(self);
/* Get the default BAMF matcher */
self->matcher = bamf_matcher_get_default();
@@ -249,7 +264,7 @@
}
/* No specific ref */
- switch_default_app (iapp, NULL);
+ switch_default_app (iapp, NULL, NULL);
if (iapp->apps != NULL) {
g_hash_table_destroy(iapp->apps);
@@ -269,6 +284,23 @@
static void
indicator_appmenu_finalize (GObject *object)
{
+ IndicatorAppmenu * iapp = INDICATOR_APPMENU(object);
+
+ if (iapp->window_menus != NULL) {
+ if (iapp->window_menus->len != 0) {
+ g_warning("Window menus weren't free'd in dispose!");
+ }
+ g_array_free(iapp->window_menus, TRUE);
+ iapp->window_menus = NULL;
+ }
+
+ if (iapp->desktop_menus != NULL) {
+ if (iapp->desktop_menus->len != 0) {
+ g_warning("Desktop menus weren't free'd in dispose!");
+ }
+ g_array_free(iapp->desktop_menus, TRUE);
+ iapp->desktop_menus = NULL;
+ }
G_OBJECT_CLASS (indicator_appmenu_parent_class)->finalize (object);
return;
@@ -300,6 +332,113 @@
return;
}
+/* Create the default window menus */
+static void
+build_window_menus (IndicatorAppmenu * iapp)
+{
+ IndicatorObjectEntry entries[2] = {{0}, {0}};
+
+ /* File Menu */
+ entries[0].label = GTK_LABEL(gtk_label_new("File"));
+ g_object_ref(G_OBJECT(entries[0].label));
+ gtk_widget_show(GTK_WIDGET(entries[0].label));
+
+ entries[0].menu = GTK_MENU(gtk_menu_new());
+ g_object_ref(G_OBJECT(entries[0].menu));
+
+ GtkMenuItem * mi = GTK_MENU_ITEM(gtk_menu_item_new_with_label("Close"));
+ gtk_widget_set_sensitive(GTK_WIDGET(mi), FALSE);
+ gtk_widget_show(GTK_WIDGET(mi));
+ gtk_menu_append(entries[0].menu, GTK_WIDGET(mi));
+
+ gtk_widget_show(GTK_WIDGET(entries[0].menu));
+
+ /* Edit Menu */
+ entries[1].label = GTK_LABEL(gtk_label_new("Edit"));
+ g_object_ref(G_OBJECT(entries[1].label));
+ gtk_widget_show(GTK_WIDGET(entries[1].label));
+
+ entries[1].menu = GTK_MENU(gtk_menu_new());
+ g_object_ref(G_OBJECT(entries[1].menu));
+
+ mi = GTK_MENU_ITEM(gtk_menu_item_new_with_label("Undo"));
+ gtk_widget_set_sensitive(GTK_WIDGET(mi), FALSE);
+ gtk_widget_show(GTK_WIDGET(mi));
+ gtk_menu_append(entries[1].menu, GTK_WIDGET(mi));
+
+ mi = GTK_MENU_ITEM(gtk_menu_item_new_with_label("Redo"));
+ gtk_widget_set_sensitive(GTK_WIDGET(mi), FALSE);
+ gtk_widget_show(GTK_WIDGET(mi));
+ gtk_menu_append(entries[1].menu, GTK_WIDGET(mi));
+
+ mi = GTK_MENU_ITEM(gtk_separator_menu_item_new());
+ gtk_widget_show(GTK_WIDGET(mi));
+ gtk_menu_append(entries[1].menu, GTK_WIDGET(mi));
+
+ mi = GTK_MENU_ITEM(gtk_menu_item_new_with_label("Cut"));
+ gtk_widget_set_sensitive(GTK_WIDGET(mi), FALSE);
+ gtk_widget_show(GTK_WIDGET(mi));
+ gtk_menu_append(entries[1].menu, GTK_WIDGET(mi));
+
+ mi = GTK_MENU_ITEM(gtk_menu_item_new_with_label("Copy"));
+ gtk_widget_set_sensitive(GTK_WIDGET(mi), FALSE);
+ gtk_widget_show(GTK_WIDGET(mi));
+ gtk_menu_append(entries[1].menu, GTK_WIDGET(mi));
+
+ mi = GTK_MENU_ITEM(gtk_menu_item_new_with_label("Paste"));
+ gtk_widget_set_sensitive(GTK_WIDGET(mi), FALSE);
+ gtk_widget_show(GTK_WIDGET(mi));
+ gtk_menu_append(entries[1].menu, GTK_WIDGET(mi));
+
+ mi = GTK_MENU_ITEM(gtk_menu_item_new_with_label("Delete"));
+ gtk_widget_set_sensitive(GTK_WIDGET(mi), FALSE);
+ gtk_widget_show(GTK_WIDGET(mi));
+ gtk_menu_append(entries[1].menu, GTK_WIDGET(mi));
+
+ mi = GTK_MENU_ITEM(gtk_separator_menu_item_new());
+ gtk_widget_show(GTK_WIDGET(mi));
+ gtk_menu_append(entries[1].menu, GTK_WIDGET(mi));
+
+ mi = GTK_MENU_ITEM(gtk_menu_item_new_with_label("Select All"));
+ gtk_widget_set_sensitive(GTK_WIDGET(mi), FALSE);
+ gtk_widget_show(GTK_WIDGET(mi));
+ gtk_menu_append(entries[1].menu, GTK_WIDGET(mi));
+
+ gtk_widget_show(GTK_WIDGET(entries[1].menu));
+
+ /* Copy the entries on the stack into the array */
+ g_array_insert_vals(iapp->window_menus, 0, entries, 2);
+
+ return;
+}
+
+/* Create the default desktop menus */
+static void
+build_desktop_menus (IndicatorAppmenu * iapp)
+{
+ IndicatorObjectEntry entries[1] = {{0}};
+
+ /* File Menu */
+ entries[0].label = GTK_LABEL(gtk_label_new("Desktop"));
+ g_object_ref(G_OBJECT(entries[0].label));
+ gtk_widget_show(GTK_WIDGET(entries[0].label));
+
+ entries[0].menu = GTK_MENU(gtk_menu_new());
+ g_object_ref(G_OBJECT(entries[0].menu));
+
+ GtkMenuItem * mi = GTK_MENU_ITEM(gtk_menu_item_new_with_label("Desktop Menus will go here"));
+ gtk_widget_set_sensitive(GTK_WIDGET(mi), FALSE);
+ gtk_widget_show(GTK_WIDGET(mi));
+ gtk_menu_append(entries[0].menu, GTK_WIDGET(mi));
+
+ gtk_widget_show(GTK_WIDGET(entries[0].menu));
+
+ /* Copy the entries on the stack into the array */
+ g_array_insert_vals(iapp->desktop_menus, 0, entries, 1);
+
+ return;
+}
+
/* Get the current set of entries */
static GList *
get_entries (IndicatorObject * io)
@@ -307,11 +446,25 @@
g_return_val_if_fail(IS_INDICATOR_APPMENU(io), NULL);
IndicatorAppmenu * iapp = INDICATOR_APPMENU(io);
- if (iapp->default_app == NULL) {
- return NULL;
- }
-
- return window_menus_get_entries(iapp->default_app);
+ if (iapp->default_app != NULL) {
+ return window_menus_get_entries(iapp->default_app);
+ }
+
+ GArray * entryarray;
+ if (iapp->active_window == NULL) {
+ entryarray = iapp->desktop_menus;
+ } else {
+ entryarray = iapp->window_menus;
+ }
+
+ GList * output = NULL;
+ int i;
+
+ for (i = 0; i < entryarray->len; i++) {
+ output = g_list_append(output, &g_array_index(entryarray, IndicatorObjectEntry, i));
+ }
+
+ return output;
}
/* Grabs the location of the entry */
@@ -321,7 +474,30 @@
guint count = 0;
IndicatorAppmenu * iapp = INDICATOR_APPMENU(io);
if (iapp->default_app != NULL) {
+ /* Find the location in the app */
count = window_menus_get_location(iapp->default_app, entry);
+ } else if (iapp->active_window != NULL) {
+ /* Find the location in the window menus */
+ for (count = 0; count < iapp->window_menus->len; count++) {
+ if (entry == &g_array_index(iapp->window_menus, IndicatorObjectEntry, count)) {
+ break;
+ }
+ }
+ if (count == iapp->window_menus->len) {
+ g_warning("Unable to find entry in default window menus");
+ count = 0;
+ }
+ } else {
+ /* Find the location in the desktop menus */
+ for (count = 0; count < iapp->desktop_menus->len; count++) {
+ if (entry == &g_array_index(iapp->desktop_menus, IndicatorObjectEntry, count)) {
+ break;
+ }
+ }
+ if (count == iapp->desktop_menus->len) {
+ g_warning("Unable to find entry in default window menus");
+ count = 0;
+ }
}
return count;
}
@@ -329,15 +505,25 @@
/* Switch applications, remove all the entires for the previous
one and add them for the new application */
static void
-switch_default_app (IndicatorAppmenu * iapp, WindowMenus * newdef)
+switch_default_app (IndicatorAppmenu * iapp, WindowMenus * newdef, BamfWindow * active_window)
{
- if (iapp->default_app == newdef) {
+ if (iapp->default_app == newdef && iapp->default_app != NULL) {
+ /* We've got an app with menus and it hasn't changed. */
+
+ /* Keep active window up-to-date, though we're probably not
+ using it much. */
+ iapp->active_window = active_window;
+ return;
+ }
+ if (iapp->default_app == NULL && iapp->active_window == active_window) {
+ /* There's no application menus, but the active window hasn't
+ changed. So there's no change. */
return;
}
GList * entries;
- /* Remove old */
+ /* No matter what, we want to remove the old application menu */
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;
@@ -352,23 +538,63 @@
g_signal_emit(G_OBJECT(iapp), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED_ID, 0, entries->data, TRUE);
}
- }
- /* Disconnect signals */
- if (iapp->sig_entry_added != 0) {
- g_signal_handler_disconnect(G_OBJECT(iapp->default_app), iapp->sig_entry_added);
- iapp->sig_entry_added = 0;
- }
- if (iapp->sig_entry_removed != 0) {
- g_signal_handler_disconnect(G_OBJECT(iapp->default_app), iapp->sig_entry_removed);
- iapp->sig_entry_removed = 0;
- }
-
- /* Switch */
- iapp->default_app = newdef;
-
- /* Connect signals */
- if (iapp->default_app != NULL) {
+ /* Disconnect signals */
+ if (iapp->sig_entry_added != 0) {
+ g_signal_handler_disconnect(G_OBJECT(iapp->default_app), iapp->sig_entry_added);
+ iapp->sig_entry_added = 0;
+ }
+ if (iapp->sig_entry_removed != 0) {
+ g_signal_handler_disconnect(G_OBJECT(iapp->default_app), iapp->sig_entry_removed);
+ iapp->sig_entry_removed = 0;
+ }
+
+ iapp->default_app = NULL;
+ } else {
+ /* If the default app was previously NULL, then we probably had other
+ menus up. Let's remove those. */
+
+ if (iapp->active_window == NULL) {
+ /* No active window means that the desktop menu items were
+ the ones being shown. */
+ int i;
+ for (i = 0; i < iapp->desktop_menus->len; i++) {
+ if (g_array_index(iapp->desktop_menus, IndicatorObjectEntry, i).label != NULL) {
+ gtk_widget_hide(GTK_WIDGET(g_array_index(iapp->desktop_menus, IndicatorObjectEntry, i).label));
+ }
+ if (g_array_index(iapp->desktop_menus, IndicatorObjectEntry, i).menu != NULL) {
+ gtk_menu_detach(g_array_index(iapp->desktop_menus, IndicatorObjectEntry, i).menu);
+ }
+ g_signal_emit(G_OBJECT(iapp), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED_ID, 0, &g_array_index(iapp->desktop_menus, IndicatorObjectEntry, i), TRUE);
+ }
+ } else {
+ /* We had an active window so we must have had the window
+ specific menu items shown. */
+ int i;
+ for (i = 0; i < iapp->window_menus->len; i++) {
+ if (g_array_index(iapp->window_menus, IndicatorObjectEntry, i).label != NULL) {
+ gtk_widget_hide(GTK_WIDGET(g_array_index(iapp->window_menus, IndicatorObjectEntry, i).label));
+ }
+ if (g_array_index(iapp->window_menus, IndicatorObjectEntry, i).menu != NULL) {
+ gtk_menu_detach(g_array_index(iapp->window_menus, IndicatorObjectEntry, i).menu);
+ }
+ g_signal_emit(G_OBJECT(iapp), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED_ID, 0, &g_array_index(iapp->window_menus, IndicatorObjectEntry, i), TRUE);
+ }
+ }
+ }
+
+ /* Through either the if or the setting, we know at this point that iapp->default_app
+ is NULL and all the menus from it have been removed. */
+
+ /* Update the active window pointer */
+ iapp->active_window = active_window;
+
+ /* If we're putting up a new window, let's do that now. */
+ if (newdef != NULL) {
+ /* Switch */
+ iapp->default_app = newdef;
+
+ /* Connect signals */
iapp->sig_entry_added = g_signal_connect(G_OBJECT(iapp->default_app),
WINDOW_MENUS_SIGNAL_ENTRY_ADDED,
G_CALLBACK(window_entry_added),
@@ -377,10 +603,8 @@
WINDOW_MENUS_SIGNAL_ENTRY_REMOVED,
G_CALLBACK(window_entry_removed),
iapp);
- }
- /* Add new */
- if (iapp->default_app != NULL) {
+ /* Add new */
for (entries = window_menus_get_entries(iapp->default_app); entries != NULL; entries = g_list_next(entries)) {
IndicatorObjectEntry * entry = (IndicatorObjectEntry *)entries->data;
@@ -390,6 +614,29 @@
g_signal_emit(G_OBJECT(iapp), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED_ID, 0, entries->data, TRUE);
}
+ } else {
+ /* No new application here we need to put up something. No blankness. */
+ if (iapp->active_window == NULL) {
+ /* No active window means that the desktop menu items were
+ the ones being shown. */
+ int i;
+ for (i = 0; i < iapp->desktop_menus->len; i++) {
+ if (g_array_index(iapp->desktop_menus, IndicatorObjectEntry, i).label != NULL) {
+ gtk_widget_show(GTK_WIDGET(g_array_index(iapp->desktop_menus, IndicatorObjectEntry, i).label));
+ }
+ g_signal_emit(G_OBJECT(iapp), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED_ID, 0, &g_array_index(iapp->desktop_menus, IndicatorObjectEntry, i), TRUE);
+ }
+ } else {
+ /* We had an active window so we must have had the window
+ specific menu items shown. */
+ int i;
+ for (i = 0; i < iapp->window_menus->len; i++) {
+ if (g_array_index(iapp->window_menus, IndicatorObjectEntry, i).label != NULL) {
+ gtk_widget_show(GTK_WIDGET(g_array_index(iapp->window_menus, IndicatorObjectEntry, i).label));
+ }
+ g_signal_emit(G_OBJECT(iapp), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED_ID, 0, &g_array_index(iapp->window_menus, IndicatorObjectEntry, i), TRUE);
+ }
+ }
}
return;
@@ -400,11 +647,11 @@
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 = NULL;
+
+ if (newview != NULL) {
+ window = BAMF_WINDOW(newview);
}
- BamfWindow * window = BAMF_WINDOW(newview);
IndicatorAppmenu * appmenu = INDICATOR_APPMENU(user_data);
@@ -424,7 +671,7 @@
g_debug("Switching to windows from XID %d", xid);
/* Note: This function can handle menus being NULL */
- switch_default_app(appmenu, menus);
+ switch_default_app(appmenu, menus, BAMF_WINDOW(newview));
return;
}
@@ -440,7 +687,7 @@
/* If we're it, let's remove ourselves and BAMF will probably
give us a new entry in a bit. */
if (iapp->default_app == wm) {
- switch_default_app(iapp, NULL);
+ switch_default_app(iapp, NULL, NULL);
}
guint xid = window_menus_get_xid(wm);
@@ -465,7 +712,7 @@
g_signal_emit(G_OBJECT(iapp), signals[WINDOW_REGISTERED], 0, windowid, objectpath, TRUE);
- /* Node: Does not cause ref */
+ /* Note: Does not cause ref */
BamfWindow * win = bamf_matcher_get_active_window(iapp->matcher);
active_window_changed(iapp->matcher, NULL, BAMF_VIEW(win), iapp);
@@ -496,7 +743,7 @@
if (error) {
/* We can rest assured no one will register with us, but let's
just ensure we're not showing anything. */
- switch_default_app(INDICATOR_APPMENU(userdata), NULL);
+ switch_default_app(INDICATOR_APPMENU(userdata), NULL, NULL);
}
g_object_unref(proxy);
Follow ups