├── .gitattributes ├── AutomaticWindowManager.ahk ├── Hotkeys.ahk ├── Includes ├── FuncFunctions.ahk └── StartUp.ahk └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto -------------------------------------------------------------------------------- /AutomaticWindowManager.ahk: -------------------------------------------------------------------------------- 1 | ; Automatically Restore Previous Window Size/Pos 2 | 3 | #SingleInstance Force 4 | #Persistent 5 | #NoEnv 6 | #NoTrayIcon 7 | SetWinDelay, 50 8 | Process, Priority, , Normal 9 | DetectHiddenWindows, Off 10 | 11 | #Include *i %A_ScriptDir%\Includes\StartUp.ahk 12 | 13 | MatchList := "" 14 | 15 | ; Build the MatchList 16 | WinGet, id, list,,, Program Manager 17 | Loop, %id% 18 | { 19 | this_id := id%A_Index% 20 | if (MatchList = "") 21 | MatchList := this_id 22 | else 23 | MatchList := MatchList . "," . this_id 24 | } 25 | 26 | ; ExclusionList 27 | ExclusionList = ShellExperienceHost.exe,SearchUI.exe 28 | 29 | ; The main program loop, which manages window positions/sizes and saves their last known configuration to an ini file in the script directory. 30 | Loop, 31 | { 32 | Sleep, 350 33 | WinGet, active_id, ID, A 34 | OwnerID := DllCall("GetWindow", "uint", active_id, "uint", "4") ; GW_OWNER = 4 35 | if (OwnerID <> 0) { 36 | continue 37 | } 38 | if active_id not in %MatchList% ; Then this is a new window ID! So, check if it has a configuration saved. 39 | { 40 | MatchList := MatchList . "," . active_id ; This window ID is not new anymore! 41 | WinGet, AProcessName, ProcessName, A 42 | WinGetClass, AClass, A 43 | WinGet, AStyle, Style, A 44 | WinGet, AExStyle, ExStyle, A 45 | IniRead, savedSizePos, %A_ScriptDir%\WindowSizePosLog.ini, Process Names, %AProcessName%%AClass%%AStyle%%AExStyle% 46 | if (savedSizePos != "ERROR" AND AClass != "MultitaskingViewFrame" AND AClass != "Shell_TrayWnd") ; Then a saved configuration exists, size/move the window! 47 | { 48 | StringSplit OutputArray, savedSizePos,`, 49 | if (AProcessName = "explorer.exe" AND AClass != "CabinetWClass") 50 | { 51 | 52 | } 53 | else 54 | { 55 | WinMove, A,, OutputArray1, OutputArray2, OutputArray3, OutputArray4 56 | } 57 | } 58 | else ; No saved configuration exists, save the current window size/pos as a configuration instead! 59 | { 60 | WinGetPos X, Y, Width, Height, A 61 | WinGet, AProcessName, ProcessName, A 62 | WinGetClass, AClass, A 63 | WinGet, AStyle, Style, A 64 | WinGet, AExStyle, ExStyle, A 65 | WinGet, WinState, MinMax, ahk_class A 66 | If (WinState == -1) { 67 | Continue 68 | } 69 | If (X != "" AND Y != "" AND Width != "" AND Height != "" AND Width > 0 AND Height > 0 AND AClass != "MultitaskingViewFrame" AND AClass != "Shell_TrayWnd") 70 | { 71 | if (AProcessName = "explorer.exe" AND AClass != "CabinetWClass") 72 | { 73 | 74 | } 75 | else if AProcessName not in %ExclusionList% 76 | { 77 | IniWrite %X%`,%Y%`,%Width%`,%Height%, %A_ScriptDir%\WindowSizePosLog.ini, Process Names, %AProcessName%%AClass%%AStyle%%AExStyle% 78 | } 79 | } 80 | } 81 | } 82 | else ; Save/overwrite the active window size and position to a file with a link to the processname, for later use. 83 | { 84 | WinGetPos X, Y, Width, Height, A 85 | WinGet, AProcessName, ProcessName, A 86 | WinGetClass, AClass, A 87 | WinGet, AStyle, Style, A 88 | WinGet, AExStyle, ExStyle, A 89 | WinGet, WinState, MinMax, A 90 | If (WinState == -1) { 91 | Continue 92 | } 93 | If (X != "" AND Y != "" AND Width != "" AND Height != "" AND Width > 0 AND Height > 0 AND AClass != "MultitaskingViewFrame" AND AClass != "Shell_TrayWnd") 94 | { 95 | if (AProcessName = "explorer.exe" AND AClass != "CabinetWClass") 96 | { 97 | 98 | } 99 | else if AProcessName not in %ExclusionList% 100 | { 101 | IniWrite %X%`,%Y%`,%Width%`,%Height%, %A_ScriptDir%\WindowSizePosLog.ini, Process Names, %AProcessName%%AClass%%AStyle%%AExStyle% 102 | } 103 | } 104 | } 105 | } 106 | Return 107 | -------------------------------------------------------------------------------- /Hotkeys.ahk: -------------------------------------------------------------------------------- 1 | #SingleInstance Force 2 | #Persistent 3 | #NoTrayIcon 4 | #InstallKeybdHook 5 | #InstallMouseHook 6 | 7 | #Include *i %A_ScriptDir%\Includes\StartUp.ahk 8 | #Include %A_ScriptDir%\Includes\FuncFunctions.ahk 9 | 10 | Return 11 | 12 | SelectModeTimer: 13 | SetTimer, SelectModeTimer, Off 14 | If (DetectContextMenu() = 1) OR (WinExist("ahk_class Chrome_WidgetWin_2") AND WinActive("ahk_exe chrome.exe")) 15 | { 16 | SetTimer, SelectModeTimer, On 17 | } 18 | else 19 | { 20 | SelectMode := 0 21 | } 22 | Return 23 | 24 | ~LWin:: 25 | if !Triggered 26 | { 27 | TimeNow := A_TickCount 28 | Triggered := 1 29 | } 30 | Return 31 | 32 | ~LCtrl:: 33 | if !Triggered 34 | { 35 | TimeNow := A_TickCount 36 | Triggered := 1 37 | } 38 | Return 39 | 40 | ~LShift:: 41 | if !Triggered 42 | { 43 | TimeNow := A_TickCount 44 | Triggered := 1 45 | } 46 | Return 47 | 48 | ~LWin Up:: 49 | if (A_PriorKey = "Lwin") and (TimeNow > 0) and (A_TickCount - TimeNow < 250) { 50 | Run, explorer.exe 51 | WinWaitActive, ahk_class CabinetWClass, , 2 52 | Send {LCtrl Down}{LShift Down}6{LShift Up}{LCtrl Up} ; Set the view type to details 53 | Send {F3} ; Set the search bar to have focus 54 | } 55 | Triggered := 0 56 | Return 57 | 58 | ~LCtrl Up:: 59 | if (A_PriorKey = "LControl") and (TimeNow > 0) and (A_TickCount - TimeNow < 250) { 60 | Run, % DefaultBrowser() 61 | } 62 | Triggered := 0 63 | Return 64 | 65 | ~LShift Up:: 66 | if (A_PriorKey = "LShift") and (TimeNow > 0) and (A_TickCount - TimeNow < 250) { 67 | If (DetectContextMenu() = 1) OR (WinExist("ahk_class Chrome_WidgetWin_2") AND WinActive("ahk_exe chrome.exe")) 68 | Send {LAlt} 69 | Else 70 | Send {AppsKey} ; Context menu 71 | } 72 | Triggered := 0 73 | Return 74 | 75 | *~LButton:: 76 | *~RButton:: 77 | *~MButton:: 78 | *~XButton1:: 79 | *~XButton2:: 80 | *~WheelDown:: 81 | *~WheelUp:: 82 | *~WheelLeft:: 83 | *~WheelRight:: 84 | TimeNow := 0 85 | Return 86 | 87 | #If (DetectContextMenu() = 1) OR (WinExist("ahk_class Chrome_WidgetWin_2") AND WinActive("ahk_exe chrome.exe")) 88 | 89 | WheelUp:: 90 | Send, {Up} 91 | SelectMode := 1 92 | SetTimer, SelectModeTimer, -15 93 | Return 94 | 95 | WheelDown:: 96 | Send, {Down} 97 | SelectMode := 1 98 | SetTimer, SelectModeTimer, -15 99 | Return 100 | 101 | $LButton:: 102 | If (SelectMode = 1) 103 | Send, {Enter} 104 | Else 105 | Send, {LButton} 106 | Return 107 | 108 | $RButton:: 109 | If (SelectMode = 1) 110 | Send, {Esc} 111 | Else 112 | Send, {RButton} 113 | Return 114 | 115 | #If 116 | -------------------------------------------------------------------------------- /Includes/FuncFunctions.ahk: -------------------------------------------------------------------------------- 1 | DefaultBrowser() { 2 | ; Find the Registry key name for the default browser 3 | RegRead, BrowserKeyName, HKEY_CURRENT_USER, Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.html\UserChoice, Progid 4 | 5 | ; Find the executable command associated with the above Registry key 6 | RegRead, BrowserFullCommand, HKEY_CLASSES_ROOT, %BrowserKeyName%\shell\open\command 7 | 8 | ; The above RegRead will return the path and executable name of the brower contained within quotes and optional parameters 9 | ; We only want the text contained inside the first set of quotes which is the path and executable 10 | ; Find the ending quote position (we know the beginning quote is in position 0 so start searching at position 1) 11 | StringGetPos, pos, BrowserFullCommand, ",,1 12 | 13 | ; Decrement the found position by one to work correctly with the StringMid function 14 | pos := --pos 15 | 16 | ; Extract and return the path and executable of the browser 17 | StringMid, BrowserPathandEXE, BrowserFullCommand, 2, %pos% 18 | Return BrowserPathandEXE 19 | } 20 | 21 | DetectContextMenu() { 22 | ; based on closeContextMenu() by Stefaan - http://www.autohotkey.com/community/viewtopic.php?p=163183#p163183 23 | GuiThreadInfoSize = 48 24 | VarSetCapacity(GuiThreadInfo, 48) 25 | NumPut(GuiThreadInfoSize, GuiThreadInfo, 0) 26 | if not DllCall("GetGUIThreadInfo", uint, 0, str, GuiThreadInfo) 27 | { 28 | MsgBox GetGUIThreadInfo() indicated a failure. 29 | return 30 | } 31 | ; GuiThreadInfo contains a DWORD flags at byte 4 32 | ; Bit 4 of this flag is set if the thread is in menu mode. GUI_INMENUMODE = 0x4 33 | if (NumGet(GuiThreadInfo, 4) & 0x4) 34 | Return 1 ; we've found a context menu 35 | Else 36 | Return 0 37 | } 38 | -------------------------------------------------------------------------------- /Includes/StartUp.ahk: -------------------------------------------------------------------------------- 1 | if not A_IsAdmin 2 | { 3 | Run *RunAs "%A_ScriptFullPath%" 4 | ExitApp 5 | } 6 | 7 | ;RegDelete, HKEY_LOCAL_MACHINE, SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run, "%A_ScriptName%" 8 | 9 | RegRead, OutputVar, HKEY_LOCAL_MACHINE, SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run, "%A_ScriptName%" 10 | if errorlevel 11 | { 12 | msgbox, 4, , Do you want this script to run automatically at startup? 13 | IfMsgBox, Yes 14 | { 15 | RegWrite, REG_SZ, HKEY_LOCAL_MACHINE, SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run, "%A_ScriptName%", "C:\Program Files\AutoHotkey\AutoHotkey.exe" "%A_ScriptFullPath%" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AHK-Windows-Enhancement 2 | AutoHotKey scripts to improve windows, the windows explorer, and the windows task switcher for windows 10. 3 | 4 | Current functionality: 5 | * **AutomaticWindowManager.ahk:** 6 | * Automatically remembers the last window position for snapped windows, even after a restart, based on the process name. 7 | 8 | * **Hotkeys.ahk:** 9 | * Single-modifier-key-press hotkeys are used to prevent users from having to memorize hotkey combinations. Measures were taken to prevent the single-modifier-key-press hotkeys from misfiring. If the press is too long, or if keyboard activity or mouse button/wheel/pad activity happens during the key press, the script will not do anything put pass the key to the system as normal. 10 | * Quickly pressing and releasing the LeftWin key (must not be a longer than 250 ms press) brings up a new explorer window to its default starting location (such as Quick Access), the script changes the view in the explorer window to "Detail" view, and puts the keyboard focus on the search-bar. Together with an indexed drive, this is used to search the local filesystem; it is intended to do the same thing as Everything by VoidTools, except with the ability to move/copy files, preview files, use the navigation sidebar, and all of the other features of Explorer. 11 | * Quickly pressing and releasing the LeftCtrl key (must not be a longer than 250 ms press) brings up a new browser window using your default browser at your default browser start page. This is intended to use the Google or Bing search engine, so that it can also be used for a quick calculator which handles units such as feet and inches. 12 | * Quickly pressing and releasing the LeftShift key (must not be a longer than 250 ms press) brings up a the context menu for the active window. Pressing the LeftShift key again will close the context menu. This allows a user to do things in Explorer such as cut/copy files without having to memorize hotkey combinations and without using the mouse. Simply press LeftShift, then use the arrow keys to navigate the menu, finally use the enter key to make a selection. 13 | * When a context menu is open, this script detects it and allows you to use your mouse wheel to go up and down the menu items, as if you were using the up/down arrow keys. After using the scroll wheel on a menu the left mouse button will then function as an enter key, and the right mouse button will function as an escape key, allowing you to choose menu items, enter a nested menu item, or close a nested menu item, or close the parent menu itself. This allows you to navigate context menus by using the mouse wheel and mouse buttons without the need to move the mouse at all. However, if you don't use the mouse wheel when a context menu opens, you can still left click outside the menu to close it. 14 | 15 | * **FuncFunctions.ahk:** 16 | * All functions are kept in this file so they can be #Included across all other script files without having to redefine functions in each script. 17 | 18 | * **StartUp.ahk:** 19 | * When #Included in another script, this will ask the user if they want to add the script they are opening to the windows start up, so they don't have to manually run the script after each system reboot. 20 | 21 | 22 | To-do: 23 | * **Windows Explorer:** Add 'Copy to folder..' and 'Move to folder..' options to the context menu of windows explorer, which each call a respective AHK script. The AHK script should show a filesave/fileopen style dialog allowing the user to navigate to a target folder, then once a target path is specified, the AHK script will either cut the active selection in windows explorer in the case of 'move to folder' and then navigate to the saved target path, paste, then navigate back to the original location in windows explorer. In the case of 'Copy to folder..', the AHK script should merely copy the selection not cut it, and repeat the steps above.** I'm aware that there exists a registry hack to implement something similar to this, but not only does it cause bugs such as the dialog popping up when you double click an outlook attachment, it also uses an inferior dialog compared to the fileopen or filesave type dialogs.** 24 | 25 | 26 | * **Windows Explorer:** Automatically choose 'size all columns to fit' when search results update or you navigate to a new folder, or when explorer first opens (Only if the 'details' view is active). This should not change the users mouse position or interfere with the user in any way. This should also trigger when the window is resized. 27 | 28 | 29 | * **Windows Explorer:** Automatically size the preview pane to occupy all but a thin margin of space from the last column when the 'details' view is active, this will be dependent on window size and should also trigger when the window is resized. If the explorer window is below a certain size, automatically turn off the preview pane. If the explorer window size becomes large enough to allow a preview pane + fit all of the columns on screen, turn on the preview pane. 30 | 31 | 32 | * **Windows Explorer:** Automatically set the keyboard focus to the windows explorer search box (hotkey F3) when explorer becomes active by other than mouse click (if explorer is just created, or if you alt-tab to it, etc, the search should have focus, otherwise, wherever the user clicks should have focus in the case of them clicking into an existing explorer window, which is the default behavior) 33 | 34 | 35 | * **Windows Explorer:** One-key press (LWin), with no mouse actions or key actions during the Lwin key press should WinActivate an existing explorer window or create a new explorer window if one does not already exist (put keyboard focus on the explorer search bar in both cases) 36 | 37 | 38 | * **Windows Explorer:** Change default search result view to "Details" not "Content" 39 | 40 | 41 | * **Windows Explorer:** Explorer automatically selects the first file when you enter a directory 42 | 43 | 44 | * **Windows Explorer:** Shift+F10 shows the context menu by default, make a single Shift key pressed alone (no mouse button during the shift keypress) show the context menu as well 45 | 46 | 47 | * **Windows Explorer:** Scroll explorer scrollbars when mouse over them even when they are not focused 48 | 49 | 50 | * **Windows Explorer:** Automatically choose 'apply to all further operations' in file operations (such as file replace). 51 | 52 | 53 | * **Windows Explorer/Desktop:** Open with.. > Choose another app should immediately go to the fileopen dialog 54 | 55 | 56 | * **Windows Dialogs:** Autocomplete filenames and paths with TAB in file dialogs 57 | 58 | 59 | * **Windows Dialogs:** Add Favorite folders, recent folders, and recent files shortcuts in standard filesave/fileopen dialogs. 60 | 61 | 62 | * **Window manager:** Automatically make new windows completely visible on the screen (in case they open partially off-screen), automatically make existing windows that now have focus completely visible on screen as well. 63 | 64 | 65 | * **Window manager:** Automatically resize adjacent snapped window when dragging edge of another snapped window. 66 | 67 | 68 | * **Window manager:** Automatically remember last known window position (even snapped positions) and restore them when that application is opened again. 69 | 70 | 71 | * **Download manager:** Automatically extract newly downloaded archives to folder of the same name as the archive and delete the archive (move to recycle bin) 72 | 73 | 74 | * **Browser/Calculator:** One-key press (LCtrl) with no other mouse or keyboard actions opens default browser. Automatically copy mathematical results from bing/google search result to clipboard, even before Enter key is pressed if calculation is detected in the address bar or omnibar. Detect calculation by existence of the calculation result. Browser calculator is superior to desktop calculator because it allows unit conversions and various units to be used in the calculation, it also allows more flexible language input (Example: 5 feet 2 inches + 6.5 feet). 75 | 76 | 77 | * **Alt+Tab replacement:** 78 | Mouse Hotkey: MiddleMouseButton+RightMouseButton 79 | Keyboard Hotkey: Alt 80 | Should show a ListView of existing windows in the center of the screen, the top window should be the last activated window besides the current active window, and selected by default. The second listing should be the active window, and from then on windows should be listed alphabetically. 81 | Mouse interaction: Scroll wheel moves listview selection up/dn, LeftMouseButton (single-click) hides the UI and that window is activated. Right click hides the UI at any time and no window switch is performed. 82 | Keybourd interaction: Up/down arrow keys moves the listview selection up/dn, Tab key moves the listview selecton down, Shift+Tab moves the listview selection up. Enter key or Space key hides the UI and that window is activated. Esc key hides the UI at any time and no window switch is performed. 83 | 84 | Known bugs/issues: 85 | * **AutomaticWindowManager.ahk:** 86 | * Rarely increases size of dialog windows 87 | * Small delay before moving window to last known position 88 | --------------------------------------------------------------------------------