Back to index

bamf  0.2.120
bamf-application.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2010-2011 Canonical Ltd
00003  *
00004  * This program is free software: you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License version 3 as
00006  * published by the Free Software Foundation.
00007  *
00008  * This program is distributed in the hope that it will be useful,
00009  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  * GNU General Public License for more details.
00012  *
00013  * You should have received a copy of the GNU General Public License
00014  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00015  *
00016  * Authored by: Jason Smith <jason.smith@canonical.com>
00017  *              Marco Trevisan (TreviƱo) <3v1n0@ubuntu.com>
00018  *
00019  */
00020 
00021 #include "bamf-application.h"
00022 #include "bamf-window.h"
00023 #include "bamf-matcher.h"
00024 #include "bamf-indicator.h"
00025 #include "bamf-legacy-window.h"
00026 #include "bamf-legacy-screen.h"
00027 #include <string.h>
00028 #include <gio/gdesktopappinfo.h>
00029 
00030 #define BAMF_APPLICATION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE(obj, \
00031 BAMF_TYPE_APPLICATION, BamfApplicationPrivate))
00032 
00033 static void bamf_application_dbus_application_iface_init (BamfDBusItemApplicationIface *iface);
00034 G_DEFINE_TYPE_WITH_CODE (BamfApplication, bamf_application, BAMF_TYPE_VIEW,
00035                          G_IMPLEMENT_INTERFACE (BAMF_DBUS_ITEM_TYPE_APPLICATION,
00036                                                 bamf_application_dbus_application_iface_init));
00037 
00038 struct _BamfApplicationPrivate
00039 {
00040   BamfDBusItemApplication *dbus_iface;
00041   char * desktop_file;
00042   GList * desktop_file_list;
00043   char * app_type;
00044   char * icon;
00045   char * wmclass;
00046   gboolean is_tab_container;
00047   gboolean show_stubs;
00048 };
00049 
00050 #define STUB_KEY  "X-Ayatana-Appmenu-Show-Stubs"
00051 
00052 static const char *
00053 bamf_application_get_icon (BamfView *view)
00054 {
00055   g_return_val_if_fail (BAMF_IS_APPLICATION (view), NULL);
00056 
00057   return BAMF_APPLICATION (view)->priv->icon;
00058 }
00059 
00060 char *
00061 bamf_application_get_application_type (BamfApplication *application)
00062 {
00063   g_return_val_if_fail (BAMF_IS_APPLICATION (application), NULL);
00064 
00065   return g_strdup (application->priv->app_type);
00066 }
00067 
00068 const char *
00069 bamf_application_get_desktop_file (BamfApplication *application)
00070 {
00071   BamfApplicationPrivate *priv;
00072 
00073   g_return_val_if_fail (BAMF_IS_APPLICATION (application), NULL);
00074   priv = application->priv;
00075 
00076   return priv->desktop_file;
00077 }
00078 
00079 const char *
00080 bamf_application_get_wmclass (BamfApplication *application)
00081 {
00082   BamfApplicationPrivate *priv;
00083 
00084   g_return_val_if_fail (BAMF_IS_APPLICATION (application), NULL);
00085   priv = application->priv;
00086 
00087   return priv->wmclass;
00088 }
00089 
00090 static gboolean
00091 icon_name_is_valid (char *name)
00092 {
00093   GtkIconTheme *icon_theme;
00094 
00095   if (name == NULL)
00096     return FALSE;
00097 
00098   icon_theme = gtk_icon_theme_get_default ();
00099   return gtk_icon_theme_has_icon (icon_theme, name);
00100 }
00101 
00102 static void
00103 bamf_application_setup_icon_and_name (BamfApplication *self)
00104 {
00105   BamfView *view;
00106   BamfWindow *window = NULL;
00107   GDesktopAppInfo *desktop;
00108   GKeyFile * keyfile;
00109   GIcon *gicon;
00110   GList *children, *l;
00111   const char *class;
00112   char *icon = NULL, *name = NULL;
00113   GError *error;
00114 
00115   g_return_if_fail (BAMF_IS_APPLICATION (self));
00116 
00117   if (self->priv->icon && bamf_view_get_name (BAMF_VIEW (self)))
00118     return;
00119 
00120   if (self->priv->desktop_file)
00121     {
00122       keyfile = g_key_file_new();
00123 
00124       if (!g_key_file_load_from_file(keyfile, self->priv->desktop_file, G_KEY_FILE_NONE, NULL))
00125         {
00126           g_key_file_free(keyfile);
00127           return;
00128         }
00129 
00130       desktop = g_desktop_app_info_new_from_keyfile (keyfile);
00131 
00132       if (!G_IS_APP_INFO (desktop))
00133         {
00134           g_key_file_free(keyfile);
00135           return;
00136         }
00137 
00138       gicon = g_app_info_get_icon (G_APP_INFO (desktop));
00139 
00140       name = g_strdup (g_app_info_get_display_name (G_APP_INFO (desktop)));
00141 
00142       if (gicon)
00143         icon = g_icon_to_string (gicon);
00144 
00145       if (g_key_file_has_key(keyfile, G_KEY_FILE_DESKTOP_GROUP, STUB_KEY, NULL))
00146         {
00147           /* This will error to return false, which is okay as it seems
00148              unlikely anyone will want to set this flag except to turn
00149              off the stub menus. */
00150           self->priv->show_stubs = g_key_file_get_boolean (keyfile,
00151                                                            G_KEY_FILE_DESKTOP_GROUP,
00152                                                            STUB_KEY, NULL);
00153         }
00154       
00155       if (g_key_file_has_key (keyfile, G_KEY_FILE_DESKTOP_GROUP, "X-GNOME-FullName", NULL))
00156         {
00157           /* Grab the better name if its available */
00158           gchar *fullname = NULL;
00159           error = NULL; 
00160           fullname = g_key_file_get_locale_string (keyfile,
00161                                                    G_KEY_FILE_DESKTOP_GROUP,
00162                                                    "X-GNOME-FullName", NULL,
00163                                                    &error);
00164           if (error != NULL)
00165             {
00166               g_error_free (error);
00167               if (fullname)
00168                 g_free (fullname);
00169             }
00170           else
00171             {
00172               g_free (name);
00173               name = fullname;
00174             }
00175         }
00176 
00177       g_object_unref (desktop);
00178       g_key_file_free(keyfile);
00179     }
00180   else if ((children = bamf_view_get_children (BAMF_VIEW (self))) != NULL)
00181     {
00182       for (l = children; l && !icon; l = l->next)
00183         {
00184           view = l->data;
00185           if (!BAMF_IS_WINDOW (view))
00186             continue;
00187           
00188           window = BAMF_WINDOW (view);
00189           
00190           do
00191             {
00192               class = bamf_legacy_window_get_class_name (bamf_window_get_window (window));
00193               icon = g_utf8_strdown (class, -1);
00194 
00195               if (icon_name_is_valid (icon))
00196                 break;
00197 
00198               g_free (icon);
00199               icon = bamf_legacy_window_get_exec_string (bamf_window_get_window (window));
00200 
00201               if (icon_name_is_valid (icon))
00202                 break;
00203 
00204               g_free (icon);
00205               icon = NULL;
00206             }
00207           while (FALSE);
00208 
00209           name = g_strdup (bamf_legacy_window_get_name (bamf_window_get_window (window)));
00210         }
00211         
00212       if (!icon)
00213         {
00214           if (window)
00215             {
00216               icon = g_strdup (bamf_legacy_window_save_mini_icon (bamf_window_get_window (window)));
00217             }
00218           
00219           if (!icon)
00220             {
00221               icon = g_strdup ("application-default-icon");
00222             }
00223         }
00224     }
00225   else
00226     {
00227       /* we do nothing as we have nothing to go on */
00228     }
00229 
00230   if (icon)
00231     {
00232       if (self->priv->icon)
00233         g_free (self->priv->icon);
00234 
00235       self->priv->icon = icon;
00236     }
00237 
00238   if (name)
00239     bamf_view_set_name (BAMF_VIEW (self), name);
00240 
00241   g_free (name);
00242 }
00243 
00244 void
00245 bamf_application_set_desktop_file (BamfApplication *application,
00246                                    const char * desktop_file)
00247 {
00248   g_return_if_fail (BAMF_IS_APPLICATION (application));
00249 
00250   if (application->priv->desktop_file)
00251     g_free (application->priv->desktop_file);
00252 
00253   if (desktop_file && desktop_file[0] != '\0')
00254     application->priv->desktop_file = g_strdup (desktop_file);
00255   else
00256     application->priv->desktop_file = NULL;
00257 
00258   bamf_application_setup_icon_and_name (application);
00259 }
00260 
00261 void
00262 bamf_application_set_wmclass (BamfApplication *application,
00263                               const char *wmclass)
00264 {
00265   g_return_if_fail (BAMF_IS_APPLICATION (application));
00266 
00267   if (application->priv->wmclass)
00268     g_free (application->priv->wmclass);
00269 
00270   if (wmclass && wmclass[0] != '\0')
00271     application->priv->wmclass = g_strdup (wmclass);
00272   else
00273     application->priv->wmclass = NULL;
00274 }
00275 
00276 GVariant *
00277 bamf_application_get_xids (BamfApplication *application)
00278 {
00279   GList *l;
00280   GVariantBuilder b;
00281   BamfView *view;
00282   guint32 xid;
00283 
00284   g_return_val_if_fail (BAMF_IS_APPLICATION (application), NULL);
00285 
00286   g_variant_builder_init (&b, G_VARIANT_TYPE ("(au)"));
00287   g_variant_builder_open (&b, G_VARIANT_TYPE ("au"));
00288 
00289   for (l = bamf_view_get_children (BAMF_VIEW (application)); l; l = l->next)
00290     {
00291       view = l->data;
00292 
00293       if (!BAMF_IS_WINDOW (view))
00294         continue;
00295 
00296       xid = bamf_window_get_xid (BAMF_WINDOW (view));
00297       g_variant_builder_add (&b, "u", xid);
00298     }
00299 
00300   g_variant_builder_close (&b);
00301 
00302   return g_variant_builder_end (&b);
00303 }
00304 
00305 gboolean
00306 bamf_application_contains_similar_to_window (BamfApplication *self,
00307                                              BamfWindow *bamf_window)
00308 {
00309   GList *children, *l;
00310   BamfView *child;
00311 
00312   g_return_val_if_fail (BAMF_IS_APPLICATION (self), FALSE);
00313   g_return_val_if_fail (BAMF_IS_WINDOW (bamf_window), FALSE);
00314 
00315   BamfLegacyWindow *window = bamf_window_get_window (bamf_window);
00316   const char *window_class = bamf_legacy_window_get_class_name (window);
00317   const char *instance_name = bamf_legacy_window_get_class_instance_name (window);
00318 
00319   if (!window_class || !instance_name)
00320     return FALSE;
00321 
00322   children = bamf_view_get_children (BAMF_VIEW (self));
00323   for (l = children; l; l = l->next)
00324     {
00325       child = l->data;
00326 
00327       if (!BAMF_IS_WINDOW (child))
00328         continue;
00329 
00330       window = bamf_window_get_window (BAMF_WINDOW (child));
00331       const char *owned_win_class = bamf_legacy_window_get_class_name (window);
00332       const char *owned_instance = bamf_legacy_window_get_class_instance_name (window);
00333 
00334       if (g_strcmp0 (window_class, owned_win_class) == 0 &&
00335           g_strcmp0 (instance_name, owned_instance) == 0)
00336         {
00337           return TRUE;
00338         }
00339     }
00340 
00341   return FALSE;
00342 }
00343 
00344 gboolean
00345 bamf_application_manages_xid (BamfApplication *application,
00346                               guint32 xid)
00347 {
00348   GList *l;
00349   gboolean result = FALSE;
00350 
00351   g_return_val_if_fail (BAMF_IS_APPLICATION (application), FALSE);
00352 
00353   for (l = bamf_view_get_children (BAMF_VIEW (application)); l; l = l->next)
00354     {
00355       BamfView *view = l->data;
00356 
00357       if (!BAMF_IS_WINDOW (view))
00358         continue;
00359 
00360       if (bamf_window_get_xid (BAMF_WINDOW (view)) == xid)
00361         {
00362           result = TRUE;
00363           break;
00364         }
00365     }
00366 
00367   return result;
00368 }
00369 
00370 static const char *
00371 bamf_application_get_view_type (BamfView *view)
00372 {
00373   return "application";
00374 }
00375 
00376 static char *
00377 bamf_application_get_stable_bus_name (BamfView *view)
00378 {
00379   BamfApplication *self;
00380   GList *children, *l;
00381   BamfView *child;
00382 
00383   g_return_val_if_fail (BAMF_IS_APPLICATION (view), NULL);
00384   self = BAMF_APPLICATION (view);
00385 
00386   if (self->priv->desktop_file)
00387     return g_strdup_printf ("application%i", abs (g_str_hash (self->priv->desktop_file)));
00388 
00389   children = bamf_view_get_children (BAMF_VIEW (self));
00390   for (l = children; l; l = l->next)
00391     {
00392       child = l->data;
00393 
00394       if (!BAMF_IS_WINDOW (child))
00395         continue;
00396 
00397       return g_strdup_printf ("application%s", 
00398                               bamf_legacy_window_get_class_name (bamf_window_get_window (BAMF_WINDOW (child))));
00399     }
00400   
00401   return g_strdup_printf ("application%p", view);
00402 }
00403 
00404 static void
00405 bamf_application_ensure_flags (BamfApplication *self)
00406 {
00407   gboolean urgent = FALSE, visible = FALSE, running = FALSE, active = FALSE;
00408   GList *l;
00409   BamfView *view;
00410 
00411   for (l = bamf_view_get_children (BAMF_VIEW (self)); l; l = l->next)
00412     {
00413       view = l->data;
00414 
00415       if (!BAMF_IS_VIEW (view))
00416         continue;
00417 
00418       running = TRUE;
00419       
00420       if (BAMF_IS_INDICATOR (view))
00421         visible = TRUE;
00422 
00423       if (!BAMF_IS_WINDOW (view))
00424         continue;
00425 
00426       if (bamf_view_is_urgent (view))
00427         urgent = TRUE;
00428       if (bamf_view_user_visible (view))
00429         visible = TRUE;
00430       if (bamf_view_is_active (view))
00431         active = TRUE;
00432 
00433       if (urgent && visible && active)
00434         break;
00435     }
00436 
00437   bamf_view_set_urgent       (BAMF_VIEW (self), urgent);
00438   bamf_view_set_user_visible (BAMF_VIEW (self), visible);
00439   bamf_view_set_running      (BAMF_VIEW (self), running);
00440   bamf_view_set_active       (BAMF_VIEW (self), active);
00441 }
00442 
00443 static void
00444 view_active_changed (BamfView *view, gboolean active, BamfApplication *self)
00445 {
00446   bamf_application_ensure_flags (self);
00447 }
00448 
00449 static void
00450 view_urgent_changed (BamfView *view, gboolean urgent, BamfApplication *self)
00451 {
00452   bamf_application_ensure_flags (self);
00453 }
00454 
00455 static void
00456 view_visible_changed (BamfView *view, gboolean visible, BamfApplication *self)
00457 {
00458   bamf_application_ensure_flags (self);
00459 }
00460 
00461 static void
00462 view_exported (BamfView *view, BamfApplication *self)
00463 {
00464   g_signal_emit_by_name (self, "window-added", bamf_view_get_path (view));
00465 }
00466 
00467 static void
00468 bamf_application_child_added (BamfView *view, BamfView *child)
00469 {
00470   BamfApplication *application;
00471 
00472   application = BAMF_APPLICATION (view);
00473 
00474   if (BAMF_IS_WINDOW (child))
00475     {
00476       if (bamf_view_is_on_bus (child))
00477         g_signal_emit_by_name (BAMF_APPLICATION (view), "window-added", bamf_view_get_path (child));
00478       else
00479         g_signal_connect (G_OBJECT (child), "exported",
00480                           (GCallback) view_exported, view);
00481     }
00482 
00483   g_signal_connect (G_OBJECT (child), "active-changed",
00484                     (GCallback) view_active_changed, view);
00485   g_signal_connect (G_OBJECT (child), "urgent-changed",
00486                     (GCallback) view_urgent_changed, view);
00487   g_signal_connect (G_OBJECT (child), "user-visible-changed",
00488                     (GCallback) view_visible_changed, view);
00489 
00490   bamf_application_ensure_flags (BAMF_APPLICATION (view));
00491 
00492   bamf_application_setup_icon_and_name (application);
00493 }
00494 
00495 static char *
00496 bamf_application_favorite_from_list (BamfApplication *self, GList *desktop_list)
00497 {
00498   BamfMatcher *matcher;
00499   GList *favs, *l;
00500   char *result = NULL;
00501   const char *desktop_class;
00502 
00503   g_return_val_if_fail (BAMF_IS_APPLICATION (self), NULL);
00504 
00505   matcher = bamf_matcher_get_default ();
00506   favs = bamf_matcher_get_favorites (matcher);
00507   
00508   if (favs)
00509     {
00510       for (l = favs; l; l = l->next)
00511         {
00512           if (g_list_find_custom (desktop_list, l->data, (GCompareFunc) g_strcmp0))
00513             {
00514               desktop_class = bamf_matcher_get_desktop_file_class (matcher, l->data);
00515 
00516               if (!desktop_class || g_strcmp0 (self->priv->wmclass, desktop_class) == 0)
00517                 {
00518                   result = l->data;
00519                   break;
00520                 }
00521             }
00522         }
00523     }
00524 
00525   return result;
00526 }
00527 
00528 static void
00529 bamf_application_set_desktop_file_from_list (BamfApplication *self, GList *list)
00530 {
00531   BamfApplicationPrivate *priv;
00532   GList *l;
00533   char *desktop_file;
00534 
00535   g_return_if_fail (BAMF_IS_APPLICATION (self));
00536   g_return_if_fail (list);
00537 
00538   priv = self->priv;
00539 
00540   if (priv->desktop_file_list)
00541     {
00542       g_list_free_full (priv->desktop_file_list, g_free);
00543       priv->desktop_file_list = NULL;
00544     }
00545 
00546   for (l = list; l; l = l->next)
00547     priv->desktop_file_list = g_list_prepend (priv->desktop_file_list, g_strdup (l->data));
00548 
00549   priv->desktop_file_list = g_list_reverse (priv->desktop_file_list);
00550 
00551   desktop_file = bamf_application_favorite_from_list (self, priv->desktop_file_list);
00552   
00553   /* items, after reversing them, are in priority order */
00554   if (!desktop_file)
00555     desktop_file = list->data;
00556 
00557   bamf_application_set_desktop_file (self, desktop_file);
00558 }
00559 
00560 static void
00561 bamf_application_child_removed (BamfView *view, BamfView *child)
00562 {
00563   if (BAMF_IS_WINDOW (child))
00564     {
00565       if (bamf_view_is_on_bus (child))
00566         g_signal_emit_by_name (BAMF_APPLICATION (view), "window-removed",
00567                                bamf_view_get_path (child));
00568     }
00569 
00570   g_signal_handlers_disconnect_by_func (G_OBJECT (child), view_active_changed, view);
00571   g_signal_handlers_disconnect_by_func (G_OBJECT (child), view_urgent_changed, view);
00572   g_signal_handlers_disconnect_by_func (G_OBJECT (child), view_visible_changed, view);
00573 
00574   bamf_application_ensure_flags (BAMF_APPLICATION (view));
00575 
00576   if (bamf_view_get_children (view) == NULL)
00577     {
00578       bamf_view_close (view);
00579     }
00580 }
00581 
00582 static void
00583 matcher_favorites_changed (BamfMatcher *matcher, BamfApplication *self)
00584 {
00585   char *new_desktop_file = NULL;
00586   
00587   g_return_if_fail (BAMF_IS_APPLICATION (self));
00588   g_return_if_fail (BAMF_IS_MATCHER (matcher));
00589   
00590   new_desktop_file = bamf_application_favorite_from_list (self, self->priv->desktop_file_list);
00591 
00592   if (new_desktop_file)
00593     {
00594       bamf_application_set_desktop_file (self, new_desktop_file);
00595     }
00596 }
00597 
00598 static void
00599 on_window_added (BamfApplication *self, const gchar *win_path, gpointer _not_used)
00600 {
00601   g_return_if_fail (BAMF_IS_APPLICATION (self));
00602   g_signal_emit_by_name (self->priv->dbus_iface, "window-added", win_path);
00603 }
00604 
00605 static void
00606 on_window_removed (BamfApplication *self, const gchar *win_path, gpointer _not_used)
00607 {
00608   g_return_if_fail (BAMF_IS_APPLICATION (self));
00609   g_signal_emit_by_name (self->priv->dbus_iface, "window-removed", win_path);
00610 }
00611 
00612 static gboolean
00613 on_dbus_handle_show_stubs (BamfDBusItemApplication *interface,
00614                            GDBusMethodInvocation *invocation,
00615                            BamfApplication *self)
00616 {
00617   gboolean show_stubs = bamf_application_get_show_stubs (self);
00618   g_dbus_method_invocation_return_value (invocation,
00619                                          g_variant_new ("(b)", show_stubs));
00620 
00621   return TRUE;
00622 }
00623 
00624 static gboolean
00625 on_dbus_handle_xids (BamfDBusItemApplication *interface,
00626                      GDBusMethodInvocation *invocation,
00627                      BamfApplication *self)
00628 {
00629   GVariant *xids = bamf_application_get_xids (self);
00630   g_dbus_method_invocation_return_value (invocation, xids);
00631 
00632   return TRUE;
00633 }
00634 
00635 static gboolean
00636 on_dbus_handle_desktop_file (BamfDBusItemApplication *interface,
00637                              GDBusMethodInvocation *invocation,
00638                              BamfApplication *self)
00639 {
00640   const char *desktop_file = self->priv->desktop_file ? self->priv->desktop_file : "";
00641   g_dbus_method_invocation_return_value (invocation,
00642                                          g_variant_new ("(s)", desktop_file));
00643 
00644   return TRUE;
00645 }
00646 
00647 static gboolean
00648 on_dbus_handle_application_type (BamfDBusItemApplication *interface,
00649                                  GDBusMethodInvocation *invocation,
00650                                  BamfApplication *self)
00651 {
00652   const char *type = self->priv->app_type ? self->priv->app_type : "";
00653   g_dbus_method_invocation_return_value (invocation,
00654                                          g_variant_new ("(s)", type));
00655 
00656   return TRUE;
00657 }
00658 
00659 static void
00660 bamf_application_dispose (GObject *object)
00661 {
00662   BamfApplication *app;
00663   BamfApplicationPrivate *priv;
00664 
00665   app = BAMF_APPLICATION (object);
00666   priv = app->priv;
00667 
00668   if (priv->desktop_file)
00669     {
00670       g_free (priv->desktop_file);
00671       priv->desktop_file = NULL;
00672     }
00673     
00674   if (priv->desktop_file_list)
00675     {
00676       g_list_free_full (priv->desktop_file_list, g_free);
00677       priv->desktop_file_list = NULL;
00678     }
00679 
00680   if (priv->app_type)
00681     {
00682       g_free (priv->app_type);
00683       priv->app_type = NULL;
00684     }
00685 
00686   if (priv->icon)
00687     {
00688       g_free (priv->icon);
00689       priv->icon = NULL;
00690     }
00691 
00692   if (priv->wmclass)
00693     {
00694       g_free (priv->wmclass);
00695       priv->wmclass = NULL;
00696     }
00697 
00698   g_signal_handlers_disconnect_by_func (G_OBJECT (bamf_matcher_get_default ()),
00699                                         matcher_favorites_changed, object);
00700 
00701   G_OBJECT_CLASS (bamf_application_parent_class)->dispose (object);
00702 }
00703 
00704 static void
00705 bamf_application_finalize (GObject *object)
00706 {
00707   BamfApplication *self;
00708   self = BAMF_APPLICATION (object);
00709 
00710   g_object_unref (self->priv->dbus_iface);
00711 
00712   G_OBJECT_CLASS (bamf_application_parent_class)->finalize (object);
00713 }
00714 
00715 static void
00716 bamf_application_init (BamfApplication * self)
00717 {
00718   BamfApplicationPrivate *priv;
00719   priv = self->priv = BAMF_APPLICATION_GET_PRIVATE (self);
00720 
00721   priv->is_tab_container = FALSE;
00722   priv->app_type = g_strdup ("system");
00723   priv->show_stubs = TRUE;
00724   priv->wmclass = NULL;
00725 
00726   /* Initializing the dbus interface */
00727   priv->dbus_iface = bamf_dbus_item_application_skeleton_new ();
00728 
00729   /* We need to connect to the object own signals to redirect them to the dbus
00730    * interface                                                                */
00731   g_signal_connect (self, "window-added", G_CALLBACK (on_window_added), NULL);
00732   g_signal_connect (self, "window-removed", G_CALLBACK (on_window_removed), NULL);
00733 
00734   /* Registering signal callbacks to reply to dbus method calls */
00735   g_signal_connect (priv->dbus_iface, "handle-show-stubs",
00736                     G_CALLBACK (on_dbus_handle_show_stubs), self);
00737 
00738   g_signal_connect (priv->dbus_iface, "handle-xids",
00739                     G_CALLBACK (on_dbus_handle_xids), self);
00740 
00741   g_signal_connect (priv->dbus_iface, "handle-desktop-file",
00742                     G_CALLBACK (on_dbus_handle_desktop_file), self);
00743 
00744   g_signal_connect (priv->dbus_iface, "handle-application-type",
00745                     G_CALLBACK (on_dbus_handle_application_type), self);
00746 
00747   /* Setting the interface for the dbus object */
00748   bamf_dbus_item_object_skeleton_set_application (BAMF_DBUS_ITEM_OBJECT_SKELETON (self),
00749                                                   priv->dbus_iface);
00750 
00751   g_signal_connect (G_OBJECT (bamf_matcher_get_default ()), "favorites-changed", 
00752                     (GCallback) matcher_favorites_changed, self);
00753 }
00754 
00755 static void
00756 bamf_application_dbus_application_iface_init (BamfDBusItemApplicationIface *iface)
00757 {
00758 }
00759 
00760 static void
00761 bamf_application_class_init (BamfApplicationClass * klass)
00762 {
00763   GObjectClass *object_class = G_OBJECT_CLASS (klass);
00764   BamfViewClass *view_class = BAMF_VIEW_CLASS (klass);
00765 
00766   object_class->dispose = bamf_application_dispose;
00767   object_class->finalize = bamf_application_finalize;
00768 
00769   view_class->view_type = bamf_application_get_view_type;
00770   view_class->child_added = bamf_application_child_added;
00771   view_class->child_removed = bamf_application_child_removed;
00772   view_class->get_icon = bamf_application_get_icon;
00773   view_class->stable_bus_name = bamf_application_get_stable_bus_name;
00774 
00775   g_type_class_add_private (klass, sizeof (BamfApplicationPrivate));
00776 }
00777 
00778 BamfApplication *
00779 bamf_application_new (void)
00780 {
00781   BamfApplication *application;
00782   application = (BamfApplication *) g_object_new (BAMF_TYPE_APPLICATION, NULL);
00783 
00784   return application;
00785 }
00786 
00787 BamfApplication *
00788 bamf_application_new_from_desktop_file (const char * desktop_file)
00789 {
00790   BamfApplication *application;
00791   application = (BamfApplication *) g_object_new (BAMF_TYPE_APPLICATION, NULL);
00792 
00793   bamf_application_set_desktop_file (application, desktop_file);
00794 
00795   return application;
00796 }
00797 
00798 BamfApplication *
00799 bamf_application_new_from_desktop_files (GList *desktop_files)
00800 {
00801   BamfApplication *application;
00802   application = (BamfApplication *) g_object_new (BAMF_TYPE_APPLICATION, NULL);
00803   
00804   bamf_application_set_desktop_file_from_list (application, desktop_files);
00805   
00806   return application;  
00807 }
00808 
00809 BamfApplication *
00810 bamf_application_new_with_wmclass (const char *wmclass)
00811 {
00812   BamfApplication *application;
00813   application = (BamfApplication *) g_object_new (BAMF_TYPE_APPLICATION, NULL);
00814 
00815   bamf_application_set_wmclass (application, wmclass);
00816 
00817   return application;
00818 }
00819 
00831 gboolean
00832 bamf_application_get_show_stubs (BamfApplication *application)
00833 {
00834     g_return_val_if_fail(BAMF_IS_APPLICATION(application), TRUE);
00835     return application->priv->show_stubs;
00836 }