├── .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 |
--------------------------------------------------------------------------------