You've already forked wine-staging
mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-09-12 18:50:20 -07:00
Rebase against 330dc601978922aa1d5864d29d94882d6b1990d1.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
From 8997ff8b93a64bd2d0db463b6789d05dc5a5fbb5 Mon Sep 17 00:00:00 2001
|
||||
From f0e7e4d7995867911e47dc54c9087cd7a57b5c90 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Gabriel=20Iv=C4=83ncescu?= <gabrielopcode@gmail.com>
|
||||
Date: Mon, 22 Jul 2019 15:29:25 +0300
|
||||
Subject: [PATCH] user32/focus: Prevent a recursive loop with the activation
|
||||
@@ -15,103 +15,24 @@ actually depend on this behavior, so it is needed.
|
||||
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46274
|
||||
Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
|
||||
---
|
||||
dlls/user32/focus.c | 44 +++++++++++++++++++++++++++--------------
|
||||
dlls/user32/tests/msg.c | 2 +-
|
||||
dlls/user32/win.h | 1 +
|
||||
3 files changed, 31 insertions(+), 16 deletions(-)
|
||||
dlls/user32/focus.c | 1 -
|
||||
dlls/user32/tests/msg.c | 2 +-
|
||||
dlls/win32u/input.c | 52 +++++++++++++++++++++++++++---------
|
||||
dlls/win32u/ntuser_private.h | 1 +
|
||||
4 files changed, 41 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/dlls/user32/focus.c b/dlls/user32/focus.c
|
||||
index a5fc376bdc6..cae559270bf 100644
|
||||
index 4998ac2feb6..f68c6080698 100644
|
||||
--- a/dlls/user32/focus.c
|
||||
+++ b/dlls/user32/focus.c
|
||||
@@ -89,7 +89,7 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
|
||||
{
|
||||
HWND previous = GetActiveWindow();
|
||||
BOOL ret;
|
||||
- DWORD old_thread, new_thread;
|
||||
+ DWORD winflags, old_thread, new_thread;
|
||||
CBTACTIVATESTRUCT cbt;
|
||||
@@ -31,7 +31,6 @@
|
||||
#include "user_private.h"
|
||||
#include "wine/server.h"
|
||||
|
||||
if (previous == hwnd)
|
||||
@@ -98,16 +98,24 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
- /* call CBT hook chain */
|
||||
- cbt.fMouse = mouse;
|
||||
- cbt.hWndActive = previous;
|
||||
- if (HOOK_CallHooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hwnd, (LPARAM)&cbt, TRUE )) return FALSE;
|
||||
-
|
||||
- if (IsWindow(previous))
|
||||
+ /* Prevent a recursive activation loop with the activation messages */
|
||||
+ winflags = win_set_flags(hwnd, WIN_IS_IN_ACTIVATION, 0);
|
||||
+ if (!(winflags & WIN_IS_IN_ACTIVATION))
|
||||
{
|
||||
- SendMessageW( previous, WM_NCACTIVATE, FALSE, (LPARAM)hwnd );
|
||||
- SendMessageW( previous, WM_ACTIVATE,
|
||||
- MAKEWPARAM( WA_INACTIVE, IsIconic(previous) ), (LPARAM)hwnd );
|
||||
+ ret = FALSE;
|
||||
+
|
||||
+ /* call CBT hook chain */
|
||||
+ cbt.fMouse = mouse;
|
||||
+ cbt.hWndActive = previous;
|
||||
+ if (HOOK_CallHooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hwnd, (LPARAM)&cbt, TRUE ))
|
||||
+ goto clear_flags;
|
||||
+
|
||||
+ if (IsWindow(previous))
|
||||
+ {
|
||||
+ SendMessageW( previous, WM_NCACTIVATE, FALSE, (LPARAM)hwnd );
|
||||
+ SendMessageW( previous, WM_ACTIVATE,
|
||||
+ MAKEWPARAM( WA_INACTIVE, IsIconic(previous) ), (LPARAM)hwnd );
|
||||
+ }
|
||||
}
|
||||
|
||||
SERVER_START_REQ( set_active_window )
|
||||
@@ -117,9 +125,9 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
|
||||
previous = wine_server_ptr_handle( reply->previous );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
- if (!ret) return FALSE;
|
||||
+ if (!ret) goto clear_flags;
|
||||
if (prev) *prev = previous;
|
||||
- if (previous == hwnd) return TRUE;
|
||||
+ if (previous == hwnd) goto clear_flags;
|
||||
|
||||
if (hwnd)
|
||||
{
|
||||
@@ -127,7 +135,11 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
|
||||
if (SendMessageW( hwnd, WM_QUERYNEWPALETTE, 0, 0 ))
|
||||
SendMessageTimeoutW( HWND_BROADCAST, WM_PALETTEISCHANGING, (WPARAM)hwnd, 0,
|
||||
SMTO_ABORTIFHUNG, 2000, NULL );
|
||||
- if (!IsWindow(hwnd)) return FALSE;
|
||||
+ if (!IsWindow(hwnd))
|
||||
+ {
|
||||
+ ret = FALSE;
|
||||
+ goto clear_flags;
|
||||
+ }
|
||||
}
|
||||
|
||||
old_thread = previous ? GetWindowThreadProcessId( previous, NULL ) : 0;
|
||||
@@ -159,7 +171,7 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
|
||||
}
|
||||
}
|
||||
|
||||
- if (IsWindow(hwnd))
|
||||
+ if (!(winflags & WIN_IS_IN_ACTIVATION) && IsWindow(hwnd))
|
||||
{
|
||||
SendMessageW( hwnd, WM_NCACTIVATE, hwnd == NtUserGetForegroundWindow(), (LPARAM)previous );
|
||||
SendMessageW( hwnd, WM_ACTIVATE,
|
||||
@@ -184,7 +196,9 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
|
||||
}
|
||||
}
|
||||
|
||||
- return TRUE;
|
||||
+clear_flags:
|
||||
+ win_set_flags(hwnd, 0, WIN_IS_IN_ACTIVATION);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* FOCUS_MouseActivate
|
||||
*
|
||||
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
|
||||
index 9164f57fdc2..01cb214acdf 100644
|
||||
--- a/dlls/user32/tests/msg.c
|
||||
@@ -125,18 +46,117 @@ index 9164f57fdc2..01cb214acdf 100644
|
||||
flush_sequence();
|
||||
|
||||
if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_MINIMIZE)
|
||||
diff --git a/dlls/user32/win.h b/dlls/user32/win.h
|
||||
index 1f51fd63314..a64cc66be5a 100644
|
||||
--- a/dlls/user32/win.h
|
||||
+++ b/dlls/user32/win.h
|
||||
@@ -79,6 +79,7 @@ typedef struct tagWND
|
||||
diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c
|
||||
index fff732097ba..cbc6cfd6b0d 100644
|
||||
--- a/dlls/win32u/input.c
|
||||
+++ b/dlls/win32u/input.c
|
||||
@@ -1180,6 +1180,18 @@ static HWND set_focus_window( HWND hwnd )
|
||||
return previous;
|
||||
}
|
||||
|
||||
+static UINT win_set_flags( HWND hwnd, UINT set_mask, UINT clear_mask )
|
||||
+{
|
||||
+ UINT ret;
|
||||
+ WND *ptr = get_win_ptr( hwnd );
|
||||
+
|
||||
+ if (!ptr || ptr == WND_OTHER_PROCESS || ptr == WND_DESKTOP) return 0;
|
||||
+ ret = ptr->flags;
|
||||
+ ptr->flags = (ret & ~clear_mask) | set_mask;
|
||||
+ release_win_ptr( ptr );
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
/*******************************************************************
|
||||
* set_active_window
|
||||
*/
|
||||
@@ -1187,7 +1199,7 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
|
||||
{
|
||||
HWND previous = get_active_window();
|
||||
BOOL ret;
|
||||
- DWORD old_thread, new_thread;
|
||||
+ DWORD winflags, old_thread, new_thread;
|
||||
CBTACTIVATESTRUCT cbt;
|
||||
|
||||
if (previous == hwnd)
|
||||
@@ -1196,16 +1208,24 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
- /* call CBT hook chain */
|
||||
- cbt.fMouse = mouse;
|
||||
- cbt.hWndActive = previous;
|
||||
- if (call_hooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hwnd, (LPARAM)&cbt, TRUE )) return FALSE;
|
||||
-
|
||||
- if (is_window( previous ))
|
||||
+ /* Prevent a recursive activation loop with the activation messages */
|
||||
+ winflags = win_set_flags(hwnd, WIN_IS_IN_ACTIVATION, 0);
|
||||
+ if (!(winflags & WIN_IS_IN_ACTIVATION))
|
||||
{
|
||||
- send_message( previous, WM_NCACTIVATE, FALSE, (LPARAM)hwnd );
|
||||
- send_message( previous, WM_ACTIVATE,
|
||||
- MAKEWPARAM( WA_INACTIVE, is_iconic(previous) ), (LPARAM)hwnd );
|
||||
+ ret = FALSE;
|
||||
+
|
||||
+ /* call CBT hook chain */
|
||||
+ cbt.fMouse = mouse;
|
||||
+ cbt.hWndActive = previous;
|
||||
+ if (call_hooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hwnd, (LPARAM)&cbt, TRUE ))
|
||||
+ goto clear_flags;
|
||||
+
|
||||
+ if (is_window(previous))
|
||||
+ {
|
||||
+ send_message( previous, WM_NCACTIVATE, FALSE, (LPARAM)hwnd );
|
||||
+ send_message( previous, WM_ACTIVATE,
|
||||
+ MAKEWPARAM( WA_INACTIVE, is_iconic(previous) ), (LPARAM)hwnd );
|
||||
+ }
|
||||
}
|
||||
|
||||
SERVER_START_REQ( set_active_window )
|
||||
@@ -1225,7 +1245,11 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
|
||||
if (send_message( hwnd, WM_QUERYNEWPALETTE, 0, 0 ) && user_callbacks)
|
||||
user_callbacks->pSendMessageTimeoutW( HWND_BROADCAST, WM_PALETTEISCHANGING, (WPARAM)hwnd, 0,
|
||||
SMTO_ABORTIFHUNG, 2000, NULL );
|
||||
- if (!is_window(hwnd)) return FALSE;
|
||||
+ if (!is_window(hwnd))
|
||||
+ {
|
||||
+ ret = FALSE;
|
||||
+ goto clear_flags;
|
||||
+ }
|
||||
}
|
||||
|
||||
old_thread = previous ? get_window_thread( previous, NULL ) : 0;
|
||||
@@ -1257,7 +1281,7 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
|
||||
}
|
||||
}
|
||||
|
||||
- if (is_window(hwnd))
|
||||
+ if (!(winflags & WIN_IS_IN_ACTIVATION) && is_window(hwnd))
|
||||
{
|
||||
send_message( hwnd, WM_NCACTIVATE, hwnd == NtUserGetForegroundWindow(), (LPARAM)previous );
|
||||
send_message( hwnd, WM_ACTIVATE,
|
||||
@@ -1282,7 +1306,9 @@ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
|
||||
}
|
||||
}
|
||||
|
||||
- return TRUE;
|
||||
+clear_flags:
|
||||
+ win_set_flags(hwnd, 0, WIN_IS_IN_ACTIVATION);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h
|
||||
index 6c10a3e77e1..b46f0426368 100644
|
||||
--- a/dlls/win32u/ntuser_private.h
|
||||
+++ b/dlls/win32u/ntuser_private.h
|
||||
@@ -109,6 +109,7 @@ typedef struct tagWND
|
||||
#define WIN_NEEDS_SHOW_OWNEDPOPUP 0x0020 /* WM_SHOWWINDOW:SC_SHOW must be sent in the next ShowOwnedPopup call */
|
||||
#define WIN_CHILDREN_MOVED 0x0040 /* children may have moved, ignore stored positions */
|
||||
#define WIN_HAS_IME_WIN 0x0080 /* the window has been registered with imm32 */
|
||||
+#define WIN_IS_IN_ACTIVATION 0x0100 /* the window is in an activation process */
|
||||
|
||||
/* Window functions */
|
||||
extern HWND get_hwnd_message_parent(void) DECLSPEC_HIDDEN;
|
||||
#define WND_OTHER_PROCESS ((WND *)1) /* returned by WIN_GetPtr on unknown window handles */
|
||||
#define WND_DESKTOP ((WND *)2) /* returned by WIN_GetPtr on the desktop window */
|
||||
--
|
||||
2.34.1
|
||||
2.35.1
|
||||
|
||||
|
Reference in New Issue
Block a user