Back to index

indicator-appmenu  12.10.0
window-menu-model.c
Go to the documentation of this file.
00001 /*
00002  * Copyright © 2012 Canonical Limited
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the licence, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
00016  *
00017  * Author: Ted Gould <ted.gould@canonical.com>
00018  */
00019 
00020 #ifdef HAVE_CONFIG_H
00021 #include "config.h"
00022 #endif
00023 
00024 #include <libbamf/libbamf.h>
00025 #include <gio/gio.h>
00026 #include <gtk/gtk.h>
00027 #include <glib/gi18n.h>
00028 #include <gio/gdesktopappinfo.h>
00029 
00030 #include "window-menu-model.h"
00031 #include "gactionmuxer.h"
00032 #include "gtkmodelmenu.h"
00033 
00034 struct _WindowMenuModelPrivate {
00035        guint xid;
00036 
00037        /* All the actions */
00038        GActionMuxer * action_mux;
00039        GtkAccelGroup * accel_group;
00040 
00041        /* Application Menu */
00042        GDBusMenuModel * app_menu_model;
00043        IndicatorObjectEntry application_menu;
00044        gboolean has_application_menu;
00045 
00046        /* Window Menus */
00047        GDBusMenuModel * win_menu_model;
00048        GtkMenu * win_menu;
00049        gulong win_menu_insert;
00050        gulong win_menu_remove;
00051 };
00052 
00053 #define WINDOW_MENU_MODEL_GET_PRIVATE(o) \
00054 (G_TYPE_INSTANCE_GET_PRIVATE ((o), WINDOW_MENU_MODEL_TYPE, WindowMenuModelPrivate))
00055 
00056 /* Base class stuff */
00057 static void                window_menu_model_class_init (WindowMenuModelClass *klass);
00058 static void                window_menu_model_init       (WindowMenuModel *self);
00059 static void                window_menu_model_dispose    (GObject *object);
00060 static void                window_menu_model_finalize   (GObject *object);
00061 
00062 /* Window Menu subclassin' */
00063 static GList *             get_entries                  (WindowMenu * wm);
00064 static guint               get_location                 (WindowMenu * wm,
00065                                                          IndicatorObjectEntry * entry);
00066 static WindowMenuStatus    get_status                   (WindowMenu * wm);
00067 static gboolean            get_error_state              (WindowMenu * wm);
00068 static guint               get_xid                      (WindowMenu * wm);
00069 
00070 /* GLib boilerplate */
00071 G_DEFINE_TYPE (WindowMenuModel, window_menu_model, WINDOW_MENU_TYPE);
00072 
00073 /* Prefixes to the action muxer */
00074 #define ACTION_MUX_PREFIX_WIN  "win"
00075 #define ACTION_MUX_PREFIX_APP  "app"
00076 
00077 /* Entry data on the menuitem */
00078 #define ENTRY_DATA  "window-menu-model-menuitem-entry"
00079 
00080 static void
00081 window_menu_model_class_init (WindowMenuModelClass *klass)
00082 {
00083        GObjectClass *object_class = G_OBJECT_CLASS (klass);
00084 
00085        g_type_class_add_private (klass, sizeof (WindowMenuModelPrivate));
00086 
00087        object_class->dispose = window_menu_model_dispose;
00088        object_class->finalize = window_menu_model_finalize;
00089 
00090        WindowMenuClass * wm_class = WINDOW_MENU_CLASS(klass);
00091 
00092        wm_class->get_entries = get_entries;
00093        wm_class->get_location = get_location;
00094        wm_class->get_status = get_status;
00095        wm_class->get_error_state = get_error_state;
00096        wm_class->get_xid = get_xid;
00097 
00098        return;
00099 }
00100 
00101 static void
00102 window_menu_model_init (WindowMenuModel *self)
00103 {
00104        self->priv = WINDOW_MENU_MODEL_GET_PRIVATE(self);
00105 
00106        self->priv->action_mux = g_action_muxer_new();
00107        self->priv->accel_group = gtk_accel_group_new();
00108 
00109        return;
00110 }
00111 
00112 static void
00113 window_menu_model_dispose (GObject *object)
00114 {
00115        WindowMenuModel * menu = WINDOW_MENU_MODEL(object);
00116 
00117        g_clear_object(&menu->priv->action_mux);
00118        g_clear_object(&menu->priv->accel_group);
00119 
00120        /* Application Menu */
00121        g_clear_object(&menu->priv->app_menu_model);
00122        g_clear_object(&menu->priv->application_menu.label);
00123        g_clear_object(&menu->priv->application_menu.menu);
00124 
00125        /* Window Menus */
00126        if (menu->priv->win_menu_insert != 0) {
00127               g_signal_handler_disconnect(menu->priv->win_menu, menu->priv->win_menu_insert);
00128               menu->priv->win_menu_insert = 0;
00129        }
00130 
00131        if (menu->priv->win_menu_remove != 0) {
00132               g_signal_handler_disconnect(menu->priv->win_menu, menu->priv->win_menu_remove);
00133               menu->priv->win_menu_remove = 0;
00134        }
00135 
00136        g_clear_object(&menu->priv->win_menu_model);
00137        g_clear_object(&menu->priv->win_menu);
00138 
00139        G_OBJECT_CLASS (window_menu_model_parent_class)->dispose (object);
00140        return;
00141 }
00142 
00143 static void
00144 window_menu_model_finalize (GObject *object)
00145 {
00146 
00147        G_OBJECT_CLASS (window_menu_model_parent_class)->finalize (object);
00148        return;
00149 }
00150 
00151 /* Adds the application menu and turns the whole thing into an object
00152    entry that can be used elsewhere */
00153 static void
00154 add_application_menu (WindowMenuModel * menu, const gchar * appname, GMenuModel * model)
00155 {
00156        g_return_if_fail(G_IS_MENU_MODEL(model));
00157 
00158        menu->priv->app_menu_model = g_object_ref(model);
00159 
00160        if (appname != NULL) {
00161               menu->priv->application_menu.label = GTK_LABEL(gtk_label_new(appname));
00162        } else {
00163               menu->priv->application_menu.label = GTK_LABEL(gtk_label_new(_("Unknown Application Name")));
00164        }
00165        g_object_ref_sink(menu->priv->application_menu.label);
00166        gtk_widget_show(GTK_WIDGET(menu->priv->application_menu.label));
00167 
00168        menu->priv->application_menu.menu = GTK_MENU(gtk_model_menu_create_menu(model, G_ACTION_OBSERVABLE(menu->priv->action_mux), menu->priv->accel_group));
00169 
00170        gtk_widget_show(GTK_WIDGET(menu->priv->application_menu.menu));
00171        g_object_ref_sink(menu->priv->application_menu.menu);
00172 
00173        menu->priv->has_application_menu = TRUE;
00174 
00175        return;
00176 }
00177 
00178 /* Find the label in a GTK MenuItem */
00179 GtkLabel *
00180 mi_find_label (GtkWidget * mi)
00181 {
00182        if (GTK_IS_LABEL(mi)) {
00183               return GTK_LABEL(mi);
00184        }
00185 
00186        GtkLabel * retval = NULL;
00187 
00188        if (GTK_IS_CONTAINER(mi)) {
00189               GList * children = gtk_container_get_children(GTK_CONTAINER(mi));
00190               GList * child = children;
00191 
00192               while (child != NULL && retval == NULL) {
00193                      if (GTK_IS_WIDGET(child->data)) {
00194                             retval = mi_find_label(GTK_WIDGET(child->data));
00195                      }
00196                      child = g_list_next(child);
00197               }
00198 
00199               g_list_free(children);
00200        }
00201 
00202        return retval;
00203 }
00204 
00205 /* Find the icon in a GTK MenuItem */
00206 GtkImage *
00207 mi_find_icon (GtkWidget * mi)
00208 {
00209        if (GTK_IS_IMAGE(mi)) {
00210               return GTK_IMAGE(mi);
00211        }
00212 
00213        GtkImage * retval = NULL;
00214 
00215        if (GTK_IS_CONTAINER(mi)) {
00216               GList * children = gtk_container_get_children(GTK_CONTAINER(mi));
00217               GList * child = children;
00218 
00219               while (child != NULL && retval == NULL) {
00220                      if (GTK_IS_WIDGET(child->data)) {
00221                             retval = mi_find_icon(GTK_WIDGET(child->data));
00222                      }
00223                      child = g_list_next(child);
00224               }
00225 
00226               g_list_free(children);
00227        }
00228 
00229        return retval;
00230 }
00231 
00232 /* Check the menu and make sure we return it if it's a menu
00233    all proper like that */
00234 GtkMenu *
00235 mi_find_menu (GtkMenuItem * mi)
00236 {
00237        GtkWidget * retval = gtk_menu_item_get_submenu(mi);
00238        if (GTK_IS_MENU(retval)) {
00239               return GTK_MENU(retval);
00240        } else {
00241               return NULL;
00242        }
00243 }
00244 
00245 typedef struct _WindowMenuEntry WindowMenuEntry;
00246 struct _WindowMenuEntry {
00247        IndicatorObjectEntry entry;
00248 
00249        GtkMenuItem * gmi;
00250 
00251        gulong label_sig;
00252        gulong sensitive_sig;
00253        gulong visible_sig;
00254 };
00255 
00256 /* Destroy and unref the items of the object entry */
00257 static void
00258 entry_object_free (gpointer inentry)
00259 {
00260        WindowMenuEntry * entry = (WindowMenuEntry *)inentry;
00261 
00262        if (entry->label_sig != 0) {
00263               g_signal_handler_disconnect(entry->gmi, entry->label_sig);
00264        }
00265 
00266        if (entry->sensitive_sig != 0) {
00267               g_signal_handler_disconnect(entry->gmi, entry->sensitive_sig);
00268        }
00269 
00270        if (entry->visible_sig != 0) {
00271               g_signal_handler_disconnect(entry->gmi, entry->visible_sig);
00272        }
00273 
00274        g_clear_object(&entry->entry.label);
00275        g_clear_object(&entry->entry.image);
00276        g_clear_object(&entry->entry.menu);
00277 
00278        g_free(entry);
00279        return;
00280 }
00281 
00282 /* Sync the menu label changing to the label object */
00283 static void
00284 entry_label_notify (GObject * obj, GParamSpec * pspec, gpointer user_data)
00285 {
00286        g_return_if_fail(GTK_IS_MENU_ITEM(obj));
00287 
00288        GtkMenuItem * gmi = GTK_MENU_ITEM(obj);
00289        WindowMenuEntry * entry = (WindowMenuEntry *)user_data;
00290 
00291        if (entry->entry.label != NULL) {
00292               const gchar * label = gtk_menu_item_get_label(gmi);
00293               gtk_label_set_label(entry->entry.label, label);
00294        }
00295 
00296        return;
00297 }
00298 
00299 /* Watch for visible changes and ensure they can be picked up by the
00300    indicator object host */
00301 static void
00302 entry_visible_notify (GObject * obj, GParamSpec * pspec, gpointer user_data)
00303 {
00304        g_return_if_fail(GTK_IS_WIDGET(obj));
00305        GtkWidget * widget = GTK_WIDGET(obj);
00306        WindowMenuEntry * entry = (WindowMenuEntry *)user_data;
00307        gboolean visible = gtk_widget_get_visible(widget);
00308 
00309        if (entry->entry.label != NULL) {
00310               gtk_widget_set_visible(GTK_WIDGET(entry->entry.label), visible);
00311        }
00312 
00313        if (entry->entry.image != NULL) {
00314               gtk_widget_set_visible(GTK_WIDGET(entry->entry.image), visible);
00315        }
00316 
00317        return;
00318 }
00319 
00320 /* Watch for sensitive changes and ensure they can be picked up by the
00321    indicator object host */
00322 static void
00323 entry_sensitive_notify (GObject * obj, GParamSpec * pspec, gpointer user_data)
00324 {
00325        g_return_if_fail(GTK_IS_WIDGET(obj));
00326        GtkWidget * widget = GTK_WIDGET(obj);
00327        WindowMenuEntry * entry = (WindowMenuEntry *)user_data;
00328        gboolean sensitive = gtk_widget_get_sensitive(widget);
00329 
00330        if (entry->entry.label != NULL) {
00331               gtk_widget_set_sensitive(GTK_WIDGET(entry->entry.label), sensitive);
00332        }
00333 
00334        if (entry->entry.image != NULL) {
00335               gtk_widget_set_sensitive(GTK_WIDGET(entry->entry.image), sensitive);
00336        }
00337 
00338        return;
00339 }
00340 
00341 /* Put an entry on a menu item */
00342 static void
00343 entry_on_menuitem (WindowMenuModel * menu, GtkMenuItem * gmi)
00344 {
00345        WindowMenuEntry * entry = g_new0(WindowMenuEntry, 1);
00346 
00347        entry->gmi = gmi;
00348 
00349        entry->entry.label = mi_find_label(GTK_WIDGET(gmi));
00350        entry->entry.image = mi_find_icon(GTK_WIDGET(gmi));
00351        entry->entry.menu = mi_find_menu(gmi);
00352 
00353        if (entry->entry.label == NULL && entry->entry.image == NULL) {
00354               const gchar * label = gtk_menu_item_get_label(gmi);
00355               if (label == NULL) {
00356                      g_warning("Item doesn't have a label or an image, aborting");
00357                      return;
00358               }
00359 
00360               entry->entry.label = GTK_LABEL(gtk_label_new(label));
00361               gtk_widget_show(GTK_WIDGET(entry->entry.label));
00362               entry->label_sig = g_signal_connect(G_OBJECT(gmi), "notify::label", G_CALLBACK(entry_label_notify), entry->entry.label);
00363        }
00364 
00365        if (entry->entry.label != NULL) {
00366               g_object_ref_sink(entry->entry.label);
00367        }
00368 
00369        if (entry->entry.image != NULL) {
00370               g_object_ref_sink(entry->entry.image);
00371        }
00372 
00373        if (entry->entry.menu != NULL) {
00374               g_object_ref_sink(entry->entry.menu);
00375        }
00376 
00377        entry->sensitive_sig = g_signal_connect(G_OBJECT(gmi), "notify::sensitive", G_CALLBACK(entry_sensitive_notify), entry);
00378        entry->visible_sig = g_signal_connect(G_OBJECT(gmi), "notify::visible", G_CALLBACK(entry_visible_notify), entry);
00379 
00380        g_object_set_data_full(G_OBJECT(gmi), ENTRY_DATA, entry, entry_object_free);
00381 
00382        return;
00383 }
00384 
00385 /* A child item was added to a menu we're watching.  Let's try to integrate it. */
00386 static void
00387 item_inserted_cb (GtkContainer *menu,
00388                   GtkWidget    *widget,
00389                   gint          position,
00390                   gpointer      data)
00391 {
00392        if (g_object_get_data(G_OBJECT(widget), ENTRY_DATA) == NULL) {
00393               entry_on_menuitem(WINDOW_MENU_MODEL(data), GTK_MENU_ITEM(widget));
00394        }
00395 
00396        if (g_object_get_data(G_OBJECT(widget), ENTRY_DATA) != NULL) {
00397               g_signal_emit_by_name(data, WINDOW_MENU_SIGNAL_ENTRY_ADDED, g_object_get_data(G_OBJECT(widget), ENTRY_DATA));
00398        }
00399 
00400        return;
00401 }
00402 
00403 /* A child item was removed from a menu we're watching. */
00404 static void
00405 item_removed_cb (GtkContainer *menu, GtkWidget *widget, gpointer data)
00406 {
00407        g_signal_emit_by_name(data, WINDOW_MENU_SIGNAL_ENTRY_REMOVED, g_object_get_data(G_OBJECT(widget), ENTRY_DATA));
00408        return;
00409 }
00410 
00411 /* Adds the window menu and turns it into a set of IndicatorObjectEntries
00412    that can be used elsewhere */
00413 static void
00414 add_window_menu (WindowMenuModel * menu, GMenuModel * model)
00415 {
00416        menu->priv->win_menu_model = g_object_ref(model);
00417 
00418        menu->priv->win_menu = GTK_MENU(gtk_model_menu_create_menu(model, G_ACTION_OBSERVABLE(menu->priv->action_mux), menu->priv->accel_group));
00419        g_assert(menu->priv->win_menu != NULL);
00420        g_object_ref_sink(menu->priv->win_menu);
00421 
00422        menu->priv->win_menu_insert = g_signal_connect(G_OBJECT (menu->priv->win_menu),
00423               "insert",
00424               G_CALLBACK (item_inserted_cb),
00425               menu);
00426        menu->priv->win_menu_remove = g_signal_connect (G_OBJECT (menu->priv->win_menu),
00427               "remove",
00428               G_CALLBACK (item_removed_cb),
00429               menu);
00430 
00431        GList * children = gtk_container_get_children(GTK_CONTAINER(menu->priv->win_menu));
00432        GList * child;
00433        for (child = children; child != NULL; child = g_list_next(child)) {
00434               GtkMenuItem * gmi = GTK_MENU_ITEM(child->data);
00435 
00436               if (gmi == NULL) {
00437                      continue;
00438               }
00439 
00440               entry_on_menuitem(menu, gmi);
00441        }
00442        g_list_free(children);
00443 
00444        return;
00445 }
00446 
00447 /* Builds the menu model from the window for the application */
00448 WindowMenuModel *
00449 window_menu_model_new (BamfApplication * app, BamfWindow * window)
00450 {
00451        g_return_val_if_fail(BAMF_IS_APPLICATION(app), NULL);
00452        g_return_val_if_fail(BAMF_IS_WINDOW(window), NULL);
00453 
00454        WindowMenuModel * menu = g_object_new(WINDOW_MENU_MODEL_TYPE, NULL);
00455 
00456        menu->priv->xid = bamf_window_get_xid(window);
00457 
00458        gchar *unique_bus_name;
00459        gchar *app_menu_object_path;
00460        gchar *menubar_object_path;
00461        gchar *application_object_path;
00462        gchar *window_object_path;
00463        GDBusConnection *session;
00464 
00465        unique_bus_name = bamf_window_get_utf8_prop (window, "_GTK_UNIQUE_BUS_NAME");
00466 
00467        if (unique_bus_name == NULL) {
00468               /* If this isn't set, we won't get very far... */
00469               return NULL;
00470        }
00471 
00472        app_menu_object_path = bamf_window_get_utf8_prop (window, "_GTK_APP_MENU_OBJECT_PATH");
00473        menubar_object_path = bamf_window_get_utf8_prop (window, "_GTK_MENUBAR_OBJECT_PATH");
00474        application_object_path = bamf_window_get_utf8_prop (window, "_GTK_APPLICATION_OBJECT_PATH");
00475        window_object_path = bamf_window_get_utf8_prop (window, "_GTK_WINDOW_OBJECT_PATH");
00476 
00477        session = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
00478 
00479        /* Setup actions */
00480        if (application_object_path != NULL) {
00481               g_action_muxer_insert(menu->priv->action_mux, ACTION_MUX_PREFIX_APP, G_ACTION_GROUP(g_dbus_action_group_get (session, unique_bus_name, application_object_path)));
00482        }
00483 
00484        if (window_object_path != NULL) {
00485               g_action_muxer_insert(menu->priv->action_mux, ACTION_MUX_PREFIX_WIN, G_ACTION_GROUP(g_dbus_action_group_get (session, unique_bus_name, window_object_path)));
00486        }
00487 
00488        /* Build us some menus */
00489        if (app_menu_object_path != NULL) {
00490               const gchar * desktop_path = bamf_application_get_desktop_file(app);
00491               gchar * app_name = NULL;
00492 
00493               if (desktop_path != NULL) {
00494                      GDesktopAppInfo * desktop = g_desktop_app_info_new_from_filename(desktop_path);
00495 
00496                      if (desktop != NULL) {
00497                             app_name = g_strdup(g_app_info_get_name(G_APP_INFO(desktop)));
00498 
00499                             g_object_unref(desktop);
00500                      }
00501               }
00502 
00503               GMenuModel * model = G_MENU_MODEL(g_dbus_menu_model_get (session, unique_bus_name, app_menu_object_path));
00504 
00505               add_application_menu(menu, app_name, model);
00506 
00507               g_object_unref(model);
00508               g_free(app_name);
00509        }
00510 
00511        if (menubar_object_path != NULL) {
00512               GMenuModel * model = G_MENU_MODEL(g_dbus_menu_model_get (session, unique_bus_name, menubar_object_path));
00513 
00514               add_window_menu(menu, model);
00515 
00516               g_object_unref(model);
00517        }
00518 
00519        /* when the action groups change, we could end up having items
00520         * enabled/disabled.  how to deal with that?
00521         */
00522 
00523        g_free (unique_bus_name);
00524        g_free (app_menu_object_path);
00525        g_free (menubar_object_path);
00526        g_free (application_object_path);
00527        g_free (window_object_path);
00528 
00529        g_object_unref (session);
00530 
00531        return menu;
00532 }
00533 
00534 /* Get the list of entries */
00535 static GList *
00536 get_entries (WindowMenu * wm)
00537 {
00538        g_return_val_if_fail(IS_WINDOW_MENU_MODEL(wm), NULL);
00539        WindowMenuModel * menu = WINDOW_MENU_MODEL(wm);
00540 
00541        GList * ret = NULL;
00542 
00543        if (menu->priv->has_application_menu) {
00544               ret = g_list_append(ret, &menu->priv->application_menu);
00545        }
00546 
00547        if (menu->priv->win_menu != NULL) {
00548               GList * children = gtk_container_get_children(GTK_CONTAINER(menu->priv->win_menu));
00549               GList * child;
00550               for (child = children; child != NULL; child = g_list_next(child)) {
00551                      gpointer entry = g_object_get_data(child->data, ENTRY_DATA);
00552 
00553                      if (entry == NULL) {
00554                             /* Try to build the entry, it is possible (but unlikely) that
00555                                we could beat the signal that this isn't created.  So we'll
00556                                just handle that race here */
00557                             entry_on_menuitem(menu, GTK_MENU_ITEM(child->data));
00558                             entry = g_object_get_data(child->data, ENTRY_DATA);
00559                      }
00560 
00561                      if (entry != NULL) {
00562                             ret = g_list_append(ret, entry);
00563                      }
00564               }
00565 
00566               g_list_free(children);
00567        }
00568 
00569        return ret;
00570 }
00571 
00572 /* Find the location of an entry */
00573 static guint
00574 get_location (WindowMenu * wm, IndicatorObjectEntry * entry)
00575 {
00576        g_return_val_if_fail(IS_WINDOW_MENU_MODEL(wm), 0);
00577        WindowMenuModel * menu = WINDOW_MENU_MODEL(wm);
00578 
00579        gboolean found = FALSE;
00580        guint pos = 0;
00581 
00582        if (menu->priv->has_application_menu) {
00583               if (entry == &menu->priv->application_menu) {
00584                      pos = 0;
00585                      found = TRUE;
00586               } else {
00587                      /* We need to put a shift in if there is an application
00588                         menu and we're not looking for that one */
00589                      pos = 1;
00590               }
00591        }
00592 
00593        if (menu->priv->win_menu != NULL) {
00594               GList * children = gtk_container_get_children(GTK_CONTAINER(menu->priv->win_menu));
00595               GList * child;
00596               for (child = children; child != NULL; child = g_list_next(child), pos++) {
00597                      gpointer lentry = g_object_get_data(child->data, ENTRY_DATA);
00598 
00599                      if (entry == lentry) {
00600                             found = TRUE;
00601                             break;
00602                      }
00603               }
00604 
00605               g_list_free(children);
00606        }
00607 
00608        if (!found) {
00609               /* NOTE: Not printing any of the values here because there's
00610                  a pretty good chance that they're not valid.  Let's not crash
00611                  things here. */
00612               g_warning("Unable to find entry: %p", entry);
00613        }
00614 
00615        return pos;
00616 }
00617 
00618 /* Get's the status of the application to whether underlines should be
00619    shown to the application.  GMenuModel doesn't give us this info. */
00620 static WindowMenuStatus
00621 get_status (WindowMenu * wm)
00622 {
00623        return WINDOW_MENU_STATUS_NORMAL;
00624 }
00625 
00626 /* Says whether the application is in error, GMenuModel doesn't give us this
00627    information on the app */
00628 static gboolean
00629 get_error_state (WindowMenu * wm)
00630 {
00631        return FALSE;
00632 }
00633 
00634 /* Get the XID of this guy */
00635 static guint
00636 get_xid (WindowMenu * wm)
00637 {
00638        g_return_val_if_fail(IS_WINDOW_MENU_MODEL(wm), 0);
00639        return WINDOW_MENU_MODEL(wm)->priv->xid;
00640 }