WinActivate does not always bring to forefront

Report problems with documented functionality
guest3456
Posts: 3453
Joined: 09 Oct 2013, 10:31

WinActivate does not always bring to forefront

04 Apr 2018, 08:03

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
Last edited by guest3456 on 04 Apr 2018, 08:34, edited 3 times in total.

joefiesta
Posts: 494
Joined: 24 Jan 2016, 13:54
Location: Pa., USA

Re: WinActivate does not always bring to forefront

04 Apr 2018, 08:25

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.
guest3456
Posts: 3453
Joined: 09 Oct 2013, 10:31

Re: WinActivate does not always bring to forefront

04 Apr 2018, 08:28

this has nothing to do with WinSet, Bottom

just me
Posts: 9407
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: WinActivate does not always bring to forefront

04 Apr 2018, 08:29

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.
guest3456
Posts: 3453
Joined: 09 Oct 2013, 10:31

Re: WinActivate does not always bring to forefront

04 Apr 2018, 08:32

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

just me
Posts: 9407
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: WinActivate does not always bring to forefront

04 Apr 2018, 08:41

guest3456 wrote:any idea why F8 fails but F9 works?
Not as yet.
just me
Posts: 9407
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: WinActivate does not always bring to forefront

04 Apr 2018, 11:05

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.
guest3456
Posts: 3453
Joined: 09 Oct 2013, 10:31

Re: WinActivate does not always bring to forefront

04 Apr 2018, 12:05

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

lexikos
Posts: 9494
Joined: 30 Sep 2013, 04:07
Contact:

Re: WinActivate does not always bring to forefront

05 Apr 2018, 03:06

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.
guest3456
Posts: 3453
Joined: 09 Oct 2013, 10:31

Re: WinActivate does not always bring to forefront

05 Apr 2018, 13:09

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

lexikos
Posts: 9494
Joined: 30 Sep 2013, 04:07
Contact:

Re: WinActivate does not always bring to forefront

06 Apr 2018, 00:58

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.
just me
Posts: 9407
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: WinActivate does not always bring to forefront

06 Apr 2018, 02:08

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.
guest3456
Posts: 3453
Joined: 09 Oct 2013, 10:31

Re: WinActivate does not always bring to forefront

06 Apr 2018, 09:02

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

lexikos
Posts: 9494
Joined: 30 Sep 2013, 04:07
Contact:

Re: WinActivate does not always bring to forefront

06 Apr 2018, 17:25

I wasn't talking about backward-compatibility. Even in v2, it may be unwanted.
guest3456
Posts: 3453
Joined: 09 Oct 2013, 10:31

Re: WinActivate does not always bring to forefront

06 Apr 2018, 18:01

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


Return to “Bug Reports”

Who is online

Users browsing this forum: No registered users and 28 guests