├── .gitignore ├── .gitmodules ├── README.md └── src ├── Lib ├── OSD.ahk └── RapidHotkey.ahk ├── Script.ahk ├── Script.ico ├── hotkeys ├── clipboardSearch.ahk ├── mouse.ahk ├── speedtest.ahk ├── spotify.ahk ├── valorant.ahk ├── voicemeeter.ahk └── wt.ahk └── other └── OfficeToPDF ├── .gitignore ├── GUI.ahk ├── OfficeToPDF.ahk ├── OfficeToPDF.ico └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | Script.exe 2 | *.gif 3 | *.zip 4 | bin 5 | .vscode 6 | config.json 7 | spotifyEdgeProfile -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/Lib/SpotifyFreeAPI"] 2 | path = src/Lib/SpotifyFreeAPI 3 | url = https://github.com/SaifAqqad/SpotifyFreeAPI.ahk.git 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | AHK_Script 3 |

4 | -------------------------------------------------------------------------------- /src/Lib/OSD.ahk: -------------------------------------------------------------------------------- 1 | Class OSD { 2 | static ACCENT:= {"-1":"4D5565" ; MAIN ACCENT 3 | ,"0":"DC3545" ; OFF ACCENT 4 | ,"1":"007BFF"} ; ON ACCENT 5 | 6 | __New(pos:="", excludeFullscreen:=0, posEditorCallback:=""){ 7 | this.excludeFullscreen:= excludeFullscreen 8 | this.state:= 0 9 | ;get the primary monitor resolution 10 | SysGet, res, Monitor 11 | this.screenHeight:= resBottom 12 | this.screenWidth:= resRight 13 | ;get the primary monitor scaling 14 | this.scale:= A_ScreenDPI/96 15 | ;set the OSD width and height 16 | this.width:= Format("{:i}", 250 * this.scale) 17 | this.height:= Format("{:i}", 40 * this.scale) 18 | ;set the default pos object 19 | pos:= pos? pos : {x:-1,y:-1} 20 | ;get the final pos object 21 | this.pos:= this.getPosObj(pos.x, pos.y) 22 | ;set up bound func objects 23 | this.hideFunc:= objBindMethod(this, "hide") 24 | this.onDragFunc:= objBindMethod(this, "__onDrag") 25 | this.onRClickFunc:= objBindMethod(this, "__onRClick") 26 | this.posEditorCallback:= posEditorCallback 27 | 28 | ;set the initial OSD theme 29 | this.setTheme(0) 30 | ;create the OSD window 31 | this.create() 32 | } 33 | 34 | ; creates the OSD window 35 | create(){ 36 | Gui, New, +Hwndhwnd, OSD 37 | this.hwnd:= hwnd 38 | Gui, +AlwaysOnTop -SysMenu +ToolWindow -caption -Border 39 | Gui, Margin, 15 40 | Gui, Color, % this.theme, % OSD.ACCENT["-1"] 41 | Gui, Font,% Format("s{:i} w500 c{}", 12*this.scale, OSD.ACCENT["-1"]), Segoe UI Variable 42 | Gui, Add, Text,% Format("HwndtxtHwnd w{} Center", this.width-30) 43 | this.hwndTxt:= txtHwnd 44 | } 45 | 46 | ; hides and destroys the OSD window 47 | destroy(){ 48 | Gui,% this.hwnd ":Default" 49 | this.hide() 50 | Gui, Destroy 51 | this.hwnd:= "" 52 | this.hwndTxt:="" 53 | } 54 | 55 | ; shows the OSD window with the specified text and accent 56 | show(text,accent:=-1){ 57 | ;if the window can't be shown -> return 58 | if(!this.canShow()) 59 | return 60 | ;if the window does not exist -> create it first 61 | if(!this.hwnd) 62 | this.create() 63 | Gui, % this.hwnd ":Default" ;set the default window 64 | ;set the accent/theme colors 65 | if(color:=OSD.ACCENT[accent ""]) 66 | accent:=color 67 | Gui, Color, % this.theme, % accent 68 | Gui, Font,% Format("s{:i} w500 c{}", 12*this.scale, accent) 69 | GuiControl, Font, % this.hwndTxt 70 | text:= this.processText(text) 71 | GuiControl, Text, % this.hwndTxt, %text% 72 | Gui, +LastFound 73 | Winset, Redraw 74 | ;show the OSD 75 | Gui, Show, % Format("w{} NoActivate NA x{} y{}", this.width, this.pos.x, this.pos.y) 76 | ;make the OSD corners rounded 77 | WinGetPos,,,Width, Height, % "ahk_id " . this.hwnd 78 | WinSet, Region, % Format("w{} h{} 0-0 R{3:i}-{3:i}", Width, Height, 15*this.scale ), % "ahk_id " . this.hwnd 79 | ;set the OSD transparency 80 | WinSet, Transparent, 252, % "ahk_id " . this.hwnd 81 | return this.state:= 1 82 | } 83 | 84 | ; shows the OSD window with the specified text and accent 85 | ; and activates a timer to hide it 86 | showAndHide(text, accent:=-1, seconds:=1){ 87 | hideFunc:= this.hideFunc 88 | this.show(text,accent) 89 | SetTimer, % hideFunc,% "-" . seconds*1000 90 | } 91 | 92 | ; shows a draggable OSD window with the specified text and accent 93 | showDraggable(text, accent:=-1){ 94 | Gui,% this.hwnd ":Default" 95 | this.show(text, accent) 96 | OnMessage(0x201, this.onDragFunc) 97 | } 98 | 99 | ; shows a draggable OSD window to set the position 100 | showPosEditor(){ 101 | Gui,% this.hwnd ":Default" 102 | this.showdraggable("RClick to confirm") 103 | OnMessage(0x205, this.onRClickFunc) 104 | } 105 | 106 | ; hides the OSD window 107 | hide(){ 108 | if(!this.hwnd) 109 | return 110 | Gui, % this.hwnd ":Default" 111 | OnMessage(0x201, this.onDragFunc, 0) 112 | OnMessage(0x205, this.onRClickFunc, 0) 113 | Gui, Hide 114 | this.state:= 0 115 | } 116 | 117 | canShow(){ 118 | return this.excludeFullscreen? !this.isWindowFullscreen() : 1 119 | } 120 | 121 | setTheme(theme:=""){ 122 | if(theme != this.theme) 123 | this.theme:= theme? (theme=1? "232323" : theme) : "f2f2f2" 124 | } 125 | 126 | processText(text){ 127 | if (StrLen(text)>28) 128 | text:= SubStr(text, 1, 26) . Chr(0x2026) ; fix overflow with ellipsis 129 | return text 130 | } 131 | 132 | isWindowFullscreen(win:="A"){ 133 | winID := WinExist(win) 134 | if(!winID) 135 | return 0 136 | WinGet style, Style, ahk_id %WinID% 137 | WinGetPos ,,,winW,winH, %winTitle% 138 | return !((style & 0x20800000) or WinActive("ahk_class Progman") 139 | or WinActive("ahk_class WorkerW") or winH < A_ScreenHeight or winW < A_ScreenWidth) 140 | } 141 | 142 | getPosObj(x:=-1,y:=-1){ 143 | p_obj:= {} 144 | p_obj.x:= x=-1? Round(this.screenWidth/2 - this.width/2) : x 145 | p_obj.y:= y=-1? this.screenHeight * 0.9 : y 146 | return p_obj 147 | } 148 | 149 | __onDrag(wParam, lParam, msg, hwnd){ 150 | if(hwnd = this.hwnd) 151 | PostMessage, 0xA1, 2,,, % "ahk_id " this.hwnd 152 | } 153 | 154 | __onRClick(wParam, lParam, msg, hwnd){ 155 | if(hwnd != this.hwnd) 156 | return 157 | WinGetPos, xPos,yPos 158 | this.hide() 159 | this.pos.x:= xPos 160 | this.pos.y:= yPos 161 | if(IsFunc(this.posEditorCallback)) 162 | this.posEditorCallback.Call(xPos,yPos) 163 | } 164 | } -------------------------------------------------------------------------------- /src/Lib/RapidHotkey.ahk: -------------------------------------------------------------------------------- 1 | RapidHotkey(keystroke, times="2", delay=0.2, IsLabel=0) 2 | { 3 | Pattern := Morse(delay*1000) 4 | If (StrLen(Pattern) < 2 and Chr(Asc(times)) != "1") 5 | Return 6 | If (times = "" and InStr(keystroke, """")) 7 | { 8 | Loop, Parse, keystroke,"" 9 | If (StrLen(Pattern) = A_Index+1) 10 | continue := A_Index, times := StrLen(Pattern) 11 | } 12 | Else if (RegExMatch(times, "^\d+$") and InStr(keystroke, """")) 13 | { 14 | Loop, Parse, keystroke,"" 15 | If (StrLen(Pattern) = A_Index+times-1) 16 | times := StrLen(Pattern), continue := A_Index 17 | } 18 | Else if InStr(times, """") 19 | { 20 | Loop, Parse, times,"" 21 | If (StrLen(Pattern) = A_LoopField) 22 | continue := A_Index, times := A_LoopField 23 | } 24 | Else if (times = "") 25 | continue := 1, times := 2 26 | Else if (times = StrLen(Pattern)) 27 | continue = 1 28 | If !continue 29 | Return 30 | Loop, Parse, keystroke,"" 31 | If (continue = A_Index) 32 | keystr := A_LoopField 33 | Loop, Parse, IsLabel,"" 34 | If (continue = A_Index) 35 | IsLabel := A_LoopField 36 | hotkey := RegExReplace(A_ThisHotkey, "[\*\~\$\#\+\!\^]") 37 | IfInString, hotkey, %A_Space% 38 | StringTrimLeft, hotkey,hotkey,% InStr(hotkey,A_Space,1,0) 39 | backspace := "{BS " times "}" 40 | keywait = Ctrl|Alt|Shift|LWin|RWin 41 | Loop, Parse, keywait, | 42 | KeyWait, %A_LoopField% 43 | If ((!IsLabel or (IsLabel and IsLabel(keystr))) and InStr(A_ThisHotkey, "~") and !RegExMatch(A_ThisHotkey 44 | , "i)\^[^\!\d]|![^\d]|#|Control|Ctrl|LCtrl|RCtrl|Shift|RShift|LShift|RWin|LWin|Alt|LAlt|RAlt|Escape|BackSpace|F\d\d?|" 45 | . "Insert|Esc|Escape|BS|Delete|Home|End|PgDn|PgUp|Up|Down|Left|Right|ScrollLock|CapsLock|NumLock|AppsKey|" 46 | . "PrintScreen|CtrlDown|Pause|Break|Help|Sleep|Browser_Back|Browser_Forward|Browser_Refresh|Browser_Stop|" 47 | . "Browser_Search|Browser_Favorites|Browser_Home|Volume_Mute|Volume_Down|Volume_Up|MButton|RButton|LButton|" 48 | . "Media_Next|Media_Prev|Media_Stop|Media_Play_Pause|Launch_Mail|Launch_Media|Launch_App1|Launch_App2")) 49 | Send % backspace 50 | If (WinExist("AHK_class #32768") and hotkey = "RButton") 51 | WinClose, AHK_class #32768 52 | If !IsLabel 53 | Send % keystr 54 | else if IsLabel(keystr) 55 | Gosub, %keystr% 56 | Return 57 | } 58 | Morse(timeout = 400) { ;by Laszo -> http://www.autohotkey.com/forum/viewtopic.php?t=16951 (Modified to return: KeyWait %key%, T%tout%) 59 | tout := timeout/1000 60 | key := RegExReplace(A_ThisHotKey,"[\*\~\$\#\+\!\^]") 61 | IfInString, key, %A_Space% 62 | StringTrimLeft, key, key,% InStr(key,A_Space,1,0) 63 | If Key in Shift,Win,Ctrl,Alt 64 | key1:="{L" key "}{R" key "}" 65 | Loop { 66 | t := A_TickCount 67 | KeyWait %key%, T%tout% 68 | Pattern .= A_TickCount-t > timeout 69 | If(ErrorLevel) 70 | Return Pattern 71 | If key in Capslock,LButton,RButton,MButton,ScrollLock,CapsLock,NumLock 72 | KeyWait,%key%,T%tout% D 73 | else if Asc(A_ThisHotkey)=36 74 | KeyWait,%key%,T%tout% D 75 | else 76 | Input,pressed,T%tout% L1 V,{%key%}%key1% 77 | If (ErrorLevel="Timeout" or ErrorLevel=1) 78 | Return Pattern 79 | else if (ErrorLevel="Max") 80 | Return 81 | } 82 | } -------------------------------------------------------------------------------- /src/Script.ahk: -------------------------------------------------------------------------------- 1 | ;@Ahk2Exe-SetMainIcon Script.ico 2 | ;@Ahk2Exe-Base Unicode 64* 3 | 4 | #Include 5 | #Include 6 | #Include 7 | #MaxThreadsBuffer, On 8 | SetBatchLines, -1 9 | SetWorkingDir, %A_ScriptDir% 10 | tray_init() 11 | 12 | global osd_obj:= new OSD("",1) 13 | , tts:= ComObjCreate("SAPI.SpVoice") 14 | osd_obj.setTheme("0A0E14") 15 | if(A_TickCount<40000) 16 | sleep 15000 17 | global spotify:= new SpotifyAPI() 18 | osd_obj.showAndHide("Connected to Spotify","1ED760",1) 19 | 20 | #Include, %A_ScriptDir%\hotkeys 21 | #Include, spotify.ahk 22 | #Include, valorant.ahk 23 | #Include, wt.ahk 24 | #Include, mouse.ahk 25 | #Include, speedtest.ahk 26 | #Include, clipboardSearch.ahk 27 | 28 | 29 | tray_init(){ 30 | Menu, Tray, NoStandard 31 | fObj:= Func("tray_toggleAutoStart") 32 | Menu, Tray, add, Start on boot, % fObj 33 | Menu, Tray, % tray_autoStartEnabled()? "Check" : "Uncheck", Start on boot 34 | fObj:= Func("tray_suspend") 35 | Menu, Tray, add, Suspend Hotkeys, % fObj 36 | fObj:= Func("tray_reload") 37 | Menu, Tray, add, Reload Script, % fObj 38 | fObj:= Func("tray_exit") 39 | Menu, Tray, add, Exit, % fObj 40 | } 41 | 42 | tray_reload(){ 43 | Reload 44 | } 45 | 46 | tray_suspend(){ 47 | Suspend, -1 48 | } 49 | 50 | tray_exit(){ 51 | ExitApp, 0 52 | } 53 | 54 | tray_toggleAutoStart(){ 55 | if(tray_autoStartEnabled()) 56 | RegDelete, HKCU\Software\Microsoft\Windows\CurrentVersion\Run, AHK_Script 57 | else 58 | RegWrite, REG_SZ, HKCU\Software\Microsoft\Windows\CurrentVersion\Run, AHK_Script, "%A_ScriptFullPath%" 59 | Menu, Tray, % tray_autoStartEnabled()? "Check" : "Uncheck", Start on boot 60 | } 61 | 62 | tray_autoStartEnabled(){ 63 | Try RegRead, val, HKCU\Software\Microsoft\Windows\CurrentVersion\Run, AHK_Script 64 | return val? 1 : 0 65 | } -------------------------------------------------------------------------------- /src/Script.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SaifAqqad/AHK_Script/2b3dfa445ed700d0975d79d4d7c3993c1c3cc321/src/Script.ico -------------------------------------------------------------------------------- /src/hotkeys/clipboardSearch.ahk: -------------------------------------------------------------------------------- 1 | ; copy and google the highlighted text 2 | !Space:: 3 | clipboard:="" 4 | SendInput {CTRLDOWN}c{CTRLUP} 5 | ClipWait, 1 6 | if(clipboard){ 7 | txt:= UrlEncode(clipboard) 8 | Run https://www.google.com/search?hl=en&q=%txt%,, UseErrorLevel 9 | }else 10 | osd_obj.showAndHide("Search failed",,2) 11 | Return 12 | 13 | ; https://autohotkey.com/board/topic/35660-url-encoding-function/ 14 | UrlEncode( String ){ 15 | OldFormat := A_FormatInteger 16 | SetFormat, Integer, H 17 | 18 | Loop, Parse, String 19 | { 20 | if A_LoopField is alnum 21 | { 22 | Out .= A_LoopField 23 | continue 24 | } 25 | Hex := SubStr( Asc( A_LoopField ), 3 ) 26 | Out .= "%" . ( StrLen( Hex ) = 1 ? "0" . Hex : Hex ) 27 | } 28 | SetFormat, Integer, %OldFormat% 29 | return Out 30 | } -------------------------------------------------------------------------------- /src/hotkeys/mouse.ahk: -------------------------------------------------------------------------------- 1 | ; mouse right scroll button 2 | F22::WheelRight 3 | 4 | ; mouse left scroll button 5 | F23::WheelLeft 6 | 7 | ; under-mouse button 8 | F24:: 9 | WinGet, active_pid, PID , A 10 | Process, Close, %active_pid% 11 | return -------------------------------------------------------------------------------- /src/hotkeys/speedtest.ahk: -------------------------------------------------------------------------------- 1 | F7:: 2 | WinKill, ahk_exe speedtest.exe 3 | Run, speedtest.exe 4 | return 5 | -------------------------------------------------------------------------------- /src/hotkeys/spotify.ahk: -------------------------------------------------------------------------------- 1 | DetectHiddenWindows, On 2 | Global SPOTIFY_EXE:= "Spotify.exe" 3 | 4 | get the PID 33 | WinGet, sPID, PID , ahk_exe %SPOTIFY_EXE% 34 | if(!sPID){ ; if not, run spotify 35 | Run, % getSpotifyFullPath() , %A_AppData%,, sPID 36 | WinWait, ahk_exe %SPOTIFY_EXE%,, 5 37 | WinShow, ahk_exe %SPOTIFY_EXE% 38 | } 39 | WinActivate, ahk_exe %SPOTIFY_EXE% 40 | return 1 41 | } Catch { 42 | return 0 43 | } 44 | } 45 | 46 | getSpotifyFullPath(){ 47 | p_path:= A_Args[1] 48 | if(!p_path){ 49 | ; works regardless of where spotify is installed 50 | RegRead, p_path, HKCR\spotify\shell\open\command 51 | SplitPath, p_path,, p_path 52 | p_path:= StrReplace(p_path, """") "\" SPOTIFY_EXE 53 | } 54 | return p_path 55 | } 56 | 57 | showPlaying(){ 58 | Try { 59 | track:= spotify.GetCurrentTrackInfo() 60 | osd_obj.showAndHide(track.item.artists[1].name " - " track.item.name,"1ED760",2) 61 | } 62 | } -------------------------------------------------------------------------------- /src/hotkeys/valorant.ahk: -------------------------------------------------------------------------------- 1 | ; VALORANT hotkeys 2 | #If, WinActive("ahk_exe VALORANT-Win64-Shipping.exe") 3 | 4 | ;disable capslock,winkey 5 | *CapsLock:: 6 | *LWin:: 7 | Return 8 | 9 | #If -------------------------------------------------------------------------------- /src/hotkeys/voicemeeter.ahk: -------------------------------------------------------------------------------- 1 | ; mic gain limit 2 | vm.strip[2].gain_limit:= -10 3 | cMode:=0 4 | 5 | Volume_Up::osd_obj.showAndHide("A1 gain: " ++vm.bus[1].gain,1,2) 6 | Volume_Down::osd_obj.showAndHide("A1 gain: " --vm.bus[1].gain,0,2) 7 | 8 | 2 | OfficeToPDF 3 | 4 |

5 | Convert Office documents to PDF format 6 |

7 | 8 | ## Install using Scoop: 9 | 10 | 1. Install scoop.sh using powershell 11 | 12 | iwr -useb get.scoop.sh | iex 13 | 2. Add my bucket to scoop 14 | 15 | scoop bucket add utils https://github.com/SaifAqqad/utils.git 16 | 3. Install OfficeToPDF 17 | 18 | scoop install officetopdf 19 | 20 | ## Usage: 21 | 1. Select the files you want to convert. 22 | 2. Right click --> Send to --> PDF file. 23 | --------------------------------------------------------------------------------