[0.4.14][NTUSER][USER32][OSK] Initial support of WS_EX_NOACTIVATE flag (#4731)

WS_EX_NOACTIVATE flag forbids the window to be activated
fix picked from 0.4.15-dev-5137-g 826bd41d88 (1 of 3 commits for CORE-18417)
My reason for picking it is that it fixes CORE-13257 'Reboot leaving Evernote 5.9.8 in tray causes WIN32K BSOD 0x50'
I also had to pick together with it the
0.4.15-dev-5491-g 1fbed1710e to prevent it from introducing (+2 failures in user32:msg_focus) unittests.
----------------
The above patch allows/encourages us to pick then also:
0.4.15-dev-5492-g 47f3a4e144 [OSK] Delete WS_EX_NOACTIVATE workaround code
(which referenced CORE-18528, but is not fixing this minor GUI glitch yet, it just removes workaround-code that is no longer needed,
I just mention the ticket here, because the commit on master did that as well)
----------------
----------------
The following 2 things were small *unrelated* improvements nearby, and I decided to take them with me:
0.4.15-dev-4323-g 9f5cde9cbe [WIN32K:NTUSER] window.c Remove broken assert in NtUserCreateWindowEx. CORE-18123 fixed
and
a tiny part of 0.4.15-dev-3476-g 55a1c29341 [WIN32K] appswitch.c: delete unused func DWORD wtodw(const WCHAR *psz)
This commit is contained in:
Joachim Henze 2022-12-24 02:05:12 +01:00
parent 1be3db2baa
commit 875b9e7c4f
7 changed files with 32 additions and 57 deletions

View file

@ -319,15 +319,6 @@ VOID OSK_RefreshLEDKeys(VOID)
*/ */
int OSK_DlgTimer(void) int OSK_DlgTimer(void)
{ {
/* FIXME: To be deleted when ReactOS will support WS_EX_NOACTIVATE */
HWND hWndActiveWindow;
hWndActiveWindow = GetForegroundWindow();
if (hWndActiveWindow != NULL && hWndActiveWindow != Globals.hMainWnd)
{
Globals.hActiveWnd = hWndActiveWindow;
}
/* /*
Update the LED key indicators accordingly to their state (if one Update the LED key indicators accordingly to their state (if one
of the specific keys is held down). of the specific keys is held down).
@ -353,19 +344,6 @@ BOOL OSK_DlgCommand(WPARAM wCommand, HWND hWndControl)
LONG WindowStyle; LONG WindowStyle;
INT i; INT i;
/* FIXME: To be deleted when ReactOS will support WS_EX_NOACTIVATE */
if (Globals.hActiveWnd)
{
MSG msg;
SetForegroundWindow(Globals.hActiveWnd);
while (PeekMessageW(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
/* KeyDown and/or KeyUp ? */ /* KeyDown and/or KeyUp ? */
WindowStyle = GetWindowLongW(hWndControl, GWL_STYLE); WindowStyle = GetWindowLongW(hWndControl, GWL_STYLE);
if ((WindowStyle & BS_AUTOCHECKBOX) == BS_AUTOCHECKBOX) if ((WindowStyle & BS_AUTOCHECKBOX) == BS_AUTOCHECKBOX)

View file

@ -34,8 +34,6 @@ typedef struct
HWND hMainWnd; HWND hMainWnd;
HBRUSH hBrushGreenLed; HBRUSH hBrushGreenLed;
UINT_PTR iTimer; UINT_PTR iTimer;
/* FIXME: To be deleted when ReactOS will support WS_EX_NOACTIVATE */
HWND hActiveWnd;
/* On-Screen Keyboard registry settings */ /* On-Screen Keyboard registry settings */
BOOL bShowWarning; BOOL bShowWarning;

View file

@ -622,7 +622,7 @@ IsAllowedFGActive(PTHREADINFO pti, PWND Wnd)
pti->rpdesk != gpdeskInputDesktop || // not current Desktop, pti->rpdesk != gpdeskInputDesktop || // not current Desktop,
pti->MessageQueue == gpqForeground || // if already the queue foreground, pti->MessageQueue == gpqForeground || // if already the queue foreground,
IsFGLocked() || // foreground is locked, IsFGLocked() || // foreground is locked,
Wnd->ExStyle & WS_EX_NOACTIVATE ) // or,,, does not become the foreground window when the user clicks it. (Wnd->ExStyle & WS_EX_NOACTIVATE)) // or, does not become the foreground window when the user clicks it.
{ {
return FALSE; return FALSE;
} }
@ -929,9 +929,8 @@ co_IntSetActiveWindow(
ThreadQueue = pti->MessageQueue; ThreadQueue = pti->MessageQueue;
ASSERT(ThreadQueue != 0); ASSERT(ThreadQueue != 0);
hWndPrev = ThreadQueue->spwndActive ? UserHMGetHandle(ThreadQueue->spwndActive) : NULL;
pWndChg = ThreadQueue->spwndActive; // Keep to notify of a preemptive switch. pWndChg = ThreadQueue->spwndActive; // Keep to notify of a preemptive switch.
hWndPrev = (pWndChg ? UserHMGetHandle(pWndChg) : NULL);
if ( !Wnd || Wnd == UserGetDesktopWindow() ) if ( !Wnd || Wnd == UserGetDesktopWindow() )
{ {
@ -943,6 +942,9 @@ co_IntSetActiveWindow(
hWnd = UserHMGetHandle(Wnd); hWnd = UserHMGetHandle(Wnd);
//ERR("co_IntSetActiveWindow 2 hWnd 0x%p\n",hWnd); //ERR("co_IntSetActiveWindow 2 hWnd 0x%p\n",hWnd);
if (Wnd->ExStyle & WS_EX_NOACTIVATE)
return TRUE;
/* check if the specified window can be set in the input data of a given queue */ /* check if the specified window can be set in the input data of a given queue */
if ( ThreadQueue != Wnd->head.pti->MessageQueue ) if ( ThreadQueue != Wnd->head.pti->MessageQueue )
{ {
@ -1136,9 +1138,12 @@ BOOL FASTCALL
co_IntMouseActivateWindow(PWND Wnd) co_IntMouseActivateWindow(PWND Wnd)
{ {
TRACE("Mouse Active\n"); TRACE("Mouse Active\n");
if (Wnd && (Wnd->ExStyle & WS_EX_NOACTIVATE))
return TRUE;
return co_IntSetForegroundAndFocusWindow(Wnd, TRUE, TRUE); return co_IntSetForegroundAndFocusWindow(Wnd, TRUE, TRUE);
} }
/* Win: PWND xxxSetActiveWindow(Wnd) */
BOOL FASTCALL BOOL FASTCALL
UserSetActiveWindow( _In_opt_ PWND Wnd ) UserSetActiveWindow( _In_opt_ PWND Wnd )
{ {
@ -1547,7 +1552,7 @@ NtUserSetActiveWindow(HWND hWnd)
{ {
USER_REFERENCE_ENTRY Ref; USER_REFERENCE_ENTRY Ref;
HWND hWndPrev; HWND hWndPrev;
PWND Window; PWND Window, pwndPrev;
DECLARE_RETURN(HWND); DECLARE_RETURN(HWND);
TRACE("Enter NtUserSetActiveWindow(%p)\n", hWnd); TRACE("Enter NtUserSetActiveWindow(%p)\n", hWnd);
@ -1566,11 +1571,12 @@ NtUserSetActiveWindow(HWND hWnd)
if (!Window || if (!Window ||
Window->head.pti->MessageQueue == gptiCurrent->MessageQueue) Window->head.pti->MessageQueue == gptiCurrent->MessageQueue)
{ {
hWndPrev = gptiCurrent->MessageQueue->spwndActive ? UserHMGetHandle(gptiCurrent->MessageQueue->spwndActive) : NULL; pwndPrev = gptiCurrent->MessageQueue->spwndActive;
hWndPrev = (pwndPrev ? UserHMGetHandle(pwndPrev) : NULL);
if (Window) UserRefObjectCo(Window, &Ref); if (Window) UserRefObjectCo(Window, &Ref);
UserSetActiveWindow(Window); UserSetActiveWindow(Window);
if (Window) UserDerefObjectCo(Window); if (Window) UserDerefObjectCo(Window);
RETURN( hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0 ); RETURN(hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : NULL) : NULL);
} }
RETURN( NULL); RETURN( NULL);

View file

@ -438,12 +438,12 @@ DefWndDoSizeMove(PWND pwnd, WORD wParam)
if (doSideSnap) if (doSideSnap)
{ {
co_WinPosSetWindowPos(pwnd, co_WinPosSetWindowPos(pwnd,
0, NULL,
snapRect.left, snapRect.left,
snapRect.top, snapRect.top,
snapRect.right - snapRect.left, snapRect.right - snapRect.left,
snapRect.bottom - snapRect.top, snapRect.bottom - snapRect.top,
0); SWP_NOACTIVATE);
pwnd->InternalPos.NormalRect = origRect; pwnd->InternalPos.NormalRect = origRect;
} }
else else
@ -552,12 +552,12 @@ DefWndDoSizeMove(PWND pwnd, WORD wParam)
//// This causes the mdi child window to jump up when it is moved. //// This causes the mdi child window to jump up when it is moved.
//IntMapWindowPoints( 0, pWndParent, (POINT *)&rect, 2 ); //IntMapWindowPoints( 0, pWndParent, (POINT *)&rect, 2 );
co_WinPosSetWindowPos(pwnd, co_WinPosSetWindowPos(pwnd,
0, NULL,
newRect.left, newRect.left,
newRect.top, newRect.top,
newRect.right - newRect.left, newRect.right - newRect.left,
newRect.bottom - newRect.top, newRect.bottom - newRect.top,
( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 ); SWP_NOACTIVATE | ((hittest == HTCAPTION) ? SWP_NOSIZE : 0));
hrgnNew = GreCreateRectRgnIndirect(&pwnd->rcWindow); hrgnNew = GreCreateRectRgnIndirect(&pwnd->rcWindow);
if (pwnd->hrgnClip != NULL) if (pwnd->hrgnClip != NULL)
@ -1532,7 +1532,8 @@ NC_HandleNCLButtonDown(PWND pWnd, WPARAM wParam, LPARAM lParam)
TopWnd = parent; TopWnd = parent;
} }
if ( co_IntSetForegroundWindowMouse(TopWnd) || if ( (pWnd && (pWnd->ExStyle & WS_EX_NOACTIVATE)) ||
co_IntSetForegroundWindowMouse(TopWnd) ||
//NtUserCallHwndLock(hTopWnd, HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOWMOUSE) || //NtUserCallHwndLock(hTopWnd, HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOWMOUSE) ||
UserGetActiveWindow() == UserHMGetHandle(TopWnd)) UserGetActiveWindow() == UserHMGetHandle(TopWnd))
{ {
@ -1689,6 +1690,7 @@ LRESULT NC_HandleNCRButtonDown( PWND pwnd, WPARAM wParam, LPARAM lParam )
if (UserHMGetHandle(pwnd) != IntGetCapture()) return 0; if (UserHMGetHandle(pwnd) != IntGetCapture()) return 0;
} }
IntReleaseCapture(); IntReleaseCapture();
if (hittest == HTCAPTION || hittest == HTSYSMENU || hittest == HTHSCROLL || hittest == HTVSCROLL) if (hittest == HTCAPTION || hittest == HTSYSMENU || hittest == HTHSCROLL || hittest == HTVSCROLL)
{ {
TRACE("Msg pt %x and Msg.lParam %x and lParam %x\n",MAKELONG(msg.pt.x,msg.pt.y),msg.lParam,lParam); TRACE("Msg pt %x and Msg.lParam %x and lParam %x\n",MAKELONG(msg.pt.x,msg.pt.y),msg.lParam,lParam);

View file

@ -2273,7 +2273,11 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
SwFlag = co_WinPosMinMaximize(Window, SwFlag, &NewPos); SwFlag = co_WinPosMinMaximize(Window, SwFlag, &NewPos);
SwFlag |= SWP_NOZORDER|SWP_FRAMECHANGED; /* Frame always gets changed */ SwFlag |= SWP_NOZORDER|SWP_FRAMECHANGED; /* Frame always gets changed */
if (!(style & WS_VISIBLE) || (style & WS_CHILD) || UserGetActiveWindow()) SwFlag |= SWP_NOACTIVATE; if (!(style & WS_VISIBLE) || (style & WS_CHILD) || UserGetActiveWindow() ||
(Window->ExStyle & WS_EX_NOACTIVATE))
{
SwFlag |= SWP_NOACTIVATE;
}
co_WinPosSetWindowPos(Window, 0, NewPos.left, NewPos.top, co_WinPosSetWindowPos(Window, 0, NewPos.left, NewPos.top,
NewPos.right, NewPos.bottom, SwFlag); NewPos.right, NewPos.bottom, SwFlag);
} }
@ -2454,8 +2458,6 @@ NtUserCreateWindowEx(
lstrClassName.Buffer = NULL; lstrClassName.Buffer = NULL;
lstrClsVersion.Buffer = NULL; lstrClsVersion.Buffer = NULL;
ASSERT(plstrWindowName);
if ( (dwStyle & (WS_POPUP|WS_CHILD)) != WS_CHILD) if ( (dwStyle & (WS_POPUP|WS_CHILD)) != WS_CHILD)
{ {
/* check hMenu is valid handle */ /* check hMenu is valid handle */

View file

@ -379,6 +379,7 @@ BOOL FASTCALL can_activate_window( PWND Wnd OPTIONAL)
if (!(style & WS_VISIBLE)) return FALSE; if (!(style & WS_VISIBLE)) return FALSE;
if (style & WS_MINIMIZE) return FALSE; if (style & WS_MINIMIZE) return FALSE;
if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE; if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
if (Wnd->ExStyle & WS_EX_NOACTIVATE) return FALSE;
return TRUE; return TRUE;
/* FIXME: This window could be disable because the child that closed /* FIXME: This window could be disable because the child that closed
was a popup. */ was a popup. */

View file

@ -71,18 +71,6 @@ int CoolSwitchColumns = 7;
const DWORD Style = WS_POPUP | WS_BORDER | WS_DISABLED; const DWORD Style = WS_POPUP | WS_BORDER | WS_DISABLED;
const DWORD ExStyle = WS_EX_TOPMOST | WS_EX_DLGMODALFRAME | WS_EX_TOOLWINDOW; const DWORD ExStyle = WS_EX_TOPMOST | WS_EX_DLGMODALFRAME | WS_EX_TOOLWINDOW;
DWORD wtodw(const WCHAR *psz)
{
const WCHAR *pch = psz;
DWORD Value = 0;
while ('0' <= *pch && *pch <= '9')
{
Value *= 10;
Value += *pch - L'0';
}
return Value;
}
BOOL LoadCoolSwitchSettings(void) BOOL LoadCoolSwitchSettings(void)
{ {
CoolSwitch = TRUE; CoolSwitch = TRUE;
@ -242,9 +230,9 @@ BOOL IsAltTabWindow(HWND hwnd)
if (!IsWindowVisible(hwnd)) if (!IsWindowVisible(hwnd))
return FALSE; return FALSE;
// must not be WS_EX_TOOLWINDOW // must not be WS_EX_TOOLWINDOW nor WS_EX_NOACTIVATE
ExStyle = GetWindowLong(hwnd, GWL_EXSTYLE); ExStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
if (ExStyle & WS_EX_TOOLWINDOW) if (ExStyle & (WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE))
return FALSE; return FALSE;
// must be not empty rect // must be not empty rect