#include #include "gm-tray.h" #include "eggtrayicon.h" #include "gm-debug.h" #define GM_TRAY_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GM_TYPE_TRAY, GmTrayPrivate)) struct _GmTrayPrivate { GtkWidget *event_box; GtkImage *image; GtkTooltips *tooltips; guint flash_timeout; GmTrayState current_state; GmTrayState prev_state; GdkPixbuf *icons[NUM_TRAY_STATES]; }; /* Signals enum { NUM_SIGNALS }; static guint tray_signals[NUM_SIGNALS] = {0};*/ G_DEFINE_TYPE(GmTray, gm_tray, EGG_TYPE_TRAY_ICON) static void gm_tray_finalize(GObject *object) { GmTray *tray = GM_TRAY(object); guint i; if (tray->priv->flash_timeout) { g_source_remove(tray->priv->flash_timeout); } for (i = 0; i < NUM_TRAY_STATES; ++i) { g_object_unref(tray->priv->icons[i]); } G_OBJECT_CLASS(gm_tray_parent_class)->finalize(object); } static void gm_tray_class_init(GmTrayClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); object_class->finalize = gm_tray_finalize; g_type_class_add_private(object_class, sizeof(GmTrayPrivate)); } static void gm_tray_init(GmTray *tray) { guint i; GtkWidget *image; tray->priv = GM_TRAY_GET_PRIVATE(tray); tray->priv->event_box = gtk_event_box_new(); tray->priv->current_state = TRAY_STATE_NORMAL; for (i = 0; i < NUM_TRAY_STATES; ++i) { tray->priv->icons[i] = NULL; } image = gtk_image_new(); gtk_container_add(GTK_CONTAINER(tray->priv->event_box), image); tray->priv->tooltips = gtk_tooltips_new(); gtk_widget_show(tray->priv->event_box); gtk_widget_show(image); gtk_container_add(GTK_CONTAINER(tray), tray->priv->event_box); gtk_widget_add_events(GTK_WIDGET(tray), GDK_BUTTON_PRESS_MASK); tray->priv->image = GTK_IMAGE(image); } static void gm_tray_update_icon(GmTray *tray) { gtk_image_set_from_pixbuf(tray->priv->image, tray->priv->icons[tray->priv->current_state]); } static void gm_tray_set_state(GmTray *tray, GmTrayState state) { if (tray->priv->current_state == state) { return; } if (tray->priv->flash_timeout) { g_source_remove(tray->priv->flash_timeout); tray->priv->flash_timeout = 0; } tray->priv->prev_state = tray->priv->current_state; tray->priv->current_state = state; gm_tray_update_icon(tray); } static gboolean gm_tray_restore_from_activity(gpointer user_data) { GmTray *tray = GM_TRAY(user_data); tray->priv->flash_timeout = 0; gm_tray_set_state(tray, tray->priv->prev_state); return FALSE; } /* Public */ GmTray * gm_tray_new(gchar const *title) { return g_object_new(GM_TYPE_TRAY, "title", title, NULL); } void gm_tray_activate(GmTray *tray) { if (tray->priv->flash_timeout) { g_source_remove(tray->priv->flash_timeout); } if (tray->priv->current_state == TRAY_STATE_NORMAL) { tray->priv->current_state = TRAY_STATE_ACTIVE; } gm_tray_set_state(tray, TRAY_STATE_ACTIVITY); tray->priv->flash_timeout = g_timeout_add(1000, gm_tray_restore_from_activity, tray); } void gm_tray_normal(GmTray *tray) { gm_tray_set_state(tray, TRAY_STATE_NORMAL); gm_tray_set_tip(tray, NULL); } void gm_tray_active(GmTray *tray) { gm_tray_set_state(tray, TRAY_STATE_ACTIVE); } void gm_tray_notify(GmTray *tray, gchar const *message) { gm_tray_set_state(tray, TRAY_STATE_NOTIFY); gm_tray_message(tray, message); gm_tray_set_tip(tray, message); } void gm_tray_set_icon(GmTray *tray, GmTrayState state, GdkPixbuf *icon) { if (tray->priv->icons[state]) { g_object_unref(tray->priv->icons[state]); } tray->priv->icons[state] = g_object_ref(icon); if (state == tray->priv->current_state) { gm_tray_update_icon(tray); } } void gm_tray_message(GmTray *tray, gchar const *message) { egg_tray_icon_send_message(EGG_TRAY_ICON(tray), 5000, message, g_utf8_strlen(message, -1)); } void gm_tray_set_tip(GmTray *tray, gchar const *message) { gtk_tooltips_set_tip(tray->priv->tooltips, tray->priv->event_box, message, message); } GmTrayState gm_tray_get_state(GmTray *tray) { if (tray->priv->current_state == TRAY_STATE_ACTIVITY) { return tray->priv->prev_state; } return tray->priv->current_state; } gboolean gm_tray_has_manager() { Screen *xscreen = DefaultScreenOfDisplay(gdk_display); Atom selection_atom; char *selection_atom_name; selection_atom_name = g_strdup_printf("_NET_SYSTEM_TRAY_S%d", XScreenNumberOfScreen(xscreen)); selection_atom = XInternAtom(DisplayOfScreen(xscreen), selection_atom_name, FALSE); g_free(selection_atom_name); if (XGetSelectionOwner(DisplayOfScreen(xscreen), selection_atom)) { return TRUE; } else { return FALSE; } }