@@ -22,6 +22,7 @@ public void JumpToDesktop(int index) {
22
22
}
23
23
24
24
public void MoveFocusedWindowToDesktop ( int index ) {
25
+ DesktopManager . MoveCurrentlyFocusedToDesktop ( index ) ;
25
26
}
26
27
27
28
public void Dispose ( ) {
@@ -35,8 +36,17 @@ public void Dispose() {
35
36
*/
36
37
37
38
internal static class DesktopManager {
39
+ // get handle of active window
40
+ [ DllImport ( "user32.dll" ) ]
41
+ private static extern IntPtr GetForegroundWindow ( ) ;
42
+
43
+ [ DllImport ( "user32.dll" ) ]
44
+ private static extern uint GetWindowThreadProcessId ( IntPtr hWnd , out int lpdwProcessId ) ;
45
+
38
46
private static IVirtualDesktopManagerInternal VirtualDesktopManagerInternal ;
39
47
internal static IVirtualDesktopNotificationService VirtualDesktopNotificationService ;
48
+ internal static IApplicationViewCollection ApplicationViewCollection ;
49
+ internal static IVirtualDesktopManager VirtualDesktopManager ;
40
50
41
51
static DesktopManager ( ) {
42
52
if ( Activator . CreateInstance ( Type . GetTypeFromCLSID ( Guids . CLSID_ImmersiveShell ) ??
@@ -49,6 +59,11 @@ static DesktopManager() {
49
59
Guids . CLSID_VirtualDesktopManagerInternal , typeof ( IVirtualDesktopManagerInternal ) . GUID ) ;
50
60
VirtualDesktopNotificationService = ( IVirtualDesktopNotificationService ) shell . QueryService (
51
61
Guids . CLSID_VirtualDesktopNotificationService , typeof ( IVirtualDesktopNotificationService ) . GUID ) ;
62
+ VirtualDesktopManager =
63
+ ( IVirtualDesktopManager ) Activator . CreateInstance (
64
+ Type . GetTypeFromCLSID ( Guids . CLSID_VirtualDesktopManager ) ) ;
65
+ ApplicationViewCollection = ( IApplicationViewCollection ) shell . QueryService (
66
+ typeof ( IApplicationViewCollection ) . GUID , typeof ( IApplicationViewCollection ) . GUID ) ;
52
67
}
53
68
54
69
// Helpers
@@ -94,6 +109,39 @@ internal static int GetCurrentDesktopNum() {
94
109
95
110
return GetIndex ( vd ) ;
96
111
}
112
+
113
+ internal static void MoveCurrentlyFocusedToDesktop ( int index ) {
114
+ int processId ;
115
+ IntPtr hWnd = GetForegroundWindow ( ) ;
116
+ if ( hWnd == IntPtr . Zero ) throw new ArgumentNullException ( ) ;
117
+ GetWindowThreadProcessId ( hWnd , out processId ) ;
118
+
119
+ var desktop = GetDesktop ( index ) ;
120
+
121
+ if ( Environment . ProcessId == processId ) {
122
+ // window of process
123
+ try // the easy way (if we are owner)
124
+ {
125
+ VirtualDesktopManager . MoveWindowToDesktop ( hWnd , desktop . GetId ( ) ) ;
126
+ } catch // window of process, but we are not the owner
127
+ {
128
+ IApplicationView view ;
129
+ ApplicationViewCollection . GetViewForHwnd ( hWnd , out view ) ;
130
+ VirtualDesktopManagerInternal . MoveViewToDesktop ( view , desktop ) ;
131
+ }
132
+ } else {
133
+ // window of other process
134
+ ApplicationViewCollection . GetViewForHwnd ( hWnd , out var view ) ;
135
+ try {
136
+ VirtualDesktopManagerInternal . MoveViewToDesktop ( view , desktop ) ;
137
+ } catch {
138
+ // could not move active window, try main window (or whatever windows thinks is the main window)
139
+ ApplicationViewCollection . GetViewForHwnd (
140
+ System . Diagnostics . Process . GetProcessById ( processId ) . MainWindowHandle , out view ) ;
141
+ VirtualDesktopManagerInternal . MoveViewToDesktop ( view , desktop ) ;
142
+ }
143
+ }
144
+ }
97
145
}
98
146
99
147
internal class VirtualDesktopNotification : IVirtualDesktopNotification {
@@ -141,6 +189,8 @@ public void RemoteVirtualDesktopConnected(IVirtualDesktop pDesktop) {
141
189
internal static class Guids {
142
190
public static readonly Guid CLSID_ImmersiveShell = new ( "C2F03A33-21F5-47FA-B4BB-156362A2F239" ) ;
143
191
192
+ public static readonly Guid CLSID_VirtualDesktopManager = new ( "AA509086-5CA9-4C25-8F95-589D3C07B48A" ) ;
193
+
144
194
public static readonly Guid CLSID_VirtualDesktopManagerInternal =
145
195
new ( "C5E0CDCA-7B6E-41B2-9FC4-D93975CC467B" ) ;
146
196
@@ -288,6 +338,32 @@ void GetDesktopSwitchIncludeExcludeViews(IVirtualDesktop desktop, out IObjectArr
288
338
void WaitForAnimationToComplete ( ) ;
289
339
}
290
340
341
+ [ ComImport ]
342
+ [ InterfaceType ( ComInterfaceType . InterfaceIsIUnknown ) ]
343
+ [ Guid ( "1841C6D7-4F9D-42C0-AF41-8747538F10E5" ) ]
344
+ internal interface IApplicationViewCollection {
345
+ int GetViews ( out IObjectArray array ) ;
346
+ int GetViewsByZOrder ( out IObjectArray array ) ;
347
+ int GetViewsByAppUserModelId ( string id , out IObjectArray array ) ;
348
+ int GetViewForHwnd ( IntPtr hwnd , out IApplicationView view ) ;
349
+ int GetViewForApplication ( object application , out IApplicationView view ) ;
350
+ int GetViewForAppUserModelId ( string id , out IApplicationView view ) ;
351
+ int GetViewInFocus ( out IntPtr view ) ;
352
+ int Unknown1 ( out IntPtr view ) ;
353
+ void RefreshCollection ( ) ;
354
+ int RegisterForApplicationViewChanges ( object listener , out int cookie ) ;
355
+ int UnregisterForApplicationViewChanges ( int cookie ) ;
356
+ }
357
+
358
+ [ ComImport ]
359
+ [ InterfaceType ( ComInterfaceType . InterfaceIsIUnknown ) ]
360
+ [ Guid ( "A5CD92FF-29BE-454C-8D04-D82879FB3F1B" ) ]
361
+ internal interface IVirtualDesktopManager {
362
+ bool IsWindowOnCurrentVirtualDesktop ( IntPtr topLevelWindow ) ;
363
+ Guid GetWindowDesktopId ( IntPtr topLevelWindow ) ;
364
+ void MoveWindowToDesktop ( IntPtr topLevelWindow , ref Guid desktopId ) ;
365
+ }
366
+
291
367
[ ComImport ]
292
368
[ InterfaceType ( ComInterfaceType . InterfaceIsIUnknown ) ]
293
369
[ Guid ( "0CD45E71-D927-4F15-8B0A-8FEF525337BF" ) ]
0 commit comments