2013-03-31 21:44:48 +02:00
|
|
|
/* X-Chat
|
|
|
|
|
* Copyright (C) 2006-2007 Peter Zelezny.
|
|
|
|
|
*
|
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
|
*/
|
2011-02-24 04:14:30 +01:00
|
|
|
|
|
|
|
|
#include <string.h>
|
2026-01-05 23:12:38 -07:00
|
|
|
#include "../common/zoitechat-plugin.h"
|
|
|
|
|
#include "../common/zoitechat.h"
|
|
|
|
|
#include "../common/zoitechatc.h"
|
2011-02-24 04:14:30 +01:00
|
|
|
#include "../common/inbound.h"
|
|
|
|
|
#include "../common/server.h"
|
|
|
|
|
#include "../common/fe.h"
|
|
|
|
|
#include "../common/util.h"
|
2012-07-21 14:26:19 +02:00
|
|
|
#include "../common/outbound.h"
|
2011-02-24 04:14:30 +01:00
|
|
|
#include "fe-gtk.h"
|
|
|
|
|
#include "pixmaps.h"
|
|
|
|
|
#include "maingui.h"
|
|
|
|
|
#include "menu.h"
|
2017-08-31 09:52:45 -04:00
|
|
|
#include "gtkutil.h"
|
2011-02-24 04:14:30 +01:00
|
|
|
|
Added per-file ICON_* macros with GTK3 icon-name mappings and GTK2 stock fallbacks across GTK UI modules like banlist, DCC, editlist, ignore, URL grabber, notify, text events, tray menu, chanview tabs, and join dialog UI.
Updated GTK helper usages to reference the new ICON_* (and label) macros so GTK3 builds no longer pass stock IDs to button/icon helpers or dialogs, including banlist buttons, DCC windows, rawlog actions, notify dialog/buttons, pevent dialog buttons, tray menu items, and join dialog image helper usage.
2026-01-30 09:23:52 -07:00
|
|
|
#if HAVE_GTK3
|
2026-01-30 20:47:26 -07:00
|
|
|
#include <gio/gio.h>
|
2026-01-30 20:07:36 -07:00
|
|
|
#if defined(HAVE_AYATANA_APPINDICATOR)
|
|
|
|
|
#include <libayatana-appindicator/app-indicator.h>
|
|
|
|
|
#else
|
|
|
|
|
#include <libappindicator/app-indicator.h>
|
|
|
|
|
#endif
|
Added per-file ICON_* macros with GTK3 icon-name mappings and GTK2 stock fallbacks across GTK UI modules like banlist, DCC, editlist, ignore, URL grabber, notify, text events, tray menu, chanview tabs, and join dialog UI.
Updated GTK helper usages to reference the new ICON_* (and label) macros so GTK3 builds no longer pass stock IDs to button/icon helpers or dialogs, including banlist buttons, DCC windows, rawlog actions, notify dialog/buttons, pevent dialog buttons, tray menu items, and join dialog image helper usage.
2026-01-30 09:23:52 -07:00
|
|
|
#define ICON_TRAY_PREFERENCES "preferences-system"
|
|
|
|
|
#define ICON_TRAY_QUIT "application-exit"
|
|
|
|
|
#endif
|
|
|
|
|
#if !HAVE_GTK3
|
|
|
|
|
#define ICON_TRAY_PREFERENCES GTK_STOCK_PREFERENCES
|
|
|
|
|
#define ICON_TRAY_QUIT GTK_STOCK_QUIT
|
|
|
|
|
#endif
|
|
|
|
|
|
2011-12-11 17:34:02 +01:00
|
|
|
#ifndef WIN32
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2011-02-24 04:14:30 +01:00
|
|
|
typedef enum /* current icon status */
|
|
|
|
|
{
|
2026-01-30 18:47:23 -07:00
|
|
|
TRAY_ICON_NONE,
|
|
|
|
|
TRAY_ICON_NORMAL,
|
|
|
|
|
TRAY_ICON_MESSAGE,
|
|
|
|
|
TRAY_ICON_HIGHLIGHT,
|
|
|
|
|
TRAY_ICON_FILEOFFER,
|
|
|
|
|
TRAY_ICON_CUSTOM1,
|
|
|
|
|
TRAY_ICON_CUSTOM2
|
|
|
|
|
} TrayIconState;
|
2011-02-24 04:14:30 +01:00
|
|
|
|
|
|
|
|
typedef enum
|
|
|
|
|
{
|
|
|
|
|
WS_FOCUSED,
|
|
|
|
|
WS_NORMAL,
|
|
|
|
|
WS_HIDDEN
|
|
|
|
|
} WinStatus;
|
|
|
|
|
|
2026-01-30 18:47:23 -07:00
|
|
|
#if HAVE_GTK3
|
2026-01-30 20:07:36 -07:00
|
|
|
/* GTK3: use AppIndicator/StatusNotifier item for tray integration. */
|
2026-01-30 20:47:26 -07:00
|
|
|
typedef GIcon *TrayIcon;
|
|
|
|
|
typedef GIcon *TrayCustomIcon;
|
|
|
|
|
#define tray_icon_free(i) g_object_unref(i)
|
|
|
|
|
|
|
|
|
|
#define ICON_NORMAL_NAME "net.zoite.Zoitechat"
|
|
|
|
|
#define ICON_MSG_NAME "mail-unread"
|
|
|
|
|
#define ICON_HILIGHT_NAME "dialog-warning"
|
|
|
|
|
#define ICON_FILE_NAME "folder-download"
|
|
|
|
|
|
|
|
|
|
static TrayIcon tray_icon_normal;
|
|
|
|
|
static TrayIcon tray_icon_msg;
|
|
|
|
|
static TrayIcon tray_icon_hilight;
|
|
|
|
|
static TrayIcon tray_icon_file;
|
|
|
|
|
|
|
|
|
|
#define ICON_NORMAL tray_icon_normal
|
|
|
|
|
#define ICON_MSG tray_icon_msg
|
|
|
|
|
#define ICON_HILIGHT tray_icon_hilight
|
|
|
|
|
#define ICON_FILE tray_icon_file
|
2026-01-30 18:47:23 -07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if !HAVE_GTK3
|
2011-02-24 04:14:30 +01:00
|
|
|
typedef GdkPixbuf* TrayIcon;
|
2026-01-30 18:47:23 -07:00
|
|
|
typedef GdkPixbuf* TrayCustomIcon;
|
2011-02-24 04:14:30 +01:00
|
|
|
#define tray_icon_from_file(f) gdk_pixbuf_new_from_file(f,NULL)
|
|
|
|
|
#define tray_icon_free(i) g_object_unref(i)
|
|
|
|
|
|
2017-06-25 04:42:57 +02:00
|
|
|
#define ICON_NORMAL pix_tray_normal
|
2012-11-03 02:57:24 +01:00
|
|
|
#define ICON_MSG pix_tray_message
|
|
|
|
|
#define ICON_HILIGHT pix_tray_highlight
|
|
|
|
|
#define ICON_FILE pix_tray_fileoffer
|
2026-01-30 18:47:23 -07:00
|
|
|
#endif
|
2011-02-24 04:14:30 +01:00
|
|
|
#define TIMEOUT 500
|
|
|
|
|
|
2026-01-30 20:07:36 -07:00
|
|
|
void tray_apply_setup (void);
|
|
|
|
|
static gboolean tray_menu_try_restore (void);
|
|
|
|
|
static void tray_cleanup (void);
|
|
|
|
|
static void tray_init (void);
|
2026-01-31 13:24:04 -07:00
|
|
|
static void tray_set_icon_state (TrayIcon icon, TrayIconState state);
|
2026-01-30 20:07:36 -07:00
|
|
|
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;
|
|
|
|
|
|
2026-01-31 13:24:04 -07:00
|
|
|
static gint flash_tag;
|
|
|
|
|
static TrayIconState tray_icon_state;
|
|
|
|
|
static TrayIcon tray_flash_icon;
|
|
|
|
|
static TrayIconState tray_flash_state;
|
|
|
|
|
#if !HAVE_GTK3 && defined(WIN32)
|
|
|
|
|
static guint tray_menu_timer;
|
|
|
|
|
static gint64 tray_menu_inactivetime;
|
|
|
|
|
#endif
|
|
|
|
|
static zoitechat_plugin *ph;
|
|
|
|
|
|
|
|
|
|
static TrayCustomIcon custom_icon1;
|
|
|
|
|
static TrayCustomIcon custom_icon2;
|
|
|
|
|
|
|
|
|
|
static int tray_priv_count = 0;
|
|
|
|
|
static int tray_pub_count = 0;
|
|
|
|
|
static int tray_hilight_count = 0;
|
|
|
|
|
static int tray_file_count = 0;
|
|
|
|
|
static int tray_restore_timer = 0;
|
|
|
|
|
|
2026-01-30 20:07:36 -07:00
|
|
|
#if HAVE_GTK3
|
2026-01-30 20:47:26 -07:00
|
|
|
static TrayCustomIcon
|
|
|
|
|
tray_icon_from_file (const char *filename)
|
|
|
|
|
{
|
|
|
|
|
GFile *file;
|
|
|
|
|
TrayCustomIcon icon;
|
|
|
|
|
|
|
|
|
|
if (!filename)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
file = g_file_new_for_path (filename);
|
|
|
|
|
icon = g_file_icon_new (file);
|
|
|
|
|
g_object_unref (file);
|
|
|
|
|
|
|
|
|
|
return icon;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-31 12:12:55 -07:00
|
|
|
static char *
|
|
|
|
|
tray_gtk3_cache_pixbuf_icon (const char *basename, GdkPixbuf *pixbuf)
|
|
|
|
|
{
|
|
|
|
|
char *cache_dir;
|
|
|
|
|
char *filename;
|
|
|
|
|
char *path;
|
|
|
|
|
|
|
|
|
|
if (!pixbuf || !basename)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
cache_dir = g_build_filename (g_get_user_cache_dir (), "zoitechat", "tray-icons", NULL);
|
|
|
|
|
if (g_mkdir_with_parents (cache_dir, 0700) != 0)
|
|
|
|
|
{
|
|
|
|
|
g_free (cache_dir);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
filename = g_strdup_printf ("%s.png", basename);
|
|
|
|
|
path = g_build_filename (cache_dir, filename, NULL);
|
|
|
|
|
g_free (filename);
|
|
|
|
|
g_free (cache_dir);
|
|
|
|
|
|
|
|
|
|
if (!g_file_test (path, G_FILE_TEST_EXISTS))
|
|
|
|
|
gdk_pixbuf_save (pixbuf, path, "png", NULL, NULL);
|
|
|
|
|
|
|
|
|
|
return path;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static char *
|
|
|
|
|
tray_gtk3_fallback_icon_path_for_name (const char *name)
|
|
|
|
|
{
|
|
|
|
|
if (g_strcmp0 (name, ICON_NORMAL_NAME) == 0)
|
|
|
|
|
return tray_gtk3_cache_pixbuf_icon ("tray_normal", pix_tray_normal);
|
|
|
|
|
if (g_strcmp0 (name, ICON_MSG_NAME) == 0)
|
|
|
|
|
return tray_gtk3_cache_pixbuf_icon ("tray_message", pix_tray_message);
|
|
|
|
|
if (g_strcmp0 (name, ICON_HILIGHT_NAME) == 0)
|
|
|
|
|
return tray_gtk3_cache_pixbuf_icon ("tray_highlight", pix_tray_highlight);
|
|
|
|
|
if (g_strcmp0 (name, ICON_FILE_NAME) == 0)
|
|
|
|
|
return tray_gtk3_cache_pixbuf_icon ("tray_fileoffer", pix_tray_fileoffer);
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-30 20:47:26 -07:00
|
|
|
static void
|
|
|
|
|
tray_gtk3_icons_init (void)
|
|
|
|
|
{
|
|
|
|
|
if (!tray_icon_normal)
|
|
|
|
|
tray_icon_normal = g_themed_icon_new (ICON_NORMAL_NAME);
|
|
|
|
|
if (!tray_icon_msg)
|
|
|
|
|
tray_icon_msg = g_themed_icon_new (ICON_MSG_NAME);
|
|
|
|
|
if (!tray_icon_hilight)
|
|
|
|
|
tray_icon_hilight = g_themed_icon_new (ICON_HILIGHT_NAME);
|
|
|
|
|
if (!tray_icon_file)
|
|
|
|
|
tray_icon_file = g_themed_icon_new (ICON_FILE_NAME);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
tray_gtk3_icons_cleanup (void)
|
|
|
|
|
{
|
|
|
|
|
g_clear_object (&tray_icon_normal);
|
|
|
|
|
g_clear_object (&tray_icon_msg);
|
|
|
|
|
g_clear_object (&tray_icon_hilight);
|
|
|
|
|
g_clear_object (&tray_icon_file);
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-31 13:24:04 -07:00
|
|
|
static GtkIconTheme *tray_gtk3_icon_theme = NULL;
|
|
|
|
|
static gulong tray_gtk3_icon_theme_changed_handler = 0;
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
tray_gtk3_reapply_icon_state (void)
|
|
|
|
|
{
|
|
|
|
|
switch (tray_icon_state)
|
|
|
|
|
{
|
|
|
|
|
case TRAY_ICON_NORMAL:
|
|
|
|
|
tray_set_icon_state (ICON_NORMAL, TRAY_ICON_NORMAL);
|
|
|
|
|
break;
|
|
|
|
|
case TRAY_ICON_MESSAGE:
|
|
|
|
|
tray_set_icon_state (ICON_MSG, TRAY_ICON_MESSAGE);
|
|
|
|
|
break;
|
|
|
|
|
case TRAY_ICON_HIGHLIGHT:
|
|
|
|
|
tray_set_icon_state (ICON_HILIGHT, TRAY_ICON_HIGHLIGHT);
|
|
|
|
|
break;
|
|
|
|
|
case TRAY_ICON_FILEOFFER:
|
|
|
|
|
tray_set_icon_state (ICON_FILE, TRAY_ICON_FILEOFFER);
|
|
|
|
|
break;
|
|
|
|
|
case TRAY_ICON_CUSTOM1:
|
|
|
|
|
tray_set_icon_state (custom_icon1, TRAY_ICON_CUSTOM1);
|
|
|
|
|
break;
|
|
|
|
|
case TRAY_ICON_CUSTOM2:
|
|
|
|
|
tray_set_icon_state (custom_icon2, TRAY_ICON_CUSTOM2);
|
|
|
|
|
break;
|
|
|
|
|
case TRAY_ICON_NONE:
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
tray_gtk3_theme_changed_cb (GtkIconTheme *theme, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
(void)theme;
|
|
|
|
|
(void)user_data;
|
|
|
|
|
|
|
|
|
|
if (!tray_backend_active)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
tray_gtk3_icons_cleanup ();
|
|
|
|
|
tray_gtk3_icons_init ();
|
|
|
|
|
tray_gtk3_reapply_icon_state ();
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-30 20:47:26 -07:00
|
|
|
static const char *
|
|
|
|
|
tray_gtk3_icon_to_name (TrayIcon icon, char **allocated)
|
|
|
|
|
{
|
|
|
|
|
const char * const *names;
|
2026-01-31 12:12:55 -07:00
|
|
|
GtkIconTheme *theme;
|
2026-01-30 20:47:26 -07:00
|
|
|
GFile *file;
|
|
|
|
|
|
|
|
|
|
if (!icon)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
if (G_IS_THEMED_ICON (icon))
|
|
|
|
|
{
|
|
|
|
|
names = g_themed_icon_get_names (G_THEMED_ICON (icon));
|
|
|
|
|
if (names && names[0])
|
2026-01-31 12:12:55 -07:00
|
|
|
{
|
|
|
|
|
theme = gtk_icon_theme_get_default ();
|
|
|
|
|
if (theme && gtk_icon_theme_has_icon (theme, names[0]))
|
|
|
|
|
return names[0];
|
|
|
|
|
|
|
|
|
|
*allocated = tray_gtk3_fallback_icon_path_for_name (names[0]);
|
|
|
|
|
if (*allocated)
|
|
|
|
|
return *allocated;
|
|
|
|
|
}
|
2026-01-30 20:47:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (G_IS_FILE_ICON (icon))
|
|
|
|
|
{
|
|
|
|
|
file = g_file_icon_get_file (G_FILE_ICON (icon));
|
|
|
|
|
if (file)
|
|
|
|
|
{
|
|
|
|
|
*allocated = g_file_get_path (file);
|
|
|
|
|
if (*allocated)
|
|
|
|
|
return *allocated;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*allocated = g_icon_to_string (icon);
|
|
|
|
|
return *allocated;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-30 20:07:36 -07:00
|
|
|
static void
|
|
|
|
|
tray_app_indicator_set_icon (TrayIcon icon)
|
|
|
|
|
{
|
2026-01-30 20:47:26 -07:00
|
|
|
char *icon_name_alloc = NULL;
|
|
|
|
|
const char *icon_name;
|
|
|
|
|
|
2026-01-30 20:07:36 -07:00
|
|
|
if (!tray_indicator)
|
|
|
|
|
return;
|
|
|
|
|
|
2026-01-30 20:47:26 -07:00
|
|
|
icon_name = tray_gtk3_icon_to_name (icon, &icon_name_alloc);
|
|
|
|
|
if (!icon_name)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
app_indicator_set_icon_full (tray_indicator, icon_name, _(DISPLAY_NAME));
|
2026-01-30 20:07:36 -07:00
|
|
|
app_indicator_set_status (tray_indicator, APP_INDICATOR_STATUS_ACTIVE);
|
2026-01-30 20:47:26 -07:00
|
|
|
|
|
|
|
|
g_free (icon_name_alloc);
|
2026-01-30 20:07:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
2026-01-30 20:47:26 -07:00
|
|
|
tray_indicator = app_indicator_new ("zoitechat", ICON_NORMAL_NAME,
|
2026-01-30 20:07:36 -07:00
|
|
|
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;
|
|
|
|
|
|
2026-01-30 20:47:26 -07:00
|
|
|
#if HAVE_GTK3
|
|
|
|
|
tray_gtk3_icons_init ();
|
2026-01-31 13:24:04 -07:00
|
|
|
if (!tray_gtk3_icon_theme)
|
|
|
|
|
tray_gtk3_icon_theme = gtk_icon_theme_get_default ();
|
|
|
|
|
if (tray_gtk3_icon_theme && tray_gtk3_icon_theme_changed_handler == 0)
|
|
|
|
|
{
|
|
|
|
|
tray_gtk3_icon_theme_changed_handler = g_signal_connect (
|
|
|
|
|
tray_gtk3_icon_theme,
|
|
|
|
|
"changed",
|
|
|
|
|
G_CALLBACK (tray_gtk3_theme_changed_cb),
|
|
|
|
|
NULL);
|
|
|
|
|
}
|
2026-01-30 20:47:26 -07:00
|
|
|
#endif
|
2026-01-30 20:07:36 -07:00
|
|
|
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 ();
|
|
|
|
|
|
2026-01-30 20:47:26 -07:00
|
|
|
#if HAVE_GTK3
|
2026-01-31 13:24:04 -07:00
|
|
|
if (tray_gtk3_icon_theme && tray_gtk3_icon_theme_changed_handler)
|
|
|
|
|
{
|
|
|
|
|
g_signal_handler_disconnect (tray_gtk3_icon_theme,
|
|
|
|
|
tray_gtk3_icon_theme_changed_handler);
|
|
|
|
|
tray_gtk3_icon_theme_changed_handler = 0;
|
|
|
|
|
}
|
|
|
|
|
tray_gtk3_icon_theme = NULL;
|
2026-01-30 20:47:26 -07:00
|
|
|
tray_gtk3_icons_cleanup ();
|
|
|
|
|
#endif
|
2026-01-30 20:07:36 -07:00
|
|
|
tray_backend_active = FALSE;
|
|
|
|
|
}
|
2011-02-24 04:14:30 +01:00
|
|
|
|
|
|
|
|
static WinStatus
|
|
|
|
|
tray_get_window_status (void)
|
|
|
|
|
{
|
|
|
|
|
const char *st;
|
|
|
|
|
|
2026-01-05 23:12:38 -07:00
|
|
|
st = zoitechat_get_info (ph, "win_status");
|
2011-02-24 04:14:30 +01:00
|
|
|
|
|
|
|
|
if (!st)
|
|
|
|
|
return WS_HIDDEN;
|
|
|
|
|
|
|
|
|
|
if (!strcmp (st, "active"))
|
|
|
|
|
return WS_FOCUSED;
|
|
|
|
|
|
|
|
|
|
if (!strcmp (st, "hidden"))
|
|
|
|
|
return WS_HIDDEN;
|
|
|
|
|
|
|
|
|
|
return WS_NORMAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
tray_count_channels (void)
|
|
|
|
|
{
|
|
|
|
|
int cons = 0;
|
|
|
|
|
GSList *list;
|
|
|
|
|
session *sess;
|
|
|
|
|
|
|
|
|
|
for (list = sess_list; list; list = list->next)
|
|
|
|
|
{
|
|
|
|
|
sess = list->data;
|
|
|
|
|
if (sess->server->connected && sess->channel[0] &&
|
|
|
|
|
sess->type == SESS_CHANNEL)
|
|
|
|
|
cons++;
|
|
|
|
|
}
|
|
|
|
|
return cons;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
tray_count_networks (void)
|
|
|
|
|
{
|
|
|
|
|
int cons = 0;
|
|
|
|
|
GSList *list;
|
|
|
|
|
|
|
|
|
|
for (list = serv_list; list; list = list->next)
|
|
|
|
|
{
|
|
|
|
|
if (((server *)list->data)->connected)
|
|
|
|
|
cons++;
|
|
|
|
|
}
|
|
|
|
|
return cons;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-30 18:47:23 -07:00
|
|
|
static void
|
|
|
|
|
tray_set_icon_state (TrayIcon icon, TrayIconState state)
|
|
|
|
|
{
|
2026-01-30 20:07:36 -07:00
|
|
|
tray_backend_set_icon (icon);
|
2026-01-30 18:47:23 -07:00
|
|
|
tray_icon_state = state;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
tray_set_custom_icon_state (TrayCustomIcon icon, TrayIconState state)
|
|
|
|
|
{
|
2026-01-30 20:07:36 -07:00
|
|
|
tray_backend_set_icon (icon);
|
2026-01-30 18:47:23 -07:00
|
|
|
tray_icon_state = state;
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-24 04:14:30 +01:00
|
|
|
void
|
|
|
|
|
fe_tray_set_tooltip (const char *text)
|
|
|
|
|
{
|
2026-01-30 20:07:36 -07:00
|
|
|
if (!tray_backend_active)
|
2026-01-30 19:37:29 -07:00
|
|
|
return;
|
2026-01-30 20:07:36 -07:00
|
|
|
|
|
|
|
|
tray_backend_set_tooltip (text);
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
tray_set_tipf (const char *format, ...)
|
|
|
|
|
{
|
|
|
|
|
va_list args;
|
|
|
|
|
char *buf;
|
|
|
|
|
|
|
|
|
|
va_start (args, format);
|
|
|
|
|
buf = g_strdup_vprintf (format, args);
|
|
|
|
|
va_end (args);
|
|
|
|
|
|
|
|
|
|
fe_tray_set_tooltip (buf);
|
|
|
|
|
g_free (buf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
tray_stop_flash (void)
|
|
|
|
|
{
|
|
|
|
|
int nets, chans;
|
|
|
|
|
|
|
|
|
|
if (flash_tag)
|
|
|
|
|
{
|
|
|
|
|
g_source_remove (flash_tag);
|
|
|
|
|
flash_tag = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-30 20:07:36 -07:00
|
|
|
if (tray_backend_active)
|
2011-02-24 04:14:30 +01:00
|
|
|
{
|
2026-01-30 18:47:23 -07:00
|
|
|
tray_set_icon_state (ICON_NORMAL, TRAY_ICON_NORMAL);
|
2011-02-24 04:14:30 +01:00
|
|
|
nets = tray_count_networks ();
|
|
|
|
|
chans = tray_count_channels ();
|
|
|
|
|
if (nets)
|
2017-09-15 17:36:02 -04:00
|
|
|
tray_set_tipf (_("Connected to %u networks and %u channels - %s"),
|
|
|
|
|
nets, chans, _(DISPLAY_NAME));
|
2011-02-24 04:14:30 +01:00
|
|
|
else
|
2017-09-15 17:36:02 -04:00
|
|
|
tray_set_tipf ("%s - %s", _("Not connected."), _(DISPLAY_NAME));
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (custom_icon1)
|
|
|
|
|
{
|
|
|
|
|
tray_icon_free (custom_icon1);
|
|
|
|
|
custom_icon1 = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (custom_icon2)
|
|
|
|
|
{
|
|
|
|
|
tray_icon_free (custom_icon2);
|
|
|
|
|
custom_icon2 = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-30 18:47:23 -07:00
|
|
|
tray_flash_icon = NULL;
|
|
|
|
|
tray_flash_state = TRAY_ICON_NONE;
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
tray_reset_counts (void)
|
|
|
|
|
{
|
|
|
|
|
tray_priv_count = 0;
|
|
|
|
|
tray_pub_count = 0;
|
|
|
|
|
tray_hilight_count = 0;
|
|
|
|
|
tray_file_count = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
2026-01-30 18:47:23 -07:00
|
|
|
tray_timeout_cb (gpointer userdata)
|
2011-02-24 04:14:30 +01:00
|
|
|
{
|
2026-01-30 18:47:23 -07:00
|
|
|
(void)userdata;
|
|
|
|
|
|
2011-02-24 04:14:30 +01:00
|
|
|
if (custom_icon1)
|
|
|
|
|
{
|
2026-01-30 18:47:23 -07:00
|
|
|
if (tray_icon_state == TRAY_ICON_CUSTOM1)
|
2011-02-24 04:14:30 +01:00
|
|
|
{
|
|
|
|
|
if (custom_icon2)
|
2026-01-30 18:47:23 -07:00
|
|
|
tray_set_custom_icon_state (custom_icon2, TRAY_ICON_CUSTOM2);
|
2011-02-24 04:14:30 +01:00
|
|
|
else
|
2026-01-30 18:47:23 -07:00
|
|
|
tray_set_icon_state (ICON_NORMAL, TRAY_ICON_NORMAL);
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2026-01-30 18:47:23 -07:00
|
|
|
tray_set_custom_icon_state (custom_icon1, TRAY_ICON_CUSTOM1);
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2026-01-30 18:47:23 -07:00
|
|
|
if (tray_icon_state == TRAY_ICON_NORMAL)
|
|
|
|
|
tray_set_icon_state (tray_flash_icon, tray_flash_state);
|
2011-02-24 04:14:30 +01:00
|
|
|
else
|
2026-01-30 18:47:23 -07:00
|
|
|
tray_set_icon_state (ICON_NORMAL, TRAY_ICON_NORMAL);
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2026-01-30 18:47:23 -07:00
|
|
|
tray_set_flash (TrayIcon icon, TrayIconState state)
|
2011-02-24 04:14:30 +01:00
|
|
|
{
|
2026-01-30 20:07:36 -07:00
|
|
|
if (!tray_backend_active)
|
2011-02-24 04:14:30 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* already flashing the same icon */
|
2026-01-30 18:47:23 -07:00
|
|
|
if (flash_tag && tray_icon_state == state)
|
2011-02-24 04:14:30 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* no flashing if window is focused */
|
|
|
|
|
if (tray_get_window_status () == WS_FOCUSED)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
tray_stop_flash ();
|
|
|
|
|
|
2026-01-30 18:47:23 -07:00
|
|
|
tray_flash_icon = icon;
|
|
|
|
|
tray_flash_state = state;
|
|
|
|
|
tray_set_icon_state (icon, state);
|
2012-12-20 19:53:58 -05:00
|
|
|
if (prefs.hex_gui_tray_blink)
|
2026-01-30 18:47:23 -07:00
|
|
|
flash_tag = g_timeout_add (TIMEOUT, (GSourceFunc) tray_timeout_cb, NULL);
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fe_tray_set_flash (const char *filename1, const char *filename2, int tout)
|
|
|
|
|
{
|
|
|
|
|
tray_apply_setup ();
|
2026-01-30 20:07:36 -07:00
|
|
|
if (!tray_backend_active)
|
2011-02-24 04:14:30 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
tray_stop_flash ();
|
|
|
|
|
|
|
|
|
|
if (tout == -1)
|
|
|
|
|
tout = TIMEOUT;
|
|
|
|
|
|
|
|
|
|
custom_icon1 = tray_icon_from_file (filename1);
|
|
|
|
|
if (filename2)
|
|
|
|
|
custom_icon2 = tray_icon_from_file (filename2);
|
|
|
|
|
|
2026-01-30 18:47:23 -07:00
|
|
|
tray_set_custom_icon_state (custom_icon1, TRAY_ICON_CUSTOM1);
|
2011-02-24 04:14:30 +01:00
|
|
|
flash_tag = g_timeout_add (tout, (GSourceFunc) tray_timeout_cb, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fe_tray_set_icon (feicon icon)
|
|
|
|
|
{
|
|
|
|
|
tray_apply_setup ();
|
2026-01-30 20:07:36 -07:00
|
|
|
if (!tray_backend_active)
|
2011-02-24 04:14:30 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
tray_stop_flash ();
|
|
|
|
|
|
|
|
|
|
switch (icon)
|
|
|
|
|
{
|
|
|
|
|
case FE_ICON_NORMAL:
|
|
|
|
|
break;
|
|
|
|
|
case FE_ICON_MESSAGE:
|
2012-07-17 20:45:51 +02:00
|
|
|
case FE_ICON_PRIVMSG:
|
2026-01-30 18:47:23 -07:00
|
|
|
tray_set_flash (ICON_MSG, TRAY_ICON_MESSAGE);
|
2011-02-24 04:14:30 +01:00
|
|
|
break;
|
|
|
|
|
case FE_ICON_HIGHLIGHT:
|
2026-01-30 18:47:23 -07:00
|
|
|
tray_set_flash (ICON_HILIGHT, TRAY_ICON_HIGHLIGHT);
|
2011-02-24 04:14:30 +01:00
|
|
|
break;
|
|
|
|
|
case FE_ICON_FILEOFFER:
|
2026-01-30 18:47:23 -07:00
|
|
|
tray_set_flash (ICON_FILE, TRAY_ICON_FILEOFFER);
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
fe_tray_set_file (const char *filename)
|
|
|
|
|
{
|
|
|
|
|
tray_apply_setup ();
|
2026-01-30 20:07:36 -07:00
|
|
|
if (!tray_backend_active)
|
2011-02-24 04:14:30 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
tray_stop_flash ();
|
|
|
|
|
|
|
|
|
|
if (filename)
|
|
|
|
|
{
|
|
|
|
|
custom_icon1 = tray_icon_from_file (filename);
|
2026-01-30 18:47:23 -07:00
|
|
|
tray_set_custom_icon_state (custom_icon1, TRAY_ICON_CUSTOM1);
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
|
tray_toggle_visibility (gboolean force_hide)
|
|
|
|
|
{
|
|
|
|
|
static int x, y;
|
|
|
|
|
static GdkScreen *screen;
|
2012-12-16 12:54:15 -05:00
|
|
|
static int maximized;
|
2013-09-19 17:52:17 -04:00
|
|
|
static int fullscreen;
|
2011-02-24 04:14:30 +01:00
|
|
|
GtkWindow *win;
|
|
|
|
|
|
2026-01-30 20:07:36 -07:00
|
|
|
if (!tray_backend_active)
|
2011-02-24 04:14:30 +01:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
/* ph may have an invalid context now */
|
2026-01-05 23:12:38 -07:00
|
|
|
zoitechat_set_context (ph, zoitechat_find_context (ph, NULL, NULL));
|
2011-02-24 04:14:30 +01:00
|
|
|
|
2026-01-05 23:12:38 -07:00
|
|
|
win = GTK_WINDOW (zoitechat_get_info (ph, "gtkwin_ptr"));
|
2011-02-24 04:14:30 +01:00
|
|
|
|
|
|
|
|
tray_stop_flash ();
|
|
|
|
|
tray_reset_counts ();
|
|
|
|
|
|
|
|
|
|
if (!win)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
if (force_hide || gtk_widget_get_visible (GTK_WIDGET (win)))
|
|
|
|
|
{
|
2012-12-20 19:39:52 -05:00
|
|
|
if (prefs.hex_gui_tray_away)
|
2026-01-05 23:12:38 -07:00
|
|
|
zoitechat_command (ph, "ALLSERV AWAY");
|
2011-02-24 04:14:30 +01:00
|
|
|
gtk_window_get_position (win, &x, &y);
|
|
|
|
|
screen = gtk_window_get_screen (win);
|
2012-12-16 12:54:15 -05:00
|
|
|
maximized = prefs.hex_gui_win_state;
|
2013-09-19 17:52:17 -04:00
|
|
|
fullscreen = prefs.hex_gui_win_fullscreen;
|
2011-02-24 04:14:30 +01:00
|
|
|
gtk_widget_hide (GTK_WIDGET (win));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2012-12-20 19:39:52 -05:00
|
|
|
if (prefs.hex_gui_tray_away)
|
2026-01-05 23:12:38 -07:00
|
|
|
zoitechat_command (ph, "ALLSERV BACK");
|
2011-02-24 04:14:30 +01:00
|
|
|
gtk_window_set_screen (win, screen);
|
|
|
|
|
gtk_window_move (win, x, y);
|
2012-12-16 12:54:15 -05:00
|
|
|
if (maximized)
|
|
|
|
|
gtk_window_maximize (win);
|
2013-09-19 17:52:17 -04:00
|
|
|
if (fullscreen)
|
|
|
|
|
gtk_window_fullscreen (win);
|
2011-02-24 04:14:30 +01:00
|
|
|
gtk_widget_show (GTK_WIDGET (win));
|
2018-03-20 10:45:11 +01:00
|
|
|
gtk_window_deiconify (win);
|
2011-02-24 04:14:30 +01:00
|
|
|
gtk_window_present (win);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
tray_menu_restore_cb (GtkWidget *item, gpointer userdata)
|
|
|
|
|
{
|
2026-01-30 20:07:36 -07:00
|
|
|
(void)item;
|
|
|
|
|
(void)userdata;
|
|
|
|
|
|
2011-02-24 04:14:30 +01:00
|
|
|
tray_toggle_visibility (FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-21 15:09:00 -05:00
|
|
|
static void
|
|
|
|
|
tray_menu_notify_cb (GObject *tray, GParamSpec *pspec, gpointer user_data)
|
|
|
|
|
{
|
2026-01-30 20:07:36 -07:00
|
|
|
(void)tray;
|
|
|
|
|
(void)pspec;
|
|
|
|
|
(void)user_data;
|
|
|
|
|
|
|
|
|
|
if (tray_backend_active)
|
2013-01-03 18:18:04 -05:00
|
|
|
{
|
2026-01-30 20:07:36 -07:00
|
|
|
if (!tray_backend_is_embedded ())
|
2013-01-03 18:18:04 -05:00
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-12-21 15:09:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
2016-02-18 08:57:22 -05:00
|
|
|
tray_menu_try_restore (void)
|
2012-12-21 15:09:00 -05:00
|
|
|
{
|
2013-01-03 18:18:04 -05:00
|
|
|
tray_cleanup();
|
|
|
|
|
tray_init();
|
|
|
|
|
return TRUE;
|
2012-12-21 15:09:00 -05:00
|
|
|
}
|
|
|
|
|
|
2011-02-24 04:14:30 +01:00
|
|
|
static void
|
|
|
|
|
tray_menu_quit_cb (GtkWidget *item, gpointer userdata)
|
|
|
|
|
{
|
2026-01-30 20:07:36 -07:00
|
|
|
(void)item;
|
|
|
|
|
(void)userdata;
|
|
|
|
|
|
2011-02-24 04:14:30 +01:00
|
|
|
mg_open_quit_dialog (FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* returns 0-mixed 1-away 2-back */
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
tray_find_away_status (void)
|
|
|
|
|
{
|
|
|
|
|
GSList *list;
|
|
|
|
|
server *serv;
|
|
|
|
|
int away = 0;
|
|
|
|
|
int back = 0;
|
|
|
|
|
|
|
|
|
|
for (list = serv_list; list; list = list->next)
|
|
|
|
|
{
|
|
|
|
|
serv = list->data;
|
|
|
|
|
|
|
|
|
|
if (serv->is_away || serv->reconnect_away)
|
|
|
|
|
away++;
|
|
|
|
|
else
|
|
|
|
|
back++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (away && back)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (away)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
return 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
tray_foreach_server (GtkWidget *item, char *cmd)
|
|
|
|
|
{
|
|
|
|
|
GSList *list;
|
|
|
|
|
server *serv;
|
|
|
|
|
|
|
|
|
|
for (list = serv_list; list; list = list->next)
|
|
|
|
|
{
|
|
|
|
|
serv = list->data;
|
|
|
|
|
if (serv->connected)
|
|
|
|
|
handle_command (serv->server_session, cmd, FALSE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static GtkWidget *
|
|
|
|
|
tray_make_item (GtkWidget *menu, char *label, void *callback, void *userdata)
|
|
|
|
|
{
|
|
|
|
|
GtkWidget *item;
|
|
|
|
|
|
|
|
|
|
if (label)
|
|
|
|
|
item = gtk_menu_item_new_with_mnemonic (label);
|
|
|
|
|
else
|
|
|
|
|
item = gtk_menu_item_new ();
|
|
|
|
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
|
|
|
|
|
g_signal_connect (G_OBJECT (item), "activate",
|
|
|
|
|
G_CALLBACK (callback), userdata);
|
|
|
|
|
gtk_widget_show (item);
|
|
|
|
|
|
|
|
|
|
return item;
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-05 19:25:08 -05:00
|
|
|
#ifndef WIN32
|
2011-02-24 04:14:30 +01:00
|
|
|
static void
|
|
|
|
|
tray_toggle_cb (GtkCheckMenuItem *item, unsigned int *setting)
|
|
|
|
|
{
|
2013-05-12 01:43:27 -04:00
|
|
|
*setting = gtk_check_menu_item_get_active (item);
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
blink_item (unsigned int *setting, GtkWidget *menu, char *label)
|
|
|
|
|
{
|
|
|
|
|
menu_toggle_item (label, menu, tray_toggle_cb, setting, *setting);
|
|
|
|
|
}
|
2018-03-05 19:25:08 -05:00
|
|
|
#endif
|
2011-02-24 04:14:30 +01:00
|
|
|
|
2026-01-30 20:07:36 -07:00
|
|
|
#if !HAVE_GTK3
|
2011-02-24 04:14:30 +01:00
|
|
|
static void
|
|
|
|
|
tray_menu_destroy (GtkWidget *menu, gpointer userdata)
|
|
|
|
|
{
|
2026-01-30 20:07:36 -07:00
|
|
|
(void)userdata;
|
|
|
|
|
|
2011-02-24 04:14:30 +01:00
|
|
|
gtk_widget_destroy (menu);
|
|
|
|
|
g_object_unref (menu);
|
2012-11-18 16:35:18 -05:00
|
|
|
#ifdef WIN32
|
|
|
|
|
g_source_remove (tray_menu_timer);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef WIN32
|
2015-02-27 17:24:57 -08:00
|
|
|
static gboolean
|
2012-11-18 16:35:18 -05:00
|
|
|
tray_menu_enter_cb (GtkWidget *menu)
|
|
|
|
|
{
|
2026-01-30 20:07:36 -07:00
|
|
|
(void)menu;
|
|
|
|
|
|
2012-11-18 16:35:18 -05:00
|
|
|
tray_menu_inactivetime = 0;
|
2015-02-27 17:24:57 -08:00
|
|
|
return FALSE;
|
2012-11-18 16:35:18 -05:00
|
|
|
}
|
|
|
|
|
|
2015-02-27 17:24:57 -08:00
|
|
|
static gboolean
|
2012-11-18 16:35:18 -05:00
|
|
|
tray_menu_left_cb (GtkWidget *menu)
|
|
|
|
|
{
|
2026-01-30 20:07:36 -07:00
|
|
|
(void)menu;
|
|
|
|
|
|
2012-11-18 16:35:18 -05:00
|
|
|
tray_menu_inactivetime = g_get_real_time ();
|
2015-02-27 17:24:57 -08:00
|
|
|
return FALSE;
|
2012-11-18 16:35:18 -05:00
|
|
|
}
|
|
|
|
|
|
2015-02-27 17:24:57 -08:00
|
|
|
static gboolean
|
2012-11-18 16:35:18 -05:00
|
|
|
tray_check_hide (GtkWidget *menu)
|
|
|
|
|
{
|
|
|
|
|
if (tray_menu_inactivetime && g_get_real_time () - tray_menu_inactivetime >= 2000000)
|
|
|
|
|
{
|
|
|
|
|
tray_menu_destroy (menu, NULL);
|
2015-02-27 17:24:57 -08:00
|
|
|
return G_SOURCE_REMOVE;
|
2012-11-18 16:35:18 -05:00
|
|
|
}
|
2015-02-27 17:24:57 -08:00
|
|
|
|
|
|
|
|
return G_SOURCE_CONTINUE;
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
2015-02-27 17:33:33 -08:00
|
|
|
#endif
|
2026-01-30 20:07:36 -07:00
|
|
|
#endif
|
2011-02-24 04:14:30 +01:00
|
|
|
|
2012-11-22 02:49:41 -05:00
|
|
|
static void
|
|
|
|
|
tray_menu_settings (GtkWidget * wid, gpointer none)
|
|
|
|
|
{
|
2026-01-30 20:07:36 -07:00
|
|
|
(void)wid;
|
|
|
|
|
(void)none;
|
|
|
|
|
|
2012-11-22 02:49:41 -05:00
|
|
|
extern void setup_open (void);
|
|
|
|
|
setup_open ();
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-24 04:14:30 +01:00
|
|
|
static void
|
2026-01-30 20:07:36 -07:00
|
|
|
tray_menu_populate (GtkWidget *menu)
|
2011-02-24 04:14:30 +01:00
|
|
|
{
|
|
|
|
|
GtkWidget *submenu;
|
|
|
|
|
GtkWidget *item;
|
|
|
|
|
int away_status;
|
|
|
|
|
|
|
|
|
|
/* ph may have an invalid context now */
|
2026-01-05 23:12:38 -07:00
|
|
|
zoitechat_set_context (ph, zoitechat_find_context (ph, NULL, NULL));
|
2011-02-24 04:14:30 +01:00
|
|
|
|
|
|
|
|
if (tray_get_window_status () == WS_HIDDEN)
|
2011-02-28 18:59:32 +01:00
|
|
|
tray_make_item (menu, _("_Restore Window"), tray_menu_restore_cb, NULL);
|
2011-02-24 04:14:30 +01:00
|
|
|
else
|
2011-02-28 18:59:32 +01:00
|
|
|
tray_make_item (menu, _("_Hide Window"), tray_menu_restore_cb, NULL);
|
2011-02-24 04:14:30 +01:00
|
|
|
tray_make_item (menu, NULL, tray_menu_quit_cb, NULL);
|
|
|
|
|
|
2012-11-23 04:40:35 -05:00
|
|
|
#ifndef WIN32 /* submenus are buggy on win32 */
|
2011-02-24 04:14:30 +01:00
|
|
|
submenu = mg_submenu (menu, _("_Blink on"));
|
2012-10-22 14:18:20 +02:00
|
|
|
blink_item (&prefs.hex_input_tray_chans, submenu, _("Channel Message"));
|
|
|
|
|
blink_item (&prefs.hex_input_tray_priv, submenu, _("Private Message"));
|
|
|
|
|
blink_item (&prefs.hex_input_tray_hilight, submenu, _("Highlighted Message"));
|
2011-02-24 04:14:30 +01:00
|
|
|
/*blink_item (BIT_FILEOFFER, submenu, _("File Offer"));*/
|
|
|
|
|
|
|
|
|
|
submenu = mg_submenu (menu, _("_Change status"));
|
2012-11-23 04:40:35 -05:00
|
|
|
#else /* so show away/back in main tray menu */
|
|
|
|
|
submenu = menu;
|
|
|
|
|
#endif
|
|
|
|
|
|
2011-02-24 04:14:30 +01:00
|
|
|
away_status = tray_find_away_status ();
|
|
|
|
|
item = tray_make_item (submenu, _("_Away"), tray_foreach_server, "away");
|
|
|
|
|
if (away_status == 1)
|
|
|
|
|
gtk_widget_set_sensitive (item, FALSE);
|
|
|
|
|
item = tray_make_item (submenu, _("_Back"), tray_foreach_server, "back");
|
|
|
|
|
if (away_status == 2)
|
|
|
|
|
gtk_widget_set_sensitive (item, FALSE);
|
|
|
|
|
|
2012-11-23 04:58:56 -05:00
|
|
|
menu_add_plugin_items (menu, "\x5$TRAY", NULL);
|
2015-02-27 17:33:33 -08:00
|
|
|
|
2011-02-24 04:14:30 +01:00
|
|
|
tray_make_item (menu, NULL, tray_menu_quit_cb, NULL);
|
Added per-file ICON_* macros with GTK3 icon-name mappings and GTK2 stock fallbacks across GTK UI modules like banlist, DCC, editlist, ignore, URL grabber, notify, text events, tray menu, chanview tabs, and join dialog UI.
Updated GTK helper usages to reference the new ICON_* (and label) macros so GTK3 builds no longer pass stock IDs to button/icon helpers or dialogs, including banlist buttons, DCC windows, rawlog actions, notify dialog/buttons, pevent dialog buttons, tray menu items, and join dialog image helper usage.
2026-01-30 09:23:52 -07:00
|
|
|
mg_create_icon_item (_("_Preferences"), ICON_TRAY_PREFERENCES, menu, tray_menu_settings, NULL);
|
2012-11-22 02:49:41 -05:00
|
|
|
tray_make_item (menu, NULL, tray_menu_quit_cb, NULL);
|
Added per-file ICON_* macros with GTK3 icon-name mappings and GTK2 stock fallbacks across GTK UI modules like banlist, DCC, editlist, ignore, URL grabber, notify, text events, tray menu, chanview tabs, and join dialog UI.
Updated GTK helper usages to reference the new ICON_* (and label) macros so GTK3 builds no longer pass stock IDs to button/icon helpers or dialogs, including banlist buttons, DCC windows, rawlog actions, notify dialog/buttons, pevent dialog buttons, tray menu items, and join dialog image helper usage.
2026-01-30 09:23:52 -07:00
|
|
|
mg_create_icon_item (_("_Quit"), ICON_TRAY_QUIT, menu, tray_menu_quit_cb, NULL);
|
2026-01-30 20:07:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#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);
|
2011-02-24 04:14:30 +01:00
|
|
|
|
|
|
|
|
g_object_ref (menu);
|
|
|
|
|
g_object_ref_sink (menu);
|
|
|
|
|
g_object_unref (menu);
|
|
|
|
|
g_signal_connect (G_OBJECT (menu), "selection-done",
|
2026-01-30 20:07:36 -07:00
|
|
|
G_CALLBACK (tray_menu_destroy), NULL);
|
2012-11-18 16:35:18 -05:00
|
|
|
#ifdef WIN32
|
|
|
|
|
g_signal_connect (G_OBJECT (menu), "leave-notify-event",
|
2026-01-30 20:07:36 -07:00
|
|
|
G_CALLBACK (tray_menu_left_cb), NULL);
|
2012-11-18 16:35:18 -05:00
|
|
|
g_signal_connect (G_OBJECT (menu), "enter-notify-event",
|
2026-01-30 20:07:36 -07:00
|
|
|
G_CALLBACK (tray_menu_enter_cb), NULL);
|
2012-11-18 16:35:18 -05:00
|
|
|
|
2018-03-05 19:25:08 -05:00
|
|
|
tray_menu_timer = g_timeout_add (500, (GSourceFunc)tray_check_hide, menu);
|
2012-11-18 16:35:18 -05:00
|
|
|
#endif
|
|
|
|
|
|
2013-02-06 12:58:14 -05:00
|
|
|
gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL,
|
2026-01-30 20:07:36 -07:00
|
|
|
userdata, button, time);
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
2026-01-30 20:07:36 -07:00
|
|
|
#endif
|
2011-02-24 04:14:30 +01:00
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
tray_init (void)
|
|
|
|
|
{
|
|
|
|
|
flash_tag = 0;
|
2026-01-30 18:47:23 -07:00
|
|
|
tray_icon_state = TRAY_ICON_NONE;
|
|
|
|
|
tray_flash_icon = NULL;
|
|
|
|
|
tray_flash_state = TRAY_ICON_NONE;
|
2011-02-24 04:14:30 +01:00
|
|
|
custom_icon1 = NULL;
|
|
|
|
|
custom_icon2 = NULL;
|
|
|
|
|
|
2026-01-30 20:07:36 -07:00
|
|
|
if (!tray_backend_init ())
|
2011-02-24 04:14:30 +01:00
|
|
|
return;
|
2026-01-30 18:47:23 -07:00
|
|
|
tray_icon_state = TRAY_ICON_NORMAL;
|
2026-01-30 20:07:36 -07:00
|
|
|
tray_set_icon_state (ICON_NORMAL, TRAY_ICON_NORMAL);
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
tray_hilight_cb (char *word[], void *userdata)
|
|
|
|
|
{
|
2026-01-30 18:47:23 -07:00
|
|
|
/*if (tray_icon_state == TRAY_ICON_HIGHLIGHT)
|
2026-01-25 16:13:47 -07:00
|
|
|
return ZOITECHAT_EAT_NONE;*/
|
2011-02-24 04:14:30 +01:00
|
|
|
|
2013-04-12 19:59:46 -03:00
|
|
|
if (prefs.hex_input_tray_hilight)
|
2011-02-24 04:14:30 +01:00
|
|
|
{
|
2026-01-30 18:47:23 -07:00
|
|
|
tray_set_flash (ICON_HILIGHT, TRAY_ICON_HIGHLIGHT);
|
2011-02-24 04:14:30 +01:00
|
|
|
|
|
|
|
|
/* FIXME: hides any previous private messages */
|
|
|
|
|
tray_hilight_count++;
|
|
|
|
|
if (tray_hilight_count == 1)
|
2017-09-15 17:36:02 -04:00
|
|
|
tray_set_tipf (_("Highlighted message from: %s (%s) - %s"),
|
2026-01-05 23:12:38 -07:00
|
|
|
word[1], zoitechat_get_info (ph, "channel"), _(DISPLAY_NAME));
|
2011-02-24 04:14:30 +01:00
|
|
|
else
|
2017-09-15 17:36:02 -04:00
|
|
|
tray_set_tipf (_("%u highlighted messages, latest from: %s (%s) - %s"),
|
2026-01-05 23:12:38 -07:00
|
|
|
tray_hilight_count, word[1], zoitechat_get_info (ph, "channel"),
|
2017-09-15 17:36:02 -04:00
|
|
|
_(DISPLAY_NAME));
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
2026-01-25 16:13:47 -07:00
|
|
|
return ZOITECHAT_EAT_NONE;
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
tray_message_cb (char *word[], void *userdata)
|
|
|
|
|
{
|
2026-01-30 18:47:23 -07:00
|
|
|
if (/*tray_icon_state == TRAY_ICON_MESSAGE ||*/ tray_icon_state == TRAY_ICON_HIGHLIGHT)
|
2026-01-25 16:13:47 -07:00
|
|
|
return ZOITECHAT_EAT_NONE;
|
2013-04-12 19:59:46 -03:00
|
|
|
|
|
|
|
|
if (prefs.hex_input_tray_chans)
|
2011-02-24 04:14:30 +01:00
|
|
|
{
|
2026-01-30 18:47:23 -07:00
|
|
|
tray_set_flash (ICON_MSG, TRAY_ICON_MESSAGE);
|
2011-02-24 04:14:30 +01:00
|
|
|
|
|
|
|
|
tray_pub_count++;
|
|
|
|
|
if (tray_pub_count == 1)
|
2017-09-15 17:36:02 -04:00
|
|
|
tray_set_tipf (_("Channel message from: %s (%s) - %s"),
|
2026-01-05 23:12:38 -07:00
|
|
|
word[1], zoitechat_get_info (ph, "channel"), _(DISPLAY_NAME));
|
2011-02-24 04:14:30 +01:00
|
|
|
else
|
2017-09-15 17:36:02 -04:00
|
|
|
tray_set_tipf (_("%u channel messages. - %s"), tray_pub_count, _(DISPLAY_NAME));
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
2026-01-25 16:13:47 -07:00
|
|
|
return ZOITECHAT_EAT_NONE;
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
tray_priv (char *from, char *text)
|
|
|
|
|
{
|
|
|
|
|
const char *network;
|
|
|
|
|
|
2012-10-22 14:50:36 +02:00
|
|
|
if (alert_match_word (from, prefs.hex_irc_no_hilight))
|
2011-02-24 04:14:30 +01:00
|
|
|
return;
|
|
|
|
|
|
2026-01-05 23:12:38 -07:00
|
|
|
network = zoitechat_get_info (ph, "network");
|
2011-02-24 04:14:30 +01:00
|
|
|
if (!network)
|
2026-01-05 23:12:38 -07:00
|
|
|
network = zoitechat_get_info (ph, "server");
|
2011-02-24 04:14:30 +01:00
|
|
|
|
2013-12-27 19:41:18 -08:00
|
|
|
if (prefs.hex_input_tray_priv)
|
|
|
|
|
{
|
2026-01-30 18:47:23 -07:00
|
|
|
tray_set_flash (ICON_MSG, TRAY_ICON_MESSAGE);
|
2013-12-27 19:41:18 -08:00
|
|
|
|
|
|
|
|
tray_priv_count++;
|
|
|
|
|
if (tray_priv_count == 1)
|
2017-09-15 17:36:02 -04:00
|
|
|
tray_set_tipf (_("Private message from: %s (%s) - %s"), from,
|
|
|
|
|
network, _(DISPLAY_NAME));
|
2013-12-27 19:41:18 -08:00
|
|
|
else
|
2017-09-15 17:36:02 -04:00
|
|
|
tray_set_tipf (_("%u private messages, latest from: %s (%s) - %s"),
|
|
|
|
|
tray_priv_count, from, network, _(DISPLAY_NAME));
|
2013-12-27 19:41:18 -08:00
|
|
|
}
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
tray_priv_cb (char *word[], void *userdata)
|
|
|
|
|
{
|
2013-12-27 19:41:18 -08:00
|
|
|
tray_priv (word[1], word[2]);
|
2011-02-24 04:14:30 +01:00
|
|
|
|
2026-01-25 16:13:47 -07:00
|
|
|
return ZOITECHAT_EAT_NONE;
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
tray_invited_cb (char *word[], void *userdata)
|
|
|
|
|
{
|
2013-12-27 19:41:18 -08:00
|
|
|
if (!prefs.hex_away_omit_alerts || tray_find_away_status () != 1)
|
2011-02-24 04:14:30 +01:00
|
|
|
tray_priv (word[2], "Invited");
|
|
|
|
|
|
2026-01-25 16:13:47 -07:00
|
|
|
return ZOITECHAT_EAT_NONE;
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
tray_dcc_cb (char *word[], void *userdata)
|
|
|
|
|
{
|
|
|
|
|
const char *network;
|
|
|
|
|
|
2026-01-30 18:47:23 -07:00
|
|
|
/* if (tray_icon_state == TRAY_ICON_FILEOFFER)
|
2026-01-25 16:13:47 -07:00
|
|
|
return ZOITECHAT_EAT_NONE;*/
|
2011-02-24 04:14:30 +01:00
|
|
|
|
2026-01-05 23:12:38 -07:00
|
|
|
network = zoitechat_get_info (ph, "network");
|
2011-02-24 04:14:30 +01:00
|
|
|
if (!network)
|
2026-01-05 23:12:38 -07:00
|
|
|
network = zoitechat_get_info (ph, "server");
|
2011-02-24 04:14:30 +01:00
|
|
|
|
2012-10-22 14:18:20 +02:00
|
|
|
if (prefs.hex_input_tray_priv && (!prefs.hex_away_omit_alerts || tray_find_away_status () != 1))
|
2011-02-24 04:14:30 +01:00
|
|
|
{
|
2026-01-30 18:47:23 -07:00
|
|
|
tray_set_flash (ICON_FILE, TRAY_ICON_FILEOFFER);
|
2011-02-24 04:14:30 +01:00
|
|
|
|
|
|
|
|
tray_file_count++;
|
|
|
|
|
if (tray_file_count == 1)
|
2017-09-15 17:36:02 -04:00
|
|
|
tray_set_tipf (_("File offer from: %s (%s) - %s"), word[1], network,
|
|
|
|
|
_(DISPLAY_NAME));
|
2011-02-24 04:14:30 +01:00
|
|
|
else
|
2017-09-15 17:36:02 -04:00
|
|
|
tray_set_tipf (_("%u file offers, latest from: %s (%s) - %s"),
|
|
|
|
|
tray_file_count, word[1], network, _(DISPLAY_NAME));
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
2026-01-25 16:13:47 -07:00
|
|
|
return ZOITECHAT_EAT_NONE;
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
tray_focus_cb (char *word[], void *userdata)
|
|
|
|
|
{
|
|
|
|
|
tray_stop_flash ();
|
|
|
|
|
tray_reset_counts ();
|
2026-01-25 16:13:47 -07:00
|
|
|
return ZOITECHAT_EAT_NONE;
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
tray_cleanup (void)
|
|
|
|
|
{
|
|
|
|
|
tray_stop_flash ();
|
|
|
|
|
|
2026-01-30 20:07:36 -07:00
|
|
|
if (tray_backend_active)
|
|
|
|
|
tray_backend_cleanup ();
|
2011-02-24 04:14:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
tray_apply_setup (void)
|
|
|
|
|
{
|
2026-01-30 20:07:36 -07:00
|
|
|
if (tray_backend_active)
|
2011-02-24 04:14:30 +01:00
|
|
|
{
|
2012-10-22 13:49:28 +02:00
|
|
|
if (!prefs.hex_gui_tray)
|
2011-02-24 04:14:30 +01:00
|
|
|
tray_cleanup ();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2026-01-05 23:12:38 -07:00
|
|
|
GtkWindow *window = GTK_WINDOW(zoitechat_get_info (ph, "gtkwin_ptr"));
|
2017-08-31 09:52:45 -04:00
|
|
|
if (prefs.hex_gui_tray && gtkutil_tray_icon_supported (window))
|
2011-02-24 04:14:30 +01:00
|
|
|
tray_init ();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2026-01-05 23:12:38 -07:00
|
|
|
tray_plugin_init (zoitechat_plugin *plugin_handle, char **plugin_name,
|
2011-02-24 04:14:30 +01:00
|
|
|
char **plugin_desc, char **plugin_version, char *arg)
|
|
|
|
|
{
|
2026-01-05 23:12:38 -07:00
|
|
|
/* we need to save this for use with any zoitechat_* functions */
|
2011-02-24 04:14:30 +01:00
|
|
|
ph = plugin_handle;
|
|
|
|
|
|
|
|
|
|
*plugin_name = "";
|
|
|
|
|
*plugin_desc = "";
|
|
|
|
|
*plugin_version = "";
|
|
|
|
|
|
2026-01-05 23:12:38 -07:00
|
|
|
zoitechat_hook_print (ph, "Channel Msg Hilight", -1, tray_hilight_cb, NULL);
|
|
|
|
|
zoitechat_hook_print (ph, "Channel Action Hilight", -1, tray_hilight_cb, NULL);
|
2011-02-24 04:14:30 +01:00
|
|
|
|
2026-01-05 23:12:38 -07:00
|
|
|
zoitechat_hook_print (ph, "Channel Message", -1, tray_message_cb, NULL);
|
|
|
|
|
zoitechat_hook_print (ph, "Channel Action", -1, tray_message_cb, NULL);
|
|
|
|
|
zoitechat_hook_print (ph, "Channel Notice", -1, tray_message_cb, NULL);
|
2011-02-24 04:14:30 +01:00
|
|
|
|
2026-01-05 23:12:38 -07:00
|
|
|
zoitechat_hook_print (ph, "Private Message", -1, tray_priv_cb, NULL);
|
|
|
|
|
zoitechat_hook_print (ph, "Private Message to Dialog", -1, tray_priv_cb, NULL);
|
|
|
|
|
zoitechat_hook_print (ph, "Private Action", -1, tray_priv_cb, NULL);
|
|
|
|
|
zoitechat_hook_print (ph, "Private Action to Dialog", -1, tray_priv_cb, NULL);
|
|
|
|
|
zoitechat_hook_print (ph, "Notice", -1, tray_priv_cb, NULL);
|
|
|
|
|
zoitechat_hook_print (ph, "Invited", -1, tray_invited_cb, NULL);
|
2011-02-24 04:14:30 +01:00
|
|
|
|
2026-01-05 23:12:38 -07:00
|
|
|
zoitechat_hook_print (ph, "DCC Offer", -1, tray_dcc_cb, NULL);
|
2011-02-24 04:14:30 +01:00
|
|
|
|
2026-01-05 23:12:38 -07:00
|
|
|
zoitechat_hook_print (ph, "Focus Window", -1, tray_focus_cb, NULL);
|
2011-02-24 04:14:30 +01:00
|
|
|
|
2026-01-05 23:12:38 -07:00
|
|
|
GtkWindow *window = GTK_WINDOW(zoitechat_get_info (ph, "gtkwin_ptr"));
|
2017-08-31 09:52:45 -04:00
|
|
|
if (prefs.hex_gui_tray && gtkutil_tray_icon_supported (window))
|
2011-02-24 04:14:30 +01:00
|
|
|
tray_init ();
|
|
|
|
|
|
|
|
|
|
return 1; /* return 1 for success */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2026-01-05 23:12:38 -07:00
|
|
|
tray_plugin_deinit (zoitechat_plugin *plugin_handle)
|
2011-02-24 04:14:30 +01:00
|
|
|
{
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
tray_cleanup ();
|
|
|
|
|
#endif
|
|
|
|
|
return 1;
|
|
|
|
|
}
|