#include "window.h"
#include <gtk/gtk.h>
#include <stdlib.h>
int window_show(const void *ptr)
{
if (!ptr)
{
return 0;
}
GtkWidget *window = (GtkWidget *)ptr;
gtk_widget_show(window);
return 1;
}
int window_hide(const void *ptr)
{
if (!ptr)
{
return 0;
}
GtkWidget *window = (GtkWidget *)ptr;
gtk_widget_hide(window);
return 1;
}
typedef struct
{
GtkWidget *menu;
GtkStatusIcon *status_icon;
const void *window_ptr;
GSList *menu_data_list;
} TrayData;
typedef struct
{
int id;
char *text;
int disabled;
int checked;
void (*callback)(const void *ptr);
} MenuItemData;
static void menu_item_callback(GtkWidget *widget, gpointer data)
{
MenuItemData *menu = (MenuItemData *)data;
if (menu->callback && !menu->disabled)
{
menu->callback(menu);
}
}
static void on_status_icon_activate(GtkStatusIcon *status_icon, gpointer user_data)
{
TrayData *tray_data = (TrayData *)user_data;
if (tray_data->menu)
{
guint32 activate_time = gtk_get_current_event_time();
gtk_menu_popup(GTK_MENU(tray_data->menu), NULL, NULL,
gtk_status_icon_position_menu,
status_icon, 1, activate_time);
}
}
static gboolean on_status_icon_popup_menu(GtkStatusIcon *status_icon,
guint button,
guint activate_time,
gpointer user_data)
{
TrayData *tray_data = (TrayData *)user_data;
if (tray_data->menu)
{
gtk_menu_popup(GTK_MENU(tray_data->menu), NULL, NULL,
gtk_status_icon_position_menu,
status_icon, button, activate_time);
return TRUE;
}
return FALSE;
}
void *window_tray(const void *ptr, const char *icon)
{
if (!ptr || !icon)
return NULL;
TrayData *tray_data = malloc(sizeof(TrayData));
if (!tray_data)
return NULL;
tray_data->window_ptr = ptr;
tray_data->menu_data_list = NULL;
tray_data->status_icon = gtk_status_icon_new_from_file(icon);
if (!tray_data->status_icon)
{
free(tray_data);
return NULL;
}
tray_data->menu = gtk_menu_new();
g_signal_connect(tray_data->status_icon, "popup-menu",
G_CALLBACK(on_status_icon_popup_menu), tray_data);
g_signal_connect(tray_data->status_icon, "activate",
G_CALLBACK(on_status_icon_activate), tray_data);
gtk_status_icon_set_visible(tray_data->status_icon, TRUE);
return tray_data;
}
void window_tray_add_menu(const void *tray, struct tray_menu *menu)
{
if (!tray || !menu)
return;
TrayData *tray_data = (TrayData *)tray;
GtkWidget *menu_item;
MenuItemData *menu_data = malloc(sizeof(MenuItemData));
menu_data->id = menu->id;
menu_data->text = strdup(menu->text);
menu_data->disabled = menu->disabled;
menu_data->checked = menu->checked;
menu_data->callback = menu->callback;
tray_data->menu_data_list = g_slist_append(tray_data->menu_data_list, menu_data);
if (menu->checked)
{
menu_item = gtk_check_menu_item_new_with_label(menu_data->text);
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item), TRUE);
}
else
{
menu_item = gtk_menu_item_new_with_label(menu_data->text);
}
gtk_widget_set_sensitive(menu_item, !menu_data->disabled);
g_signal_connect(menu_item, "activate",
G_CALLBACK(menu_item_callback), menu_data);
gtk_menu_shell_append(GTK_MENU_SHELL(tray_data->menu), menu_item);
gtk_widget_show(menu_item);
}
void window_tray_remove(void *tray)
{
if (!tray)
return;
TrayData *tray_data = (TrayData *)tray;
if (tray_data->status_icon)
{
g_object_unref(tray_data->status_icon);
}
if (tray_data->menu)
{
gtk_widget_destroy(tray_data->menu);
}
free(tray_data);
}