mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-07-07 04:29:24 +00:00
Fix Windows taskbar click not minimizing the active window
This commit is contained in:
@@ -5004,6 +5004,94 @@ mg_tabwindow_de_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
|
/* GTK3's win32 backend does not minimize the window when its taskbar
|
||||||
|
* button is clicked while the window is active; the shell's minimize
|
||||||
|
* fails and, as the upstream report puts it, "the window only becomes
|
||||||
|
* unfocused but remains in the foreground"
|
||||||
|
* (https://gitlab.gnome.org/GNOME/gtk/-/issues/3749).
|
||||||
|
*
|
||||||
|
* We use exactly that signature to tell the two taskbar gestures apart:
|
||||||
|
* after a taskbar click deactivates the window, look at the foreground
|
||||||
|
* window. If this window is still the foreground window (the shell tried
|
||||||
|
* to minimize it and failed), the click was on its own button, so
|
||||||
|
* minimize it manually. If activation moved to the taskbar, the Start
|
||||||
|
* menu, another application or one of our other windows, the user was
|
||||||
|
* not clicking this window's button, so leave it alone.
|
||||||
|
*/
|
||||||
|
#define MG_WIN32_TASKBAR_MINIMIZE_DELAY_MS 200
|
||||||
|
|
||||||
|
static guint mg_win32_taskbar_minimize_source_id = 0;
|
||||||
|
static HWND mg_win32_taskbar_minimize_hwnd = NULL;
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
mg_win32_hwnd_is_taskbar (HWND hwnd)
|
||||||
|
{
|
||||||
|
wchar_t class_name[32];
|
||||||
|
HWND root;
|
||||||
|
|
||||||
|
if (!hwnd)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
root = GetAncestor (hwnd, GA_ROOT);
|
||||||
|
if (!root)
|
||||||
|
root = hwnd;
|
||||||
|
|
||||||
|
if (GetClassNameW (root, class_name, G_N_ELEMENTS (class_name)) == 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return lstrcmpW (class_name, L"Shell_TrayWnd") == 0
|
||||||
|
|| lstrcmpW (class_name, L"Shell_SecondaryTrayWnd") == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
mg_win32_taskbar_minimize_cb (gpointer userdata)
|
||||||
|
{
|
||||||
|
HWND hwnd = mg_win32_taskbar_minimize_hwnd;
|
||||||
|
HWND foreground;
|
||||||
|
|
||||||
|
mg_win32_taskbar_minimize_source_id = 0;
|
||||||
|
mg_win32_taskbar_minimize_hwnd = NULL;
|
||||||
|
|
||||||
|
if (!hwnd || !IsWindow (hwnd) || !IsWindowVisible (hwnd) || IsIconic (hwnd))
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
|
||||||
|
foreground = GetForegroundWindow ();
|
||||||
|
|
||||||
|
/* Activation moved to another window (another application, the
|
||||||
|
* taskbar itself for an empty-space/Start/tray click, or one of our
|
||||||
|
* other windows), so the taskbar click was not on this window's own
|
||||||
|
* button - leave it alone. Only the failed shell-minimize leaves this
|
||||||
|
* window still foreground (or leaves nothing foreground at all). */
|
||||||
|
if (foreground != NULL && foreground != hwnd)
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
|
||||||
|
PostMessage (hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mg_win32_taskbar_click_check (HWND hwnd)
|
||||||
|
{
|
||||||
|
POINT cursor_pos;
|
||||||
|
|
||||||
|
if (!IsWindowVisible (hwnd) || IsIconic (hwnd))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!GetCursorPos (&cursor_pos))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!mg_win32_hwnd_is_taskbar (WindowFromPoint (cursor_pos)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (mg_win32_taskbar_minimize_source_id)
|
||||||
|
g_source_remove (mg_win32_taskbar_minimize_source_id);
|
||||||
|
|
||||||
|
mg_win32_taskbar_minimize_hwnd = hwnd;
|
||||||
|
mg_win32_taskbar_minimize_source_id =
|
||||||
|
g_timeout_add (MG_WIN32_TASKBAR_MINIMIZE_DELAY_MS,
|
||||||
|
mg_win32_taskbar_minimize_cb, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static GdkFilterReturn
|
static GdkFilterReturn
|
||||||
mg_win32_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data)
|
mg_win32_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data)
|
||||||
{
|
{
|
||||||
@@ -5012,6 +5100,13 @@ mg_win32_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data)
|
|||||||
if (!msg)
|
if (!msg)
|
||||||
return GDK_FILTER_CONTINUE;
|
return GDK_FILTER_CONTINUE;
|
||||||
|
|
||||||
|
if (msg->message == WM_ACTIVATE)
|
||||||
|
{
|
||||||
|
if (LOWORD (msg->wParam) == WA_INACTIVE)
|
||||||
|
mg_win32_taskbar_click_check (msg->hwnd);
|
||||||
|
return GDK_FILTER_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (msg->message == WM_TIMECHANGE)
|
if (msg->message == WM_TIMECHANGE)
|
||||||
{
|
{
|
||||||
_tzset();
|
_tzset();
|
||||||
|
|||||||
Reference in New Issue
Block a user