Skip to content

Instantly share code, notes, and snippets.

@vysmaty
Created April 8, 2024 19:00
Show Gist options
  • Save vysmaty/4ec8e83a569a33ae1b66084736e03b08 to your computer and use it in GitHub Desktop.
Save vysmaty/4ec8e83a569a33ae1b66084736e03b08 to your computer and use it in GitHub Desktop.
TabsOnWheels v2: Switch browser (or other program's) tabs with your mouse wheel when hovering over the tab bar (and optionally address bar). Press Middle/Wheel Mouse Click to switch tabs from anywhere in the program.
; ---------------------------------------------------- ;
; TabsOnWheels v2 ;
; ---------------------------------------------------- ;
; https://gist.github.com/Chematronix/5d7e12f7e580652aac46dc8080906e4f
; Switch browser (or other program's) tabs with your mouse wheel when hovering over the tab bar (and optionally address bar).
; Press Middle/Wheel Mouse Click to switch tabs from anywhere in the program.
; If the target window is inactive when starting to scroll, it will be activated.
;
; Install https://www.autohotkey.com/ (Windows only) to run.
; To auto-start, copy the script or a shortcut to your
; Start Menu\Programs\Startup directory
; (%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup)
;
; Modify from https://gist.github.com/Chematronix/5d7e12f7e580652aac46dc8080906e4f Chematronix
; Converted to v2 by vysmaty
; Fix some issues when using the script that prevents middle mouse button click and drag.
; BUGS:
; Makes tabSwitchAnywhereKey trigger on release, not on click. That's bad for fast games. xD
; Sometimes the tab switch activates randomly
; It's also triggered when using mouse wheel in a web page's select menus, for some reason
#Requires AutoHotkey v2
; Area to enable tab wheel scroll. ~45 for tab bar, ~80 to include address bar
tabAreaHeight := 80
; If enabled: Press Middle/Wheel Mouse Click to switch tabs from anywhere in the program.
enable_tabSwitchAnywhereKey := true
; Key or button to enable tab scrolling anywhere in the program. RButton for right mouse button, MButton for Middle/Wheel button.
tabSwitchAnywhereKey := "MButton"
; If enabled: When the hotkey fires, its key's native function will not be blocked (hidden from the system). For example: When true, it does not limit the MButton in 3D modeling.
enable_tilde_AnywhereKey := true
; List of '"WindowClass", "Descriptions",' . Change a program's "Description" to False to disable it.
; Map Object: "Key", "Value",
enabledPrograms := Map()
enabledPrograms.__New(
; "WindowsClass", "Description"
"Chrome_WidgetWin_1", "Chrome,Chromium",
"MozillaWindowClass", "Firefox",
"Notepad++", "Notepad++",
"IEFrame", "Internet Explorer",
"0ApplicationFrameWindow", "Edge",
"AcrobatSDIWindow", "Adobe Acrobat DC Pro",
"CabinetWClass", "Windows Explorer",
"classFoxitReader", "Foxit",
"BricscadMainWindow", "Bricscad",
"Solitaire", False
)
; Because there are many Chrome-based programs and sometimes TabsOnWheels makes mischief in them. It is possible to give an exception for the process.
disabledPrograms := Map()
disabledPrograms.__New(
; "Process Name", "Description
"vivaldi.exe", "Vivaldi"
)
VERSION := 4
#Warn ; Detect common errors.
#SingleInstance force
#UseHook false ; Using the keyboard hook is usually preferred for hotkeys - but here we only need the mouse hook.
InstallMouseHook()
A_MaxHotkeysPerInterval := 1000 ; Avoids warning messages for high speed wheel users.
SendMode("Input") ; Recommended for new scripts due to its superior speed and reliability.
A_IconTip := "TabsOnWheels " . VERSION
TraySetIcon("imageres.dll","306")
if(enable_tabSwitchAnywhereKey)
{
; Set HotkeyAnywhereKey
if(enable_tilde_AnywhereKey)
{
HotkeyAnywhereKey := "~" tabSwitchAnywhereKey
}
else {
HotkeyAnywhereKey := tabSwitchAnywhereKey
}
; Register tabSwitchAnywhereKey to make it a prefix and prevent its normal behaviour
Hotkey(HotkeyAnywhereKey " & WheelUp", TabsOnWheels)
Hotkey(HotkeyAnywhereKey " & WheelDown", TabsOnWheels)
; Enable tabSwitchAnywhereKey when clicked by itself
Hotkey(HotkeyAnywhereKey, SendThisHotkey)
}
WheelUp::
WheelDown::
;RButton & WheelUp::
;RButton & WheelDown::
{
TabsOnWheels(ThisHotkey)
Return
}
SendThisHotkey(ThisHotkey)
{
Send("{" A_ThisHotkey "}")
Return
}
TabsOnWheels(ThisHotkey)
;; Compare mouse position on the screen with the window beneath
;; to check if we are in the tab area
{
CoordMode("Mouse", "Screen")
MouseGetPos(&mouseXPos, &mouseYPos, &winId)
WinGetPos(&winXPos, &winYPos, &winWidth, &winHeight, "ahk_id " winId)
winClass := WinGetClass("ahk_id " winId) ; Get Window class
winProcess := WinGetProcessName("ahk_id " winId) ; Get Process Name
; Check if we got an enabled class, and if pointer is over tab bar or tabSwitchAnywhereKey is pressed
If (enabledPrograms.Has(winClass) AND !disabledPrograms.Has(winProcess) AND ((enable_tabSwitchAnywhereKey AND GetKeyState(tabSwitchAnywhereKey, "P")) OR (mouseYPos > winYPos and mouseYPos < winYPos + tabAreaHeight)))
{
if !WinActive("ahk_id " winId)
WinActivate("ahk_id " winId) ; Focus target window
if (A_ThisHotkey ~= "^(?i:WheelUp|%tabSwitchAnywhereKey% & WheelUp)$")
Send("^+{Tab}")
Else
Send("^{Tab}")
}
Else
{
Send("{" A_ThisHotkey "}")
}
Return
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment