mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-06-11 01:10:18 +00:00
Add Win32 taskbar attention alerts for highlights/PMs
This commit is contained in:
@@ -31,7 +31,7 @@
|
|||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<AdditionalLibraryDirectories>$(ArchiveLibDir);$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
<AdditionalLibraryDirectories>$(ArchiveLibDir);$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
<AdditionalDependencies>$(DepLibs);$(ZoiteChatLib)common.lib;wbemuuid.lib;dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>$(DepLibs);$(ZoiteChatLib)common.lib;wbemuuid.lib;dwmapi.lib;ole32.lib;uuid.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
<EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
|
<EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
|||||||
@@ -92,6 +92,8 @@ if host_machine.system() == 'windows'
|
|||||||
zoitechat_gtk_sources += 'notifications/notification-windows.c'
|
zoitechat_gtk_sources += 'notifications/notification-windows.c'
|
||||||
zoitechat_gtk_deps += cc.find_library('dwmapi', required: true)
|
zoitechat_gtk_deps += cc.find_library('dwmapi', required: true)
|
||||||
zoitechat_gtk_deps += cc.find_library('shell32', required: true)
|
zoitechat_gtk_deps += cc.find_library('shell32', required: true)
|
||||||
|
zoitechat_gtk_deps += cc.find_library('ole32', required: true)
|
||||||
|
zoitechat_gtk_deps += cc.find_library('uuid', required: true)
|
||||||
zoitechat_theme_deps += cc.find_library('dwmapi', required: true)
|
zoitechat_theme_deps += cc.find_library('dwmapi', required: true)
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
|
#include <shobjidl.h>
|
||||||
#include <gdk/gdkwin32.h>
|
#include <gdk/gdkwin32.h>
|
||||||
#endif
|
#endif
|
||||||
#if defined(GTK_DISABLE_DEPRECATED)
|
#if defined(GTK_DISABLE_DEPRECATED)
|
||||||
@@ -131,6 +132,7 @@ static void tray_menu_notify_cb (GObject *tray, GParamSpec *pspec, gpointer user
|
|||||||
static void tray_update_toggle_item_label (void);
|
static void tray_update_toggle_item_label (void);
|
||||||
static gboolean tray_window_state_cb (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata);
|
static gboolean tray_window_state_cb (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata);
|
||||||
static void tray_window_visibility_cb (GtkWidget *widget, gpointer userdata);
|
static void tray_window_visibility_cb (GtkWidget *widget, gpointer userdata);
|
||||||
|
static WinStatus tray_get_window_status (void);
|
||||||
static void tray_toggle_item_destroy_cb (GtkWidget *widget, gpointer userdata);
|
static void tray_toggle_item_destroy_cb (GtkWidget *widget, gpointer userdata);
|
||||||
#if HAVE_APPINDICATOR_BACKEND
|
#if HAVE_APPINDICATOR_BACKEND
|
||||||
static void tray_menu_show_cb (GtkWidget *menu, gpointer userdata) G_GNUC_UNUSED;
|
static void tray_menu_show_cb (GtkWidget *menu, gpointer userdata) G_GNUC_UNUSED;
|
||||||
@@ -158,6 +160,8 @@ static GtkStatusIcon *tray_status_icon;
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
static HWND tray_win32_hwnd;
|
static HWND tray_win32_hwnd;
|
||||||
static HICON tray_win32_icon;
|
static HICON tray_win32_icon;
|
||||||
|
static HICON tray_win32_overlay_icon;
|
||||||
|
static ITaskbarList3 *tray_win32_taskbar;
|
||||||
static gboolean tray_win32_active;
|
static gboolean tray_win32_active;
|
||||||
static UINT tray_win32_taskbar_created;
|
static UINT tray_win32_taskbar_created;
|
||||||
static const UINT tray_win32_callback_msg = WM_APP + 42;
|
static const UINT tray_win32_callback_msg = WM_APP + 42;
|
||||||
@@ -606,6 +610,132 @@ tray_win32_pixbuf_to_hicon (GdkPixbuf *pixbuf)
|
|||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HWND
|
||||||
|
tray_win32_get_main_hwnd (void)
|
||||||
|
{
|
||||||
|
GtkWindow *win;
|
||||||
|
GdkWindow *gdk_window;
|
||||||
|
|
||||||
|
win = GTK_WINDOW (zoitechat_get_info (ph, "gtkwin_ptr"));
|
||||||
|
if (!win)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
gdk_window = gtk_widget_get_window (GTK_WIDGET (win));
|
||||||
|
if (!gdk_window)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return gdk_win32_window_get_handle (gdk_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ITaskbarList3 *
|
||||||
|
tray_win32_get_taskbar (void)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (tray_win32_taskbar)
|
||||||
|
return tray_win32_taskbar;
|
||||||
|
|
||||||
|
hr = CoCreateInstance (&CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER,
|
||||||
|
&IID_ITaskbarList3, (void **)&tray_win32_taskbar);
|
||||||
|
if (FAILED (hr))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
hr = tray_win32_taskbar->lpVtbl->HrInit (tray_win32_taskbar);
|
||||||
|
if (FAILED (hr))
|
||||||
|
{
|
||||||
|
tray_win32_taskbar->lpVtbl->Release (tray_win32_taskbar);
|
||||||
|
tray_win32_taskbar = NULL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tray_win32_taskbar;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tray_win32_release_attention (void)
|
||||||
|
{
|
||||||
|
if (tray_win32_overlay_icon)
|
||||||
|
{
|
||||||
|
DestroyIcon (tray_win32_overlay_icon);
|
||||||
|
tray_win32_overlay_icon = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tray_win32_taskbar)
|
||||||
|
{
|
||||||
|
tray_win32_taskbar->lpVtbl->Release (tray_win32_taskbar);
|
||||||
|
tray_win32_taskbar = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tray_win32_clear_attention (void)
|
||||||
|
{
|
||||||
|
FLASHWINFO flash;
|
||||||
|
ITaskbarList3 *taskbar;
|
||||||
|
HWND hwnd;
|
||||||
|
|
||||||
|
hwnd = tray_win32_get_main_hwnd ();
|
||||||
|
if (!hwnd)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ZeroMemory (&flash, sizeof (flash));
|
||||||
|
flash.cbSize = sizeof (flash);
|
||||||
|
flash.hwnd = hwnd;
|
||||||
|
flash.dwFlags = FLASHW_STOP;
|
||||||
|
FlashWindowEx (&flash);
|
||||||
|
|
||||||
|
taskbar = tray_win32_get_taskbar ();
|
||||||
|
if (taskbar)
|
||||||
|
taskbar->lpVtbl->SetOverlayIcon (taskbar, hwnd, NULL, L"");
|
||||||
|
|
||||||
|
if (tray_win32_overlay_icon)
|
||||||
|
{
|
||||||
|
DestroyIcon (tray_win32_overlay_icon);
|
||||||
|
tray_win32_overlay_icon = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tray_win32_set_attention (TrayIcon icon)
|
||||||
|
{
|
||||||
|
FLASHWINFO flash;
|
||||||
|
ITaskbarList3 *taskbar;
|
||||||
|
HICON hicon;
|
||||||
|
HWND hwnd;
|
||||||
|
|
||||||
|
if (tray_get_window_status () == WS_FOCUSED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
hwnd = tray_win32_get_main_hwnd ();
|
||||||
|
if (!hwnd)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ZeroMemory (&flash, sizeof (flash));
|
||||||
|
flash.cbSize = sizeof (flash);
|
||||||
|
flash.hwnd = hwnd;
|
||||||
|
flash.dwFlags = FLASHW_TRAY | FLASHW_TIMERNOFG;
|
||||||
|
FlashWindowEx (&flash);
|
||||||
|
|
||||||
|
taskbar = tray_win32_get_taskbar ();
|
||||||
|
if (!taskbar)
|
||||||
|
return;
|
||||||
|
|
||||||
|
hicon = tray_win32_pixbuf_to_hicon (icon);
|
||||||
|
if (!hicon)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (SUCCEEDED (taskbar->lpVtbl->SetOverlayIcon (taskbar, hwnd, hicon, L"")))
|
||||||
|
{
|
||||||
|
if (tray_win32_overlay_icon)
|
||||||
|
DestroyIcon (tray_win32_overlay_icon);
|
||||||
|
tray_win32_overlay_icon = hicon;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DestroyIcon (hicon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tray_win32_init_data (NOTIFYICONDATAW *nid)
|
tray_win32_init_data (NOTIFYICONDATAW *nid)
|
||||||
{
|
{
|
||||||
@@ -710,6 +840,8 @@ tray_win32_cleanup (void)
|
|||||||
tray_win32_icon = NULL;
|
tray_win32_icon = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tray_win32_release_attention ();
|
||||||
|
|
||||||
if (tray_win32_hwnd)
|
if (tray_win32_hwnd)
|
||||||
{
|
{
|
||||||
DestroyWindow (tray_win32_hwnd);
|
DestroyWindow (tray_win32_hwnd);
|
||||||
@@ -1025,6 +1157,10 @@ tray_stop_flash (void)
|
|||||||
flash_tag = 0;
|
flash_tag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
tray_win32_clear_attention ();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (tray_backend_active)
|
if (tray_backend_active)
|
||||||
{
|
{
|
||||||
tray_set_icon_state (ICON_NORMAL, TRAY_ICON_NORMAL);
|
tray_set_icon_state (ICON_NORMAL, TRAY_ICON_NORMAL);
|
||||||
@@ -1641,6 +1777,9 @@ tray_hilight_cb (char *word[], void *userdata)
|
|||||||
if (prefs.hex_input_tray_hilight)
|
if (prefs.hex_input_tray_hilight)
|
||||||
{
|
{
|
||||||
tray_set_flash (ICON_HILIGHT, TRAY_ICON_HIGHLIGHT);
|
tray_set_flash (ICON_HILIGHT, TRAY_ICON_HIGHLIGHT);
|
||||||
|
#ifdef WIN32
|
||||||
|
tray_win32_set_attention (ICON_HILIGHT);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* FIXME: hides any previous private messages */
|
/* FIXME: hides any previous private messages */
|
||||||
tray_hilight_count++;
|
tray_hilight_count++;
|
||||||
@@ -1692,6 +1831,9 @@ tray_priv (char *from, char *text)
|
|||||||
if (prefs.hex_input_tray_priv)
|
if (prefs.hex_input_tray_priv)
|
||||||
{
|
{
|
||||||
tray_set_flash (ICON_MSG, TRAY_ICON_MESSAGE);
|
tray_set_flash (ICON_MSG, TRAY_ICON_MESSAGE);
|
||||||
|
#ifdef WIN32
|
||||||
|
tray_win32_set_attention (ICON_MSG);
|
||||||
|
#endif
|
||||||
|
|
||||||
tray_priv_count++;
|
tray_priv_count++;
|
||||||
if (tray_priv_count == 1)
|
if (tray_priv_count == 1)
|
||||||
@@ -1763,6 +1905,9 @@ tray_cleanup (void)
|
|||||||
|
|
||||||
if (tray_backend_active)
|
if (tray_backend_active)
|
||||||
tray_backend_cleanup ();
|
tray_backend_cleanup ();
|
||||||
|
#ifdef WIN32
|
||||||
|
tray_win32_release_attention ();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
Reference in New Issue
Block a user