Page 1 of 1

WinActivate does not always bring to forefront

Posted: 04 Apr 2018, 08:03
by guest3456
https://autohotkey.com/docs/commands/WinActivate.htm
WinActivate
Activates the specified window (makes it foremost).
WinActivate does not guarantee bringing the window foremost, it just guarantees that the window is 'active' and therefore focused (I guess for keyboard input)

test script:

Code: Select all

f6::
   MouseGetPos,,,mhwnd
   WinSet, bottom,, ahk_id %mhwnd%
return

f7::
   MouseGetPos,,,mhwnd
   WinActivate, ahk_id %mhwnd%
return

f8::
   MouseGetPos,,,mhwnd
   DllCall("SetForegroundWindow", "uInt", mhwnd)
return

f9::
   MouseGetPos,,,mhwnd
   MsgBox, % DllCall("SetForegroundWindow", "uInt", mhwnd)
return

f10::
   MouseGetPos,,,mhwnd
   DllCall("BringWindowToTop", "uInt", mhwnd)
return
tested on both win7 and win10

open notepad. click it to activate it. mouseover and press F6 to send it to bottom. the window is now at bottom, but its still 'active' according to windows and will still accepts keyboard input. if you mouseover again and press F7, the window will not be brought to the foreground.

F8 fails too. yet somehow F9 works. F10 seems to always work

so either a bug in the sense that its not doing what is documented, or the documentation is incorrect

Re: WinActivate does not always bring to forefront

Posted: 04 Apr 2018, 08:25
by joefiesta
95% of the time the documentation is correct... probably higher. But, the PROBLEM is interpretting it. I usually have to read a entry over and over and over to get it all (because it is SO TERSE). Your problem, I believe, is WINSET, BOTTOM. About it, the doc says:
Bottom: Sends a window to the bottom of stack; that is, beneath all other windows. The effect is similar to pressing Alt-Escape. For example: WinSet, Bottom,, WinTitle.
If you read this CAREFULLY, you will see it says "... IS SIMILAR TO ...". I interpret, as I must, in a 100% literal fashion, as: BUT IT MIGHT NOT REALLY BE EXACTLY THE SAME AS ... And, Indeed on my Win 7 system ALT+ESC acts differently than Winset, Bottom.

So, what does WINSET BOTTOM actually do? Answer: we don't know.

Re: WinActivate does not always bring to forefront

Posted: 04 Apr 2018, 08:28
by guest3456
this has nothing to do with WinSet, Bottom

Re: WinActivate does not always bring to forefront

Posted: 04 Apr 2018, 08:29
by just me
guest3456 wrote:... the window is now at bottom, but its still 'active' according to windows and will still accepts keyboard input.
Winactivate wrote:If a matching window is already active, that window will be kept active rather than activating any other matching window beneath it.
In other words, AHK does nothing in this case.

Code: Select all

	if (aTargetWindow == orig_foreground_wnd) // It's already the active window.
		return aTargetWindow;
This might be more clear though:
If a matching window is already active, that window's state and position in the z-order will not be changed.

Re: WinActivate does not always bring to forefront

Posted: 04 Apr 2018, 08:32
by guest3456
just me wrote:
guest3456 wrote:... the window is now at bottom, but its still 'active' according to windows and will still accepts keyboard input.
Winactivate wrote:If a matching window is already active, that window will be kept active rather than activating any other matching window beneath it.
In other words, AHK does nothing in this case.

Code: Select all

	if (aTargetWindow == orig_foreground_wnd) // It's already the active window.
		return aTargetWindow;
This might be more clear though:
If a matching window is already active, that window's state and position in the z-order will not be changed.
ok gotcha.perhaps the docs should be changed to that.

any idea why F8 fails but F9 works?

i think there is merit to also trying to bring the window to front. is there any case where someone would be calling WinActivate, and yet wanting an existing active window to stay in the back? i can't think of any. i understand this would break scripts so might be a change for v2

Re: WinActivate does not always bring to forefront

Posted: 04 Apr 2018, 08:41
by just me
guest3456 wrote:any idea why F8 fails but F9 works?
Not as yet.

Re: WinActivate does not always bring to forefront

Posted: 04 Apr 2018, 11:05
by just me
I think I got it. AFAICS

Code: Select all

DllCall("SetForegroundWindow", "uInt", mhwnd)
behaves the identically in both cases. But the MsgBox in F9 steals the focus from the active notepad window. After the MsgBox is closed, the notepad window is moved to the top, probably by the system.

Re: WinActivate does not always bring to forefront

Posted: 04 Apr 2018, 12:05
by guest3456
just me wrote:I think I got it. AFAICS

Code: Select all

DllCall("SetForegroundWindow", "uInt", mhwnd)
behaves the identically in both cases. But the MsgBox in F9 steals the focus from the active notepad window. After the MsgBox is closed, the notepad window is moved to the top, probably by the system.
but why would the system bring notepad to the top? because a modal window (the msgbox) was closed and so it brings the active window to foreground?

msdn says: "If the window was brought to the foreground, the return value is nonzero."

changing MsgBox to ToolTip also returns "1" for me (indicating success), but with ToolTip, notepad is not brought to the top

Re: WinActivate does not always bring to forefront

Posted: 05 Apr 2018, 03:06
by lexikos
WinActivate does not guarantee bringing the window foremost, it just guarantees that the window is 'active'
It guarantees neither. It tries very hard, and sometimes that is enough. The OS works against us, providing several functions to change focus but preventing them from working under hard to predict circumstances, under the premise that it is protecting the user.

The documentation already implies that WinActivate is expected to be unreliable:
Six attempts will be made to activate the target window over the course of 60ms. Thus, it is usually unnecessary to follow WinActivate with WinWaitActive or IfWinNotActive.
because a modal window (the msgbox) was closed and so it brings the active window to foreground?
By "the active window", I assume you mean Notepad, but the MsgBox is the active window. When it is closed, the OS activates another window and (sometimes) simultaneously brings it to the foreground.

The same thing will happen if you replace MsgBox with Gui Show followed by Gui Destroy, or Run cmd /c exit.

Re: WinActivate does not always bring to forefront

Posted: 05 Apr 2018, 13:09
by guest3456
lexikos wrote:It tries very hard, and sometimes that is enough.
What do you think about adding BringWindowToTop to its try? It looked like it was commented out in the WinActivate source
lexikos wrote:By "the active window", I assume you mean Notepad, but the MsgBox is the active window. When it is closed, the OS activates another window and (sometimes) simultaneously brings it to the foreground.

The same thing will happen if you replace MsgBox with Gui Show followed by Gui Destroy, or Run cmd /c exit.
gotcha

Re: WinActivate does not always bring to forefront

Posted: 06 Apr 2018, 00:58
by lexikos
If it is in the source but commented out, that is probably because Chris found it to not make WinActivate more reliable. Why do you want it added? To bring the window to top if it's already active, or to try to activate the window when SetForegroundWindow fails? The former change in behaviour might not be warranted or desired by everyone.

Re: WinActivate does not always bring to forefront

Posted: 06 Apr 2018, 02:08
by just me
The whole issue is caused by performing WinSet, Bottom for the active window and trying to activate the same window after that while it is still active. IMO, it seems to be reasonable that you have to perform WinSet, Top after or instead of WinActivate to move the window to the top again in this special case.

Re: WinActivate does not always bring to forefront

Posted: 06 Apr 2018, 09:02
by guest3456
lexikos wrote:To bring the window to top if it's already active, or to try to activate the window when SetForegroundWindow fails? The former change in behaviour might not be warranted or desired by everyone.
right, the former, and yes it would be a breaking change probably for v2
just me wrote:The whole issue is caused by performing WinSet, Bottom for the active window and trying to activate the same window after that while it is still active. IMO, it seems to be reasonable that you have to perform WinSet, Top after or instead of WinActivate to move the window to the top again in this special case.
fair enough. then the first line of the doc page should be changed

Re: WinActivate does not always bring to forefront

Posted: 06 Apr 2018, 17:25
by lexikos
I wasn't talking about backward-compatibility. Even in v2, it may be unwanted.

Re: WinActivate does not always bring to forefront

Posted: 06 Apr 2018, 18:01
by guest3456
it may be unwanted. but i can't think of a reason why though. i think it far far far far more likely that someone would use WinActivate to actually WANT to bring a window to the forefront (as it says in the AHK docs) even if it was already active