diff options
-rw-r--r-- | libindicate/indicator.c | 75 | ||||
-rw-r--r-- | libindicate/indicator.h | 11 | ||||
-rw-r--r-- | libindicate/server.c | 44 | ||||
-rw-r--r-- | libindicate/server.h | 3 | ||||
-rw-r--r-- | libindicate/tests/indicate-and-crash.c | 4 |
5 files changed, 133 insertions, 4 deletions
diff --git a/libindicate/indicator.c b/libindicate/indicator.c index 2db8468..e16492d 100644 --- a/libindicate/indicator.c +++ b/libindicate/indicator.c @@ -1,9 +1,12 @@ #include "glib.h" +#include "glib/gmessages.h" #include "indicator.h" /* Signals */ enum { + HIDE, + SHOW, USER_DISPLAY, LAST_SIGNAL }; @@ -19,6 +22,8 @@ static void indicate_indicator_finalize (GObject * object); static void indicate_indicator_class_init (IndicateIndicatorClass * class) { + g_debug("Indicator Class Initialized."); + GObjectClass * gobj; gobj = G_OBJECT_CLASS(class); @@ -31,6 +36,20 @@ indicate_indicator_class_init (IndicateIndicatorClass * class) NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + signals[HIDE] = g_signal_new(INDICATE_INDICATOR_SIGNAL_HIDE, + G_TYPE_FROM_CLASS(class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(IndicateIndicatorClass, hide), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + signals[SHOW] = g_signal_new(INDICATE_INDICATOR_SIGNAL_SHOW, + G_TYPE_FROM_CLASS(class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(IndicateIndicatorClass, show), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); return; } @@ -38,7 +57,10 @@ indicate_indicator_class_init (IndicateIndicatorClass * class) static void indicate_indicator_init (IndicateIndicator * indicator) { + g_debug("Indicator Object Initialized."); + indicator->id = 0; + indicator->is_visible = FALSE; indicator->server = indicate_server_ref_default(); indicate_server_add_indicator(indicator->server, indicator); @@ -65,3 +87,56 @@ indicate_indicator_new (void) return indicator; } +void +indicate_indicator_show (IndicateIndicator * indicator) +{ + if (indicator->is_visible) { + return; + } + + if (indicator->server) { + indicate_server_show(indicator->server); + } + + indicator->is_visible = TRUE; + g_signal_emit(indicator, signals[SHOW], 0, TRUE); +} + +void +indicate_indicator_hide (IndicateIndicator * indicator) +{ + if (!indicator->is_visible) { + return; + } + + indicator->is_visible = FALSE; + g_signal_emit(indicator, signals[HIDE], 0, TRUE); +} + +gboolean +indicate_indicator_is_visible (IndicateIndicator * indicator) +{ + return indicator->is_visible; +} + +guint +indicate_indicator_get_id (IndicateIndicator * indicator) +{ + g_return_val_if_fail(INDICATE_IS_INDICATOR(indicator), 0); + return indicator->id; +} + +const gchar * +indicate_indicator_get_indicator_type (IndicateIndicator * indicator) +{ + g_return_val_if_fail(INDICATE_IS_INDICATOR(indicator), NULL); + IndicateIndicatorClass * class = INDICATE_INDICATOR_GET_CLASS(indicator); + + if (class->get_type != NULL) { + return INDICATE_INDICATOR_GET_CLASS(indicator)->get_type(indicator); + } + + return NULL; +} + + diff --git a/libindicate/indicator.h b/libindicate/indicator.h index 77fd82f..3c8efc8 100644 --- a/libindicate/indicator.h +++ b/libindicate/indicator.h @@ -11,11 +11,13 @@ #define INDICATE_IS_INDICATOR(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), INDICATE_TYPE_INDICATOR)) #define INDICATE_INDICATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), INDICATE_TYPE_INDICATOR, IndicateIndicatorClass)) #define INDICATE_IS_INDICATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), INDICATE_TYPE_INDICATOR)) -#define INDICATE_INDICATOR_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), INDICATE_TYPE_INDICATOR, IndicateIndicatorCLass)) +#define INDICATE_INDICATOR_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), INDICATE_TYPE_INDICATOR, IndicateIndicatorClass)) /* This is a signal that signals to the indicator that the user * has done an action where they'd like this indicator to be * displayed. */ +#define INDICATE_INDICATOR_SIGNAL_HIDE "hide" +#define INDICATE_INDICATOR_SIGNAL_SHOW "show" #define INDICATE_INDICATOR_SIGNAL_DISPLAY "user-display" typedef struct _IndicateIndicator IndicateIndicator; @@ -27,15 +29,18 @@ struct _IndicateIndicator { GObject parent; guint id; + gboolean is_visible; IndicateServer * server; }; struct _IndicateIndicatorClass { GObjectClass parent_class; + void (*hide) (IndicateIndicator * indicator, gpointer data); + void (*show) (IndicateIndicator * indicator, gpointer data); void (*user_display) (IndicateIndicator * indicator, gpointer data); - gchar * (*get_type) (IndicateIndicator * indicator); + const gchar * (*get_type) (IndicateIndicator * indicator); }; IndicateIndicator * indicate_indicator_new (void); @@ -47,6 +52,8 @@ void indicate_indicator_set_property (IndicateIndicator * indicator, const gchar void indicate_indicator_show (IndicateIndicator * indicator); void indicate_indicator_hide (IndicateIndicator * indicator); +gboolean indicate_indicator_is_visible (IndicateIndicator * indicator); + /* Every entry has an ID, here's how to get it */ guint indicate_indicator_get_id (IndicateIndicator * indicator); diff --git a/libindicate/server.c b/libindicate/server.c index dd4513a..48f1c71 100644 --- a/libindicate/server.c +++ b/libindicate/server.c @@ -44,6 +44,7 @@ static gboolean show_indicator_to_user (IndicateServer * server, guint id, GErro static void indicate_server_class_init (IndicateServerClass * class) { + g_debug("Server Class Initialized"); GObjectClass * gobj; gobj = G_OBJECT_CLASS(class); @@ -90,8 +91,11 @@ indicate_server_class_init (IndicateServerClass * class) static void indicate_server_init (IndicateServer * server) { + g_debug("Server Object Initialized"); + server->path = g_strdup("/org/freedesktop/indicate"); server->indicators = NULL; + server->num_hidden = 0; return; } @@ -133,11 +137,37 @@ indicate_server_show (IndicateServer * server) return; } +static void +indicator_show_cb (IndicateIndicator * indicator, IndicateServer * server) +{ + server->num_hidden--; + g_signal_emit(server, signals[INDICATOR_ADDED], 0, indicate_indicator_get_id(indicator), indicate_indicator_get_indicator_type(indicator), TRUE); + return; +} + +static void +indicator_hide_cb (IndicateIndicator * indicator, IndicateServer * server) +{ + server->num_hidden++; + g_signal_emit(server, signals[INDICATOR_REMOVED], 0, indicate_indicator_get_id(indicator), indicate_indicator_get_indicator_type(indicator), TRUE); + return; +} + void indicate_server_add_indicator (IndicateServer * server, IndicateIndicator * indicator) { g_object_ref(indicator); server->indicators = g_slist_prepend(server->indicators, indicator); + + if (!indicate_indicator_is_visible(indicator)) { + server->num_hidden++; + } else { + g_signal_emit(server, signals[INDICATOR_ADDED], 0, indicate_indicator_get_id(indicator), indicate_indicator_get_indicator_type(indicator), TRUE); + } + + g_signal_connect(indicator, INDICATE_INDICATOR_SIGNAL_SHOW, indicator_show_cb, server); + g_signal_connect(indicator, INDICATE_INDICATOR_SIGNAL_HIDE, indicator_hide_cb, server); + return; } @@ -145,6 +175,15 @@ void indicate_server_remove_indicator (IndicateServer * server, IndicateIndicator * indicator) { server->indicators = g_slist_remove(server->indicators, indicator); + if (indicate_indicator_is_visible(indicator)) { + g_signal_emit(server, signals[INDICATOR_REMOVED], 0, indicate_indicator_get_id(indicator), indicate_indicator_get_indicator_type(indicator), TRUE); + } else { + server->num_hidden--; + } + + g_signal_handlers_disconnect_by_func(indicator, indicator_show_cb, server); + g_signal_handlers_disconnect_by_func(indicator, indicator_hide_cb, server); + g_object_unref(indicator); return; } @@ -191,6 +230,11 @@ get_desktop (IndicateServer * server, gchar ** desktop_path, GError **error) static gboolean get_indicator_count (IndicateServer * server, guint * count, GError **error) { + guint lstcnt = g_slist_length(server->indicators); + + g_return_val_if_fail(server->num_hidden < lstcnt, TRUE); + + *count = lstcnt - server->num_hidden; return TRUE; } diff --git a/libindicate/server.h b/libindicate/server.h index 78c4d4b..486252c 100644 --- a/libindicate/server.h +++ b/libindicate/server.h @@ -22,6 +22,9 @@ struct _IndicateServer { gchar * path; GSList * indicators; + + // TODO: Should have a more robust way to track this, but this'll work for now + guint num_hidden; }; typedef struct _IndicateServerClass IndicateServerClass; diff --git a/libindicate/tests/indicate-and-crash.c b/libindicate/tests/indicate-and-crash.c index 1886a24..3cf4428 100644 --- a/libindicate/tests/indicate-and-crash.c +++ b/libindicate/tests/indicate-and-crash.c @@ -10,9 +10,9 @@ main (int argc, char ** argv) g_type_init(); IndicateIndicator * indicator = indicate_indicator_new(); - indicate_server_show(indicator->server); + indicate_indicator_show(indicator); - g_timeout_add_seconds(15, crashfunc, NULL); + //g_timeout_add_seconds(15, crashfunc, NULL); g_main_loop_run(g_main_loop_new(NULL, FALSE)); |