FuPeiJiang / VD.ahk

Windows Virtual Desktop, AutoHotkey, Windows 11 support, Windows Server 2022, switch desktop, move window(wintitle) to current desktop; createDesktop, PinWindow, getCount, getDesktopNumOfWindow -> mute all windows in Virtual Desktop
MIT License
348 stars 47 forks source link

Window loses Focus when switching Virtual Desktops #37

Open arakis opened 1 year ago

arakis commented 1 year ago

Actual

When switching between two desktops, it always loses focus of the last used app of the new desktop. NO window is focused after switching.

Example: VD 1 have Notepad focused, on VD 2 the calculator. Currently i'm on VD1. When switching to VD2, NO window is focused. If i move back, NO window is focused (you see this on the task bar).

Expected

The last focused app should reminded and re-focused when switching to that desktop.

What works

When using build-in key combination CTRL+WIN+Left/Right, it works as expected.

Analysis

It happens regardles if i move away with build-in command and jump back via VD.ahk, or first jump away via VD.ahk and switches back with build-in command.

Background information

#NumpadEnd::VD.goToDesktopNum(1) ;1
#NumpadDown::VD.goToDesktopNum(2) ;2
#NumpadPgDn::VD.goToDesktopNum(3) ;3

I do not think this has todo with the WIN-Key, because when i move windows to other desktop via:

#NumpadLeft::VD.MoveWindowToDesktopNum("A",1) ;4
#NumpadClear::VD.MoveWindowToDesktopNum("A",2) ;5
#NumpadRight::VD.MoveWindowToDesktopNum("A",3) ;6

The next Windows of the current VD is focused, like expected.

Ideas

https://github.com/Ciantic/VirtualDesktopAccessor/issues/4:

I tried this:

;switch desktop
NumpadEnd::{ ;1
    VD.goToDesktopNum(1)
    ;Send !{Esc} 
    Sleep 1
    Send "!{Esc}" ; ALT+Esc activates last window
}
NumpadDown::{ ;2
    VD.goToDesktopNum(2)
    ;Send !{Esc} 
    Sleep 1
    Send "!{Esc}" ; ALT+Esc activates last window
}
NumpadPgDn::{ ;3
    VD.goToDesktopNum(3)
    ;Send !{Esc} 
    Sleep 1
    Send "!{Esc}" ; ALT+Esc activates last window
}

It seems to work, but in some (unpredictable) cases, it will restore the wrong window, and using higher sleep values does not solve that.

FuPeiJiang commented 1 year ago

@arakis I can't reproduce on Windows 11 nor Windows 10

;you should first Run this, then Read this
;Ctrl + F: jump to #useful stuff

;#SETUP START
#SingleInstance force
ListLines 0
SendMode "Input"
SetWorkingDir A_ScriptDir
KeyHistory 0
#WinActivateForce

ProcessSetPriority "H"

SetWinDelay -1
SetControlDelay -1

;include the library
#Include %A_LineFile%\..\VD.ah2
; or
; #Include %A_LineFile%\..\_VD.ahk
; ...{startup code}
; VD.init()

; VD.ahk : calls `VD.init()` on #Include
; _VD.ahk : `VD.init()` when you want, like after a GUI has rendered, for startup performance reasons

;you should WinHide invisible programs that have a window.
try WinHide "Malwarebytes Tray Application"
;#SETUP END

VD.createUntil(3) ;create until we have at least 3 VD

return

foo(desktopNum) {
    VD.goToDesktopNum(desktopNum)
    ToolTip WinGetTitle("A") " ahk_class " WinGetClass("A") " ahk_exe " WinGetProcessName("A")
}

#NumpadEnd::foo(1)
#NumpadDown::foo(2)
#NumpadPgDn::foo(3)

f3::Exitapp

What's the active window after switch ? is it that no window is active ? is it an invisible window ?

FuPeiJiang commented 1 year ago

the next step in debugging would be to put

ToolTip WinGetTitle("ahk_id " theHwnd) " ahk_class " WinGetClass("ahk_id " theHwnd) " ahk_exe " WinGetProcessName("ahk_id " theHwnd)

above

WinActivate "ahk_id " theHwnd

in the function _activateWindowUnder

arakis commented 1 year ago

Thank you for the debugging script. I tried the initial script, without modifying the _activateWindowUnder method. I found now the reason, but not the solution. The reason is that application: https://apps.microsoft.com/store/detail/virtual-desktop-indicator/9NHCL1XQWXF1?hl=en-us&gl=us It's a small utility app, that shows the active desktop after switching. After switch, a small window will shown, and then disappiers after some seconds. That utility window is never visible in "alt-tab"-List, so it should be impossible to focus it - but AutoHotkey does! Because the utility app it's a commercial, closed source app, it would be impossible to debug the problem further. But I'm still asking me why this problem never occurs, when using the built-in windows shortcut. In other words: Without the autohotkey script, the correct windows will always be focused (and never the utility app), regardless how fast i switch between the VD with the build-in windows shortcut.

arakis commented 1 year ago

I have now an idea, but for that I need to learn the AutoHotkey Script language a little bit more: Sending the ALT+ESC conditionally when the VirtualDesktopIndicator.exe is focused. Or finding other ways to unfocus the app, if it's focused.

FuPeiJiang commented 1 year ago

@arakis it should work now

But I'm still asking me why this problem never occurs, when using the built-in windows shortcut. In other words: Without the autohotkey script, the correct windows will always be focused (and never the utility app), regardless how fast i switch between the VD with the build-in windows shortcut.

nice question

The reason is that application: apps.microsoft.com/store/detail/virtual-desktop-indicator/9NHCL1XQWXF1?hl=en-us&gl=us

thanks, I used the free trial to figure out

turns out, if you set GW_OWNER to the desktop window (which has className:#32769) it will disappear from taskbar, alt+tab list, and appear on all desktops, this is how to set it:

SetWindowLongPtrW(hWnd, GWLP_HWNDPARENT, (LONG_PTR)GetDesktopWindow());

notice how it's GWLP_HWNDPARENT instead of GW_OWNER, the name is misleading https://stackoverflow.com/questions/133122/how-to-change-a-window-owner-using-its-handle#comment-24839121 > GWL_HWNDPARENT changes the OWNER, not the parent, of a window

arakis commented 1 year ago

@FuPeiJiang thank you very, very much, it works! I appreciate your work and the effort you invested in nailing down this problem. Can I buy you a coffee? :-)