···11+; in YOUR app
22+#Include %A_LineFile%\..\VD.ahk
33+; or
44+; #Include %A_LineFile%\..\_VD.ahk
55+; ...{startup code}
66+; VD.init()
77+88+; VD.ahk : calls `VD.init()` on #Include
99+; _VD.ahk : `VD.init()` when you want, like after a GUI has rendered, for startup performance reasons
+1087
Windows/AutoHotKey/_VD.ahk
···11+; VD.getCurrentDesktopNum()
22+; VD.getDesktopNumOfWindow(wintitle) ;please use VD.goToDesktopOfWindow instead if you just want to go there.
33+; VD.getDesktopNumOfWindow(wintitle) ;returns 0 for "Show on all desktops"
44+55+; VD.getCount() ;how many virtual desktops you now have
66+; VD.getRelativeDesktopNum(anchor_desktopNum, relative_count)
77+88+; VD.goToDesktopNum(desktopNum)
99+; VD.goToDesktopOfWindow(wintitle, activateYourWindow:=true)
1010+; VD.gotoRelativeDesktopNum(relative_count)
1111+1212+; VD.MoveWindowToDesktopNum(wintitle, desktopNum)
1313+; VD.MoveWindowToCurrentDesktop(wintitle, activateYourWindow:=true)
1414+; VD.MoveWindowToRelativeDesktopNum(wintitle, relative_count)
1515+1616+; VD.createDesktop(goThere:=true) ; VD.createUntil(howMany, goToLastlyCreated:=true)
1717+; VD.removeDesktop(desktopNum, fallback_desktopNum:=false)
1818+1919+; "Show this window on all desktops"
2020+; VD.IsWindowPinned(wintitle)
2121+; VD.TogglePinWindow(wintitle)
2222+; VD.PinWindow(wintitle)
2323+; VD.UnPinWindow(wintitle)
2424+2525+; "Show windows from this app on all desktops"
2626+; VD.IsAppPinned(wintitle)
2727+; VD.TogglePinApp(wintitle)
2828+; VD.PinApp(wintitle)
2929+; VD.UnPinApp(wintitle)
3030+3131+; Thanks to:
3232+; Blackholyman:
3333+; https://www.autohotkey.com/boards/viewtopic.php?t=67642#p291160
3434+; and
3535+; Flipeador:
3636+; https://www.autohotkey.com/boards/viewtopic.php?t=54202#p234192
3737+; https://www.autohotkey.com/boards/viewtopic.php?t=54202#p234309
3838+; and then later
3939+; MScholtes:
4040+; https://github.com/MScholtes/VirtualDesktop/blob/812c321e286b82a10f8050755c94d21c4b69812f/VirtualDesktop.cs
4141+; (for all the other functions I didnt know about. and windows 11)
4242+4343+class VD {
4444+4545+ ; #Include %A_LineFile%\..\VD.ahk
4646+ ; or
4747+ ; #Include %A_LineFile%\..\_VD.ahk
4848+ ; ...{startup code}
4949+ ; VD.init()
5050+5151+ ; VD.ahk : calls `VD.init()` on #Include
5252+ ; _VD.ahk : `VD.init()` when you want, like after a GUI has rendered, for startup performance reasons
5353+ init()
5454+ {
5555+ splitByDot:=StrSplit(A_OSVersion, ".")
5656+ buildNumber:=splitByDot[3]
5757+ if (buildNumber < 22000)
5858+ {
5959+ ; Windows 10
6060+ IID_IVirtualDesktopManagerInternal_:="{F31574D6-B682-4CDC-BD56-1827860ABEC6}" ;https://github.com/MScholtes/VirtualDesktop/blob/812c321e286b82a10f8050755c94d21c4b69812f/VirtualDesktop.cs#L177-L191
6161+ IID_IVirtualDesktop_:="{FF72FFDD-BE7E-43FC-9C03-AD81681E88E4}" ;https://github.com/MScholtes/VirtualDesktop/blob/812c321e286b82a10f8050755c94d21c4b69812f/VirtualDesktop.cs#L149-L150
6262+ ;conditionally assign method to method
6363+ this._dll_GetCurrentDesktop:=this._dll_GetCurrentDesktop_Win10
6464+ this._dll_GetDesktops:=this._dll_GetDesktops_Win10
6565+ this._dll_CreateDesktop:=this._dll_CreateDesktop_Win10
6666+ this._dll_GetName:=this._dll_GetName_Win10
6767+ this.RegisterDesktopNotifications:=this.RegisterDesktopNotifications_Win10
6868+ }
6969+ else
7070+ {
7171+ ; Windows 11
7272+ IID_IVirtualDesktopManagerInternal_:="{B2F925B9-5A0F-4D2E-9F4D-2B1507593C10}" ;https://github.com/MScholtes/VirtualDesktop/blob/812c321e286b82a10f8050755c94d21c4b69812f/VirtualDesktop11.cs#L163-L185
7373+ IID_IVirtualDesktop_:="{536D3495-B208-4CC9-AE26-DE8111275BF8}" ;https://github.com/MScholtes/VirtualDesktop/blob/812c321e286b82a10f8050755c94d21c4b69812f/VirtualDesktop11.cs#L149-L150
7474+ ;conditionally assign method to method
7575+ this._dll_GetCurrentDesktop:=this._dll_GetCurrentDesktop_Win11
7676+ this._dll_GetDesktops:=this._dll_GetDesktops_Win11
7777+ this._dll_CreateDesktop:=this._dll_CreateDesktop_Win11
7878+ this._dll_GetName:=this._dll_GetName_Win11
7979+ this.RegisterDesktopNotifications:=this.RegisterDesktopNotifications_Win11
8080+ }
8181+ ;----------------------
8282+ this.IVirtualDesktopManager := ComObjCreate("{AA509086-5CA9-4C25-8F95-589D3C07B48A}", "{A5CD92FF-29BE-454C-8D04-D82879FB3F1B}")
8383+ this.GetWindowDesktopId := this._vtable(this.IVirtualDesktopManager, 4)
8484+ this.MoveWindowToDesktop := this._vtable(this.IVirtualDesktopManager, 5)
8585+8686+ this.IServiceProvider := ComObjCreate("{C2F03A33-21F5-47FA-B4BB-156362A2F239}", "{6D5140C1-7436-11CE-8034-00AA006009FA}")
8787+8888+ this.IVirtualDesktopManagerInternal := ComObjQuery(this.IServiceProvider, "{C5E0CDCA-7B6E-41B2-9FC4-D93975CC467B}", IID_IVirtualDesktopManagerInternal_)
8989+9090+ ; this.GetCount := this._vtable(this.IVirtualDesktopManagerInternal, 3 ; int GetCount();
9191+ this.MoveViewToDesktop := this._vtable(this.IVirtualDesktopManagerInternal, 4) ; void MoveViewToDesktop(object pView, IVirtualDesktop desktop);
9292+ this.CanViewMoveDesktops := this._vtable(this.IVirtualDesktopManagerInternal, 5) ; bool CanViewMoveDesktops(IApplicationView view);
9393+ this.GetCurrentDesktop := this._vtable(this.IVirtualDesktopManagerInternal, 6) ; IVirtualDesktop GetCurrentDesktop(); || IVirtualDesktop GetCurrentDesktop(IntPtr hWndOrMon);
9494+ if (buildNumber < 22000) {
9595+ ;Windows 10 https://github.com/MScholtes/VirtualDesktop/blob/812c321e286b82a10f8050755c94d21c4b69812f/VirtualDesktop.cs#L177-L191
9696+9797+ this.GetDesktops := this._vtable(this.IVirtualDesktopManagerInternal, 7) ; void GetDesktops(out IObjectArray desktops);
9898+ ; this.GetAdjacentDesktop := this._vtable(this.IVirtualDesktopManagerInternal, 8) ; int GetAdjacentDesktop(IVirtualDesktop from, int direction, out IVirtualDesktop desktop);
9999+ ; this.SwitchDesktop := this._vtable(this.IVirtualDesktopManagerInternal, 9) ; void SwitchDesktop(IVirtualDesktop desktop);
100100+ this.Ptr_CreateDesktop := this._vtable(this.IVirtualDesktopManagerInternal, 10) ; IVirtualDesktop CreateDesktop();
101101+ this.Ptr_RemoveDesktop := this._vtable(this.IVirtualDesktopManagerInternal, 11) ; void RemoveDesktop(IVirtualDesktop desktop, IVirtualDesktop fallback);
102102+ this.FindDesktop := this._vtable(this.IVirtualDesktopManagerInternal, 12) ; IVirtualDesktop FindDesktop(ref Guid desktopid);
103103+ } else if (buildNumber < 22489) {
104104+ ;Windows 11 https://github.com/MScholtes/VirtualDesktop/blob/812c321e286b82a10f8050755c94d21c4b69812f/VirtualDesktop11.cs#L163-L185
105105+106106+ this.GetDesktops := this._vtable(this.IVirtualDesktopManagerInternal, 7) ; void GetDesktops(IntPtr hWndOrMon, out IObjectArray desktops);
107107+ ; this.GetAdjacentDesktop := this._vtable(this.IVirtualDesktopManagerInternal, 8) ; int GetAdjacentDesktop(IVirtualDesktop from, int direction, out IVirtualDesktop desktop);
108108+ ; this.SwitchDesktop := this._vtable(this.IVirtualDesktopManagerInternal, 9) ; void SwitchDesktop(IntPtr hWndOrMon, IVirtualDesktop desktop);
109109+ this.Ptr_CreateDesktop := this._vtable(this.IVirtualDesktopManagerInternal, 10) ; IVirtualDesktop CreateDesktop(IntPtr hWndOrMon);
110110+ ; this.MoveDesktop := this._vtable(this.IVirtualDesktopManagerInternal, 11) ; void MoveDesktop(IVirtualDesktop desktop, IntPtr hWndOrMon, int nIndex);
111111+ this.Ptr_RemoveDesktop := this._vtable(this.IVirtualDesktopManagerInternal, 12) ; void RemoveDesktop(IVirtualDesktop desktop, IVirtualDesktop fallback);
112112+ this.FindDesktop := this._vtable(this.IVirtualDesktopManagerInternal, 13) ; IVirtualDesktop FindDesktop(ref Guid desktopid);
113113+ } else {
114114+ ;Windows 11 Insider build 22489 https://github.com/MScholtes/VirtualDesktop/blob/9f3872e1275408a0802bdbe46df499bb7645dc87/VirtualDesktop11Insider.cs#L163-L186
115115+116116+ ; this.GetAllCurrentDesktops := this._vtable(this.IVirtualDesktopManagerInternal, 7) ; IObjectArray GetAllCurrentDesktops();
117117+ this.GetDesktops := this._vtable(this.IVirtualDesktopManagerInternal, 8) ; void GetDesktops(IntPtr hWndOrMon, out IObjectArray desktops);
118118+ ; this.GetAdjacentDesktop := this._vtable(this.IVirtualDesktopManagerInternal, 9) ; int GetAdjacentDesktop(IVirtualDesktop from, int direction, out IVirtualDesktop desktop);
119119+ ; this.SwitchDesktop := this._vtable(this.IVirtualDesktopManagerInternal, 10) ; void SwitchDesktop(IntPtr hWndOrMon, IVirtualDesktop desktop);
120120+ this.Ptr_CreateDesktop := this._vtable(this.IVirtualDesktopManagerInternal, 11) ; IVirtualDesktop CreateDesktop(IntPtr hWndOrMon);
121121+ ; this.MoveDesktop := this._vtable(this.IVirtualDesktopManagerInternal, 12) ; void MoveDesktop(IVirtualDesktop desktop, IntPtr hWndOrMon, int nIndex);
122122+ this.Ptr_RemoveDesktop := this._vtable(this.IVirtualDesktopManagerInternal, 13) ; void RemoveDesktop(IVirtualDesktop desktop, IVirtualDesktop fallback);
123123+ this.FindDesktop := this._vtable(this.IVirtualDesktopManagerInternal, 14) ; IVirtualDesktop FindDesktop(ref Guid desktopid);
124124+ }
125125+126126+ ;https://github.com/MScholtes/VirtualDesktop/blob/812c321e286b82a10f8050755c94d21c4b69812f/VirtualDesktop.cs#L225-L234
127127+ this.IVirtualDesktopPinnedApps := ComObjQuery(this.IServiceProvider, "{B5A399E7-1C87-46B8-88E9-FC5747B171BD}", "{4CE81583-1E4C-4632-A621-07A53543148F}")
128128+129129+ ; this.IsAppIdPinned := this._vtable(this.IVirtualDesktopPinnedApps, 3) ; bool IsAppIdPinned(string appId);
130130+ ; this.PinAppID := this._vtable(this.IVirtualDesktopPinnedApps, 4) ; void PinAppID(string appId);
131131+ ; this.UnpinAppID := this._vtable(this.IVirtualDesktopPinnedApps, 5) ; void UnpinAppID(string appId);
132132+ this.IsViewPinned := this._vtable(this.IVirtualDesktopPinnedApps, 6) ; bool IsViewPinned(IApplicationView applicationView);
133133+ this.PinView := this._vtable(this.IVirtualDesktopPinnedApps, 7) ; void PinView(IApplicationView applicationView);
134134+ this.UnpinView := this._vtable(this.IVirtualDesktopPinnedApps, 8) ; void UnpinView(IApplicationView applicationView);
135135+136136+137137+ ImmersiveShell := ComObjCreate("{C2F03A33-21F5-47FA-B4BB-156362A2F239}", "{00000000-0000-0000-C000-000000000046}")
138138+ ; if !(IApplicationViewCollection := ComObjQuery(ImmersiveShell,"{1841C6D7-4F9D-42C0-AF41-8747538F10E5}" ) ) ; doesn't work
139139+ ; SAME CLSID and IID ?
140140+ ; wait it's not CLSID:
141141+ ; SID
142142+ ; A service identifier in the same form as IID. When omitting this parameter, also omit the comma.
143143+ this.IApplicationViewCollection := ComObjQuery(ImmersiveShell,"{1841C6D7-4F9D-42C0-AF41-8747538F10E5}","{1841C6D7-4F9D-42C0-AF41-8747538F10E5}" )
144144+ if (!this.IApplicationViewCollection) ; 1607-1809
145145+ {
146146+ MsgBox IApplicationViewCollection interface not supported.
147147+ }
148148+ this.GetViewForHwnd := this._vtable(this.IApplicationViewCollection, 6) ; (IntPtr hwnd, out IApplicationView view);
149149+150150+151151+ ;----------------------
152152+153153+ ; VarSetCapacity(IID_IVirtualDesktop, 16)
154154+ ; this will never be garbage collected
155155+ this.Ptr_IID_IVirtualDesktop := DllCall( "GlobalAlloc", "UInt",0x00, "UInt", 16, "Ptr")
156156+ DllCall("Ole32.dll\CLSIDFromString", "Str", IID_IVirtualDesktop_, "Ptr", this.Ptr_IID_IVirtualDesktop)
157157+158158+ ;----------------------
159159+160160+ this.savedLocalizedWord_Desktop:=false
161161+162162+ }
163163+ ;dll methods start
164164+ _dll_GetCurrentDesktop_Win10() {
165165+ IVirtualDesktop_ofCurrentDesktop := 0
166166+ DllCall(this.GetCurrentDesktop, "UPtr", this.IVirtualDesktopManagerInternal, "Ptr*", IVirtualDesktop_ofCurrentDesktop)
167167+ return IVirtualDesktop_ofCurrentDesktop
168168+ }
169169+ _dll_GetCurrentDesktop_Win11() {
170170+ IVirtualDesktop_ofCurrentDesktop := 0
171171+ DllCall(this.GetCurrentDesktop, "UPtr", this.IVirtualDesktopManagerInternal, "Ptr", 0, "Ptr*", IVirtualDesktop_ofCurrentDesktop)
172172+ return IVirtualDesktop_ofCurrentDesktop
173173+ }
174174+ _dll_GetDesktops_Win10() {
175175+ IObjectArray := 0
176176+ DllCall(this.GetDesktops, "UPtr", this.IVirtualDesktopManagerInternal, "Ptr*", IObjectArray)
177177+ return IObjectArray
178178+ }
179179+ _dll_GetDesktops_Win11() {
180180+ IObjectArray := 0
181181+ DllCall(this.GetDesktops, "UPtr", this.IVirtualDesktopManagerInternal, "Ptr", 0, "UPtr*", IObjectArray)
182182+ return IObjectArray
183183+ }
184184+ _dll_CreateDesktop_Win10() {
185185+ IVirtualDesktop_ofNewDesktop:=0
186186+ DllCall(this.Ptr_CreateDesktop, "UPtr", this.IVirtualDesktopManagerInternal, "Ptr*", IVirtualDesktop_ofNewDesktop)
187187+ return IVirtualDesktop_ofNewDesktop
188188+ }
189189+ _dll_CreateDesktop_Win11() {
190190+ IVirtualDesktop_ofNewDesktop:=0
191191+ DllCall(this.Ptr_CreateDesktop, "UPtr", this.IVirtualDesktopManagerInternal, "Ptr", 0, "Ptr*", IVirtualDesktop_ofNewDesktop)
192192+ return IVirtualDesktop_ofNewDesktop
193193+ }
194194+ _dll_GetName_Win10(IVirtualDesktop) {
195195+ QueryInterface:=this._vtable(IVirtualDesktop, 0)
196196+ VarSetCapacity(CLSID, 16)
197197+ DllCall("Ole32.dll\CLSIDFromString", "Str","{31EBDE3F-6EC3-4CBD-B9FB-0EF6D09B41F4}", "Ptr",&CLSID)
198198+ DllCall(QueryInterface, "UPtr",IVirtualDesktop, "Ptr",&CLSID, "Ptr*", IVirtualDesktop2)
199199+200200+ GetName:=this._vtable(IVirtualDesktop2,5)
201201+ DllCall(GetName, "UPtr", IVirtualDesktop2, "Ptr*", Handle_DesktopName)
202202+ if (Handle_DesktopName==0) {
203203+ return "" ;you can't have empty desktopName so this can represent error
204204+ }
205205+ Ptr_DesktopName:=DllCall("combase\WindowsGetStringRawBuffer", "Ptr",Handle_DesktopName, "UInt*",length, "Ptr")
206206+ desktopName:=StrGet(Ptr_DesktopName+0,"UTF-16")
207207+ return desktopName
208208+ }
209209+ /* _dll_GetName_Win10(IVirtualDesktop) {
210210+ GetId := this._vtable(IVirtualDesktop, 4)
211211+ VarSetCapacity(GUID_Desktop, 16)
212212+ DllCall(GetId, "UPtr",IVirtualDesktop, "Ptr",&GUID_Desktop)
213213+214214+ strGUID:=this._string_from_GUID(GUID_Desktop)
215215+ KeyName:="HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VirtualDesktops\Desktops\" strGUID
216216+ ;RegRead gives "" on key not found, convenient
217217+ RegRead, desktopName, % KeyName, % "Name"
218218+ ; I don't like this because registry can be edited, then it wouldn't reflect the desktopName
219219+ return desktopName
220220+ }
221221+ */
222222+ _dll_GetName_Win11(IVirtualDesktop) {
223223+ GetName:=this._vtable(IVirtualDesktop,6)
224224+ DllCall(GetName, "UPtr", IVirtualDesktop, "Ptr*", Handle_DesktopName)
225225+ if (Handle_DesktopName==0) {
226226+ return "" ;you can't have empty desktopName so this can represent error
227227+ }
228228+ Ptr_DesktopName:=DllCall("combase\WindowsGetStringRawBuffer", "Ptr",Handle_DesktopName, "UInt*",length, "Ptr")
229229+ desktopName:=StrGet(Ptr_DesktopName+0,"UTF-16")
230230+ return desktopName
231231+ }
232232+ ;dll methods end
233233+234234+ ;actual methods start
235235+ getCount() { ;how many virtual desktops you now have
236236+ return this._GetDesktops_Obj().GetCount()
237237+ }
238238+239239+ goToDesktopNum(desktopNum) { ; Lej77 https://github.com/Grabacr07/VirtualDesktop/pull/23#issuecomment-334918711
240240+ firstWindowId:=this._getFirstWindowInVD(desktopNum)
241241+242242+ Gui VD_animation_gui:New, % "-Border -SysMenu +Owner -Caption +HwndVD_animation_gui_hwnd_tmp"
243243+ VD_animation_gui_hwnd:=VD_animation_gui_hwnd_tmp+0
244244+ IVirtualDesktop := this._GetDesktops_Obj().GetAt(desktopNum)
245245+ GetId:=this._vtable(IVirtualDesktop, 4)
246246+ VarSetCapacity(GUID_Desktop, 16)
247247+ DllCall(GetId, "Ptr", IVirtualDesktop, "Ptr", &GUID_Desktop)
248248+ DllCall(this.MoveWindowToDesktop, "Ptr", this.IVirtualDesktopManager, "Ptr", VD_animation_gui_hwnd, "Ptr", &GUID_Desktop)
249249+ DllCall("ShowWindow","Ptr",VD_animation_gui_hwnd,"Int",4) ;after gui on current desktop owned by current process became active window, Show gui on different desktop owned by current process
250250+ this._WinActivate_NewProcess(VD_animation_gui_hwnd)
251251+ loop 20 {
252252+ if (this.getCurrentDesktopNum()==desktopNum) { ; wildest hack ever..
253253+ if (firstWindowId) {
254254+ DllCall("SetForegroundWindow","Ptr",firstWindowId)
255255+ } else {
256256+ this._activateDesktopBackground()
257257+ }
258258+ break
259259+ }
260260+ Sleep 25
261261+ }
262262+ Gui VD_animation_gui:Destroy
263263+264264+ }
265265+266266+ _getLocalizedWord_Desktop() {
267267+ if (this.savedLocalizedWord_Desktop) {
268268+ return this.savedLocalizedWord_Desktop
269269+ }
270270+271271+ hModule := DllCall("GetModuleHandle", "Str","shell32.dll", "Ptr") ;ahk always loads "shell32.dll"
272272+ length:=DllCall("LoadString", "Uint",hModule, "Uint",21769, "Ptr*",lpBuffer, "Int",0) ;21769="Desktop"
273273+ this.savedLocalizedWord_Desktop := StrGet(lpBuffer, length, "UTF-16")
274274+ return this.savedLocalizedWord_Desktop
275275+ }
276276+ getNameFromDesktopNum(desktopNum) {
277277+ IVirtualDesktop:=this._GetDesktops_Obj().GetAt(desktopNum)
278278+ _name:=this._dll_GetName(IVirtualDesktop)
279279+ if (!_name) {
280280+ _name:=this._getLocalizedWord_Desktop() " " desktopNum
281281+ }
282282+ return _name
283283+ }
284284+285285+ getDesktopNumOfWindow(wintitle) {
286286+ found:=this._tryGetValidWindow(wintitle)
287287+ if (!found) {
288288+ return -1 ;for false
289289+ }
290290+ theHwnd:=found[1]
291291+292292+ desktopNum_ofWindow:=this._desktopNum_from_Hwnd(theHwnd)
293293+ return desktopNum_ofWindow ; 0 for "Show on all desktops"
294294+ }
295295+296296+ goToDesktopOfWindow(wintitle, activateYourWindow:=true) {
297297+ found:=this._tryGetValidWindow(wintitle)
298298+ if (!found) {
299299+ return -1 ;for false
300300+ }
301301+ theHwnd:=found[1]
302302+303303+ desktopNum_ofWindow:=this._desktopNum_from_Hwnd(theHwnd)
304304+ this.goToDesktopNum(desktopNum_ofWindow)
305305+306306+ if (activateYourWindow) {
307307+ WinActivate, ahk_id %theHwnd%
308308+ }
309309+ }
310310+311311+ MoveWindowToDesktopNum(wintitle, desktopNum) {
312312+ found:=this._tryGetValidWindow(wintitle)
313313+ if (!found) {
314314+ return -1 ;for false
315315+ }
316316+ theHwnd:=found[1]
317317+ thePView:=found[2]
318318+319319+ needActivateWindowUnder:=false
320320+ if (activeHwnd:=WinExist("A")) {
321321+ if (activeHwnd==theHwnd) {
322322+ currentDesktopNum:=this.getCurrentDesktopNum()
323323+ if (!(currentDesktopNum==desktopNum)) {
324324+ needActivateWindowUnder:=true
325325+ }
326326+ }
327327+ }
328328+329329+ IVirtualDesktop:=this._GetDesktops_Obj().GetAt(desktopNum)
330330+ DllCall(this.MoveViewToDesktop, "ptr", this.IVirtualDesktopManagerInternal, "Ptr", thePView, "Ptr", IVirtualDesktop)
331331+332332+ if (needActivateWindowUnder) {
333333+ firstWindowId:=this._getFirstWindowInVD(currentDesktopNum, theHwnd)
334334+ if (firstWindowId) {
335335+ VD._WinActivate_NewProcess(firstWindowId)
336336+ } else {
337337+ this._activateDesktopBackground()
338338+ }
339339+ }
340340+341341+ }
342342+343343+ getRelativeDesktopNum(anchor_desktopNum, relative_count)
344344+ {
345345+ Desktops_Obj:=this._GetDesktops_Obj()
346346+ count_Desktops:=Desktops_Obj.GetCount()
347347+348348+ absolute_desktopNum:=anchor_desktopNum + relative_count
349349+ ;// The 1-based indices wrap around on the first and last desktop.
350350+ ;// say count_Desktops:=3
351351+ absolute_desktopNum:=Mod(absolute_desktopNum, count_Desktops)
352352+ ; 4 -> 1
353353+ if (absolute_desktopNum <= 0) {
354354+ ; 0 -> 3
355355+ absolute_desktopNum:=absolute_desktopNum + count_Desktops
356356+ }
357357+358358+ return absolute_desktopNum
359359+ }
360360+361361+ MoveWindowToRelativeDesktopNum(wintitle, relative_count) {
362362+363363+ desktopNum_ofWindow := this.getDesktopNumOfWindow(wintitle)
364364+ absolute_desktopNum := this.getRelativeDesktopNum(desktopNum_ofWindow, relative_count)
365365+366366+ this.MoveWindowToDesktopNum(wintitle, absolute_desktopNum)
367367+368368+ return absolute_desktopNum
369369+ }
370370+371371+ gotoRelativeDesktopNum(relative_count) {
372372+ this.goToDesktopNum(this.getRelativeDesktopNum(this.getCurrentDesktopNum(), relative_count))
373373+ }
374374+375375+ MoveWindowToCurrentDesktop(wintitle, activateYourWindow:=true) {
376376+ found:=this._tryGetValidWindow(wintitle)
377377+ if (!found) {
378378+ return -1 ;for false
379379+ }
380380+ theHwnd:=found[1]
381381+ thePView:=found[2]
382382+383383+ currentDesktopNum:=this.getCurrentDesktopNum()
384384+ IVirtualDesktop:=this._GetDesktops_Obj().GetAt(currentDesktopNum)
385385+386386+ DllCall(this.MoveViewToDesktop, "ptr", this.IVirtualDesktopManagerInternal, "Ptr", thePView, "Ptr", IVirtualDesktop)
387387+388388+ if (activateYourWindow) {
389389+ WinActivate % "ahk_id " theHwnd
390390+ }
391391+ }
392392+393393+ getCurrentDesktopNum() {
394394+ IVirtualDesktop_ofCurrentDesktop:=this._dll_GetCurrentDesktop()
395395+396396+ desktopNum:=this._desktopNum_from_IVirtualDesktop(IVirtualDesktop_ofCurrentDesktop)
397397+ return desktopNum
398398+ }
399399+400400+ createDesktop(goThere:=false) {
401401+ IVirtualDesktop_ofNewDesktop:=this._dll_CreateDesktop()
402402+403403+ if (goThere) {
404404+ ;we could assume that it's the rightmost desktop:
405405+ ; desktopNum:=this.getCount()
406406+ ;but I'm not risking it
407407+ desktopNum:=this._desktopNum_from_IVirtualDesktop(IVirtualDesktop_ofNewDesktop)
408408+ this.goToDesktopNum(desktopNum)
409409+ }
410410+ }
411411+412412+ createUntil(howMany, goToLastlyCreated:=false) {
413413+ howManyThereAlreadyAre:=this.getCount()
414414+ if (howManyThereAlreadyAre>=howMany) {
415415+ return
416416+ }
417417+418418+ ;this will create until one less than wanted
419419+ loop % howMany - howManyThereAlreadyAre - 1 {
420420+ this.createDesktop(false)
421421+ }
422422+ this.createDesktop(goToLastlyCreated)
423423+ }
424424+425425+ removeDesktop(desktopNum, fallback_desktopNum:=false) {
426426+ ;FALLBACK IS ONLY USED IF YOU ARE CURRENTLY ON THE VD BEING DELETED
427427+ ;but we NEED a fallback, regardless, so I'm not checking if you are currently on the vd being deleted
428428+429429+ Desktops_Obj:=this._GetDesktops_Obj()
430430+431431+ ;if no fallback,
432432+ if (!fallback_desktopNum) {
433433+434434+ ;look left
435435+ if (desktopNum > 1) {
436436+ fallback_desktopNum:=desktopNum - 1
437437+ }
438438+ ;look right
439439+ else if (desktopNum < Desktops_Obj.GetCount()) {
440440+ fallback_desktopNum:=desktopNum + 1
441441+ }
442442+ ;no fallback to go to
443443+ else {
444444+ return false
445445+ }
446446+ }
447447+448448+ IVirtualDesktop:=Desktops_Obj.GetAt(desktopNum)
449449+ IVirtualDesktop_fallback:=Desktops_Obj.GetAt(fallback_desktopNum)
450450+451451+ DllCall(this.Ptr_RemoveDesktop, "UPtr", this.IVirtualDesktopManagerInternal, "Ptr", IVirtualDesktop, "Ptr", IVirtualDesktop_fallback)
452452+ }
453453+454454+ IsWindowPinned(wintitle) {
455455+ found:=this._tryGetValidWindow(wintitle)
456456+ if (!found) {
457457+ return -1 ;for false
458458+ }
459459+ thePView:=found[2]
460460+461461+ viewIsPinned:=this._IsViewPinned(thePView)
462462+ return viewIsPinned
463463+ }
464464+ TogglePinWindow(wintitle) {
465465+ found:=this._tryGetValidWindow(wintitle)
466466+ if (!found) {
467467+ return -1 ;for false
468468+ }
469469+ thePView:=found[2]
470470+471471+ viewIsPinned:=this._IsViewPinned(thePView)
472472+ if (viewIsPinned) {
473473+ DllCall(this.UnPinView, "UPtr", this.IVirtualDesktopPinnedApps, "Ptr", thePView)
474474+ } else {
475475+ DllCall(this.PinView, "UPtr", this.IVirtualDesktopPinnedApps, "Ptr", thePView)
476476+ }
477477+478478+ }
479479+ PinWindow(wintitle) {
480480+ found:=this._tryGetValidWindow(wintitle)
481481+ if (!found) {
482482+ return -1 ;for false
483483+ }
484484+ thePView:=found[2]
485485+486486+ DllCall(this.PinView, "UPtr", this.IVirtualDesktopPinnedApps, "Ptr", thePView)
487487+ }
488488+ UnPinWindow(wintitle) {
489489+ found:=this._tryGetValidWindow(wintitle)
490490+ if (!found) {
491491+ return -1 ;for false
492492+ }
493493+ thePView:=found[2]
494494+495495+ DllCall(this.UnPinView, "UPtr", this.IVirtualDesktopPinnedApps, "Ptr", thePView)
496496+ }
497497+498498+ ; COM class start ;https://github.com/Ciantic/VirtualDesktopAccessor/blob/5bc1bbaab247b5d72e70abc9432a15275fd2d229/VirtualDesktopAccessor/dllmain.h#L718-L794
499499+ _QueryInterface_Win10(riid, ppvObject) {
500500+ if (!ppvObject) {
501501+ return 0x80070057 ;E_INVALIDARG
502502+ }
503503+504504+ str_IID_IUnknown:="{00000000-0000-0000-C000-000000000046}"
505505+ str_IID_IVirtualDesktopNotification:="{C179334C-4295-40D3-BEA1-C654D965605A}"
506506+507507+ VarSetCapacity(someStr, 40*2)
508508+ DllCall("Ole32\StringFromGUID2", "Ptr", riid, "Ptr",&someStr, "Ptr",40)
509509+ str_riid:=StrGet(&someStr)
510510+511511+ if (str_riid==str_IID_IUnknown || str_riid==str_IID_IVirtualDesktopNotification) {
512512+ NumPut(this, ppvObject+0, 0, "Ptr")
513513+ VD._AddRef_Same.Call(this)
514514+ return 0 ;S_OK
515515+ }
516516+ ; *ppvObject = NULL;
517517+ NumPut(0, ppvObject+0, 0, "Ptr")
518518+ return 0x80004002 ;E_NOINTERFACE
519519+520520+ ; // Always set out parameter to NULL, validating it first.
521521+ ; if (!ppvObject)
522522+ ; return E_INVALIDARG;
523523+ ; *ppvObject = NULL;
524524+;
525525+ ; if (riid == IID_IUnknown || riid == IID_IVirtualDesktopNotification)
526526+ ; {
527527+ ; // Increment the reference count and return the pointer.
528528+ ; *ppvObject = (LPVOID)this;
529529+ ; AddRef();
530530+ ; return S_OK;
531531+ ; }
532532+ ; return E_NOINTERFACE;
533533+ }
534534+ _AddRef_Same() {
535535+ refCount:=NumGet(this+0, A_PtrSize, "UInt")
536536+ refCount++
537537+ NumPut(refCount, this+0, A_PtrSize, "UInt")
538538+ ; NumPut(this + 4)
539539+ ; refCount:=
540540+541541+ ; return InterlockedIncrement(&_referenceCount);
542542+ return refCount
543543+ }
544544+ _Release_Same() {
545545+ refCount:=NumGet(this+0, A_PtrSize, "UInt")
546546+ refCount--
547547+ NumPut(refCount, this+0, A_PtrSize, "UInt")
548548+ ; ULONG result = InterlockedDecrement(&_referenceCount);
549549+ ; if (result == 0)
550550+ ; {
551551+ ; delete this;
552552+ ; }
553553+ return refCount
554554+ }
555555+ _VirtualDesktopCreated_Win10(pDesktop) {
556556+ ; Tooltip % 11111
557557+ VD.VirtualDesktopCreated.Call(VD._desktopNum_from_IVirtualDesktop(pDesktop))
558558+ return 0 ;S_OK
559559+ }
560560+ _VirtualDesktopDestroyBegin_Win10(pDesktopDestroyed, pDesktopFallback) {
561561+ ; Tooltip % 22222
562562+ VD.VirtualDesktopDestroyBegin.Call(VD._desktopNum_from_IVirtualDesktop(pDesktopDestroyed), VD._desktopNum_from_IVirtualDesktop(pDesktopFallback))
563563+ return 0 ;S_OK
564564+ }
565565+ _VirtualDesktopDestroyFailed_Win10(pDesktopDestroyed, pDesktopFallback) {
566566+ ; Tooltip % 33333
567567+ VD.VirtualDesktopDestroyFailed.Call(VD._desktopNum_from_IVirtualDesktop(pDesktopDestroyed), VD._desktopNum_from_IVirtualDesktop(pDesktopFallback))
568568+ return 0 ;S_OK
569569+ }
570570+ _VirtualDesktopDestroyed_Win10(pDesktopDestroyed, pDesktopFallback) {
571571+ ; Tooltip % 44444
572572+ VD.VirtualDesktopDestroyed.Call(VD._desktopNum_from_IVirtualDesktop(pDesktopDestroyed), VD._desktopNum_from_IVirtualDesktop(pDesktopFallback))
573573+ return 0 ;S_OK
574574+ }
575575+ _ViewVirtualDesktopChanged_Win10(pView) {
576576+ ; Tooltip % 55555
577577+ VD.ViewVirtualDesktopChanged.Call(pView)
578578+ return 0 ;S_OK
579579+ }
580580+ _CurrentVirtualDesktopChanged_Win10(pDesktopOld, pDesktopNew) {
581581+ VD.CurrentVirtualDesktopChanged.Call(VD._desktopNum_from_IVirtualDesktop(pDesktopOld), VD._desktopNum_from_IVirtualDesktop(pDesktopNew))
582582+ return 0 ;S_OK
583583+ }
584584+ RegisterDesktopNotifications_Win10() { ;https://github.com/Ciantic/VirtualDesktopAccessor/blob/5bc1bbaab247b5d72e70abc9432a15275fd2d229/VirtualDesktopAccessor/dllmain.h#L718-L794
585585+ methods:=DllCall("GlobalAlloc", "Uint",0x00, "Uint",9*A_PtrSize) ;PLEASE DON'T GARBAGE COLLECT IT, this took me hours to debug, I was lucky ahkv2 garbage collected slowly
586586+ NumPut(RegisterCallback("VD._QueryInterface_Win10", "F"), methods+0, 0*A_PtrSize, "Ptr")
587587+ NumPut(RegisterCallback("VD._AddRef_Same", "F"), methods+0, 1*A_PtrSize, "Ptr")
588588+ NumPut(RegisterCallback("VD._Release_Same", "F"), methods+0, 2*A_PtrSize, "Ptr")
589589+ NumPut(RegisterCallback("VD._VirtualDesktopCreated_Win10", "F"), methods+0, 3*A_PtrSize, "Ptr")
590590+ NumPut(RegisterCallback("VD._VirtualDesktopDestroyBegin_Win10", "F"), methods+0, 4*A_PtrSize, "Ptr")
591591+ NumPut(RegisterCallback("VD._VirtualDesktopDestroyFailed_Win10", "F"), methods+0, 5*A_PtrSize, "Ptr")
592592+ NumPut(RegisterCallback("VD._VirtualDesktopDestroyed_Win10", "F"), methods+0, 6*A_PtrSize, "Ptr")
593593+ NumPut(RegisterCallback("VD._ViewVirtualDesktopChanged_Win10", "F"), methods+0, 7*A_PtrSize, "Ptr")
594594+ NumPut(RegisterCallback("VD._CurrentVirtualDesktopChanged_Win10", "F"), methods+0, 8*A_PtrSize, "Ptr")
595595+596596+ this.RegisterDesktopNotifications_Same(methods)
597597+ }
598598+ ;COM class for Win11
599599+ _QueryInterface_Win11(riid, ppvObject) {
600600+ if (!ppvObject) {
601601+ return 0x80070057 ;E_INVALIDARG
602602+ }
603603+604604+ str_IID_IUnknown:="{00000000-0000-0000-C000-000000000046}"
605605+ str_IID_IVirtualDesktopNotification:="{CD403E52-DEED-4C13-B437-B98380F2B1E8}"
606606+607607+ VarSetCapacity(someStr, 40*2)
608608+ DllCall("Ole32\StringFromGUID2", "Ptr", riid, "Ptr",&someStr, "Ptr",40)
609609+ str_riid:=StrGet(&someStr)
610610+611611+ if (str_riid==str_IID_IUnknown || str_riid==str_IID_IVirtualDesktopNotification) {
612612+ NumPut(this, ppvObject+0, 0, "Ptr")
613613+ VD._AddRef_Same.Call(this)
614614+ return 0 ;S_OK
615615+ }
616616+ ; *ppvObject = NULL;
617617+ NumPut(0, ppvObject+0, 0, "Ptr")
618618+ return 0x80004002 ;E_NOINTERFACE
619619+ }
620620+ _VirtualDesktopCreated_Win11(p0, pDesktop) {
621621+ ; Tooltip % 11111
622622+ VD.VirtualDesktopCreated.Call(VD._desktopNum_from_IVirtualDesktop(pDesktop))
623623+ return 0 ;S_OK
624624+ }
625625+ _VirtualDesktopDestroyBegin_Win11(p0, pDesktopDestroyed, pDesktopFallback) {
626626+ ; Tooltip % 22222
627627+ VD.VirtualDesktopDestroyBegin.Call(VD._desktopNum_from_IVirtualDesktop(pDesktopDestroyed), VD._desktopNum_from_IVirtualDesktop(pDesktopFallback))
628628+ return 0 ;S_OK
629629+ }
630630+ _VirtualDesktopDestroyFailed_Win11(p0, pDesktopDestroyed, pDesktopFallback) {
631631+ ; Tooltip % 33333
632632+ VD.VirtualDesktopDestroyFailed.Call(VD._desktopNum_from_IVirtualDesktop(pDesktopDestroyed), VD._desktopNum_from_IVirtualDesktop(pDesktopFallback))
633633+ return 0 ;S_OK
634634+ }
635635+ _VirtualDesktopDestroyed_Win11(p0, pDesktopDestroyed, pDesktopFallback) {
636636+ ; Tooltip % 44444
637637+ VD.VirtualDesktopDestroyed.Call(VD._desktopNum_from_IVirtualDesktop(pDesktopDestroyed), VD._desktopNum_from_IVirtualDesktop(pDesktopFallback))
638638+ return 0 ;S_OK
639639+ }
640640+ _ViewVirtualDesktopChanged_Win11(pView) {
641641+ ; Tooltip % 55555
642642+ VD.ViewVirtualDesktopChanged.Call(pView)
643643+ return 0 ;S_OK
644644+ }
645645+ _CurrentVirtualDesktopChanged_Win11(p0, pDesktopOld, pDesktopNew) {
646646+ VD.CurrentVirtualDesktopChanged.Call(VD._desktopNum_from_IVirtualDesktop(pDesktopOld), VD._desktopNum_from_IVirtualDesktop(pDesktopNew))
647647+ return 0 ;S_OK
648648+ }
649649+ _No_Op() {
650650+ }
651651+ RegisterDesktopNotifications_Win11() {
652652+ methods:=DllCall("GlobalAlloc", "Uint",0x00, "Uint",13*A_PtrSize) ;PLEASE DON'T GARBAGE COLLECT IT, this took me hours to debug, I was lucky ahkv2 garbage collected slowly
653653+ ; Thanks to mntone for IID and signatures https://mntone.hateblo.jp/entry/2021/05/23/121028#IVirtualDesktopNotification-3
654654+ ; Thanks to NyaMisty for explanation https://github.com/mntone/VirtualDesktop/pull/1#issuecomment-922269079
655655+ NumPut(RegisterCallback("VD._QueryInterface_Win11", "F"), methods+0, 0*A_PtrSize, "Ptr")
656656+ NumPut(RegisterCallback("VD._AddRef_Same", "F"), methods+0, 1*A_PtrSize, "Ptr")
657657+ NumPut(RegisterCallback("VD._Release_Same", "F"), methods+0, 2*A_PtrSize, "Ptr")
658658+ NumPut(RegisterCallback("VD._VirtualDesktopCreated_Win11", "F"), methods+0, 3*A_PtrSize, "Ptr")
659659+ NumPut(RegisterCallback("VD._VirtualDesktopDestroyBegin_Win11", "F"), methods+0, 4*A_PtrSize, "Ptr")
660660+ NumPut(RegisterCallback("VD._VirtualDesktopDestroyFailed_Win11", "F"), methods+0, 5*A_PtrSize, "Ptr")
661661+ NumPut(RegisterCallback("VD._VirtualDesktopDestroyed_Win11", "F"), methods+0, 6*A_PtrSize, "Ptr")
662662+ ; NumPut(RegisterCallback("VD._VirtualDesktopIsPerMonitorChanged_Win11", "F"), methods+0, 7*A_PtrSize, "Ptr")
663663+ NumPut(RegisterCallback("VD._No_Op", "F"), methods+0, 7*A_PtrSize, "Ptr")
664664+ ; NumPut(RegisterCallback("VD._VirtualDesktopMoved_Win11", "F"), methods+0, 8*A_PtrSize, "Ptr")
665665+ NumPut(RegisterCallback("VD._No_Op", "F"), methods+0, 8*A_PtrSize, "Ptr")
666666+ ; NumPut(RegisterCallback("VD._VirtualDesktopNameChanged_Win11", "F"), methods+0, 9*A_PtrSize, "Ptr")
667667+ NumPut(RegisterCallback("VD._No_Op", "F"), methods+0, 9*A_PtrSize, "Ptr")
668668+ NumPut(RegisterCallback("VD._ViewVirtualDesktopChanged_Win11", "F"), methods+0, 10*A_PtrSize, "Ptr")
669669+ NumPut(RegisterCallback("VD._CurrentVirtualDesktopChanged_Win11", "F"), methods+0, 11*A_PtrSize, "Ptr")
670670+ ; NumPut(RegisterCallback("VD._VirtualDesktopWallpaperChanged_Win11", "F"), methods+0, 12*A_PtrSize, "Ptr")
671671+ NumPut(RegisterCallback("VD._No_Op", "F"), methods+0, 12*A_PtrSize, "Ptr")
672672+673673+ this.RegisterDesktopNotifications_Same(methods)
674674+ }
675675+ RegisterDesktopNotifications_Same(methods) {
676676+ obj:=DllCall("GlobalAlloc", "Uint",0x00, "Uint",A_PtrSize + 4) ;PLEASE DON'T GARBAGE COLLECT IT, this took me hours to debug, I was lucky ahkv2 garbage collected slowly
677677+ NumPut(methods, obj+0, 0, "Ptr")
678678+ NumPut(0, obj+0, A_PtrSize, "UInt") ;refCount
679679+680680+ pDesktopNotificationService := ComObjQuery(this.IServiceProvider, "{A501FDEC-4A09-464C-AE4E-1B9C21B84918}", "{0CD45E71-D927-4F15-8B0A-8FEF525337BF}")
681681+ Register:=this._vtable(pDesktopNotificationService, 3)
682682+ HRESULT:=DllCall(Register,"UPtr",pDesktopNotificationService, "Ptr",obj, "Uint*",pdwCookie:=0)
683683+ ; ok1:=ErrorLevel
684684+ ; ok2:=A_LastError
685685+ ; ok:=0
686686+687687+ ; HRESULT hrNotificationService = pServiceProvider->QueryService(
688688+ ; CLSID_IVirtualNotificationService,
689689+ ; __uuidof(IVirtualDesktopNotificationService),
690690+ ; (PVOID*)&pDesktopNotificationService);
691691+ }
692692+693693+ VirtualDesktopCreated(desktopNum:=0) {
694694+ }
695695+ VirtualDesktopDestroyBegin(desktopNum_Destroyed:=0, desktopNum_Fallback:=0) {
696696+ }
697697+ VirtualDesktopDestroyFailed(desktopNum_Destroyed:=0, desktopNum_Fallback:=0) {
698698+ }
699699+ VirtualDesktopDestroyed(desktopNum_Destroyed:=0, desktopNum_Fallback:=0) {
700700+ }
701701+ ViewVirtualDesktopChanged(pView:=0) {
702702+ }
703703+ CurrentVirtualDesktopChanged(desktopNum_Old:=0, desktopNum_New:=0) {
704704+ }
705705+706706+ ; <Run in VD
707707+ startShellMessage() {
708708+ ; https://www.autohotkey.com/boards/viewtopic.php?t=63424#p271528
709709+ DllCall("RegisterShellHookWindow", "Ptr", A_ScriptHwnd)
710710+ MsgNum := DllCall("RegisterWindowMessage", "Str", "SHELLHOOK")
711711+ OnMessage(MsgNum, func("VD.ShellMessage").bind(this))
712712+713713+ ; this.map_title_class:={"":{"":{"Hourglass.exe":func("VD.callback").bind(this, 2)}}}
714714+ this.map_title_class:={}
715715+ }
716716+717717+ Run(Target, WorkingDir, this_titleName, this_class, this_processName, desktopNum) {
718718+ this.addToWaitNewWindow(this_titleName, this_class, this_processName, func("VD.callback_MoveWindow").bind(this, desktopNum))
719719+720720+ Run % Target, % WorkingDir
721721+ }
722722+723723+ Run_lock_VD(Target, WorkingDir, this_titleName, this_class, this_processName, window_desktopNum, your_desktopNum) {
724724+ this.addToWaitNewWindow(this_titleName, this_class, this_processName, func("VD.callback_MoveWindow_lockVD").bind(this, [window_desktopNum, your_desktopNum]))
725725+726726+ Run % Target, % WorkingDir
727727+ }
728728+729729+ addToWaitNewWindow(this_titleName, this_class, this_processName, callback) {
730730+ map_class_processName:=this.map_title_class.HasKey(this_titleName) ? this.map_title_class[this_titleName] : this.map_title_class[this_titleName]:={}
731731+ map_processName_data:=map_class_processName.HasKey(this_class) ? map_class_processName[this_class] : map_class_processName[this_class]:={}
732732+ arrOfCallback:=map_processName_data.HasKey(this_processName) ? map_processName_data[this_processName] : map_processName_data[this_processName]:=[]
733733+ arrOfCallback.Push(callback)
734734+ }
735735+736736+ callback_MoveWindow(desktopNum, hwnd) {
737737+ WinActivate % "ahk_id " hwnd
738738+ this.MoveWindowToDesktopNum("ahk_id " hwnd,desktopNum)
739739+ }
740740+741741+ callback_MoveWindow_lockVD(tuple, hwnd) {
742742+ window_desktopNum:=tuple[1]
743743+ your_desktopNum:=tuple[2]
744744+ WinActivate % "ahk_id " hwnd
745745+ this.goToDesktopNum(your_desktopNum)
746746+ WinActivate % "ahk_id " hwnd
747747+ this.MoveWindowToDesktopNum("ahk_id " hwnd,window_desktopNum)
748748+ WinActivate % "ahk_id " hwnd
749749+ }
750750+751751+ ShellMessage(wParam, lParam, msg, hwnd) {
752752+ Critical ;this is what makes many callbacks AT THE SAME TIME possible
753753+ Sleep 100 ;necessary
754754+755755+ if (wParam == 1) { ; HSHELL_WINDOWCREATED := 1, HSHELL_MONITORCHANGED := 16
756756+ theHwnd:=lParam
757757+758758+ bak_DetectHiddenWindows := A_DetectHiddenWindows
759759+ DetectHiddenWindows, ON ;very important
760760+761761+ arrOfCallback:=false
762762+ outside_map_processName_data:=false
763763+ outside_map_class_processName:=false
764764+ outside_subString_title:=false
765765+766766+ WinGetTitle, this_title, % "ahk_id " theHwnd
767767+ for subString_title, map_class_processName in this.map_title_class {
768768+ if (InStr(this_title, subString_title, true)) {
769769+ WinGetClass, this_class, % "ahk_id " theHwnd
770770+ for subString_class, map_processName_data in map_class_processName {
771771+ if (InStr(this_class, subString_class, true)) {
772772+ WinGet, this_processName, ProcessName, % "ahk_id " theHwnd
773773+ for subString_processName, possibly_arrOfCallback in map_processName_data {
774774+ if (InStr(this_processName, subString_processName, true)) {
775775+ arrOfCallback:=possibly_arrOfCallback
776776+ outside_map_processName_data:=map_processName_data
777777+ outside_map_class_processName:=map_class_processName
778778+ outside_subString_title:=subString_title
779779+ break
780780+ }
781781+ }
782782+ break
783783+ }
784784+ }
785785+ break
786786+ }
787787+ }
788788+789789+ DetectHiddenWindows % bak_DetectHiddenWindows
790790+791791+ if (arrOfCallback) {
792792+ callback:=arrOfCallback[1]
793793+ callback.Call(theHwnd)
794794+795795+ if (arrOfCallback.Length() > 1) {
796796+ arrOfCallback.RemoveAt(1)
797797+ } else if (outside_map_processName_data.Count() > 1) {
798798+ outside_map_processName_data.Delete(subString_processName)
799799+ } else if (outside_map_class_processName.Count() > 1) {
800800+ outside_map_class_processName.Delete(subString_class)
801801+ } else {
802802+ this.map_title_class.Delete(outside_subString_title)
803803+ }
804804+805805+ }
806806+ }
807807+ }
808808+ ; Run in VD>
809809+810810+ ;actual methods end
811811+812812+ ;internal methods start
813813+814814+ _WinActivate_NewProcess(hWnd) {
815815+ ; WinActivate of AHK will first try SetForegroundWindow(), it will work if the keyboard hook is not used
816816+ ; so it will work for
817817+ ; Numpad2::
818818+ ; it will not work for
819819+ ; ^#Right::
820820+ ; Right always uses the keyboard hook
821821+822822+ ; AHK will then try AttachThreadInput(), it works reliably, but fails for Teams.exe for reasons I have yet to uncover
823823+ ; let's just say that either Teams.exe is resistant to AttachThreadInput, or the code inside Teams.exe has a weird defined behavior once AttachThreadInput is called
824824+825825+ ; this ? there's only one way to find out how well it works, by testing in production
826826+ ; attempt Number 2
827827+ ; new Thread doesn't work, somehow new Process works
828828+829829+ foregroundWindow:=DllCall("GetForegroundWindow","Ptr")
830830+ threadID:=DllCall("GetWindowThreadProcessId","Ptr",foregroundWindow,"Uint*",PID)
831831+ currentThreadID:=DllCall("GetCurrentThreadId")
832832+ if (threadID==currentThreadID) {
833833+ DllCall("SetForegroundWindow","Ptr",hWnd)
834834+ } else {
835835+ loop 10 {
836836+ Run % """" A_LineFile "\..\SetForeGroundWindow.exe"" " hWnd
837837+ if (DllCall("GetForegroundWindow","Ptr")==hWnd) {
838838+ break
839839+ }
840840+ Sleep 10
841841+ if (DllCall("GetForegroundWindow","Ptr")==hWnd) {
842842+ break
843843+ }
844844+ }
845845+ }
846846+ }
847847+848848+ _activateDesktopBackground() { ;this is really copying extremely long comments for short code like in AHK source code
849849+ ; Win10:
850850+ ; "FolderView ahk_class SysListView32 ahk_exe explorer.exe"
851851+ ; "ahk_class SHELLDLL_DefView ahk_exe explorer.exe"
852852+ ; "Program Manager ahk_class Progman ahk_exe explorer.exe" is the top level parent
853853+854854+ ; the parent parent of FolderView BECOMES "ahk_class WorkerW ahk_exe explorer.exe" after you press Win+Tab
855855+ ; WorkerW doesn't exist before you press Win+Tab
856856+ ; it's the same for Win11, Progman gets replaced by WorkerW, Progman still exists but isn't the parent of FolderView or top-level window that gets activated
857857+858858+ ; Q: if WinActivate Progman activates WorkerW(we want that) then what's the problem ?
859859+ ; A: WinActivate will send {Alt down}{Alt up}{Alt down}{Alt up} if Progman is not activated : AHK source code: ((VK_MENU | 0x12 | ALT key)) https://github.com/AutoHotkey/AutoHotkey/blob/df84a3e902b522db0756a7366bd9884c80fa17b6/source/window.cpp#L260-L261
860860+ ; the desktop background is correctly activated, we just don't want the extra Alt keys:
861861+ ; if the hotkey is Ctrl+Shift+Win, and you add an Alt in there, Office 365 hotkey is triggered:
862862+ ; https://github.com/FuPeiJiang/VD.ahk/issues/40#issuecomment-1548252485
863863+ ; https://answers.microsoft.com/en-us/msoffice/forum/all/help-disabling-office-hotkey-of-ctrl-win-alt-shift/040ef6e5-8152-449b-849a-7494323101bb
864864+ ; https://superuser.com/questions/1457073/how-do-i-disable-specific-windows-10-office-keyboard-shortcut-ctrlshiftwinal
865865+ ; this is also bad because it prevents subsequent uses of the hotkey #!Right:: because {Alt up} releases Alt
866866+ ; if (WinExist("ahk_class WorkerW ahk_exe explorer.exe")) {
867867+ ; WinActivate % "ahk_class WorkerW ahk_exe explorer.exe"
868868+ ; } else {
869869+ ; WinActivate % "ahk_class Progman ahk_exe explorer.exe"
870870+ ; }
871871+ DllCall("SetForegroundWindow","Ptr",WinExist("ahk_class Progman ahk_exe explorer.exe"))
872872+ }
873873+874874+ _getFirstWindowInVD(desktopNum, excludeHwnd:=0) {
875875+ bak_DetectHiddenWindows:=A_DetectHiddenWindows
876876+ DetectHiddenWindows, on
877877+ returnValue:=0
878878+ WinGet, outHwndList, List
879879+ VarSetCapacity(GUID_Desktop, 16)
880880+ Desktops_Obj:=this._GetDesktops_Obj()
881881+ IVirtualDesktop:=Desktops_Obj.GetAt(desktopNum)
882882+ loop % outHwndList {
883883+ theHwnd:=outHwndList%A_Index%+0
884884+ if (theHwnd==excludeHwnd) {
885885+ continue
886886+ }
887887+ arr_success_pView_hWnd:=this._isValidWindow(theHwnd)
888888+ if (arr_success_pView_hWnd[1]==0) {
889889+ pView:=arr_success_pView_hWnd[2]
890890+ WinGet, OutputVar_MinMax, MinMax, % "ahk_id " theHwnd
891891+ if (!(OutputVar_MinMax==-1)) { ;not Minimized
892892+893893+ HRESULT := DllCall(this.GetWindowDesktopId, "UPtr", this.IVirtualDesktopManager, "Ptr", theHwnd, "Ptr", &GUID_Desktop)
894894+ if (!(HRESULT==0)) {
895895+ continue
896896+ }
897897+ DllCall(this.FindDesktop, "UPtr", this.IVirtualDesktopManagerInternal, "Ptr", &GUID_Desktop, "Ptr*", IVirtualDesktop_ofWindow)
898898+ if (IVirtualDesktop_ofWindow == IVirtualDesktop) {
899899+ ; WinActivate % "ahk_id " theHwnd
900900+ returnValue:=theHwnd
901901+ break
902902+ }
903903+ }
904904+ }
905905+ }
906906+ DetectHiddenWindows % bak_DetectHiddenWindows
907907+ return returnValue
908908+ }
909909+910910+ _tryGetValidWindow(wintitle) {
911911+ bak_DetectHiddenWindows:=A_DetectHiddenWindows
912912+ bak_TitleMatchMode:=A_TitleMatchMode
913913+ DetectHiddenWindows, on
914914+ SetTitleMatchMode, 2
915915+ WinGet, outHwndList, List, % wintitle
916916+ returnValue:=false
917917+ loop % outHwndList {
918918+ theHwnd:=outHwndList%A_Index%+0
919919+ arr_success_pView_hWnd:=this._isValidWindow(theHwnd)
920920+ pView:=arr_success_pView_hWnd[2]
921921+ if (pView) {
922922+ returnValue:=[arr_success_pView_hWnd[3], pView]
923923+ break
924924+ }
925925+ }
926926+927927+ SetTitleMatchMode % bak_TitleMatchMode
928928+ DetectHiddenWindows % bak_DetectHiddenWindows
929929+ return returnValue
930930+ }
931931+932932+ _view_from_Hwnd(theHwnd) {
933933+ pView := 0
934934+ DllCall(this.GetViewForHwnd, "UPtr", this.IApplicationViewCollection, "Ptr", theHwnd, "Ptr*", pView)
935935+ return pView
936936+ }
937937+938938+ _IVirtualDesktop_from_Hwnd(theHwnd) {
939939+ VarSetCapacity(GUID_Desktop, 16)
940940+ HRESULT := DllCall(this.GetWindowDesktopId, "UPtr", this.IVirtualDesktopManager, "Ptr", theHwnd, "Ptr", &GUID_Desktop)
941941+ if (!(HRESULT==0)) {
942942+ return false
943943+ }
944944+945945+ IVirtualDesktop_ofWindow:=0
946946+ DllCall(this.FindDesktop, "UPtr", this.IVirtualDesktopManagerInternal, "Ptr", &GUID_Desktop, "Ptr*", IVirtualDesktop_ofWindow)
947947+948948+ return IVirtualDesktop_ofWindow
949949+ }
950950+951951+ _desktopNum_from_IVirtualDesktop(IVirtualDesktop) {
952952+ Desktops_Obj:=this._GetDesktops_Obj()
953953+ Loop % Desktops_Obj.GetCount()
954954+ {
955955+ IVirtualDesktop_ofDesktop:=Desktops_Obj.GetAt(A_Index)
956956+957957+ if (IVirtualDesktop_ofDesktop == IVirtualDesktop) {
958958+ return A_Index
959959+ }
960960+ }
961961+ return 0 ;for "Show on all desktops"
962962+ }
963963+964964+ _desktopNum_from_Hwnd(theHwnd) {
965965+ IVirtualDesktop:=this._IVirtualDesktop_from_Hwnd(theHwnd)
966966+ desktopNum:=this._desktopNum_from_IVirtualDesktop(IVirtualDesktop)
967967+ return desktopNum
968968+ }
969969+970970+ _GetDesktops_Obj() {
971971+ IObjectArray:=this._dll_GetDesktops()
972972+ return new this.IObjectArray_Wrapper(IObjectArray, this.Ptr_IID_IVirtualDesktop)
973973+ }
974974+975975+ _IsViewPinned(thePView) {
976976+ viewIsPinned:=0
977977+ DllCall(this.IsViewPinned, "UPtr", this.IVirtualDesktopPinnedApps, "Ptr", thePView, "Int*",viewIsPinned)
978978+ return viewIsPinned
979979+ }
980980+981981+ ;internal methods end
982982+983983+ ;utility methods start
984984+ _isWindowFullScreen( winTitle ) {
985985+ ;checks if the specified window is full screen
986986+987987+ winID := WinExist( winTitle )
988988+989989+ If ( !winID )
990990+ Return false
991991+992992+ WinGet style, Style, ahk_id %WinID%
993993+ WinGetPos ,,,winW,winH, %winTitle%
994994+ ; 0x800000 is WS_BORDER.
995995+ ; 0x20000000 is WS_MINIMIZE.
996996+ ; no border and not minimized
997997+ Return ((style & 0x20800000) or winH < A_ScreenHeight or winW < A_ScreenWidth) ? false : true
998998+ }
999999+10001000+ _isValidWindow(hWnd,checkUpper:=true) ;returns [0,pView,hWnd] if succeeded
10011001+ {
10021002+ returnValue:=[1,0,0]
10031003+ breakToReturnFalse:
10041004+ loop 1 {
10051005+ dwStyle:=DllCall("GetWindowLongPtrW","Ptr",hWnd,"Int",-16,"Ptr")
10061006+ if (!(dwStyle & 0x10000000)) { ;0x10000000=WS_VISIBLE
10071007+ break breakToReturnFalse
10081008+ }
10091009+ dwExStyle:=DllCall("GetWindowLongPtrW","Ptr",hWnd,"Int",-20,"Ptr")
10101010+ if (!(dwExStyle&0x00040000)) { ;0x00040000=WS_EX_APPWINDOW
10111011+ if (dwExStyle&0x00000080 || dwExStyle&0x08000000) { ;0x00000080=WS_EX_TOOLWINDOW, 0x08000000=WS_EX_NOACTIVATE
10121012+ break breakToReturnFalse
10131013+ }
10141014+ ; if any of ancestor is valid window, can't be valid window
10151015+ if (checkUpper) {
10161016+ toCheck:=[]
10171017+ upHwnd:=hWnd
10181018+ while (upHwnd := DllCall("GetWindow","Ptr",upHwnd,"Uint",4)) { ;4=GW_OWNER
10191019+ if (upHwnd==65552) {
10201020+ break breakToReturnFalse
10211021+ }
10221022+ toCheck.Push(upHwnd)
10231023+ }
10241024+ i:=toCheck.Length() + 1
10251025+ while (i-->1) { ;i goes to 1 (lmao)
10261026+ arr_success_pView_hWnd:=this._isValidWindow(toCheck[i],false)
10271027+ if (arr_success_pView_hWnd[1]==0) {
10281028+ arr_success_pView_hWnd[1]:=2
10291029+ returnValue:=arr_success_pView_hWnd
10301030+ break breakToReturnFalse
10311031+ }
10321032+ }
10331033+ }
10341034+ }
10351035+10361036+ pView:=this._view_from_Hwnd(hWnd)
10371037+ if (!pView) {
10381038+ break breakToReturnFalse
10391039+ }
10401040+ pfCanViewMoveDesktops := 0
10411041+ DllCall(this.CanViewMoveDesktops, "UPtr", this.IVirtualDesktopManagerInternal, "Ptr", pView, "int*", pfCanViewMoveDesktops) ; return value BOOL
10421042+ if (!pfCanViewMoveDesktops) {
10431043+ break breakToReturnFalse
10441044+ }
10451045+10461046+ returnValue:=[0,pView,hWnd]
10471047+ }
10481048+ return returnValue
10491049+ }
10501050+ ;-------------------
10511051+ _vtable(ppv, index) {
10521052+ Return NumGet(NumGet(0+ppv)+A_PtrSize*index)
10531053+ }
10541054+ ; _string_from_GUID(Byref byref_GUID) {
10551055+ ; VarSetCapacity(strGUID, 38 * 2) ;38 is StrLen("{FF72FFDD-BE7E-43FC-9C03-AD81681E88E4}")
10561056+ ; DllCall("Ole32.dll\StringFromGUID2", "UPtr", &byref_GUID, "UPtr", &strGUID, "Int", 38 + 1)
10571057+ ; return StrGet(&strGUID, "UTF-16")
10581058+ ; }
10591059+10601060+ class IObjectArray_Wrapper {
10611061+ __New(IObjectArray, Ptr_IID_Interface) {
10621062+ this.IObjectArray:=IObjectArray
10631063+ this.Ptr_IID_Interface:=Ptr_IID_Interface
10641064+10651065+ this.Ptr_GetAt:=VD._vtable(IObjectArray,4)
10661066+ }
10671067+ __Delete() {
10681068+ ;IUnknown::Release
10691069+ Ptr_Release:=VD._vtable(this.IObjectArray,2)
10701070+ DllCall(Ptr_Release, "UPtr", this.IObjectArray)
10711071+ }
10721072+ GetAt(oneBasedIndex) {
10731073+ Ptr_Interface:=0
10741074+ DllCall(this.Ptr_GetAt, "UPtr", this.IObjectArray, "UInt", oneBasedIndex - 1, "Ptr", this.Ptr_IID_Interface, "Ptr*", Ptr_Interface)
10751075+ return Ptr_Interface
10761076+ }
10771077+ GetCount() {
10781078+ Ptr_GetCount:=VD._vtable(this.IObjectArray,3)
10791079+ Count := 0
10801080+ DllCall(Ptr_GetCount, "UPtr", this.IObjectArray, "UInt*", Count)
10811081+ return Count
10821082+ }
10831083+10841084+ }
10851085+ ;utility methods end
10861086+10871087+}
+758
Windows/AutoHotKey/capslock_sspaeti.ahk
···11+;=====================================================================o
22+; Feng Ruohang's AHK Script |
33+; CapsLock Enhancement |
44+; Updated Simon Späti |
55+;---------------------------------------------------------------------o
66+;Description: |
77+; This Script is wrote by Feng Ruohang via AutoHotKey Script. It |
88+; Provieds an enhancement towards the "Useless Key" CapsLock, and |
99+; turns CapsLock into an useful function Key just like Ctrl and Alt |
1010+; by combining CapsLock with almost all other keys in the keyboard. |
1111+; |
1212+;Summary: |
1313+;o----------------------o---------------------------------------------o
1414+;|CapsLock; | {ESC} Especially Convient for vim user |
1515+;|CaspLock + ` | {CapsLock}CapsLock Switcher as a Substituent|
1616+;|CapsLock + hjklwb | Vim-Style Cursor Mover |
1717+;|CaspLock + uiop | Convient Home/End PageUp/PageDn |
1818+;|CaspLock + nm,. | Convient Delete Controller |
1919+;|CapsLock + zxcvay | Windows-Style Editor |
2020+;|CapsLock + Direction | Mouse Move |
2121+;|CapsLock + Enter | Mouse Click |
2222+;|CaspLock + {F1}~{F6} | Media Volume Controller |
2323+;|CapsLock + qs | Windows & Tags Control |
2424+;|CapsLock + ;'[] | Convient Key Mapping |
2525+;|CaspLock + dfert | Frequently Used Programs (Self Defined) |
2626+;|CaspLock + 123456 | Dev-Hotkey for Visual Studio (Self Defined) |
2727+;|CapsLock + 67890-= | Shifter as Shift |
2828+;-----------------------o---------------------------------------------o
2929+;|Use it whatever and wherever you like. Hope it help |
3030+;=====================================================================o
3131+3232+3333+;=====================================================================o
3434+; CapsLock Initializer ;|
3535+;---------------------------------------------------------------------o
3636+SetCapsLockState, AlwaysOff ;|
3737+;---------------------------------------------------------------------o
3838+3939+4040+;=====================================================================o
4141+; CapsLock Switcher: ;|
4242+;---------------------------------o-----------------------------------o
4343+; CapsLock + ` | {CapsLock} ;|
4444+;---------------------------------o-----------------------------------o
4545+CapsLock & `:: ;|
4646+GetKeyState, CapsLockState, CapsLock, T ;|
4747+if CapsLockState = D ;|
4848+ SetCapsLockState, AlwaysOff ;|
4949+else ;|
5050+ SetCapsLockState, AlwaysOn ;|
5151+KeyWait, `` ;|
5252+return ;|
5353+;---------------------------------------------------------------------o
5454+5555+5656+;=====================================================================o
5757+; CapsLock Escaper: ;|
5858+;----------------------------------o----------------------------------o
5959+; CapsLock | {ESC} ;|
6060+;----------------------------------o----------------------------------o
6161+CapsLock::Send, {ESC} ;|
6262+;---------------------------------------------------------------------o
6363+6464+6565+;=====================================================================o
6666+; CapsLock Direction Navigator ;|
6767+;-----------------------------------o---------------------------------o
6868+; CapsLock + h | Left ;|
6969+; CapsLock + j | Down ;|
7070+; CapsLock + k | Up ;|
7171+; CapsLock + l | Right ;|
7272+; Ctrl, Alt Compatible ;|
7373+;-----------------------------------o---------------------------------o
7474+CapsLock & h:: ;|
7575+if GetKeyState("control") = 0 ;|
7676+{ ;|
7777+ if GetKeyState("alt") = 0 ;|
7878+ Send, {Left} ;|
7979+ else ;|
8080+ Send, +{Left} ;|
8181+ return ;|
8282+} ;|
8383+else { ;|
8484+ if GetKeyState("alt") = 0 ;|
8585+ Send, ^{Left} ;|
8686+ else ;|
8787+ Send, +^{Left} ;|
8888+ return ;|
8989+} ;|
9090+return ;|
9191+;-----------------------------------o ;|
9292+CapsLock & j:: ;|
9393+if GetKeyState("control") = 0 ;|
9494+{ ;|
9595+ if GetKeyState("alt") = 0 ;|
9696+ Send, {Down} ;|
9797+ else ;|
9898+ Send, +{Down} ;|
9999+ return ;|
100100+} ;|
101101+else { ;|
102102+ if GetKeyState("alt") = 0 ;|
103103+ Send, ^{Down} ;|
104104+ else ;|
105105+ Send, +^{Down} ;|
106106+ return ;|
107107+} ;|
108108+return ;|
109109+;-----------------------------------o ;|
110110+CapsLock & k:: ;|
111111+if GetKeyState("control") = 0 ;|
112112+{ ;|
113113+ if GetKeyState("alt") = 0 ;|
114114+ Send, {Up} ;|
115115+ else ;|
116116+ Send, +{Up} ;|
117117+ return ;|
118118+} ;|
119119+else { ;|
120120+ if GetKeyState("alt") = 0 ;|
121121+ Send, ^{Up} ;|
122122+ else ;|
123123+ Send, +^{Up} ;|
124124+ return ;|
125125+} ;|
126126+return ;|
127127+;-----------------------------------o ;|
128128+CapsLock & l:: ;|
129129+if GetKeyState("control") = 0 ;|
130130+{ ;|
131131+ if GetKeyState("alt") = 0 ;|
132132+ Send, {Right} ;|
133133+ else ;|
134134+ Send, +{Right} ;|
135135+ return ;|
136136+} ;|
137137+else { ;|
138138+ if GetKeyState("alt") = 0 ;|
139139+ Send, ^{Right} ;|
140140+ else ;|
141141+ Send, +^{Right} ;|
142142+ return ;|
143143+} ;|
144144+return ;|
145145+;---------------------------------------------------------------------o
146146+147147+148148+;=====================================================================o
149149+; CapsLock Home/End Navigator ;|
150150+;-----------------------------------o---------------------------------o
151151+; CapsLock + i | Home ;|
152152+; CapsLock + o | End ;|
153153+; Ctrl, Alt Compatible ;|
154154+;-----------------------------------o---------------------------------o
155155+CapsLock & i:: ;|
156156+if GetKeyState("control") = 0 ;|
157157+{ ;|
158158+ if GetKeyState("alt") = 0 ;|
159159+ Send, {Home} ;|
160160+ else ;|
161161+ Send, +{Home} ;|
162162+ return ;|
163163+} ;|
164164+else { ;|
165165+ if GetKeyState("alt") = 0 ;|
166166+ Send, ^{Home} ;|
167167+ else ;|
168168+ Send, +^{Home} ;|
169169+ return ;|
170170+} ;|
171171+return ;|
172172+;-----------------------------------o ;|
173173+;CapsLock & o:: ;|
174174+;if GetKeyState("control") = 0 ;|
175175+;{ ;|
176176+; if GetKeyState("alt") = 0 ;|
177177+; Send, {End} ;|
178178+; else ;|
179179+; Send, +{End} ;|
180180+; return ;|
181181+;} ;|
182182+;else { ;|
183183+; if GetKeyState("alt") = 0 ;|
184184+; Send, ^{End} ;|
185185+; else ;|
186186+; Send, +^{End} ;|
187187+; return ;|
188188+;} ;|
189189+;return ;|
190190+;---------------------------------------------------------------------o
191191+192192+193193+;=====================================================================o
194194+; CapsLock Page Navigator ;|
195195+;-----------------------------------o---------------------------------o
196196+; CapsLock + u | PageUp ;|
197197+; CapsLock + p | PageDown ;|
198198+; Ctrl, Alt Compatible ;|
199199+;-----------------------------------o---------------------------------o
200200+;CapsLock & u:: ;|
201201+;if GetKeyState("control") = 0 ;|
202202+;{ ;|
203203+; if GetKeyState("alt") = 0 ;|
204204+; Send, {PgUp} ;|
205205+; else ;|
206206+; Send, +{PgUp} ;|
207207+; return ;|
208208+;} ;|
209209+;else { ;|
210210+; if GetKeyState("alt") = 0 ;|
211211+; Send, ^{PgUp} ;|
212212+; else ;|
213213+; Send, +^{PgUp} ;|
214214+; return ;|
215215+;} ;|
216216+;return ;|
217217+;-----------------------------------o ;|
218218+CapsLock & p:: ;|
219219+if GetKeyState("control") = 0 ;|
220220+{ ;|
221221+ if GetKeyState("alt") = 0 ;|
222222+ Send, {PgDn} ;|
223223+ else ;|
224224+ Send, +{PgDn} ;|
225225+ return ;|
226226+} ;|
227227+else { ;|
228228+ if GetKeyState("alt") = 0 ;|
229229+ Send, ^{PgDn} ;|
230230+ else ;|
231231+ Send, +^{PgDn} ;|
232232+ return ;|
233233+} ;|
234234+return ;|
235235+;---------------------------------------------------------------------o
236236+237237+238238+;=====================================================================o
239239+; CapsLock Mouse Controller ;|
240240+;-----------------------------------o---------------------------------o
241241+; CapsLock + Up | Mouse Up ;|
242242+; CapsLock + Down | Mouse Down ;|
243243+; CapsLock + Left | Mouse Left ;|
244244+; CapsLock + Right | Mouse Right ;|
245245+; CapsLock + Enter(Push Release) | Mouse Left Push(Release) ;|
246246+;-----------------------------------o---------------------------------o
247247+CapsLock & Up:: MouseMove, 0, -10, 0, R ;|
248248+CapsLock & Down:: MouseMove, 0, 10, 0, R ;|
249249+CapsLock & Left:: MouseMove, -10, 0, 0, R ;|
250250+CapsLock & Right:: MouseMove, 10, 0, 0, R ;|
251251+;-----------------------------------o ;|
252252+CapsLock & Enter:: ;|
253253+SendEvent {Blind}{LButton down} ;|
254254+KeyWait Enter ;|
255255+SendEvent {Blind}{LButton up} ;|
256256+return ;|
257257+;---------------------------------------------------------------------o
258258+259259+260260+;=====================================================================o
261261+; CapsLock Deletor ;|
262262+;-----------------------------------o---------------------------------o
263263+; CapsLock + n | Ctrl + Delete (Delete a Word) ;|
264264+; CapsLock + m | Delete ;|
265265+; CapsLock + , | BackSpace ;|
266266+; CapsLock + . | Ctrl + BackSpace ;|
267267+;-----------------------------------o---------------------------------o
268268+CapsLock & ,:: Send, {Del} ;|
269269+CapsLock & .:: Send, ^{Del} ;|
270270+CapsLock & m:: Send, {BS} ;|
271271+CapsLock & n:: Send, ^{BS} ;|
272272+;---------------------------------------------------------------------o
273273+274274+275275+;=====================================================================o
276276+; CapsLock Editor ;|
277277+;-----------------------------------o---------------------------------o
278278+; CapsLock + z | Ctrl + z (Cancel) ;|
279279+; CapsLock + x | Ctrl + x (Cut) ;|
280280+; CapsLock + c | Ctrl + c (Copy) ;|
281281+; CapsLock + v | Ctrl + z (Paste) ;|
282282+; CapsLock + a | Ctrl + a (Select All) ;|
283283+; CapsLock + y | Ctrl + z (Yeild) ;|
284284+; CapsLock + w | Ctrl + Right(Move as [vim: w]);|
285285+; CapsLock + b | Ctrl + Left (Move as [vim: b]);|
286286+;-----------------------------------o---------------------------------o
287287+CapsLock & z:: Send, ^z ;|
288288+CapsLock & x:: Send, ^x ;|
289289+CapsLock & c:: Send, ^c ;|
290290+CapsLock & v:: Send, ^v ;|
291291+;CapsLock & a:: Send, ^a ;|
292292+CapsLock & y:: Send, ^y ;|
293293+CapsLock & w:: Send, ^{Right} ;|
294294+CapsLock & b:: Send, ^{Left} ;|
295295+;---------------------------------------------------------------------o
296296+297297+298298+;=====================================================================o
299299+; CapsLock Media Controller ;|
300300+;-----------------------------------o---------------------------------o
301301+; CapsLock + F1 | Volume_Mute ;|
302302+; CapsLock + F2 | Volume_Down ;|
303303+; CapsLock + F3 | Volume_Up ;|
304304+; CapsLock + F3 | Media_Play_Pause ;|
305305+; CapsLock + F5 | Media_Next ;|
306306+; CapsLock + F6 | Media_Stop ;|
307307+;-----------------------------------o---------------------------------o
308308+CapsLock & F1:: Send, {Volume_Mute} ;|
309309+CapsLock & F2:: Send, {Volume_Down} ;|
310310+CapsLock & F3:: Send, {Volume_Up} ;|
311311+CapsLock & F4:: Send, {Media_Play_Pause} ;|
312312+CapsLock & F5:: Send, {Media_Next} ;|
313313+CapsLock & F6:: Send, {Media_Stop} ;|
314314+;---------------------------------------------------------------------o
315315+316316+317317+;=====================================================================o
318318+; CapsLock Window Controller ;|
319319+;-----------------------------------o---------------------------------o
320320+; CapsLock + s | Ctrl + Tab (Swith Tag) ;|
321321+; Alt + CapsLock + q | Ctrl + Tab (Close Windows) ;|
322322+; CapsLock + g | AppsKey (Menu Key) ;|
323323+;-----------------------------------o---------------------------------o
324324+CapsLock & s::Send, ^{Tab} ;|
325325+;-----------------------------------o ;|
326326+CapsLock & q:: ;|
327327+if GetKeyState("alt") = 0 ;|
328328+{ ;|
329329+ Send, ^w ;|
330330+} ;|
331331+else { ;|
332332+ Send, !{F4} ;|
333333+ return ;|
334334+} ;|
335335+return ;|
336336+;-----------------------------------o ;|
337337+CapsLock & g:: Send, {AppsKey} ;|
338338+;---------------------------------------------------------------------o
339339+340340+341341+;=====================================================================o
342342+; CapsLock Self Defined Area ;|
343343+;-----------------------------------o---------------------------------o
344344+; CapsLock + d | Alt + d(Dictionary) ;|
345345+; CapsLock + f | Alt + f(Search via Everything);|
346346+; CapsLock + e | Open Search Engine ;|
347347+; CapsLock + r | Open Shell ;|
348348+; CapsLock + t | Open Text Editor ;|
349349+;-----------------------------------o---------------------------------o
350350+CapsLock & d:: Send, !d ;|
351351+CapsLock & f:: Send, !f ;|
352352+CapsLock & e:: Run http://cn.bing.com/ ;|
353353+CapsLock & r:: Run Powershell ;|
354354+CapsLock & t:: Run C:\Program Files (x86)\Notepad++\notepad++.exe ;|
355355+;---------------------------------------------------------------------o
356356+357357+358358+;=====================================================================o
359359+; CapsLock Char Mapping ;|
360360+;-----------------------------------o---------------------------------o
361361+; CapsLock + ; | Enter (Cancel) ;|
362362+; CapsLock + ' | = ;|
363363+; CapsLock + [ | Back (Visual Studio) ;|
364364+; CapsLock + ] | Goto Define (Visual Studio) ;|
365365+; CapsLock + / | Comment (Visual Studio) ;|
366366+; CapsLock + \ | Uncomment (Visual Studio) ;|
367367+; CapsLock + 1 | Build and Run(Visual Studio) ;|
368368+; CapsLock + 2 | Debuging (Visual Studio) ;|
369369+; CapsLock + 3 | Step Over (Visual Studio) ;|
370370+; CapsLock + 4 | Step In (Visual Studio) ;|
371371+; CapsLock + 5 | Stop Debuging(Visual Studio) ;|
372372+; CapsLock + 6 | Shift + 6 ^ ;|
373373+; CapsLock + 7 | Shift + 7 & ;|
374374+; CapsLock + 8 | Shift + 8 * ;|
375375+; CapsLock + 9 | Shift + 9 ( ;|
376376+; CapsLock + 0 | Shift + 0 ) ;|
377377+;-----------------------------------o---------------------------------o
378378+CapsLock & `;:: Send, {Enter} ;|
379379+CapsLock & ':: Send, = ;|
380380+CapsLock & [:: Send, ^- ;|
381381+CapsLock & ]:: Send, {F12} ;|
382382+;-----------------------------------o ;|
383383+CapsLock & /:: ;|
384384+Send, ^e ;|
385385+Send, c ;|
386386+return ;|
387387+;-----------------------------------o ;|
388388+CapsLock & \:: ;|
389389+Send, ^e ;|
390390+Send, u ;|
391391+return ;|
392392+;-----------------------------------o ;|
393393+CapsLock & 1:: Send,^{F5} ;|
394394+CapsLock & 2:: Send,{F5} ;|
395395+CapsLock & 3:: Send,{F10} ;|
396396+CapsLock & 4:: Send,{F11} ;|
397397+CapsLock & 5:: Send,+{F5} ;|
398398+;-----------------------------------o ;|
399399+CapsLock & 6:: Send,+6 ;|
400400+CapsLock & 7:: Send,+7 ;|
401401+CapsLock & 8:: Send,+8 ;|
402402+CapsLock & 9:: Send,+9 ;|
403403+CapsLock & 0:: Send,+0 ;|
404404+;---------------------------------------------------------------------o
405405+;=====================================================================o
406406+; Umlaut Char Mapping ;|
407407+;-----------------------------------o---------------------------------o
408408+; CapsLock + a | ä ;|
409409+; CapsLock + a | ä ;|
410410+; CapsLock + u | ü ;|
411411+; LAlt + o | ö ;|
412412+; LAlt + u | ü ;|
413413+; LAlt + o | ö ;|
414414+; z | y ;|
415415+; y | z ;|
416416+;-----------------------------------o---------------------------------o
417417+CapsLock & a::
418418+{
419419+ GetKeyState, state, Lshift
420420+ if state = D
421421+ SendInput, {U+00C4}
422422+ else
423423+ SendInput, {U+00E4}
424424+ return
425425+}
426426+CapsLock & u::
427427+{
428428+ GetKeyState, state, Lshift
429429+ if state = D
430430+ SendInput, {U+00DC}
431431+ else
432432+ SendInput, {U+00FC}
433433+ return
434434+}
435435+CapsLock & o::
436436+{
437437+ GetKeyState, state, Lshift
438438+ if state = D
439439+ SendInput, {U+00D6}
440440+ else
441441+ SendInput, {U+00F6}
442442+ return
443443+}
444444+;---------------------------------------------------------------------o
445445+<!a::
446446+{
447447+ GetKeyState, state, Lshift
448448+ if state = D
449449+ SendInput, {U+00C4}
450450+ else
451451+ SendInput, {U+00E4}
452452+ return
453453+}
454454+<!u::
455455+{
456456+ GetKeyState, state, Lshift
457457+ if state = D
458458+ SendInput, {U+00DC}
459459+ else
460460+ SendInput, {U+00FC}
461461+ return
462462+}
463463+<!o::
464464+{
465465+ GetKeyState, state, Lshift
466466+ if state = D
467467+ SendInput, {U+00D6}
468468+ else
469469+ SendInput, {U+00F6}
470470+ return
471471+}
472472+;---------------------------------------------------------------------o
473473+; this is only used if keyboard has not switched it automatically o
474474+; default is switching it, as US layout has z and y not like QWERY as o
475475+; I want o
476476+;---------------------------------------------------------------------o
477477+SC015::z ;|
478478+SC02C::y ;|
479479+;---------------------------------------------------------------------o
480480+481481+482482+;=====================================================================o
483483+; Delta Phoenix's AHK Script |
484484+; Virtual Desktop Enhancement |
485485+;---------------------------------------------------------------------o
486486+;from: https://superuser.com/a/1050690
487487+;IMPORTANT:
488488+;
489489+;In order for it to work you must ONLY use hotkeys for opening, closing, and changing desktops because the script listens for these hotkeys to know the current and total number of desktops.
490490+;
491491+;If you do create, close, or change desktops via the WIN+TAB menu with the mouse the script will stop working. In order to get it working again you will need to edit the first two lines to reflect the current state of your desktops. (desktopcount/currentdesktop)
492492+;
493493+;This doesn't mean you can't use the WIN+TAB screen as an overview of your current desktops. You can actually use it in combination of the hotkeys to organize your desktops. Yes, the hotkeys still work when the windows task viewer is open! (WIN+TAB) Just DO NOT use the mouse!!!
494494+;
495495+;Also, wait for the script to load after Windows startup before creating new desktops or it will not work. This could take a moment depending on how many startup programs you have.
496496+;
497497+;Ok, I added one more thing to make it easier to re-sync the script with your desktop state. There is now a hotkey that will display the state the script believes the desktops to be in so all you have to do is adjust your desktops with the mouse to fit the script and it will be all synced up again! For me with a Swiss keyboard it worked out nicely having the '? key next to 0 and it makes sense with a ? on it, but on other keyboards you may wish to change this which can be done easily by changing the line right after the hotkey for 0/10 (starting with #') to whatever you like.
498498+;
499499+;Actually, I just realized.... as long as the Desktop Count is correct than creating a new desktop will automatically re-sync the Current Desktop value.
500500+;
501501+#NoTrayIcon
502502+;If the script stops working:
503503+;Change the following values to reflect your current desktop state and reload the script.
504504+;Remember to change them back to 1 after reloading the script if you have it set to start with Windows
505505+506506+desktopcount := 1
507507+currentdesktop := 1
508508+509509+;You can change the hotkeys for creating, closing, and switching desktops bellow.
510510+;The current hotkeys are CTRL+WIN+D for new desktop, CTRL+WIN+F4 to close desktop
511511+;and ALT+NUMBER for switching desktops.
512512+;For example, to change the hotkey for new desktop replace !^#D bellow with the desired hotkey.
513513+;Refer to the autohotkey documentation for a full list of symbols refering to modifier keys,
514514+;as you can see ! is ALT (^ would be CTRL) and # is WIN key.
515515+;If you wanted to change the switch desktop from WIN key to CTRL for example you would have
516516+517517+!^D::NewDesktop()
518518+!^w::CloseDesktop()
519519+!1::SwitchDesktop(1)
520520+!2::SwitchDesktop(2)
521521+!3::SwitchDesktop(3)
522522+!4::SwitchDesktop(4)
523523+!5::SwitchDesktop(5)
524524+!6::SwitchDesktop(6)
525525+!7::SwitchDesktop(7)
526526+!8::SwitchDesktop(8)
527527+!9::SwitchDesktop(9)
528528+!0::SwitchDesktop(10)
529529+!'::MsgBox Desktop Count = %desktopcount%`nCurrent Desktop = %currentdesktop%
530530+531531+;Do not change anything after this line, unless you know what you are doing ;)
532532+;-----------------------------------------------------------------------------------------------
533533+SwitchDesktop(desktop)
534534+{
535535+536536+ global desktopcount
537537+ global currentdesktop
538538+ desktopdiff := desktop - currentdesktop
539539+ if (desktop > desktopcount)
540540+ {
541541+ return
542542+ }
543543+ if (desktopdiff < 0)
544544+ {
545545+ desktopdiff *= -1
546546+ Loop %desktopdiff%
547547+ {
548548+ Send ^#{Left}
549549+ }
550550+ }
551551+ else if (desktopdiff > 0)
552552+ {
553553+ Loop %desktopdiff%
554554+ {
555555+ Send ^#{Right}
556556+ }
557557+ }
558558+ currentdesktop := desktop
559559+}
560560+561561+NewDesktop()
562562+{
563563+ global desktopcount
564564+ global currentdesktop
565565+ if (desktopcount > 9)
566566+ {
567567+ return
568568+ }
569569+ desktopcount ++
570570+ currentdesktop := desktopcount
571571+ Send ^#d
572572+}
573573+574574+CloseDesktop()
575575+{
576576+ global desktopcount
577577+ global currentdesktop
578578+ desktopcount --
579579+ if (currentdesktop != 1)
580580+ {
581581+ currentdesktop --
582582+ }
583583+ Send ^#{f4}
584584+}
585585+;=====================================================================o
586586+; Jump to App |
587587+;---------------------------------------------------------------------o
588588+;start apps with hotkey
589589+;from: https://gist.github.com/datmt/5b7d17e8886d14bb0024f8e6c45dabcd
590590+;
591591+#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
592592+; #Warn ; Enable warnings to assist with detecting common errors.
593593+SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
594594+SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
595595+;
596596+;
597597+SetTitleMatchMode, 2
598598+!b::
599599+600600+if WinExist("ahk_exe brave.exe")
601601+{
602602+ WinActivate
603603+} else
604604+{
605605+ Run "C:\Program Files\BraveSoftware\Brave-Browser\Application\brave.exe"
606606+}
607607+608608+Return
609609+610610+611611+!n::
612612+613613+if WinExist("ahk_exe Obsidian.exe")
614614+{
615615+ WinActivate
616616+} else
617617+{
618618+ Run "C:\Users\rah9\AppData\Local\Obsidian\Obsidian.exe"
619619+}
620620+621621+Return
622622+623623+624624+!w::
625625+626626+if WinExist("ahk_exe wt.exe")
627627+{
628628+ WinActivate
629629+} else
630630+{
631631+ Run "C:\Users\rah9\AppData\Local\Microsoft\WindowsApps\wt.exe"
632632+}
633633+634634+Return
635635+636636+!t::
637637+638638+if WinExist("ahk_exe wt.exe")
639639+{
640640+ WinActivate
641641+} else
642642+{
643643+ Run "C:\Users\rah9\AppData\Local\Microsoft\WindowsApps\wt.exe"
644644+}
645645+646646+Return
647647+648648+649649+!v::
650650+651651+if WinExist("ahk_exe Code.exe")
652652+{
653653+ WinActivate
654654+} else
655655+{
656656+ Run "C:\Users\rah9\AppData\Local\Programs\Microsoft VS Code\Code.exe"
657657+}
658658+659659+Return
660660+661661+; DOES NOT WORK YET - therefore commented out
662662+;;=====================================================================o
663663+;; VD.akh: Virtual Desktop AHK Script |
664664+;; Move apps to Virtual Desktops |
665665+;;---------------------------------------------------------------------o
666666+;;from: https://github.com/FuPeiJiang/VD.ahk
667667+;;
668668+;;#SETUP START
669669+;#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
670670+;#SingleInstance force
671671+;ListLines Off
672672+;SetBatchLines -1
673673+;SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
674674+;SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
675675+;#KeyHistory 0
676676+;#WinActivateForce
677677+;
678678+;Process, Priority,, H
679679+;
680680+;SetWinDelay -1
681681+;SetControlDelay -1
682682+;
683683+;;START of gui stuff
684684+;Gui,Font, s12, Segoe UI
685685+;explanation=
686686+;(
687687+;Numpad0 to pin this Window on all desktops
688688+;you can spam (Numpad2,Numpad1,Numpad2,Numpad1) for fun
689689+;
690690+;here's a challenge (you might lose this window):
691691+;Unpin this using Numpad0
692692+;go to Desktop 3 (Numpad3)
693693+;this time, use Win + * on Numpad to come back to this window wherever you are
694694+;(and wherever this window is)
695695+;so you can move this window to desktop 2 (Numpad5), you go to desktop 1, and use Win + * on Numpad
696696+;(if you want to search in this script, the hotkey is #NumpadMult)
697697+;
698698+;Numpad9 to throw a window to Desktop 3 (and not follow it)
699699+;
700700+;getters:
701701+;f1 to see which desktop you currently are in
702702+;f6 to see which desktop this window is in
703703+;f2 to see the total number of virtual desktops
704704+;
705705+;(You might want to pin this window for this part):
706706+;!NumpadAdd (Alt + Numpad+) to createDesktop and go to it
707707+;f1 to see which desktop you currently are in
708708+;
709709+;but at this point, just use Win + Tab..
710710+;these functions are mostly for script only,
711711+;for example: I used VD.createUntil(3)
712712+;at the start of this tutorial, to make sure we have at least 3 VD
713713+;
714714+;^+NumpadAdd (Ctrl Alt + Numpad+) to create until you have 3 desktops
715715+;!NumpadSub (Alt + Numpad-) to remove the current desktop
716716+;^+NumpadSub (Ctrl ALt + Numpad-) to delete the 3rd desktop
717717+;
718718+;more below, look at the hotkeys in code.
719719+;)
720720+;gui, add, Edit, -vscroll -E0x200 +hwndHWndExplanation_Edit, % explanation ; https://www.autohotkey.com/boards/viewtopic.php?t=3956#p21359
721721+;;deselect edit text BY moving caret to start
722722+;Postmessage,0xB1,0,0,, % "ahk_id " HWndExplanation_Edit
723723+;gui, show,, VD.ahk examples WinTitle
724724+;;END of gui stuff
725725+;
726726+;;include the library
727727+;#Include %A_LineFile%\..\VD.ahk
728728+;; or
729729+;; #Include %A_LineFile%\..\_VD.ahk
730730+;; ...{startup code}
731731+;; VD.init()
732732+;
733733+;; VD.ahk : calls `VD.init()` on #Include
734734+;; _VD.ahk : `VD.init()` when you want, like after a GUI has rendered, for startup performance reasons
735735+;
736736+;
737737+;;you should WinHide invisible programs that have a window.
738738+;WinHide, % "Malwarebytes Tray Application"
739739+;;#SETUP END
740740+;
741741+;VD.createUntil(3) ;create until we have at least 3 VD
742742+;
743743+;return
744744+;;
745745+;;
746746+;!^1::VD.MoveWindowToDesktopNum("A",1), VD.goToDesktopNum(1)
747747+;!^2::VD.MoveWindowToDesktopNum("A",2), VD.goToDesktopNum(2)
748748+;!^3::VD.MoveWindowToDesktopNum("A",3), VD.goToDesktopNum(3)
749749+;!^4::VD.MoveWindowToDesktopNum("A",4), VD.goToDesktopNum(4)
750750+;!^5::VD.MoveWindowToDesktopNum("A",5), VD.goToDesktopNum(5)
751751+;!^6::VD.MoveWindowToDesktopNum("A",6), VD.goToDesktopNum(6)
752752+;!^7::VD.MoveWindowToDesktopNum("A",7), VD.goToDesktopNum(7)
753753+;!^8::VD.MoveWindowToDesktopNum("A",8), VD.goToDesktopNum(8)
754754+;!^9::VD.MoveWindowToDesktopNum("A",9), VD.goToDesktopNum(9)
755755+;; move window to left and follow it
756756+;!^left::VD.goToDesktopNum(VD.MoveWindowToRelativeDesktopNum("A", -1))
757757+;; move window to right and follow it
758758+;!^right::VD.goToDesktopNum(VD.MoveWindowToRelativeDesktopNum("A", 1))