Ciantic / VirtualDesktopAccessor

DLL for accessing Windows 11/10 Virtual Desktop features from e.g. AutoHotkey
MIT License
759 stars 93 forks source link

Move window to different workspace #2

Closed c0ffeeartc closed 8 years ago

c0ffeeartc commented 8 years ago

Simply wow, such a great addition you made. Along with your tip about AHK icon it looks as native as it could get. 1 thing left for me is to find a way to move current window to a different workspace. Is this planned or even possible to make?

Also how about adding an FAQ or Tips section to Readme

Ciantic commented 8 years ago

Yes I've planned this, probably as a custom shortcut.

Right now I can't find the C# app that has implemented it. It created a context menu for each window title, and one could send the window to different desktop from there...

dustinlacewell commented 8 years ago

+1!

Ciantic commented 8 years ago

The MSDN documents MoveWindowToDesktop https://msdn.microsoft.com/en-us/library/windows/desktop/mt186443(v=vs.85).aspx but forgets to mention that it only works for windows in same process.

Other have made cumbersome hack to overcome this, injecting a DLL to target window and calling the function within the process...

c0ffeeartc commented 8 years ago

There is some info here

Update: I've started looking into this. There's a registry value that changes when the app is moved between desktops. In that location, there are all the open apps:

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\SessionInfo\1\ApplicationViewManagement (I guess the session number will change if there is more than one logged in).

The id of the current desktop is here:

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\SessionInfo\1\VirtualDesktops\CurrentVirtualDesktop

It's not enough to change it to the other virtual desktop key because some UI refresh is needed.

I've checked with procmon, and the dll's that are used in the process are:

msctf.dll
twinui.dll
windows.immersiveshell.serviceprovider.dll
shell32.dll
UIAnimation.dll

I'll guess that one of them is responsible for the visual refresh, and the main suspect is UIAnimation.dll!

If someone wants to keep investigating, this will serve as a start.

Ciantic commented 8 years ago

@c0ffeeartc also in the same thread there is the tool I talked about: https://github.com/Eun/MoveToDesktop

It is possible if one is willing to inject code in other processes, which I'm not going to do in this DLL.

I'd rather in-memory patch the explorer.exe again to support moving windows between desktops. But right now I'm not going to heat up the x64dbg and look in to the internals, it's rather time consuming.

Also there is way bigger issues with Microsoft's implementation, e.g. the programs are not minimized when switching desktop. For instance Google Chrome can't release the GPU memory of Chrome windows on different desktop, I call that really unfortunate. I know how to solve it, and probably try to solve it sometime. I just secretly minimize all windows (like VirtuaWin) and restore them before switching back, this is probably outside the scope of this DLL but anyway.

Ciantic commented 8 years ago

Good news everyone! I found a way. Download the new dll and you can just use it:

MoveWindowToDesktopNumberProc := DllCall("GetProcAddress", Ptr, hVirtualDesktopAccessor, AStr, "MoveWindowToDesktopNumber", "Ptr")
RegisterPostMessageHookProc := DllCall("GetProcAddress", Ptr, hVirtualDesktopAccessor, AStr, "RegisterPostMessageHook", "Ptr")
UnregisterPostMessageHookProc := DllCall("GetProcAddress", Ptr, hVirtualDesktopAccessor, AStr, "UnregisterPostMessageHook", "Ptr")
; GetWindowDesktopNumberProc := DllCall("GetProcAddress", Ptr, hVirtualDesktopAccessor, AStr, "GetWindowDesktopNumber", "Ptr")
activeWindowByDesktop := {}

MoveCurrentWindowToDesktop(number) {
    global MoveWindowToDesktopNumberProc
    WinGet, activeHwnd, ID, A
    DllCall(MoveWindowToDesktopNumberProc, UInt, activeHwnd, UInt, number)
    GoToDesktopNumber(number)
    Sleep, 100
    WinActivate, ahk_id %activeHwnd%
}

See GoToDesktopNumber implementation from the README.