Last active
June 21, 2024 19:13
-
-
Save apfelchips/e30321f33abc1eb1a481e83b1e79d5c5 to your computer and use it in GitHub Desktop.
First remap modifier keys with sharpkeys; AHK script has to run as Administrator to work on System Windows / Apps running as Administrator; see Watchdog ScheduledTask below, when you do this make sure to remove the inherited file permissions from C:/tools and only allow administrators write access.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;#NoTrayIcon | |
TraySetIcon("accessibilitycpl.dll","6") ; Keyboard Icon | |
;#Persistent https://www.autohotkey.com/docs/commands/_Persistent.htm | |
SetWorkingDir(A_ScriptDir) ; Ensures a consistent starting directory. | |
#SingleInstance force | |
;#InstallKeybdHook ; see: https://www.autohotkey.com/docs/v1/lib/_HotkeyModifierTimeout.htm | |
; Debugging | |
; #Warn All, OutputDebug ; Show Warnings on DebugView | |
; src: https://gist.github.com/apfelchips/e30321f33abc1eb1a481e83b1e79d5c5/ | |
; doc: | |
; https://www.ahkgen.com/ | |
; https://autohotkey.com/docs/Hotkeys.htm | |
; https://autohotkey.com/docs/KeyList.htm | |
; https://www.autohotkey.com/docs/commands/Send.htm | |
; Ref https://github.com/rbreaves/kinto/blob/master/windows/kinto.ahk | |
; Ref https://autohotkey.com/board/topic/60675-osx-style-command-keys-in-windows/ | |
; Ref https://gist.github.com/trevoreyre/8df3a186bb18df4b17d5417a5d1143ad | |
; Ref https://github.com/Drugoy/Autohotkey-scripts-.ahk | |
; ^ = Control | |
; ! = Alt | |
; + = Shift | |
; # = Windows | |
; * = Wildcard / ignore Modifiers | |
; $ = no Recursion | |
; ~ = no Key Masking | |
; sc063 = Thinkpad FN | |
; sharpkeys: https://github.com/randyrants/sharpkeys/releases/ | |
; online .reg remap generator: https://n8ta.com/projects/windows_key_remapper.html | |
; LWin --> LALT | |
; LAlt --> RControl | |
; optional (right side) | |
; RAlt --> RControl | |
; RWin --> RAlt | |
; AppsKey --> RWin | |
; optional (needed for AppleKeyboardLayoutMode) | |
; LControl --> 0x005C | |
; Remap keys back | |
sc005C::LControl | |
; define application groups | |
;GroupAdd AltTabWindow, ahk_class MultitaskingViewFrame ; Windows 10 | |
;GroupAdd AltTabWindow, ahk_class TaskSwitcherWnd ; Windows Vista, 7, 8.1 | |
;GroupAdd AltTabWindow, ahk_class #32771 ; Older, or with classic alt-tab enabled | |
ResetModifiers(){ | |
Send("{Shift up}") | |
Send("{Control up}") | |
Send("{LControl up}") | |
Send("{RControl up}") | |
Send("{Alt up}") | |
Send("{LWin up}") | |
Send("{RWin up}") | |
Send("{CapsLock up}") | |
SetStoreCapsLockMode( "Off" ) | |
SetCapsLockState( "AlwaysOff" ) | |
return | |
} | |
resetcounter:=0 | |
if ( resetcounter = 0 ) { | |
ResetModifiers( ) | |
resetcounter++ | |
} | |
; CapsLock Protection | |
+CapsLock::CapsLock | |
CapsLock::Ctrl | |
; TODO: Find AutoElevate replacement | |
;AutoElevate := "true" | |
; src: https://autohotkey.com/board/topic/46526-run-as-administrator-xpvista7-a-isadmin-params-lib/?p=289601 | |
Log(msg){ | |
OutputDebug("[AHK] " Msg) | |
} | |
; #SetTitleMatchMode RegEx breaks too much / has undefined behaviour | |
WinActiveProcessRegEx(regexNeedle, comfort:=true){ | |
try { | |
tmp := WinGetProcessName("A") | |
if (comfort){ | |
regexNeedle := "i)^" . regexNeedle . "$" | |
} | |
return RegExMatch(tmp, regexNeedle) | |
} catch as e { | |
return false | |
} | |
} | |
WinActiveClassRegEx(regexNeedle, comfort:=true){ | |
try { | |
tmp := WinGetClass("A") | |
if (comfort){ | |
regexNeedle := "i)^" . regexNeedle . "$" | |
} | |
return RegExMatch(tmp, regexNeedle) | |
} catch as e { | |
return false | |
} | |
} | |
WinActiveTitleRegEx(regexNeedle, comfort := true){ | |
try { | |
tmp := WinGetTitle("A") | |
if (comfort){ | |
regexNeedle := "i)" . regexNeedle | |
} | |
return RegExMatch(tmp, regexNeedle) | |
} catch as e { | |
return false | |
} | |
} | |
CountWindows(){ | |
owindows := WinGetList(,,,) | |
awindows := Array() | |
windows := owindows.Length | |
For v in owindows { | |
awindows.Push(v) | |
} | |
wCount := 0 | |
wTitleOut := "" | |
Loop awindows.Length | |
{ | |
id := awindows[A_Index] | |
wTitle := WinGetTitle("ahk_id " id) | |
;wTitleOut .= wTitle . "`n" | |
if (wTitle != "") { | |
wCount += 1 | |
} | |
} | |
;MsgBox, %wCount% | |
return wCount | |
} | |
WaitForWindowChange(){ | |
If (WinActiveClassRegEx("awindows.Length\.UI\.Core\.CoreWindow")){ | |
return | |
} | |
ErrorLevel := !WinWaitNotActive("A") | |
return | |
} | |
;reset all modifiers on escape | |
*~Esc:: | |
{ | |
Send("{Control up}") | |
Send("{LControl up}") | |
Send("{RControl up}") | |
Send("{Shift up}") | |
Send("{Alt up}") | |
Send("{LWin up}") | |
Send("{RWin up}") | |
;Send {AppsKey up} | |
Send("{CapsLock up}") | |
SetCapsLockState("Off") | |
;KeyHistory | |
} | |
/** | |
* Disable Alt key acceleration. | |
* These next two lines are very important. You have to change the "menu mask | |
* key" away from being Control, to something that won't result in cross-talk. | |
* https://autohotkey.com/boards/viewtopic.php?f=76&t=57683 | |
*/ | |
; Send{Alt up}{sc0EA up}{sc0E9 up} when using alt | |
A_MenuMaskKey := "vk07" ; vk07 is unassigned | |
;#UseHook On ; https://www.autohotkey.com/docs/commands/_UseHook.htm | |
~LAlt:: | |
{ | |
SendInput("{Blind}{sc0E9}") | |
ErrorLevel := !KeyWait("LAlt") ; this wasit for the key to be RELEASED. So that it doesn't keep spamming SC0E9 (as seen from an AHK window Key history and script info... window.) | |
SendInput("{Blind}{sc0EA}") | |
} | |
~RAlt:: | |
{ | |
SendInput("{Blind}{sc0E9}") | |
ErrorLevel := !KeyWait("RAlt") ; so that it doesn't keep spamming SC0E9 | |
SendInput("{Blind}{sc0EA}") | |
;#UseHook Off | |
} | |
#HotIf ( WinActiveProcessRegEx("ConEmu(64)?\.exe") ) | |
~LAlt:: | |
{ | |
SendInput("{Blind}") | |
} | |
~RAlt:: | |
{ | |
SendInput("{Blind}") | |
} | |
#HotIf | |
; rctrl+Tab --> Expose | |
+F11:: | |
>^Tab:: | |
>^+Tab:: | |
;$!<Tab:: | |
;$!<+Tab:: | |
{ | |
;KeyWait LAlt | |
SendInput("#{Tab}") | |
;Send("#{Tab}") | |
Send("{Control up}") ; sometimes get stuck here | |
; Send("{Alt up}{sc0EA up}{sc0E9 up}{LWin down}{Tab}{LWin up}") | |
} | |
; FIXME: somethimes hangs | |
; Command-Tab --> Switch windows | |
; Ref: https://autohotkey.com/board/topic/148298-ctrl-tab-ctrl-shift-tab-for-alttabshiftalttab-task-switching-windows-10/ | |
; https://www.autohotkey.com/docs/Hotkeys.htm#AltTabRemarks | |
;#HotIf ( CountWindows() > 0 ) | |
; >^Tab:: | |
; { | |
; Send("{Alt down}{Tab}") | |
; } | |
; >^+Tab:: | |
; { | |
; Send("{Alt down}{Shift down}{Tab}{Shift up}") | |
; } | |
;#HotIf | |
;#HotIf ( WinExist("ahk_class MultitaskingViewFrame") ) | |
; ~sc0EA up:: | |
; ~sc0E9 up:: | |
; ~*Alt up:: | |
; ~*Esc:: | |
; { | |
; Send("{Control up}") ; RControl up or LControl up don't get detected reliably!!! | |
; Send("{Alt up}") | |
; } | |
;#HotIf | |
; disable StartMenu on Command+Escape | |
$>^Escape:: | |
{ | |
SendInput("+{Escape}") | |
} | |
; StartMenu aka Spotlight light --> Use Powertoys Run instead | |
;>^Space:: | |
;{ | |
;Send {blind}^<{Esc} | |
;Send {blind}# | |
;Send {F15} | |
;} | |
; Command+Shift+V - Pure / PlainText Clipboard / Paste | |
$>^+v:: | |
{ | |
wholeclipboard:=ClipboardAll() | |
global A_Clipboard := A_Clipboard | |
Sleep(100) ; wait for clipboard to be cleansed | |
Send("^{v}") | |
Sleep(100) ; wait before restoring original clipboard content | |
global A_Clipboard:=wholeclipboard | |
} | |
; Command+Shift+opt+V - Pure / PlainText Clipboard / Paste | |
$>^+!v:: | |
{ | |
wholeclipboard:=ClipboardAll() | |
global A_Clipboard := A_Clipboard | |
;Clipboard := StrReplace(Clipboard, "\", " ") | |
A_Clipboard := StrReplace(A_Clipboard, "`r`n", "") | |
Sleep(100) ; wait for clipboard to be cleansed | |
Send("^{v}") | |
Sleep(100) ; wait before restoring original clipboard content | |
global A_Clipboard:=wholeclipboard | |
} | |
; Command-M / Command-H - Minimize active window | |
$>^m:: | |
$>^h:: | |
{ | |
WinMinimize("A") | |
} | |
; Command-R - Reload | |
$>^r:: | |
{ | |
Send("{F5}") | |
} | |
$>^q:: | |
$!f4:: | |
{ | |
if ( WinActiveProcessRegEx("notes2\.exe") or ( WinActiveProcessRegEx("Outlook\.exe") and WinActiveTitleRegEx("- Outlook$") ) or WinActiveProcessRegEx("PSRClient\.exe") or WinActiveTitleRegEx("^Valuemation") ){ | |
WinMinimize("A") | |
} else if (WinActiveProcessRegEx("explorer\.exe") and ( WinActiveClassRegEx("Progman") or WinActiveClassRegEx("WorkerW") or WinActiveClassRegEx("Shell_TrayWnd") )) { | |
; do nothing to prevent opening the shutdown dialog | |
} else { | |
Send("{LAlt down}{F4}{LAlt up}") | |
;WinClose, A | |
} | |
} | |
; "force close" | |
$>^!<q:: | |
{ | |
WinKill("A") | |
} | |
$#+w:: ; Logitech Options Gesture Mapping | |
$>^w:: | |
{ | |
if ( WinActiveProcessRegEx("KeePassXC\.exe") | |
or WinActiveProcessRegEx("SumatraPDF\.exe") | |
or WinActiveProcessRegEx("mdview\.exe") | |
or WinActiveProcessRegEx("AutoHotkey\.exe") | |
or WinActiveClassRegEx("Photo_Lightweight_Viewer") | |
or WinActiveClassRegEx("TaskManagerWindow") | |
or (WinActiveProcessRegEx("Outlook\.exe") and not ( WinActiveTitleRegEx("- Outlook$") )) | |
or (WinActiveProcessRegEx("ApplicationFrameHost\.exe") and not WinActiveTitleRegEx("- Remote Desktop$")) ; UWP apps | |
or (WinActiveProcessRegEx("explorer\.exe") and ( not ( WinActiveClassRegEx("Progman") or WinActiveClassRegEx("WorkerW") or WinActiveClassRegEx("Shell_TrayWnd") ))) ) | |
{ | |
WinClose("A") | |
} else if ( WinActiveProcessRegEx("WindowsTerminal\.exe") ){ | |
Send("+^{w}") | |
} else if ( WinActiveProcessRegEx("PSRClient\.exe") ){ | |
Send("{Esc}") | |
} else if ( WinActiveTitleRegEx("- Outlook$") or WinActiveTitleRegEx("^Valuemation") or WinActiveProcessRegEx("Teams\.exe") or WinActiveProcessRegEx("ms-teams\.exe") ){ | |
WinMinimize("A") | |
} else if ( WinActiveProcessRegEx("ConEmu(64)?\.exe")){ ; Programs that can differentiate between LControl <=> RControl | |
Send("{RControl down}{w}{RControl up}") | |
} else { | |
Send("^{w}") | |
Send("{Control up}") ; sometimes get stuck here | |
} | |
} | |
; Sublime Notes Shortcut | |
;#HotIf ( WinActiveProcessRegEx("sublime_text\.exe") and WinActiveTitleRegEx("\(notes\).-.Sublime.Text$")) | |
; !Space:: | |
; { | |
; Send ^{p} | |
; } | |
;#HotIf | |
;!Space:: | |
;{ | |
; ;; SetTitleMatchMode 3 | |
; ;; DetectHiddenWindows, On | |
; ;; WinGet, obsidian_window_id, IDLast, ahk_exe Obsidian.exe | |
; ;; SetTitleMatchMode 1 | |
; | |
; EnvGet, ProgFiles, ProgramFiles | |
; EnvGet, UserProfile, UserProfile | |
; RunWait %ProgramFiles%\Sublime Text\subl.exe %UserProfile%\Nextcloud\notes\notes.sublime-project, | |
; if ErrorLevel { | |
; Run notepad.exe ; fallback software tip: https://www.binaryfortress.com/NotepadReplacer/Download/ | |
; } | |
; ;; DetectHiddenWindows, Off | |
;} | |
#HotIf (WinActiveProcessRegEx("Outlook\.exe") and ( WinActiveTitleRegEx("- Outlook$") )) | |
Ins:: | |
{ | |
Send("{LControl down}{q}{LControl up}") | |
} | |
^F:: | |
{ | |
Send("{Enter}") | |
Send("{F4}") | |
} | |
#HotIf | |
#HotIf (WinActiveProcessRegEx("Outlook\.exe")) | |
^F:: | |
{ | |
Send("{F4}") | |
} | |
#HotIf | |
#HotIf (WinActiveProcessRegEx("notes2\.exe") ) | |
^<TAB:: | |
^<+TAB:: | |
{ | |
Send("{blind}{F8}") | |
} | |
#HotIf | |
;; Windows Terminal RCtrl Shim | https://aka.ms/terminal-keybindings | |
#HotIf ( WinActiveProcessRegEx("WindowsTerminal\.exe")) | |
>^c:: Send("{blind}{Shift down}{c}{Shift up}") | |
>^v:: Send("{blind}{Shift down}{v}{Shift up}") | |
>^n:: Send("{blind}{Shift down}{n}{Shift up}") | |
>^t:: Send("{blind}{Shift down}{t}{Shift up}") | |
>^f:: Send("{blind}{Shift down}{f}{Shift up}") | |
>^a:: Send("{blind}{Shift down}{a}{Shift up}") | |
#HotIf | |
;; macOS text navigation | |
; Command-Shift-arrow navigation + highlight | |
;;>^+Left::Send("{Shift down}{Home}{Shift up}") | |
;;>^+Right::Send("{Shift down}{End}{Shift down}") | |
;;>^+Up::Send("{Control down}{Shift down}{Home}{Shift up}{Control up}") | |
;;>^+Down::Send("{Control down}{Shift down}{End}{Shift up}{Control up}") | |
;; Option-arrow navigation | |
;;!<Left::Send("{Control down}{Left}{Control up}") | |
;;!<Right::Send("{Control down}{Right}{Control up}") | |
;; Option-Shift-arrow navigation + highlight | |
;;!<+Left::Send("{Control down}{Shift down}{Left}{Shift up}{Control up}") | |
;;!<+Right::Send("{Control down}{Shift down}{Right}{Shift up}{Control up}") | |
; Command-D - Delete forward | |
;;>^d::Send("{Delete} | |
;; Command-Delete - Delete line | |
;;>^Backspace::Send("{Shift down}{Home}{Shift up}{Delete}") | |
;; Command-Shift-Delete - Delete line forward | |
;;>^+Backspace::Send("{Shift down}{End}{Shift up}{Delete}") | |
;; Option-Delete - Delete word | |
;;!Backspace::Send("{Control down}{Backspace}{Control up}") | |
;; Option-Shift-Delete - Delete word forward | |
;;!+Backspace::Send("{Control down}{Delete}{Control up}") | |
;; Screenshots | |
; https://docs.microsoft.com/en-us/windows/uwp/launch-resume/launch-screen-snipping | |
$+>^3:: | |
$+>^4:: | |
{ | |
Run("explorer.exe ms-screenclip:") | |
;Run, C:\WINDOWS\system32\SnippingTool.exe /clip ; legacy Snipping Tool | |
} | |
;; Finder Emulation | |
#HotIf ( WinActiveProcessRegEx("explorer\.exe") and WinActiveClassRegEx("CabinetWClass") ) | |
>^Left:: | |
{ | |
SendEvent("{RControl up}") | |
SendEvent("!{Left}") | |
} | |
>^Right:: | |
{ | |
SendEvent("{RControl up}") | |
SendEvent("!{Right}") | |
} | |
>^Up:: | |
{ | |
SendEvent("{RControl up}") | |
SendEvent("!{Up}") | |
} | |
>^Down:: | |
{ | |
SendEvent("{RControl up}") | |
SendEvent("!{Down}") | |
} | |
#HotIf | |
;; Affinity Suite RControl weirdness fix | |
#HotIf ( WinActiveProcessRegEx("photo\.exe") ) or ( WinActiveProcessRegEx("designer\.exe") ) or ( WinActiveProcessRegEx("publisher\.exe") ) | |
>^d:: | |
{ | |
Send("^{d}") | |
} | |
#HotIf | |
#HotIf ( WinActiveProcessRegEx("explorer\.exe") ) | |
$+Enter:: | |
{ | |
SendEvent("{F2}") ; rename action | |
} | |
$>^o:: | |
{ | |
Send("{Control up}") | |
SendEvent("{Control up}") | |
SendEvent("{Enter}") | |
} | |
$!>^i:: | |
$>^i:: | |
{ | |
SendEvent("!{Enter}") | |
} | |
$^+.:: | |
{ | |
HiddenFiles_Status := RegRead("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced", "Hidden") | |
if (HiddenFiles_Status = 2){ | |
RegWrite(1, "REG_DWORD", "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced", "Hidden") | |
Send("{F5}") | |
} else { | |
RegWrite(2, "REG_DWORD", "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced", "Hidden") | |
Send("{F5}") | |
} | |
} | |
$>^k:: ; connect to server | |
$>^+g:: ; goto file | |
{ | |
if ( WinActiveClassRegEx("CabinetWClass") ){ | |
SendEvent("{F4}") | |
} else if ( WinActiveClassRegEx("Progman") ){ | |
Run("explore " A_MyDocuments "\..\") | |
Sleep(200) | |
SendEvent("{F4}") | |
} | |
} | |
$>^+Backspace:: | |
$>^+Delete:: | |
{ | |
msgResult := MsgBox("`"Empty Recycle Bin?`"", "", 1) | |
if (msgResult = "Ok"){ | |
FileRecycleEmpty() | |
} | |
} | |
#HotIf | |
; Media Controls | |
^F7::Send("{Media_Prev}") | |
^F8::Send("{Media_Play_Pause}") | |
^F9::Send("{Media_Next}") | |
^F10::Send("{Volume_Mute}") | |
^F11::Send("{Volume_Down}") | |
^F12::Send("{Volume_Up}") | |
; HotCorners | |
CoordMode("Mouse") ; mouse coords to screen | |
SetTimer(MouseCheck, 250) ; MouseCheck execution interval | |
MouseCheck(){ | |
try { | |
if (!WinExist("A")) || (WinGetProcessName("A") == "LockApp.exe") { ; check if currently on windows lockscreen | |
return | |
} | |
} | |
catch as e { | |
return | |
} | |
static origx:=-1,origy:=-1 ; init values of origx|origy | |
MouseGetPos(&mx,&my) | |
if (mx=origx) && (my=origy) { ; check if mouse coordinates chaged | |
return | |
} | |
origx:=mx,origy:=my ; remember last coordinates | |
if (mx=0) && (my=0){ ; Top Left | |
sleep 500 | |
MouseGetPos(&mx,&my) | |
if (mx=0) && (my=0){ ; mouse is still in the corner | |
;send the monitor into off mode | |
;SendMessage(0x112, 0xF170, 2, , "Program Manager") | |
MouseMove( 1, 1, 2, "R" ) | |
DllCall("LockWorkStation") | |
} | |
return | |
} else if (mx=A_ScreenWidth-1) && (my=0){ ; Top Right | |
return | |
} else if (mx=0) && (my=A_ScreenHeight-1){ ; Bottom Left | |
return | |
} else if (mx=A_ScreenWidth-1) && (my=A_ScreenHeight-1){ ; Bottom Right | |
return | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
while ($true) { | |
$WatchedProcesses = Get-CimInstance -ClassName Win32_Process -Filter "name = 'AutoHotkey.exe'" | |
$WatchedCli = Write-Output $WatchedProcesses | Select CommandLine | Select-String -Pattern 'macOS-shortcuts.ahk' | |
if ( $WatchedCli.Count -eq 0 ){ | |
Start-Process -FilePath "${env:ProgramFiles}\AutoHotkey\Autohotkey.exe" -ArgumentList "${env:SystemDrive}\tools\macOS-shortcuts.ahk" -Verb RunAs | |
Write-Host "starting watched process" | |
} | |
#Write-Host "nothing to do, waiting..." | |
Start-Sleep -s 35 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-16"?> | |
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"> | |
<RegistrationInfo> | |
<Date>2021-03-18T16:51:09.0308012</Date> | |
<Author>apfelchips</Author> | |
<URI>\macOS-shortcuts-watchdog</URI> | |
</RegistrationInfo> | |
<Triggers> | |
<LogonTrigger> | |
<Enabled>true</Enabled> | |
<UserId>.\user</UserId> | |
<Delay>PT13S</Delay> | |
</LogonTrigger> | |
</Triggers> | |
<Principals> | |
<Principal id="Author"> | |
<UserId>xxxxxxxxxxxxxxxxx</UserId> | |
<LogonType>InteractiveToken</LogonType> | |
<RunLevel>HighestAvailable</RunLevel> | |
</Principal> | |
</Principals> | |
<Settings> | |
<MultipleInstancesPolicy>StopExisting</MultipleInstancesPolicy> | |
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries> | |
<StopIfGoingOnBatteries>true</StopIfGoingOnBatteries> | |
<AllowHardTerminate>true</AllowHardTerminate> | |
<StartWhenAvailable>false</StartWhenAvailable> | |
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable> | |
<IdleSettings> | |
<StopOnIdleEnd>true</StopOnIdleEnd> | |
<RestartOnIdle>false</RestartOnIdle> | |
</IdleSettings> | |
<AllowStartOnDemand>true</AllowStartOnDemand> | |
<Enabled>true</Enabled> | |
<Hidden>true</Hidden> | |
<RunOnlyIfIdle>false</RunOnlyIfIdle> | |
<WakeToRun>false</WakeToRun> | |
<ExecutionTimeLimit>PT0S</ExecutionTimeLimit> | |
<Priority>7</Priority> | |
</Settings> | |
<Actions Context="Author"> | |
<Exec> | |
<Command>C:\Windows\System32\wscript.exe</Command> | |
<Arguments>"C:\tools\HiddenPowershell.vbs" -ExecutionPolicy ByPass -noProfile -File "C:\tools\macOS-shortcuts-watchdog.ps1"</Arguments> | |
</Exec> | |
</Actions> | |
</Task> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. | |
;#NoTrayIcon | |
Menu, Tray, Icon, pifmgr.dll, 13 ; Keyboard Icon | |
;#Persistent https://www.autohotkey.com/docs/commands/_Persistent.htm | |
SendMode Input ; Recommended for new scripts due to its superior speed and reliability. | |
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory. | |
#SingleInstance force | |
; Debugging | |
; #Warn All, OutputDebug ; Show Warnings on DebugView | |
#Warn UseUnsetLocal, Off ; Can't use default Parameters without warning | |
; doc: | |
; https://www.ahkgen.com/ | |
; https://autohotkey.com/docs/Hotkeys.htm | |
; https://autohotkey.com/docs/KeyList.htm | |
; see DebugMessages with: https://learn.microsoft.com/en-us/sysinternals/downloads/debugview | |
; Ref https://autohotkey.com/board/topic/60675-osx-style-command-keys-in-windows/ | |
; Ref https://gist.github.com/trevoreyre/8df3a186bb18df4b17d5417a5d1143ad | |
; Ref https://github.com/Drugoy/Autohotkey-scripts-.ahk | |
; ! = Alt | |
; ^ = Control | |
; + = Shift | |
; # = Windows | |
; * = Wildcard / ignore Modifiers | |
; $ = no Recursion | |
; ~ = no Key Masking | |
; sharpkeys: https://github.com/randyrants/sharpkeys/releases/ | |
; PgDown --> Unknown: 0x0070 | |
; PgUp --> Unknown: 0x0071 | |
; PrintScr --> Unknown: 0x007F | |
; src: AHKHID.akh: https://github.com/jleb/AHKHID | |
AHKHID_GetDevCount() { | |
global iCount = "" | |
;Get the device count | |
r := DllCall("GetRawInputDeviceList", "Ptr", 0, "UInt*", iCount, "UInt", A_PtrSize * 2) | |
;Check for error | |
If (r = -1) Or ErrorLevel { | |
ErrorLevel = GetRawInputDeviceList call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError% | |
Return -1 | |
} Else Return iCount | |
} | |
AHKHID_Initialize(bRefresh = False) { | |
global iCount | |
Static uHIDList, bInitialized := False | |
If bInitialized And Not bRefresh | |
Return &uHIDList | |
;Get the device count | |
r := DllCall("GetRawInputDeviceList", "Ptr", 0, "UInt*", iCount, "UInt", A_PtrSize * 2) | |
;Check for error | |
If (r = -1) Or ErrorLevel { | |
ErrorLevel = GetRawInputDeviceList call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError% | |
Return -1 | |
} | |
;Prep var | |
VarSetCapacity(uHIDList, iCount * (A_PtrSize * 2)) | |
r := DllCall("GetRawInputDeviceList", "Ptr", &uHIDList, "UInt*", iCount, "UInt", A_PtrSize * 2) | |
If (r = -1) Or ErrorLevel { | |
ErrorLevel = GetRawInputDeviceList call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError% | |
Return -1 | |
} | |
bInitialized := True | |
Return &uHIDList | |
} | |
AHKHID_GetDevIndex(Handle) { | |
Loop % AHKHID_GetDevCount() | |
If (NumGet(AHKHID_Initialize(), (A_Index - 1) * (A_PtrSize * 2)) = Handle) | |
Return A_Index | |
Return 0 | |
} | |
AHKHID_GetDevHandle(i) { | |
Return NumGet(AHKHID_Initialize(), (i - 1) * (A_PtrSize * 2)) | |
} | |
AHKHID_GetDevType(i, IsHandle = False) { | |
Return Not IsHandle ? NumGet(AHKHID_Initialize(), ((i - 1) * (A_PtrSize * 2)) + A_PtrSize, "UInt") | |
: NumGet(AHKHID_Initialize(), ((AHKHID_GetDevIndex(i) - 1) * (A_PtrSize * 2)) + A_PtrSize, "UInt") | |
} | |
AHKHID_GetDevName(i, IsHandle = False) { | |
;Get index if i is handle | |
h := IsHandle ? i : AHKHID_GetDevHandle(i) | |
;Get device name length. RIDI_DEVICENAME | |
r := DllCall("GetRawInputDeviceInfo", "Ptr", h, "UInt", 0x20000007, "Ptr", 0, "UInt*", iLength) | |
If (r = -1) Or ErrorLevel { | |
ErrorLevel = GetRawInputDeviceInfo call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError% | |
Return "" | |
} | |
;Get device name. | |
VarSetCapacity(s, (iLength + 1) * 2) ;RIDI_DEVICENAME | |
r := DllCall("GetRawInputDeviceInfo", "Ptr", h, "UInt", 0x20000007, "Str", s, "UInt*", iLength) | |
If (r = -1) Or ErrorLevel { | |
ErrorLevel = GetRawInputDeviceInfo call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError% | |
Return "" | |
} | |
Return s | |
} | |
; see hardmode: https://autohotkey.com/board/topic/113250-detect-usb-keypad/#entry663129 | |
; watcher https://autohotkey.com/board/topic/45042-detect-when-specific-usb-device-is-connected/#entry280394 | |
on_device_changed(wParam, lParam, msg, hwnd){ | |
;OutputDebug, ### on_device_changed(%wParam%, %lParam%, %msg%, %hwnd%) ### | |
if ( msg = 537 ) { ; watcher on WM_DEVICECHANGE 0x219 | |
Reload | |
} | |
} | |
externalKeyboardCount := 0 | |
updateExternalKeyboardCount() | |
OnMessage(0x219, "on_device_changed") ;https://www.autohotkey.com/docs/misc/SendMessageList.htm | |
sleep 500 | |
return | |
updateExternalKeyboardCount(){ | |
global externalKeyboardCount | |
externalKeyboardCount := 0 | |
devCount := AHKHID_GetDevCount() | |
iterator := 0 | |
internalKeyboards := [] | |
internalKeyboards.Push("\\?\ACPI#LEN0071#4&1b7d46ad&0#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}") ; ThinkPad Keyboard | |
internalKeyboards.Push("\\?\HID#VID_1050&PID_0407&MI_00#7&1165288&0&0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}") | |
internalKeyboards.Push("\\?\HID#VID_04D9&PID_FC45&MI_01#9&2c2eeb1&0&0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}") | |
loop %devCount% { | |
isInternal := False | |
deviceTypeID := AHKHID_GetDevType(iterator) | |
if (deviceTypeID = 1) { | |
devName := AHKHID_GetDevName(iterator) | |
OutputDebug, ### %iterator%: %devName% ### | |
for each, internalKeyboard in internalKeyboards { | |
if ( internalKeyboard = devName ) { | |
OutputDebug, ### Internal Keyboard: %devName% ### | |
isInternal = True | |
} | |
} | |
if not ( isInternal ){ | |
OutputDebug, ### External Keyboard: %devName% ### | |
externalKeyboardCount += 1 | |
} | |
} | |
iterator += 1 | |
} | |
OutputDebug, ### externalKeyboardCount: "%externalKeyboardCount%" ### | |
return | |
} | |
#If ( externalKeyboardCount = 0 ) | |
*SC07F::Send {Blind}{RAlt down} | |
*SC07F Up::Send {Blind}{RAlt up} | |
#If | |
#If ( externalKeyboardCount > 0 ) | |
*SC071::Send {Blind}{PgUp} | |
*SC070::Send {Blind}{PgDn} | |
*SC07F::Send {Blind}{PrintScreen} | |
#If |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Windows Registry Editor Version 5.00 | |
; https://github.com/randyrants/sharpkeys/blob/master/SharpKeys/Dialog_Main.cs#L581 | |
; Left Alt --> Right Ctrl | |
; Left Win --> Left Alt | |
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout] | |
"Scancode Map"=hex:00,00,00,00,00,00,00,00,03,00,00,00,1d,e0,38,00,38,00,5b,e0,\ | |
00,00,00,00 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment