This repository has been archived on 2020-04-11. You can view files and clone it, but cannot push or open issues or pull requests.
gnoemoe/gnoemoe/widgets/gm-tray.c

209 lines
4.5 KiB
C

#include <gtk/gtk.h>
#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;
}
}