mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-03-18 19:50:18 +00:00
Added a GTK3 AppIndicator tray backend with a unified tray interface while keeping the GtkStatusIcon backend for GTK2 builds.
Reworked tray menu population and tray initialization to use the backend abstraction and GTK3 menu refresh behavior. Linked AppIndicator dependencies conditionally for GTK3 builds in Meson.
This commit is contained in:
@@ -30,19 +30,30 @@ zoitechat_gtk_sources = [
|
|||||||
|
|
||||||
zoitechat_gtk_cflags = []
|
zoitechat_gtk_cflags = []
|
||||||
|
|
||||||
|
zoitechat_gtk_deps = [
|
||||||
|
zoitechat_common_dep,
|
||||||
|
libgmodule_dep, # used by libsexy
|
||||||
|
]
|
||||||
|
|
||||||
if get_option('gtk3')
|
if get_option('gtk3')
|
||||||
gtk_dep = dependency('gtk+-3.0', version: '>= 3.22')
|
gtk_dep = dependency('gtk+-3.0', version: '>= 3.22')
|
||||||
zoitechat_gtk_cflags += '-DHAVE_GTK3'
|
zoitechat_gtk_cflags += '-DHAVE_GTK3'
|
||||||
|
|
||||||
|
appindicator_dep = dependency('ayatana-appindicator3-0.1', required: false)
|
||||||
|
if appindicator_dep.found()
|
||||||
|
zoitechat_gtk_deps += appindicator_dep
|
||||||
|
zoitechat_gtk_cflags += '-DHAVE_AYATANA_APPINDICATOR'
|
||||||
|
else
|
||||||
|
appindicator_dep = dependency('appindicator3-0.1', required: true)
|
||||||
|
zoitechat_gtk_deps += appindicator_dep
|
||||||
|
zoitechat_gtk_cflags += '-DHAVE_APPINDICATOR'
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
gtk_dep = dependency('gtk+-2.0', version: '>= 2.24.0')
|
gtk_dep = dependency('gtk+-2.0', version: '>= 2.24.0')
|
||||||
zoitechat_gtk_cflags += '-DHAVE_GTK2'
|
zoitechat_gtk_cflags += '-DHAVE_GTK2'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
zoitechat_gtk_deps = [
|
zoitechat_gtk_deps += gtk_dep
|
||||||
zoitechat_common_dep,
|
|
||||||
libgmodule_dep, # used by libsexy
|
|
||||||
gtk_dep
|
|
||||||
]
|
|
||||||
|
|
||||||
if gtk_dep.get_pkgconfig_variable('target') == 'x11'
|
if gtk_dep.get_pkgconfig_variable('target') == 'x11'
|
||||||
zoitechat_gtk_deps += dependency('x11')
|
zoitechat_gtk_deps += dependency('x11')
|
||||||
|
|||||||
@@ -32,6 +32,11 @@
|
|||||||
#include "gtkutil.h"
|
#include "gtkutil.h"
|
||||||
|
|
||||||
#if HAVE_GTK3
|
#if HAVE_GTK3
|
||||||
|
#if defined(HAVE_AYATANA_APPINDICATOR)
|
||||||
|
#include <libayatana-appindicator/app-indicator.h>
|
||||||
|
#else
|
||||||
|
#include <libappindicator/app-indicator.h>
|
||||||
|
#endif
|
||||||
#define ICON_TRAY_PREFERENCES "preferences-system"
|
#define ICON_TRAY_PREFERENCES "preferences-system"
|
||||||
#define ICON_TRAY_QUIT "application-exit"
|
#define ICON_TRAY_QUIT "application-exit"
|
||||||
#endif
|
#endif
|
||||||
@@ -63,7 +68,7 @@ typedef enum
|
|||||||
} WinStatus;
|
} WinStatus;
|
||||||
|
|
||||||
#if HAVE_GTK3
|
#if HAVE_GTK3
|
||||||
/* GTK3: keep GtkStatusIcon and use tooltip/text properties for tray tooltips. */
|
/* GTK3: use AppIndicator/StatusNotifier item for tray integration. */
|
||||||
typedef const char *TrayIcon;
|
typedef const char *TrayIcon;
|
||||||
typedef char *TrayCustomIcon;
|
typedef char *TrayCustomIcon;
|
||||||
#define tray_icon_from_file(f) g_strdup(f)
|
#define tray_icon_from_file(f) g_strdup(f)
|
||||||
@@ -88,12 +93,238 @@ typedef GdkPixbuf* TrayCustomIcon;
|
|||||||
#endif
|
#endif
|
||||||
#define TIMEOUT 500
|
#define TIMEOUT 500
|
||||||
|
|
||||||
static GtkStatusIcon *sticon;
|
void tray_apply_setup (void);
|
||||||
|
static gboolean tray_menu_try_restore (void);
|
||||||
|
static void tray_cleanup (void);
|
||||||
|
static void tray_init (void);
|
||||||
|
static void tray_menu_restore_cb (GtkWidget *item, gpointer userdata);
|
||||||
|
static void tray_menu_notify_cb (GObject *tray, GParamSpec *pspec, gpointer user_data);
|
||||||
|
#if HAVE_GTK3
|
||||||
|
static void tray_menu_show_cb (GtkWidget *menu, gpointer userdata);
|
||||||
|
#endif
|
||||||
|
#if !HAVE_GTK3
|
||||||
|
static void tray_menu_cb (GtkWidget *widget, guint button, guint time, gpointer userdata);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
gboolean (*init)(void);
|
||||||
|
void (*set_icon)(TrayIcon icon);
|
||||||
|
void (*set_tooltip)(const char *text);
|
||||||
|
gboolean (*is_embedded)(void);
|
||||||
|
void (*cleanup)(void);
|
||||||
|
} TrayBackendOps;
|
||||||
|
|
||||||
|
#if HAVE_GTK3
|
||||||
|
static AppIndicator *tray_indicator;
|
||||||
|
static GtkWidget *tray_menu;
|
||||||
|
#endif
|
||||||
|
#if !HAVE_GTK3
|
||||||
|
static GtkStatusIcon *tray_status_icon;
|
||||||
|
#endif
|
||||||
|
static gboolean tray_backend_active = FALSE;
|
||||||
|
|
||||||
|
#if HAVE_GTK3
|
||||||
|
static void
|
||||||
|
tray_app_indicator_set_icon (TrayIcon icon)
|
||||||
|
{
|
||||||
|
if (!tray_indicator)
|
||||||
|
return;
|
||||||
|
|
||||||
|
app_indicator_set_icon_full (tray_indicator, icon, _(DISPLAY_NAME));
|
||||||
|
app_indicator_set_status (tray_indicator, APP_INDICATOR_STATUS_ACTIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tray_app_indicator_set_tooltip (const char *text)
|
||||||
|
{
|
||||||
|
if (!tray_indicator)
|
||||||
|
return;
|
||||||
|
|
||||||
|
app_indicator_set_title (tray_indicator, text ? text : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
tray_app_indicator_is_embedded (void)
|
||||||
|
{
|
||||||
|
gboolean connected = TRUE;
|
||||||
|
GObjectClass *klass;
|
||||||
|
|
||||||
|
if (!tray_indicator)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
klass = G_OBJECT_GET_CLASS (tray_indicator);
|
||||||
|
if (klass && g_object_class_find_property (klass, "connected"))
|
||||||
|
{
|
||||||
|
g_object_get (tray_indicator, "connected", &connected, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tray_app_indicator_cleanup (void)
|
||||||
|
{
|
||||||
|
if (tray_indicator)
|
||||||
|
{
|
||||||
|
g_object_unref (tray_indicator);
|
||||||
|
tray_indicator = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tray_menu)
|
||||||
|
{
|
||||||
|
gtk_widget_destroy (tray_menu);
|
||||||
|
tray_menu = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
tray_app_indicator_init (void)
|
||||||
|
{
|
||||||
|
GObjectClass *klass;
|
||||||
|
|
||||||
|
tray_indicator = app_indicator_new ("zoitechat", ICON_NORMAL,
|
||||||
|
APP_INDICATOR_CATEGORY_COMMUNICATIONS);
|
||||||
|
if (!tray_indicator)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
tray_menu = gtk_menu_new ();
|
||||||
|
g_signal_connect (G_OBJECT (tray_menu), "show",
|
||||||
|
G_CALLBACK (tray_menu_show_cb), NULL);
|
||||||
|
app_indicator_set_menu (tray_indicator, GTK_MENU (tray_menu));
|
||||||
|
app_indicator_set_status (tray_indicator, APP_INDICATOR_STATUS_ACTIVE);
|
||||||
|
|
||||||
|
klass = G_OBJECT_GET_CLASS (tray_indicator);
|
||||||
|
if (klass && g_object_class_find_property (klass, "connected"))
|
||||||
|
{
|
||||||
|
g_signal_connect (G_OBJECT (tray_indicator), "notify::connected",
|
||||||
|
G_CALLBACK (tray_menu_notify_cb), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const TrayBackendOps tray_backend_ops = {
|
||||||
|
tray_app_indicator_init,
|
||||||
|
tray_app_indicator_set_icon,
|
||||||
|
tray_app_indicator_set_tooltip,
|
||||||
|
tray_app_indicator_is_embedded,
|
||||||
|
tray_app_indicator_cleanup
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !HAVE_GTK3
|
||||||
|
static void
|
||||||
|
tray_status_icon_set_icon (TrayIcon icon)
|
||||||
|
{
|
||||||
|
if (!tray_status_icon)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gtk_status_icon_set_from_pixbuf (tray_status_icon, icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tray_status_icon_set_tooltip (const char *text)
|
||||||
|
{
|
||||||
|
if (!tray_status_icon)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gtk_status_icon_set_tooltip_text (tray_status_icon, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
tray_status_icon_is_embedded (void)
|
||||||
|
{
|
||||||
|
if (!tray_status_icon)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return gtk_status_icon_is_embedded (tray_status_icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tray_status_icon_cleanup (void)
|
||||||
|
{
|
||||||
|
if (tray_status_icon)
|
||||||
|
{
|
||||||
|
g_object_unref (tray_status_icon);
|
||||||
|
tray_status_icon = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
tray_status_icon_init (void)
|
||||||
|
{
|
||||||
|
tray_status_icon = gtk_status_icon_new_from_pixbuf (ICON_NORMAL);
|
||||||
|
if (!tray_status_icon)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
g_signal_connect (G_OBJECT (tray_status_icon), "popup-menu",
|
||||||
|
G_CALLBACK (tray_menu_cb), tray_status_icon);
|
||||||
|
|
||||||
|
g_signal_connect (G_OBJECT (tray_status_icon), "activate",
|
||||||
|
G_CALLBACK (tray_menu_restore_cb), NULL);
|
||||||
|
|
||||||
|
g_signal_connect (G_OBJECT (tray_status_icon), "notify::embedded",
|
||||||
|
G_CALLBACK (tray_menu_notify_cb), NULL);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const TrayBackendOps tray_backend_ops = {
|
||||||
|
tray_status_icon_init,
|
||||||
|
tray_status_icon_set_icon,
|
||||||
|
tray_status_icon_set_tooltip,
|
||||||
|
tray_status_icon_is_embedded,
|
||||||
|
tray_status_icon_cleanup
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
tray_backend_init (void)
|
||||||
|
{
|
||||||
|
if (!tray_backend_ops.init)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
tray_backend_active = tray_backend_ops.init ();
|
||||||
|
return tray_backend_active;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tray_backend_set_icon (TrayIcon icon)
|
||||||
|
{
|
||||||
|
if (tray_backend_active && tray_backend_ops.set_icon)
|
||||||
|
tray_backend_ops.set_icon (icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tray_backend_set_tooltip (const char *text)
|
||||||
|
{
|
||||||
|
if (tray_backend_active && tray_backend_ops.set_tooltip)
|
||||||
|
tray_backend_ops.set_tooltip (text);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
tray_backend_is_embedded (void)
|
||||||
|
{
|
||||||
|
if (!tray_backend_active || !tray_backend_ops.is_embedded)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return tray_backend_ops.is_embedded ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tray_backend_cleanup (void)
|
||||||
|
{
|
||||||
|
if (tray_backend_ops.cleanup)
|
||||||
|
tray_backend_ops.cleanup ();
|
||||||
|
|
||||||
|
tray_backend_active = FALSE;
|
||||||
|
}
|
||||||
static gint flash_tag;
|
static gint flash_tag;
|
||||||
static TrayIconState tray_icon_state;
|
static TrayIconState tray_icon_state;
|
||||||
static TrayIcon tray_flash_icon;
|
static TrayIcon tray_flash_icon;
|
||||||
static TrayIconState tray_flash_state;
|
static TrayIconState tray_flash_state;
|
||||||
#ifdef WIN32
|
#if !HAVE_GTK3 && defined(WIN32)
|
||||||
static guint tray_menu_timer;
|
static guint tray_menu_timer;
|
||||||
static gint64 tray_menu_inactivetime;
|
static gint64 tray_menu_inactivetime;
|
||||||
#endif
|
#endif
|
||||||
@@ -108,13 +339,6 @@ static int tray_hilight_count = 0;
|
|||||||
static int tray_file_count = 0;
|
static int tray_file_count = 0;
|
||||||
static int tray_restore_timer = 0;
|
static int tray_restore_timer = 0;
|
||||||
|
|
||||||
|
|
||||||
void tray_apply_setup (void);
|
|
||||||
static gboolean tray_menu_try_restore (void);
|
|
||||||
static void tray_cleanup (void);
|
|
||||||
static void tray_init (void);
|
|
||||||
|
|
||||||
|
|
||||||
static WinStatus
|
static WinStatus
|
||||||
tray_get_window_status (void)
|
tray_get_window_status (void)
|
||||||
{
|
{
|
||||||
@@ -168,83 +392,24 @@ tray_count_networks (void)
|
|||||||
static void
|
static void
|
||||||
tray_set_icon_state (TrayIcon icon, TrayIconState state)
|
tray_set_icon_state (TrayIcon icon, TrayIconState state)
|
||||||
{
|
{
|
||||||
#if HAVE_GTK3
|
tray_backend_set_icon (icon);
|
||||||
gtk_status_icon_set_from_icon_name (sticon, icon);
|
|
||||||
#endif
|
|
||||||
#if !HAVE_GTK3
|
|
||||||
gtk_status_icon_set_from_pixbuf (sticon, icon);
|
|
||||||
#endif
|
|
||||||
tray_icon_state = state;
|
tray_icon_state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tray_set_custom_icon_state (TrayCustomIcon icon, TrayIconState state)
|
tray_set_custom_icon_state (TrayCustomIcon icon, TrayIconState state)
|
||||||
{
|
{
|
||||||
#if HAVE_GTK3
|
tray_backend_set_icon (icon);
|
||||||
gtk_status_icon_set_from_file (sticon, icon);
|
|
||||||
#endif
|
|
||||||
#if !HAVE_GTK3
|
|
||||||
gtk_status_icon_set_from_pixbuf (sticon, icon);
|
|
||||||
#endif
|
|
||||||
tray_icon_state = state;
|
tray_icon_state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
tray_set_tooltip_text (GtkStatusIcon *icon, const char *text)
|
|
||||||
{
|
|
||||||
#if HAVE_GTK3
|
|
||||||
GObjectClass *klass;
|
|
||||||
|
|
||||||
if (!icon)
|
|
||||||
return;
|
|
||||||
|
|
||||||
klass = G_OBJECT_GET_CLASS (icon);
|
|
||||||
if (klass && g_object_class_find_property (klass, "tooltip-text"))
|
|
||||||
{
|
|
||||||
g_object_set (G_OBJECT (icon), "tooltip-text", text, NULL);
|
|
||||||
}
|
|
||||||
else if (klass && g_object_class_find_property (klass, "title"))
|
|
||||||
{
|
|
||||||
g_object_set (G_OBJECT (icon), "title", text, NULL);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if !HAVE_GTK3
|
|
||||||
gtk_status_icon_set_tooltip_text (icon, text);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
tray_is_embedded (GtkStatusIcon *icon)
|
|
||||||
{
|
|
||||||
#if HAVE_GTK3
|
|
||||||
GObjectClass *klass;
|
|
||||||
gboolean embedded = TRUE;
|
|
||||||
|
|
||||||
if (!icon)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
klass = G_OBJECT_GET_CLASS (icon);
|
|
||||||
if (klass && g_object_class_find_property (klass, "embedded"))
|
|
||||||
g_object_get (G_OBJECT (icon), "embedded", &embedded, NULL);
|
|
||||||
|
|
||||||
return embedded;
|
|
||||||
#endif
|
|
||||||
#if !HAVE_GTK3
|
|
||||||
return gtk_status_icon_is_embedded (icon);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
fe_tray_set_tooltip (const char *text)
|
fe_tray_set_tooltip (const char *text)
|
||||||
{
|
{
|
||||||
if (!sticon)
|
if (!tray_backend_active)
|
||||||
return;
|
return;
|
||||||
#if HAVE_GTK3
|
|
||||||
tray_set_tooltip_text (sticon, text);
|
tray_backend_set_tooltip (text);
|
||||||
#endif
|
|
||||||
#if !HAVE_GTK3
|
|
||||||
tray_set_tooltip_text (sticon, text);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -272,7 +437,7 @@ tray_stop_flash (void)
|
|||||||
flash_tag = 0;
|
flash_tag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sticon)
|
if (tray_backend_active)
|
||||||
{
|
{
|
||||||
tray_set_icon_state (ICON_NORMAL, TRAY_ICON_NORMAL);
|
tray_set_icon_state (ICON_NORMAL, TRAY_ICON_NORMAL);
|
||||||
nets = tray_count_networks ();
|
nets = tray_count_networks ();
|
||||||
@@ -341,7 +506,7 @@ tray_timeout_cb (gpointer userdata)
|
|||||||
static void
|
static void
|
||||||
tray_set_flash (TrayIcon icon, TrayIconState state)
|
tray_set_flash (TrayIcon icon, TrayIconState state)
|
||||||
{
|
{
|
||||||
if (!sticon)
|
if (!tray_backend_active)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* already flashing the same icon */
|
/* already flashing the same icon */
|
||||||
@@ -365,7 +530,7 @@ void
|
|||||||
fe_tray_set_flash (const char *filename1, const char *filename2, int tout)
|
fe_tray_set_flash (const char *filename1, const char *filename2, int tout)
|
||||||
{
|
{
|
||||||
tray_apply_setup ();
|
tray_apply_setup ();
|
||||||
if (!sticon)
|
if (!tray_backend_active)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tray_stop_flash ();
|
tray_stop_flash ();
|
||||||
@@ -385,7 +550,7 @@ void
|
|||||||
fe_tray_set_icon (feicon icon)
|
fe_tray_set_icon (feicon icon)
|
||||||
{
|
{
|
||||||
tray_apply_setup ();
|
tray_apply_setup ();
|
||||||
if (!sticon)
|
if (!tray_backend_active)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tray_stop_flash ();
|
tray_stop_flash ();
|
||||||
@@ -410,7 +575,7 @@ void
|
|||||||
fe_tray_set_file (const char *filename)
|
fe_tray_set_file (const char *filename)
|
||||||
{
|
{
|
||||||
tray_apply_setup ();
|
tray_apply_setup ();
|
||||||
if (!sticon)
|
if (!tray_backend_active)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tray_stop_flash ();
|
tray_stop_flash ();
|
||||||
@@ -431,7 +596,7 @@ tray_toggle_visibility (gboolean force_hide)
|
|||||||
static int fullscreen;
|
static int fullscreen;
|
||||||
GtkWindow *win;
|
GtkWindow *win;
|
||||||
|
|
||||||
if (!sticon)
|
if (!tray_backend_active)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* ph may have an invalid context now */
|
/* ph may have an invalid context now */
|
||||||
@@ -476,25 +641,22 @@ tray_toggle_visibility (gboolean force_hide)
|
|||||||
static void
|
static void
|
||||||
tray_menu_restore_cb (GtkWidget *item, gpointer userdata)
|
tray_menu_restore_cb (GtkWidget *item, gpointer userdata)
|
||||||
{
|
{
|
||||||
|
(void)item;
|
||||||
|
(void)userdata;
|
||||||
|
|
||||||
tray_toggle_visibility (FALSE);
|
tray_toggle_visibility (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tray_menu_notify_cb (GObject *tray, GParamSpec *pspec, gpointer user_data)
|
tray_menu_notify_cb (GObject *tray, GParamSpec *pspec, gpointer user_data)
|
||||||
{
|
{
|
||||||
if (sticon)
|
(void)tray;
|
||||||
|
(void)pspec;
|
||||||
|
(void)user_data;
|
||||||
|
|
||||||
|
if (tray_backend_active)
|
||||||
{
|
{
|
||||||
#if HAVE_GTK3
|
if (!tray_backend_is_embedded ())
|
||||||
if (!tray_is_embedded (sticon))
|
|
||||||
tray_restore_timer = g_timeout_add(500, (GSourceFunc)tray_menu_try_restore, NULL);
|
|
||||||
else if (tray_restore_timer)
|
|
||||||
{
|
|
||||||
g_source_remove (tray_restore_timer);
|
|
||||||
tray_restore_timer = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if !HAVE_GTK3
|
|
||||||
if (!tray_is_embedded (sticon))
|
|
||||||
{
|
{
|
||||||
tray_restore_timer = g_timeout_add(500, (GSourceFunc)tray_menu_try_restore, NULL);
|
tray_restore_timer = g_timeout_add(500, (GSourceFunc)tray_menu_try_restore, NULL);
|
||||||
}
|
}
|
||||||
@@ -506,7 +668,6 @@ tray_menu_notify_cb (GObject *tray, GParamSpec *pspec, gpointer user_data)
|
|||||||
tray_restore_timer = 0;
|
tray_restore_timer = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -521,6 +682,9 @@ tray_menu_try_restore (void)
|
|||||||
static void
|
static void
|
||||||
tray_menu_quit_cb (GtkWidget *item, gpointer userdata)
|
tray_menu_quit_cb (GtkWidget *item, gpointer userdata)
|
||||||
{
|
{
|
||||||
|
(void)item;
|
||||||
|
(void)userdata;
|
||||||
|
|
||||||
mg_open_quit_dialog (FALSE);
|
mg_open_quit_dialog (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -598,9 +762,12 @@ blink_item (unsigned int *setting, GtkWidget *menu, char *label)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !HAVE_GTK3
|
||||||
static void
|
static void
|
||||||
tray_menu_destroy (GtkWidget *menu, gpointer userdata)
|
tray_menu_destroy (GtkWidget *menu, gpointer userdata)
|
||||||
{
|
{
|
||||||
|
(void)userdata;
|
||||||
|
|
||||||
gtk_widget_destroy (menu);
|
gtk_widget_destroy (menu);
|
||||||
g_object_unref (menu);
|
g_object_unref (menu);
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@@ -612,6 +779,8 @@ tray_menu_destroy (GtkWidget *menu, gpointer userdata)
|
|||||||
static gboolean
|
static gboolean
|
||||||
tray_menu_enter_cb (GtkWidget *menu)
|
tray_menu_enter_cb (GtkWidget *menu)
|
||||||
{
|
{
|
||||||
|
(void)menu;
|
||||||
|
|
||||||
tray_menu_inactivetime = 0;
|
tray_menu_inactivetime = 0;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -619,6 +788,8 @@ tray_menu_enter_cb (GtkWidget *menu)
|
|||||||
static gboolean
|
static gboolean
|
||||||
tray_menu_left_cb (GtkWidget *menu)
|
tray_menu_left_cb (GtkWidget *menu)
|
||||||
{
|
{
|
||||||
|
(void)menu;
|
||||||
|
|
||||||
tray_menu_inactivetime = g_get_real_time ();
|
tray_menu_inactivetime = g_get_real_time ();
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -635,18 +806,21 @@ tray_check_hide (GtkWidget *menu)
|
|||||||
return G_SOURCE_CONTINUE;
|
return G_SOURCE_CONTINUE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tray_menu_settings (GtkWidget * wid, gpointer none)
|
tray_menu_settings (GtkWidget * wid, gpointer none)
|
||||||
{
|
{
|
||||||
|
(void)wid;
|
||||||
|
(void)none;
|
||||||
|
|
||||||
extern void setup_open (void);
|
extern void setup_open (void);
|
||||||
setup_open ();
|
setup_open ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tray_menu_cb (GtkWidget *widget, guint button, guint time, gpointer userdata)
|
tray_menu_populate (GtkWidget *menu)
|
||||||
{
|
{
|
||||||
static GtkWidget *menu;
|
|
||||||
GtkWidget *submenu;
|
GtkWidget *submenu;
|
||||||
GtkWidget *item;
|
GtkWidget *item;
|
||||||
int away_status;
|
int away_status;
|
||||||
@@ -654,15 +828,6 @@ tray_menu_cb (GtkWidget *widget, guint button, guint time, gpointer userdata)
|
|||||||
/* ph may have an invalid context now */
|
/* ph may have an invalid context now */
|
||||||
zoitechat_set_context (ph, zoitechat_find_context (ph, NULL, NULL));
|
zoitechat_set_context (ph, zoitechat_find_context (ph, NULL, NULL));
|
||||||
|
|
||||||
/* close any old menu */
|
|
||||||
if (G_IS_OBJECT (menu))
|
|
||||||
{
|
|
||||||
tray_menu_destroy (menu, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
menu = gtk_menu_new ();
|
|
||||||
/*gtk_menu_set_screen (GTK_MENU (menu), gtk_widget_get_screen (widget));*/
|
|
||||||
|
|
||||||
if (tray_get_window_status () == WS_HIDDEN)
|
if (tray_get_window_status () == WS_HIDDEN)
|
||||||
tray_make_item (menu, _("_Restore Window"), tray_menu_restore_cb, NULL);
|
tray_make_item (menu, _("_Restore Window"), tray_menu_restore_cb, NULL);
|
||||||
else
|
else
|
||||||
@@ -695,24 +860,67 @@ tray_menu_cb (GtkWidget *widget, guint button, guint time, gpointer userdata)
|
|||||||
mg_create_icon_item (_("_Preferences"), ICON_TRAY_PREFERENCES, menu, tray_menu_settings, NULL);
|
mg_create_icon_item (_("_Preferences"), ICON_TRAY_PREFERENCES, menu, tray_menu_settings, NULL);
|
||||||
tray_make_item (menu, NULL, tray_menu_quit_cb, NULL);
|
tray_make_item (menu, NULL, tray_menu_quit_cb, NULL);
|
||||||
mg_create_icon_item (_("_Quit"), ICON_TRAY_QUIT, menu, tray_menu_quit_cb, NULL);
|
mg_create_icon_item (_("_Quit"), ICON_TRAY_QUIT, menu, tray_menu_quit_cb, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_GTK3
|
||||||
|
static void
|
||||||
|
tray_menu_clear (GtkWidget *menu)
|
||||||
|
{
|
||||||
|
GList *children;
|
||||||
|
GList *iter;
|
||||||
|
|
||||||
|
children = gtk_container_get_children (GTK_CONTAINER (menu));
|
||||||
|
for (iter = children; iter; iter = iter->next)
|
||||||
|
gtk_widget_destroy (GTK_WIDGET (iter->data));
|
||||||
|
g_list_free (children);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tray_menu_show_cb (GtkWidget *menu, gpointer userdata)
|
||||||
|
{
|
||||||
|
(void)userdata;
|
||||||
|
|
||||||
|
tray_menu_clear (menu);
|
||||||
|
tray_menu_populate (menu);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !HAVE_GTK3
|
||||||
|
static void
|
||||||
|
tray_menu_cb (GtkWidget *widget, guint button, guint time, gpointer userdata)
|
||||||
|
{
|
||||||
|
static GtkWidget *menu;
|
||||||
|
|
||||||
|
(void)widget;
|
||||||
|
|
||||||
|
/* close any old menu */
|
||||||
|
if (G_IS_OBJECT (menu))
|
||||||
|
{
|
||||||
|
tray_menu_destroy (menu, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
menu = gtk_menu_new ();
|
||||||
|
/*gtk_menu_set_screen (GTK_MENU (menu), gtk_widget_get_screen (widget));*/
|
||||||
|
tray_menu_populate (menu);
|
||||||
|
|
||||||
g_object_ref (menu);
|
g_object_ref (menu);
|
||||||
g_object_ref_sink (menu);
|
g_object_ref_sink (menu);
|
||||||
g_object_unref (menu);
|
g_object_unref (menu);
|
||||||
g_signal_connect (G_OBJECT (menu), "selection-done",
|
g_signal_connect (G_OBJECT (menu), "selection-done",
|
||||||
G_CALLBACK (tray_menu_destroy), NULL);
|
G_CALLBACK (tray_menu_destroy), NULL);
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
g_signal_connect (G_OBJECT (menu), "leave-notify-event",
|
g_signal_connect (G_OBJECT (menu), "leave-notify-event",
|
||||||
G_CALLBACK (tray_menu_left_cb), NULL);
|
G_CALLBACK (tray_menu_left_cb), NULL);
|
||||||
g_signal_connect (G_OBJECT (menu), "enter-notify-event",
|
g_signal_connect (G_OBJECT (menu), "enter-notify-event",
|
||||||
G_CALLBACK (tray_menu_enter_cb), NULL);
|
G_CALLBACK (tray_menu_enter_cb), NULL);
|
||||||
|
|
||||||
tray_menu_timer = g_timeout_add (500, (GSourceFunc)tray_check_hide, menu);
|
tray_menu_timer = g_timeout_add (500, (GSourceFunc)tray_check_hide, menu);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL,
|
gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL,
|
||||||
userdata, button, time);
|
userdata, button, time);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tray_init (void)
|
tray_init (void)
|
||||||
@@ -724,24 +932,10 @@ tray_init (void)
|
|||||||
custom_icon1 = NULL;
|
custom_icon1 = NULL;
|
||||||
custom_icon2 = NULL;
|
custom_icon2 = NULL;
|
||||||
|
|
||||||
#if HAVE_GTK3
|
if (!tray_backend_init ())
|
||||||
sticon = gtk_status_icon_new_from_icon_name (ICON_NORMAL);
|
|
||||||
#endif
|
|
||||||
#if !HAVE_GTK3
|
|
||||||
sticon = gtk_status_icon_new_from_pixbuf (ICON_NORMAL);
|
|
||||||
#endif
|
|
||||||
if (!sticon)
|
|
||||||
return;
|
return;
|
||||||
tray_icon_state = TRAY_ICON_NORMAL;
|
tray_icon_state = TRAY_ICON_NORMAL;
|
||||||
|
tray_set_icon_state (ICON_NORMAL, TRAY_ICON_NORMAL);
|
||||||
g_signal_connect (G_OBJECT (sticon), "popup-menu",
|
|
||||||
G_CALLBACK (tray_menu_cb), sticon);
|
|
||||||
|
|
||||||
g_signal_connect (G_OBJECT (sticon), "activate",
|
|
||||||
G_CALLBACK (tray_menu_restore_cb), NULL);
|
|
||||||
|
|
||||||
g_signal_connect (G_OBJECT (sticon), "notify::embedded",
|
|
||||||
G_CALLBACK (tray_menu_notify_cb), NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -873,17 +1067,14 @@ tray_cleanup (void)
|
|||||||
{
|
{
|
||||||
tray_stop_flash ();
|
tray_stop_flash ();
|
||||||
|
|
||||||
if (sticon)
|
if (tray_backend_active)
|
||||||
{
|
tray_backend_cleanup ();
|
||||||
g_object_unref ((GObject *)sticon);
|
|
||||||
sticon = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tray_apply_setup (void)
|
tray_apply_setup (void)
|
||||||
{
|
{
|
||||||
if (sticon)
|
if (tray_backend_active)
|
||||||
{
|
{
|
||||||
if (!prefs.hex_gui_tray)
|
if (!prefs.hex_gui_tray)
|
||||||
tray_cleanup ();
|
tray_cleanup ();
|
||||||
|
|||||||
Reference in New Issue
Block a user