microsoft / PowerToys

Windows system utilities to maximize productivity
MIT License
111.39k stars 6.56k forks source link

[Run] Summon existing window to current virtual desktop/display #18475

Open harvastum opened 2 years ago

harvastum commented 2 years ago

Description of the new feature / enhancement

A new button in Window Walker plugin entries that moves the selected window to the display/virtual desktop from which PowerToys Run is used.

Scenario when this would be used?

I use virtual desktops extensively. Sometimes a window I want to use gets lost in the chaos. Window Walker plugin is what helps me find what I need, but it could be even better if it offered the option to summon the lost window to current virtual desktop (and display) in addition of allowing me to jump to it. Right now I can obviously jump to the window, go to Task View and then drag the window to the virtual desktop I want it in and then go to that desktop, but that's two clicks and one drag-and-drop more than I would have to do if window summoning was a thing. In addition, I have to actually know which virtual desktop I am on to be able to perform this relatively swiftly and that is not always the case.

Supporting information

I think that my use case is more general than the one described in #6885, hence a new issue.

htcfreek commented 2 years ago

This is should be an easy thing to implement. The backend helpers are there and we only have to implement the frontend feature. (If button is clicked: Check desktop state of window and then move to current visible desktop.)

htcfreek commented 2 years ago

@jaimecbernardo , @crutkas I can pick this up.

jaimecbernardo commented 2 years ago

@htcfreek, I think moving other Windows between virtualdesktops might require some non-public API to make it work. At least that seemed to be the case last time we looked into it. But if it doesn't require a private API, it sounds good. Thank you!

htcfreek commented 2 years ago

@htcfreek, I think moving other Windows between virtualdesktops might require some non-public API to make it work. At least that seemed to be the case last time we looked into it. But if it doesn't require a private API, it sounds good. Thank you!

@jaimecbernardo The code and required methods are public and official documented on docs. And in the helper I wrote we already have the required helper method. We only have to use it. 😉

https://github.com/microsoft/PowerToys/blob/main/src/modules/launcher/Wox.Plugin/Common/VirtualDesktop/VirtualDesktopHelper.cs#L406

I didn't implemented something similar because I didn't saw a use case. Now we have one that makes sense. 🚀

htcfreek commented 2 years ago

The only thing we have to pay attention on is that we have to move the window to the current visible desktop and not to the desktop where PT Run is shown/assigned to. Otherwise we can fail if the desktop id of PT Run is a generic one for the 'all desktops' view. (Additional using the active desktop's id is simplier than getting the on of PT Run's window.)

crutkas commented 2 years ago

if we can directly point to docs.msft documentation, i'm ok with it.

htcfreek commented 2 years ago

if we can directly point to docs.msft documentation, i'm ok with it.

this is done at the top of the helper class.

jaimecbernardo commented 2 years ago

Links to here. Looks good if that works :) https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-ivirtualdesktopmanager

htcfreek commented 2 years ago

@crutkas, @jaimecbernardo I tried to implement this. But there is a requirement that block us: The VirtualDesktopHelper method to move a window is only allowed for the process that owns the window. So we need non-public (private) classes and methods of the com-interface. It's on you if we close this issue as can't implement.

Log:

[2022-06-12 14:45:12.7258] [ERROR] [D:\AppDev\Github\htcfreek\PT_SummonVdWin\src\modules\launcher\Wox.Plugin\Common\VirtualDesktop\VirtualDesktopHelper.cs::417]
-------------------------- Begin exception --------------------------
Message: VirtualDesktopHelper.MoveWindowToDesktop() failed: An exception was thrown when moving the window (394436) to an other desktop (4dc858c8-9af9-45c8-a803-1755a0860332).

Exception full name  : System.UnauthorizedAccessException
Exception message    : Access is denied. (0x80070005 (E_ACCESSDENIED))
Exception stack trace:

Exception source     : 
Exception target site: 
Exception HResult    : -2147024891
-------------------------- End exception --------------------------

Code changes: https://github.com/htcfreek/PowerToys/commit/09348c14d9d02698c5a5db56e89f40e11e135e4d

Code added to ContextMenuHelper.cs:

            // Show move to current desktop context menu as first menu, but only if windows is not on the current desktop ar assigned to all desktops
            if (!windowData.Desktop.IsVisible && !windowData.Desktop.IsAllDesktopsView)
            {
                contextMenu.Insert(0, new ContextMenuResult
                {
                    AcceleratorKey = Key.D,
                    AcceleratorModifiers = ModifierKeys.Control,
                    FontFamily = "Segoe MDL2 Assets",
                    Glyph = "\xE8A0",                       // E8A0 => Symbol: Open Pane
                    Title = $"{Resources.wox_plugin_windowwalker_MoveCurrentDesktop} (Ctrl+D)",
                    Action = _ => windowData.MoveToCurrentDesktop(),
                });
            }

Code added to Window.cs:

        /// <summary>
        /// Move this window the the currently visible desktop and switches to the window
        /// </summary>
        internal bool MoveToCurrentDesktop()
        {
            if (!desktopInfo.IsVisible && !desktopInfo.IsAllDesktopsView)
            {
                return Main.VirtualDesktopHelperInstance.MoveWindowToDesktop(hwnd, Main.VirtualDesktopHelperInstance.GetCurrentDesktopId());
            }

            return true;
        }
jaimecbernardo commented 2 years ago

Yes, I remember this being possible only through some hidden API back in the day, unfortunately. Another way would be to inject a dll hook into every running process so that the process calls that itself, but that's kind of intrusive and would trigger off antivirus software (for good reason). I think this is more of a blocked issue while there isn't an API that allows this.

jaimecbernardo commented 2 years ago

Thanks for re-investigating this, btw ;)

gemisigo commented 1 year ago

Yes, I remember this being possible only through some hidden API back in the day, unfortunately. Another way would be to inject a dll hook into every running process so that the process calls that itself, but that's kind of intrusive and would trigger off antivirus software (for good reason). I think this is more of a blocked issue while there isn't an API that allows this.

Has there been any progress on this matter? Who is to be treated (or threatened) with a sandwich of sufficient size to create that API (or make it public)?

htcfreek commented 1 year ago

No, there hasn't been any progress.

gemisigo commented 1 year ago

Thanks for the quick reply, @htcfreek !

maciekkukuczka commented 9 months ago

Any news?

htcfreek commented 9 months ago

Any news?

No.

maciekkukuczka commented 9 months ago

Thank You.


Od: Heiko @.> Wysłane: sobota, 20 stycznia 2024 09:55 Do: microsoft/PowerToys @.> DW: thepeche @.>; Comment @.> Temat: Re: [microsoft/PowerToys] [Run] Summon existing window to current virtual desktop/display (Issue #18475)

Any news?

No.

— Reply to this email directly, view it on GitHubhttps://github.com/microsoft/PowerToys/issues/18475#issuecomment-1901987379, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AHWVJXOOD57SJITGB536Y5LYPOBB5AVCNFSM5W4ZWN2KU5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOJQGE4TQNZTG44Q. You are receiving this because you commented.Message ID: @.***>

htcfreek commented 4 months ago

@jaimecbernardo I have updated the https://github.com/microsoft/PowerToys/issues/18475#issuecomment-1153155344 above with the code I added in my test branch in case I delete it sometime. And I unassigned me as this is nothing I can implement.