[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)
{
/* 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
of the specific keys is held down).
@ -353,19 +344,6 @@ BOOL OSK_DlgCommand(WPARAM wCommand, HWND hWndControl)
LONG WindowStyle;
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 ? */
WindowStyle = GetWindowLongW(hWndControl, GWL_STYLE);
if ((WindowStyle & BS_AUTOCHECKBOX) == BS_AUTOCHECKBOX)

View file

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

View file

@ -622,7 +622,7 @@ IsAllowedFGActive(PTHREADINFO pti, PWND Wnd)
pti->rpdesk != gpdeskInputDesktop || // not current Desktop,
pti->MessageQueue == gpqForeground || // if already the queue foreground,
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;
}
@ -929,9 +929,8 @@ co_IntSetActiveWindow(
ThreadQueue = pti->MessageQueue;
ASSERT(ThreadQueue != 0);
hWndPrev = ThreadQueue->spwndActive ? UserHMGetHandle(ThreadQueue->spwndActive) : NULL;
pWndChg = ThreadQueue->spwndActive; // Keep to notify of a preemptive switch.
hWndPrev = (pWndChg ? UserHMGetHandle(pWndChg) : NULL);
if ( !Wnd || Wnd == UserGetDesktopWindow() )
{
@ -943,6 +942,9 @@ co_IntSetActiveWindow(
hWnd = UserHMGetHandle(Wnd);
//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 */
if ( ThreadQueue != Wnd->head.pti->MessageQueue )
{
@ -1136,9 +1138,12 @@ BOOL FASTCALL
co_IntMouseActivateWindow(PWND Wnd)
{
TRACE("Mouse Active\n");
if (Wnd && (Wnd->ExStyle & WS_EX_NOACTIVATE))
return TRUE;
return co_IntSetForegroundAndFocusWindow(Wnd, TRUE, TRUE);
}
/* Win: PWND xxxSetActiveWindow(Wnd) */
BOOL FASTCALL
UserSetActiveWindow( _In_opt_ PWND Wnd )
{
@ -1547,7 +1552,7 @@ NtUserSetActiveWindow(HWND hWnd)
{
USER_REFERENCE_ENTRY Ref;
HWND hWndPrev;
PWND Window;
PWND Window, pwndPrev;
DECLARE_RETURN(HWND);
TRACE("Enter NtUserSetActiveWindow(%p)\n", hWnd);
@ -1566,11 +1571,12 @@ NtUserSetActiveWindow(HWND hWnd)
if (!Window ||
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);
UserSetActiveWindow(Window);
if (Window) UserDerefObjectCo(Window);
RETURN( hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0 );
RETURN(hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : NULL) : NULL);
}
RETURN( NULL);

View file

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

View file

@ -2273,7 +2273,11 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
SwFlag = co_WinPosMinMaximize(Window, SwFlag, &NewPos);
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,
NewPos.right, NewPos.bottom, SwFlag);
}
@ -2454,8 +2458,6 @@ NtUserCreateWindowEx(
lstrClassName.Buffer = NULL;
lstrClsVersion.Buffer = NULL;
ASSERT(plstrWindowName);
if ( (dwStyle & (WS_POPUP|WS_CHILD)) != WS_CHILD)
{
/* 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_MINIMIZE) return FALSE;
if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
if (Wnd->ExStyle & WS_EX_NOACTIVATE) return FALSE;
return TRUE;
/* FIXME: This window could be disable because the child that closed
was a popup. */

View file

@ -71,18 +71,6 @@ int CoolSwitchColumns = 7;
const DWORD Style = WS_POPUP | WS_BORDER | WS_DISABLED;
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)
{
CoolSwitch = TRUE;
@ -242,9 +230,9 @@ BOOL IsAltTabWindow(HWND hwnd)
if (!IsWindowVisible(hwnd))
return FALSE;
// must not be WS_EX_TOOLWINDOW
// must not be WS_EX_TOOLWINDOW nor WS_EX_NOACTIVATE
ExStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
if (ExStyle & WS_EX_TOOLWINDOW)
if (ExStyle & (WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE))
return FALSE;
// must be not empty rect