Back to index

bamf  0.2.120
bamf-view.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2010 Canonical Ltd.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of either or both of the following licenses:
00006  *
00007  * 1) the GNU Lesser General Public License version 3, as published by the
00008  * Free Software Foundation; and/or
00009  * 2) the GNU Lesser General Public License version 2.1, as published by
00010  * the Free Software Foundation.
00011  *
00012  * This program is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranties of
00014  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00015  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00016  * License for more details.
00017  *
00018  * You should have received a copy of both the GNU Lesser General Public
00019  * License version 3 and version 2.1 along with this program.  If not, see
00020  * <http://www.gnu.org/licenses/>
00021  *
00022  * Authored by: Jason Smith <jason.smith@canonical.com>
00023  *              Neil Jagdish Patel <neil.patel@canonical.com>
00024  *
00025  */
00033 #if HAVE_CONFIG_H
00034 #include <config.h>
00035 #endif
00036 
00037 #include "bamf-view.h"
00038 #include "bamf-view-private.h"
00039 #include "bamf-factory.h"
00040 #include "bamf-window.h"
00041 #include "bamf-marshal.h"
00042 
00043 #include <dbus/dbus.h>
00044 #include <dbus/dbus-glib.h>
00045 #include <dbus/dbus-glib-lowlevel.h>
00046 
00047 G_DEFINE_TYPE (BamfView, bamf_view, G_TYPE_INITIALLY_UNOWNED);
00048 
00049 #define BAMF_VIEW_GET_PRIVATE(o) \
00050   (G_TYPE_INSTANCE_GET_PRIVATE ((o), BAMF_TYPE_VIEW, BamfViewPrivate))
00051 
00052 enum
00053 {
00054   BAMF_VIEW_RUNNING_FLAG = 1 << 0,
00055   BAMF_VIEW_URGENT_FLAG  = 1 << 1,
00056   BAMF_VIEW_VISIBLE_FLAG = 1 << 2,
00057   BAMF_VIEW_ACTIVE_FLAG  = 1 << 3,
00058 };
00059 
00060 enum
00061 {
00062   ACTIVE_CHANGED,
00063   CLOSED,
00064   CHILD_ADDED,
00065   CHILD_REMOVED,
00066   RUNNING_CHANGED,
00067   URGENT_CHANGED,
00068   VISIBLE_CHANGED,
00069   NAME_CHANGED,
00070 
00071   LAST_SIGNAL,
00072 };
00073 
00074 enum
00075 {
00076   PROP_0,
00077 
00078   PROP_PATH,
00079   PROP_RUNNING,
00080   PROP_ACTIVE,
00081   PROP_USER_VISIBLE,
00082   PROP_URGENT,
00083 };
00084 
00085 static guint view_signals[LAST_SIGNAL] = { 0 };
00086 
00087 struct _BamfViewPrivate
00088 {
00089   DBusGConnection *connection;
00090   DBusGProxy      *proxy;
00091   gchar           *path;
00092   gchar           *type;
00093   gchar           *local_icon;
00094   gchar           *local_name;
00095   guint            checked_flags;
00096   guint            set_flags;
00097   gboolean         is_closed;
00098   gboolean         sticky;
00099   GList           *cached_children;
00100 };
00101 
00102 static void bamf_view_unset_proxy (BamfView *self);
00103 
00104 static void
00105 bamf_view_set_flag (BamfView *view, guint flag, gboolean value)
00106 {
00107   BamfViewPrivate *priv;
00108   
00109   g_return_if_fail (BAMF_IS_VIEW (view));
00110   
00111   priv = view->priv;
00112   
00113   if (value)
00114     priv->set_flags |= flag;
00115   else
00116     priv->set_flags &= ~flag;
00117   
00118   priv->checked_flags |= flag;
00119 }
00120 
00121 static gboolean
00122 bamf_view_flag_is_set (BamfView *view, guint flag)
00123 {
00124   BamfViewPrivate *priv;
00125   
00126   g_return_val_if_fail (BAMF_IS_VIEW (view), FALSE);
00127   
00128   priv = view->priv;
00129   
00130   return priv->checked_flags & flag;
00131 }
00132 
00133 static gboolean
00134 bamf_view_get_flag (BamfView *view, guint flag)
00135 {
00136   BamfViewPrivate *priv;
00137   
00138   g_return_val_if_fail (BAMF_IS_VIEW (view), FALSE);
00139   
00140   priv = view->priv;
00141   
00142   return priv->set_flags & flag;
00143 }
00144 
00145 GList *
00146 bamf_view_get_children (BamfView *view)
00147 {
00148   char ** children;
00149   int i, len;
00150   GList *results = NULL;
00151   GError *error = NULL;
00152   BamfViewPrivate *priv;
00153 
00154   g_return_val_if_fail (BAMF_IS_VIEW (view), NULL);
00155 
00156   if (BAMF_VIEW_GET_CLASS (view)->get_children)
00157     return BAMF_VIEW_GET_CLASS (view)->get_children (view);
00158 
00159   if (!_bamf_view_remote_ready (view))
00160     return NULL;
00161 
00162   priv = view->priv;
00163 
00164   if (priv->cached_children)
00165     return g_list_copy (priv->cached_children);
00166 
00167   if (!dbus_g_proxy_call (priv->proxy,
00168                           "Children",
00169                           &error,
00170                           G_TYPE_INVALID,
00171                           G_TYPE_STRV, &children,
00172                           G_TYPE_INVALID))
00173     {
00174       g_warning ("Unable to fetch children: %s\n", error->message);
00175       g_error_free (error);
00176       return NULL;
00177     }
00178 
00179   if (!children)
00180     return NULL;
00181 
00182   len = g_strv_length (children);
00183 
00184   for (i = len-1; i >= 0; i--)
00185     {
00186       view = _bamf_factory_view_for_path (_bamf_factory_get_default (), children[i]);
00187       results = g_list_prepend (results, g_object_ref (view));
00188     }
00189 
00190   priv->cached_children = results;
00191   return g_list_copy (priv->cached_children);
00192 }
00193 
00194 static gboolean
00195 bamf_view_get_boolean (BamfView *self, const char *method_name, guint flag)
00196 {
00197   BamfViewPrivate *priv;
00198   gboolean result = FALSE;
00199   GError *error = NULL;
00200 
00201   g_return_val_if_fail (BAMF_IS_VIEW (self), FALSE);
00202   priv = self->priv;
00203 
00204   if (bamf_view_flag_is_set (self, flag))
00205     return bamf_view_get_flag (self, flag);
00206 
00207   if (!_bamf_view_remote_ready (self))
00208     return FALSE;
00209 
00210   if (!dbus_g_proxy_call (priv->proxy,
00211                           method_name,
00212                           &error,
00213                           G_TYPE_INVALID,
00214                           G_TYPE_BOOLEAN, &result,
00215                           G_TYPE_INVALID))
00216     {
00217       g_warning ("Failed to fetch boolean: %s", error->message);
00218       g_error_free (error);
00219 
00220       return FALSE;
00221     }
00222 
00223   bamf_view_set_flag (self, flag, result);
00224   return result;
00225 }
00226 
00227 gboolean
00228 bamf_view_is_closed (BamfView *view)
00229 {
00230   g_return_val_if_fail (BAMF_IS_VIEW (view), TRUE);
00231 
00232   return view->priv->is_closed;
00233 }
00234 
00235 gboolean
00236 bamf_view_is_active (BamfView *view)
00237 {
00238   g_return_val_if_fail (BAMF_IS_VIEW (view), FALSE);
00239 
00240   if (BAMF_VIEW_GET_CLASS (view)->is_active)
00241     return BAMF_VIEW_GET_CLASS (view)->is_active (view);
00242 
00243   return bamf_view_get_boolean (view, "IsActive", BAMF_VIEW_ACTIVE_FLAG);
00244 
00245 }
00246 
00247 gboolean          
00248 bamf_view_user_visible (BamfView *self)
00249 {
00250   g_return_val_if_fail (BAMF_IS_VIEW (self), FALSE);
00251   
00252   return bamf_view_get_boolean (self, "UserVisible", BAMF_VIEW_VISIBLE_FLAG);
00253 
00254 }
00255 
00256 gboolean
00257 bamf_view_is_running (BamfView *self)
00258 {
00259   g_return_val_if_fail (BAMF_IS_VIEW (self), FALSE);
00260   
00261   if (BAMF_VIEW_GET_CLASS (self)->is_running)
00262     return BAMF_VIEW_GET_CLASS (self)->is_running (self);
00263 
00264   return bamf_view_get_boolean (self, "IsRunning", BAMF_VIEW_RUNNING_FLAG);
00265 }
00266 
00267 gboolean
00268 bamf_view_is_urgent (BamfView *self)
00269 {
00270   g_return_val_if_fail (BAMF_IS_VIEW (self), FALSE);
00271   
00272   if (BAMF_VIEW_GET_CLASS (self)->is_urgent)
00273     return BAMF_VIEW_GET_CLASS (self)->is_urgent (self);
00274 
00275   return bamf_view_get_boolean (self, "IsUrgent", BAMF_VIEW_URGENT_FLAG);
00276 }
00277 
00278 void
00279 _bamf_view_set_name (BamfView *view, const char *name)
00280 {
00281   g_return_if_fail (BAMF_IS_VIEW (view));
00282   
00283   if (!g_strcmp0 (name, view->priv->local_name))
00284     return;
00285 
00286   g_free (view->priv->local_name);
00287 
00288   if (name && name[0] == '\0')
00289     {
00290       view->priv->local_name = NULL;
00291     }
00292   else
00293     {
00294       view->priv->local_name = g_strdup (name);
00295     }
00296 }
00297 
00298 void
00299 _bamf_view_set_icon (BamfView *view, const char *icon)
00300 {
00301   g_return_if_fail (BAMF_IS_VIEW (view));
00302 
00303   g_free (view->priv->local_icon);
00304 
00305   if (icon && icon[0] == '\0')
00306     {
00307       view->priv->local_icon = NULL;
00308     }
00309   else
00310     {
00311       view->priv->local_icon = g_strdup (icon);
00312     }
00313 }
00314 
00315 gboolean 
00316 bamf_view_is_sticky (BamfView *view)
00317 {
00318   g_return_val_if_fail (BAMF_IS_VIEW (view), FALSE);
00319   
00320   return view->priv->sticky;
00321 }
00322 
00323 void 
00324 bamf_view_set_sticky (BamfView *view, gboolean value)
00325 {
00326   g_return_if_fail (BAMF_IS_VIEW (view));
00327   
00328   if (value == view->priv->sticky)
00329     return;
00330 
00331   view->priv->sticky = value;
00332   
00333   if (value)
00334     g_object_ref_sink (view);
00335   else
00336     g_object_unref (view);
00337 }
00338 
00339 gchar *
00340 bamf_view_get_icon (BamfView *self)
00341 {
00342   BamfViewPrivate *priv;
00343   char *icon = NULL;
00344   GError *error = NULL;
00345 
00346   g_return_val_if_fail (BAMF_IS_VIEW (self), NULL);
00347   priv = self->priv;
00348   
00349   if (BAMF_VIEW_GET_CLASS (self)->get_icon)
00350     return BAMF_VIEW_GET_CLASS (self)->get_icon (self);
00351 
00352   if (!_bamf_view_remote_ready (self))
00353     return g_strdup (priv->local_icon);
00354 
00355   if (!dbus_g_proxy_call (priv->proxy,
00356                           "Icon",
00357                           &error,
00358                           G_TYPE_INVALID,
00359                           G_TYPE_STRING, &icon,
00360                           G_TYPE_INVALID))
00361     {
00362       g_warning ("Failed to fetch icon: %s", error->message);
00363       g_error_free (error);
00364       
00365       return NULL;
00366     }
00367 
00368   if (icon && icon[0] == '\0')
00369     {
00370       g_free (icon);
00371       return NULL;
00372     }
00373 
00374   return icon;
00375 }
00376 
00377 gchar *
00378 bamf_view_get_name (BamfView *self)
00379 {
00380   BamfViewPrivate *priv;
00381   char *name = NULL;
00382   GError *error = NULL;
00383 
00384   g_return_val_if_fail (BAMF_IS_VIEW (self), NULL);
00385   priv = self->priv;
00386   
00387   if (BAMF_VIEW_GET_CLASS (self)->get_name)
00388     return BAMF_VIEW_GET_CLASS (self)->get_name (self);
00389 
00390   if (!_bamf_view_remote_ready (self))
00391     return g_strdup (priv->local_name);
00392     
00393   if (!dbus_g_proxy_call (priv->proxy,
00394                           "Name",
00395                           &error,
00396                           G_TYPE_INVALID,
00397                           G_TYPE_STRING, &name,
00398                           G_TYPE_INVALID))
00399     {
00400       g_warning ("Failed to fetch name: %s", error->message);
00401       g_error_free (error);
00402       
00403       return NULL;
00404     }
00405 
00406   if (name && name[0] == '\0')
00407     {
00408       g_free (name);
00409       return NULL;
00410     }
00411 
00412   return name;
00413 }
00414 
00415 gboolean 
00416 _bamf_view_remote_ready (BamfView *view)
00417 {
00418   if (BAMF_IS_VIEW (view) && view->priv->proxy)
00419     return !view->priv->is_closed;
00420 
00421   return FALSE;
00422 }
00423 
00424 const gchar *
00425 bamf_view_get_view_type (BamfView *self)
00426 {
00427   BamfViewPrivate *priv;
00428   char *type = NULL;
00429   GError *error = NULL;
00430 
00431   g_return_val_if_fail (BAMF_IS_VIEW (self), NULL);
00432   priv = self->priv;
00433   
00434   if (BAMF_VIEW_GET_CLASS (self)->view_type)
00435     return BAMF_VIEW_GET_CLASS (self)->view_type (self);
00436   
00437   if (priv->type)
00438     return priv->type;
00439 
00440   if (!dbus_g_proxy_call (priv->proxy,
00441                           "ViewType",
00442                           &error,
00443                           G_TYPE_INVALID,
00444                           G_TYPE_STRING, &type,
00445                           G_TYPE_INVALID))
00446     {
00447       g_warning ("Failed to fetch view type at %s: %s", dbus_g_proxy_get_path (priv->proxy), error ? error->message : "");
00448       g_error_free (error);
00449       return NULL;
00450     }
00451 
00452   priv->type = type;
00453   return type;
00454 }
00455 
00456 BamfClickBehavior 
00457 bamf_view_get_click_suggestion (BamfView *self)
00458 {
00459   g_return_val_if_fail (BAMF_IS_VIEW (self), BAMF_CLICK_BEHAVIOR_NONE);
00460 
00461   if (BAMF_VIEW_GET_CLASS (self)->click_behavior)
00462     return BAMF_VIEW_GET_CLASS (self)->click_behavior (self);
00463     
00464   return BAMF_CLICK_BEHAVIOR_NONE;
00465 }
00466 
00467 static void
00468 bamf_view_on_child_added (DBusGProxy *proxy, char *path, BamfView *self)
00469 {
00470   BamfView *view;
00471   BamfViewPrivate *priv;
00472 
00473   view = _bamf_factory_view_for_path (_bamf_factory_get_default (), path);
00474   priv = self->priv;
00475 
00476   if (priv->cached_children)
00477     {
00478       g_list_free_full (priv->cached_children, g_object_unref);
00479       priv->cached_children = NULL;
00480     }
00481 
00482   g_signal_emit (G_OBJECT (self), view_signals[CHILD_ADDED], 0, view);
00483 }
00484 
00485 static void
00486 bamf_view_on_child_removed (DBusGProxy *proxy, char *path, BamfView *self)
00487 {
00488   BamfView *view;
00489   BamfViewPrivate *priv;
00490   view = _bamf_factory_view_for_path (_bamf_factory_get_default (), path);
00491   priv = self->priv;
00492 
00493   if (priv->cached_children)
00494     {
00495       g_list_free_full (priv->cached_children, g_object_unref);
00496       priv->cached_children = NULL;
00497     }
00498 
00499   g_signal_emit (G_OBJECT (self), view_signals[CHILD_REMOVED], 0, view);
00500 }
00501 
00502 static void
00503 bamf_view_on_active_changed (DBusGProxy *proxy, gboolean active, BamfView *self)
00504 {
00505   bamf_view_set_flag (self, BAMF_VIEW_ACTIVE_FLAG, active);
00506 
00507   g_signal_emit (G_OBJECT(self), view_signals[ACTIVE_CHANGED], 0, active);
00508   g_object_notify (G_OBJECT (self), "active");
00509 }
00510 
00511 static void
00512 bamf_view_on_name_changed (DBusGProxy*  proxy,
00513                            const gchar* old_name,
00514                            const gchar* new_name,
00515                            BamfView*    self)
00516 {
00517   g_free (self->priv->local_name);
00518   self->priv->local_name = g_strdup (new_name);
00519 
00520   g_signal_emit (self, view_signals[NAME_CHANGED], 0, old_name, new_name);
00521 }
00522 
00523 static void
00524 bamf_view_on_running_changed (DBusGProxy *proxy, gboolean running, BamfView *self)
00525 {
00526   bamf_view_set_flag (self, BAMF_VIEW_RUNNING_FLAG, running);
00527 
00528   g_signal_emit (G_OBJECT (self), view_signals[RUNNING_CHANGED], 0, running);
00529   g_object_notify (G_OBJECT (self), "running");
00530 }
00531 
00532 static void
00533 bamf_view_on_urgent_changed (DBusGProxy *proxy, gboolean urgent, BamfView *self)
00534 {
00535   bamf_view_set_flag (self, BAMF_VIEW_URGENT_FLAG, urgent);
00536 
00537   g_signal_emit (G_OBJECT (self), view_signals[URGENT_CHANGED], 0, urgent);
00538   g_object_notify (G_OBJECT (self), "urgent");
00539 }
00540 
00541 static void
00542 bamf_view_on_user_visible_changed (DBusGProxy *proxy, gboolean visible, BamfView *self)
00543 {
00544   bamf_view_set_flag (self, BAMF_VIEW_VISIBLE_FLAG, visible);
00545 
00546   g_signal_emit (G_OBJECT (self), view_signals[VISIBLE_CHANGED], 0, visible);
00547   g_object_notify (G_OBJECT (self), "user-visible");
00548 }
00549 
00550 static void
00551 on_view_proxy_destroyed (GObject *proxy, gpointer user_data)
00552 {
00553   BamfView *view = user_data;
00554   g_return_if_fail (BAMF_IS_VIEW (view));
00555 
00556   view->priv->checked_flags = 0x0;
00557   view->priv->proxy = NULL;
00558 
00559   g_free (view->priv->path);
00560   view->priv->path = NULL;
00561 }
00562 
00563 void
00564 _bamf_view_set_closed (BamfView *view, gboolean closed)
00565 {
00566   BamfViewPrivate *priv;
00567   g_return_if_fail (BAMF_IS_VIEW (view));
00568 
00569   priv = view->priv;
00570 
00571   if (priv->is_closed != closed)
00572     {
00573       priv->is_closed = closed;
00574 
00575       if (closed && priv->cached_children)
00576         {
00577           g_list_free_full (priv->cached_children, g_object_unref);
00578           priv->cached_children = NULL;
00579         }
00580     }
00581 }
00582 
00583 static void
00584 bamf_view_on_closed (DBusGProxy *proxy, BamfView *self)
00585 {
00586   _bamf_view_set_closed (self, TRUE);
00587 
00588   g_object_ref (self);
00589   g_signal_emit (G_OBJECT (self), view_signals[CLOSED], 0);
00590   g_object_unref (self);
00591 }
00592 
00593 static void
00594 bamf_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
00595 {
00596   switch (property_id)
00597     {
00598       default:
00599         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
00600     }
00601 }
00602 
00603 static void
00604 bamf_view_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
00605 {
00606   BamfView *self;
00607 
00608   self = BAMF_VIEW (object);
00609 
00610   switch (property_id)
00611     {
00612       case PROP_PATH:
00613         g_value_set_string (value, self->priv->is_closed ? NULL : self->priv->path);
00614         break;
00615       
00616       case PROP_ACTIVE:
00617         g_value_set_boolean (value, bamf_view_is_active (self));
00618         break;
00619       
00620       case PROP_RUNNING:
00621         g_value_set_boolean (value, bamf_view_is_running (self));
00622         break;
00623       
00624       case PROP_URGENT:
00625         g_value_set_boolean (value, bamf_view_is_urgent (self));
00626         break;
00627       
00628       case PROP_USER_VISIBLE:
00629         g_value_set_boolean (value, bamf_view_user_visible (self));
00630         break;
00631       
00632       default:
00633         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
00634     }
00635 }
00636 
00637 static void
00638 bamf_view_unset_proxy (BamfView *self)
00639 {
00640   BamfViewPrivate *priv;
00641 
00642   g_return_if_fail (BAMF_IS_VIEW (self));
00643   priv = self->priv;
00644 
00645   if (!priv->proxy)
00646     return;
00647 
00648   dbus_g_proxy_disconnect_signal (priv->proxy,
00649                                   "ActiveChanged",
00650                                   (GCallback) bamf_view_on_active_changed,
00651                                   self);
00652 
00653   dbus_g_proxy_disconnect_signal (priv->proxy,
00654                                   "Closed",
00655                                   (GCallback) bamf_view_on_closed,
00656                                   self);
00657 
00658   dbus_g_proxy_disconnect_signal (priv->proxy,
00659                                   "ChildAdded",
00660                                   (GCallback) bamf_view_on_child_added,
00661                                   self);
00662 
00663   dbus_g_proxy_disconnect_signal (priv->proxy,
00664                                   "ChildRemoved",
00665                                   (GCallback) bamf_view_on_child_removed,
00666                                   self);
00667 
00668   dbus_g_proxy_disconnect_signal (priv->proxy,
00669                                   "RunningChanged",
00670                                   (GCallback) bamf_view_on_running_changed,
00671                                   self);
00672 
00673   dbus_g_proxy_disconnect_signal (priv->proxy,
00674                                  "UrgentChanged",
00675                                  (GCallback) bamf_view_on_urgent_changed,
00676                                  self);
00677 
00678   dbus_g_proxy_disconnect_signal (priv->proxy,
00679                                  "UserVisibleChanged",
00680                                  (GCallback) bamf_view_on_user_visible_changed,
00681                                  self);
00682 
00683   g_signal_handlers_disconnect_by_func (priv->proxy, on_view_proxy_destroyed, self);
00684   g_object_unref (priv->proxy);
00685   priv->proxy = NULL;
00686 }
00687 
00688 static void
00689 bamf_view_dispose (GObject *object)
00690 {
00691   BamfView *view;
00692   BamfViewPrivate *priv;
00693 
00694   view = BAMF_VIEW (object);
00695 
00696   priv = view->priv;
00697 
00698   if (priv->path)
00699     {
00700       g_free (priv->path);
00701       priv->path = NULL;
00702     }
00703 
00704   if (priv->type)
00705     {
00706       g_free (priv->type);
00707       priv->type = NULL;
00708     }
00709  
00710   if (priv->local_icon)
00711     {
00712       g_free (priv->local_icon);
00713       priv->local_icon = NULL;
00714     }
00715 
00716   if (priv->local_name)
00717     {
00718       g_free (priv->local_name);
00719       priv->local_name = NULL;
00720     }
00721 
00722   if (priv->cached_children)
00723     {
00724       g_list_free_full (priv->cached_children, g_object_unref);
00725       priv->cached_children = NULL;
00726     }
00727 
00728   bamf_view_unset_proxy (view);
00729 
00730   G_OBJECT_CLASS (bamf_view_parent_class)->dispose (object);
00731 }
00732 
00733 const char *
00734 _bamf_view_get_path (BamfView *view)
00735 {
00736   g_return_val_if_fail (BAMF_IS_VIEW (view), NULL);
00737 
00738   return view->priv->path;
00739 }
00740 
00741 void
00742 _bamf_view_reset_flags (BamfView *view)
00743 {
00744   BamfViewPrivate *priv;
00745   g_return_if_fail (BAMF_IS_VIEW (view));
00746 
00747   priv = view->priv;
00748   priv->checked_flags = 0x0;
00749 
00750   if (bamf_view_user_visible (view))
00751     {
00752       g_signal_emit (G_OBJECT(view), view_signals[VISIBLE_CHANGED], 0, TRUE);
00753       g_object_notify (G_OBJECT (view), "user-visible");
00754     }
00755   
00756   if (bamf_view_is_active (view))
00757     {
00758       g_signal_emit (G_OBJECT(view), view_signals[ACTIVE_CHANGED], 0, TRUE);
00759       g_object_notify (G_OBJECT (view), "active");
00760     }
00761   
00762   if (bamf_view_is_running (view))
00763     {
00764       g_signal_emit (G_OBJECT(view), view_signals[RUNNING_CHANGED], 0, TRUE);
00765       g_object_notify (G_OBJECT (view), "running");
00766     }
00767     
00768   if (bamf_view_is_urgent (view))
00769     {
00770       g_signal_emit (G_OBJECT(view), view_signals[URGENT_CHANGED], 0, TRUE);
00771       g_object_notify (G_OBJECT (view), "urgent");
00772     }
00773 }
00774 
00775 void
00776 _bamf_view_set_path (BamfView *view, const char *path)
00777 {
00778   BamfViewPrivate *priv;
00779 
00780   g_return_if_fail (BAMF_IS_VIEW (view));
00781   g_return_if_fail (path);
00782 
00783   priv = view->priv;
00784 
00785   _bamf_view_set_closed (view, FALSE);
00786 
00787   if (priv->proxy && g_strcmp0 (priv->path, path) == 0)
00788     {
00789       // The proxy path has not been changed, no need to unset and re-set it again
00790       return;
00791     }
00792 
00793   g_free (priv->path);
00794   bamf_view_unset_proxy (view);
00795 
00796   priv->path = g_strdup (path);
00797   priv->proxy = dbus_g_proxy_new_for_name (priv->connection,
00798                                            "org.ayatana.bamf",
00799                                            priv->path,
00800                                            "org.ayatana.bamf.view");
00801 
00802   if (priv->proxy == NULL)
00803     {
00804       g_critical ("Unable to get org.ayatana.bamf.view view");
00805       return;
00806     }
00807 
00808   g_signal_connect (priv->proxy, "destroy", G_CALLBACK (on_view_proxy_destroyed), view);
00809 
00810   dbus_g_proxy_add_signal (priv->proxy,
00811                            "ActiveChanged",
00812                            G_TYPE_BOOLEAN,
00813                            G_TYPE_INVALID);
00814 
00815   dbus_g_proxy_add_signal (priv->proxy,
00816                            "Closed",
00817                            G_TYPE_INVALID);
00818 
00819   dbus_g_proxy_add_signal (priv->proxy,
00820                            "ChildAdded",
00821                            G_TYPE_STRING,
00822                            G_TYPE_INVALID);
00823 
00824   dbus_g_proxy_add_signal (priv->proxy,
00825                            "ChildRemoved",
00826                            G_TYPE_STRING,
00827                            G_TYPE_INVALID);
00828 
00829   dbus_g_proxy_add_signal (priv->proxy,
00830                            "RunningChanged",
00831                            G_TYPE_BOOLEAN,
00832                            G_TYPE_INVALID);
00833 
00834   dbus_g_proxy_add_signal (priv->proxy,
00835                            "UrgentChanged",
00836                            G_TYPE_BOOLEAN,
00837                            G_TYPE_INVALID);
00838 
00839   dbus_g_proxy_add_signal (priv->proxy,
00840                            "UserVisibleChanged",
00841                            G_TYPE_BOOLEAN,
00842                            G_TYPE_INVALID);
00843 
00844   dbus_g_proxy_add_signal (priv->proxy,
00845                            "NameChanged",
00846                            G_TYPE_STRING,
00847                            G_TYPE_STRING,
00848                            G_TYPE_INVALID);
00849 
00850   dbus_g_proxy_connect_signal (priv->proxy,
00851                                "ActiveChanged",
00852                                (GCallback) bamf_view_on_active_changed,
00853                                view,
00854                                NULL);
00855 
00856   dbus_g_proxy_connect_signal (priv->proxy,
00857                                "Closed",
00858                                (GCallback) bamf_view_on_closed,
00859                                view,
00860                                NULL);
00861 
00862   dbus_g_proxy_connect_signal (priv->proxy,
00863                                "ChildAdded",
00864                                (GCallback) bamf_view_on_child_added,
00865                                view,
00866                                NULL);
00867 
00868   dbus_g_proxy_connect_signal (priv->proxy,
00869                                "ChildRemoved",
00870                                (GCallback) bamf_view_on_child_removed,
00871                                view,
00872                                NULL);
00873 
00874   dbus_g_proxy_connect_signal (priv->proxy,
00875                                "RunningChanged",
00876                                (GCallback) bamf_view_on_running_changed,
00877                                view,
00878                                NULL);
00879 
00880   dbus_g_proxy_connect_signal (priv->proxy,
00881                                "UrgentChanged",
00882                                (GCallback) bamf_view_on_urgent_changed,
00883                                view,
00884                                NULL);
00885 
00886   dbus_g_proxy_connect_signal (priv->proxy,
00887                                "UserVisibleChanged",
00888                                (GCallback) bamf_view_on_user_visible_changed,
00889                                view,
00890                                NULL);
00891 
00892   dbus_g_proxy_connect_signal (priv->proxy,
00893                                "NameChanged",
00894                                (GCallback) bamf_view_on_name_changed,
00895                                view,
00896                                NULL);
00897 
00898   if (bamf_view_is_sticky (view))
00899     {
00900       _bamf_view_reset_flags (view);
00901     }
00902 
00903   if (BAMF_VIEW_GET_CLASS (view)->set_path)
00904     BAMF_VIEW_GET_CLASS (view)->set_path (view, path);
00905 }
00906 
00907 static void
00908 bamf_view_constructed (GObject *object)
00909 {
00910   if (G_OBJECT_CLASS (bamf_view_parent_class)->constructed)
00911     G_OBJECT_CLASS (bamf_view_parent_class)->constructed (object);
00912 }
00913 
00914 static void
00915 bamf_view_class_init (BamfViewClass *klass)
00916 {
00917   GParamSpec *pspec;
00918   GObjectClass *obj_class = G_OBJECT_CLASS (klass);
00919 
00920   obj_class->constructed  = bamf_view_constructed;
00921   obj_class->dispose      = bamf_view_dispose;
00922   obj_class->get_property = bamf_view_get_property;
00923   obj_class->set_property = bamf_view_set_property;
00924 
00925   pspec = g_param_spec_string ("path", "path", "path", NULL, G_PARAM_READABLE);
00926   g_object_class_install_property (obj_class, PROP_PATH, pspec);
00927   
00928   pspec = g_param_spec_boolean ("active", "active", "active", FALSE, G_PARAM_READABLE);
00929   g_object_class_install_property (obj_class, PROP_ACTIVE, pspec);
00930 
00931   pspec = g_param_spec_boolean ("urgent", "urgent", "urgent", FALSE, G_PARAM_READABLE);
00932   g_object_class_install_property (obj_class, PROP_URGENT, pspec);
00933   
00934   pspec = g_param_spec_boolean ("running", "running", "running", FALSE, G_PARAM_READABLE);
00935   g_object_class_install_property (obj_class, PROP_RUNNING, pspec);
00936   
00937   pspec = g_param_spec_boolean ("user-visible", "user-visible", "user-visible", FALSE, G_PARAM_READABLE);
00938   g_object_class_install_property (obj_class, PROP_USER_VISIBLE, pspec);
00939 
00940   g_type_class_add_private (obj_class, sizeof (BamfViewPrivate));
00941 
00942   view_signals [ACTIVE_CHANGED] = 
00943        g_signal_new ("active-changed",
00944                      G_OBJECT_CLASS_TYPE (klass),
00945                      G_SIGNAL_RUN_FIRST,
00946                      G_STRUCT_OFFSET (BamfViewClass, active_changed), 
00947                      NULL, NULL,
00948                      g_cclosure_marshal_VOID__BOOLEAN,
00949                      G_TYPE_NONE, 1, 
00950                      G_TYPE_BOOLEAN);
00951 
00952   view_signals [CLOSED] = 
00953        g_signal_new ("closed",
00954                      G_OBJECT_CLASS_TYPE (klass),
00955                      G_SIGNAL_RUN_FIRST,
00956                      G_STRUCT_OFFSET (BamfViewClass, closed), 
00957                      NULL, NULL,
00958                      g_cclosure_marshal_VOID__VOID,
00959                      G_TYPE_NONE, 0);
00960 
00961   view_signals [CHILD_ADDED] = 
00962        g_signal_new ("child-added",
00963                      G_OBJECT_CLASS_TYPE (klass),
00964                      G_SIGNAL_RUN_FIRST,
00965                      G_STRUCT_OFFSET (BamfViewClass, child_added), 
00966                      NULL, NULL,
00967                      g_cclosure_marshal_VOID__OBJECT,
00968                      G_TYPE_NONE, 1, 
00969                      BAMF_TYPE_VIEW);
00970 
00971   view_signals [CHILD_REMOVED] = 
00972        g_signal_new ("child-removed",
00973                      G_OBJECT_CLASS_TYPE (klass),
00974                      G_SIGNAL_RUN_FIRST,
00975                      G_STRUCT_OFFSET (BamfViewClass, child_removed), 
00976                      NULL, NULL,
00977                      g_cclosure_marshal_VOID__OBJECT,
00978                      G_TYPE_NONE, 1, 
00979                      BAMF_TYPE_VIEW);
00980 
00981   view_signals [RUNNING_CHANGED] = 
00982        g_signal_new ("running-changed",
00983                      G_OBJECT_CLASS_TYPE (klass),
00984                      G_SIGNAL_RUN_FIRST,
00985                      G_STRUCT_OFFSET (BamfViewClass, running_changed), 
00986                      NULL, NULL,
00987                      g_cclosure_marshal_VOID__BOOLEAN,
00988                      G_TYPE_NONE, 1, 
00989                      G_TYPE_BOOLEAN);
00990 
00991   view_signals [URGENT_CHANGED] = 
00992        g_signal_new ("urgent-changed",
00993                      G_OBJECT_CLASS_TYPE (klass),
00994                      G_SIGNAL_RUN_FIRST,
00995                      G_STRUCT_OFFSET (BamfViewClass, urgent_changed), 
00996                      NULL, NULL,
00997                      g_cclosure_marshal_VOID__BOOLEAN,
00998                      G_TYPE_NONE, 1, 
00999                      G_TYPE_BOOLEAN);
01000   
01001   view_signals [VISIBLE_CHANGED] = 
01002        g_signal_new ("user-visible-changed",
01003                      G_OBJECT_CLASS_TYPE (klass),
01004                      G_SIGNAL_RUN_FIRST,
01005                      G_STRUCT_OFFSET (BamfViewClass, user_visible_changed), 
01006                      NULL, NULL,
01007                      g_cclosure_marshal_VOID__BOOLEAN,
01008                      G_TYPE_NONE, 1, 
01009                      G_TYPE_BOOLEAN);
01010 
01011   view_signals [NAME_CHANGED] =
01012         g_signal_new ("name-changed",
01013                       G_OBJECT_CLASS_TYPE (klass),
01014                       0,
01015                       0, NULL, NULL,
01016                       _bamf_marshal_VOID__STRING_STRING,
01017                      G_TYPE_NONE, 2,
01018                      G_TYPE_STRING,
01019                       G_TYPE_STRING);
01020 }
01021 
01022 
01023 static void
01024 bamf_view_init (BamfView *self)
01025 {
01026   BamfViewPrivate *priv;
01027   GError *error = NULL;
01028 
01029   priv = self->priv = BAMF_VIEW_GET_PRIVATE (self);
01030   _bamf_view_set_closed (self, TRUE);
01031 
01032   priv->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
01033   if (priv->connection == NULL)
01034     {
01035       g_critical ("Failed to open connection to bus: %s",
01036                error != NULL ? error->message : "Unknown");
01037       if (error)
01038         g_error_free (error);
01039       return;
01040     }
01041 }