2006-01-06 00:30:07 +01:00
|
|
|
#include <gtk/gtk.h>
|
|
|
|
#include "gm-tray.h"
|
|
|
|
#include "eggtrayicon.h"
|
2006-01-10 01:39:05 +01:00
|
|
|
#include "gm-debug.h"
|
2006-01-06 00:30:07 +01:00
|
|
|
|
|
|
|
#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), 2000, 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;
|
|
|
|
}
|
|
|
|
}
|