Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Chematronix/5d7e12f7e580652aac46dc8080906e4f to your computer and use it in GitHub Desktop.
Save Chematronix/5d7e12f7e580652aac46dc8080906e4f to your computer and use it in GitHub Desktop.
TabsOnWheels: 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 ;
; ---------------------------------------------------- ;
; 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)
;
; 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
; Area to enable tab wheel scroll. ~45 for tab bar, ~80 to include address bar
tabAreaHeight := 80
; Key or button to enable tab scrolling anywhere in the program. RButton for right mouse button, MButton for Middle/Wheel button.
tabSwitchAnywhereKey := "MButton"
; List of WindowClass: "Descriptions". Change a program's "Description" to False to disable it.
enabledPrograms := {Chrome_WidgetWin_1: "Chrome, Chromium", MozillaWindowClass: "Firefox", IEFrame: "Internet Explorer", ApplicationFrameWindow: "Edge", "Notepad++": "Notepad++", TMainForm: "HeidiSQL - heidisql.exe", "SunAwtFrame_NotWorking": "IntelliJ Idea - idea64.exe", AcrobatSDIWindow: "Adobe Acrobat DC Pro", Solitaire: False}
VERSION := 3
#NoEnv ; Disable using enviroment variables without calling EnvGet(), for performance.
#Warn ; Detect common errors.
#SingleInstance force
#UseHook Off ; Using the keyboard hook is usually preferred for hotkeys - but here we only need the mouse hook.
#InstallMouseHook
#MaxHotkeysPerInterval 1000 ; Avoids warning messages for high speed wheel users.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
Menu, Tray, Tip, TabsOnWheels %VERSION%
Menu, Tray, Icon, imageres.dll, 306
; Register tabSwitchAnywhereKey to make it a prefix and prevent its normal behaviour
Hotkey, %tabSwitchAnywhereKey% & WheelUp, TabsOnWheels
Hotkey, %tabSwitchAnywhereKey% & WheelDown, TabsOnWheels
; Enable tabSwitchAnywhereKey when clicked by itself
Hotkey, %tabSwitchAnywhereKey%, SendThisHotkey
WheelUp::
WheelDown::
;RButton & WheelUp::
;RButton & WheelDown::
Gosub TabsOnWheels
Return
SendThisHotkey:
Send {%A_ThisHotkey%}
Return
TabsOnWheels:
;; 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%
WinGetClass, winClass, ahk_id %winId% ; Get Window class
; Check if we got an enabled class, and if pointer is over tab bar or tabSwitchAnywhereKey is pressed
If (enabledPrograms.hasKey(winClass) AND (GetKeyState(tabSwitchAnywhereKey, "P") OR (mouseYPos > winYPos and mouseYPos < winYPos + tabAreaHeight)))
{
IfWinNotActive ahk_id %winId%
WinActivate ahk_id %winId% ; Focus target window
If A_ThisHotkey in WheelUp,%tabSwitchAnywhereKey% & WheelUp
Send ^+{Tab}
Else
Send ^{Tab}
}
Else
{
Send {%A_ThisHotkey%}
}
Return
@SkullHex2
Copy link

Can you add support to AutoHotKey v2.0?

@vysmaty
Copy link

vysmaty commented Apr 8, 2024

I don't know if I missed some fix from @sd016808 – now that I'm looking at it.

But here is the modified version for v2 and some conditions for running. Disabling MButton completely or not blocking it. + Vivaldi:

https://gist.github.com/vysmaty/4ec8e83a569a33ae1b66084736e03b08

And thanks a lot @Chematronix !

@Chematronix
Copy link
Author

Chematronix commented Apr 14, 2024 via email

@vysmaty
Copy link

vysmaty commented Apr 20, 2024

I could move this to an actual repo, to facilitate merging. What's good about AHK v2? All my scripts are still v1 and w

Repo sounds like a good idea. I'm still getting the hang of repos, but it's kind of working for me.

I don't really know what advantages to disadvantages AHK v2 has. It seems to me that everything is like a function or object in AHK v2 and it's somehow more consistent. But for me scripting is just a hobby, so what i now?

I solved running both v1 and v2 by: AHK Startup v2. The author converted it into a new version. Without that I wouldn't go into v2 at all. After all, autohotkey is a set of tools for me to work with and I will not break my workflow unnecessarily. https://www.autohotkey.com/boards/viewtopic.php?f=83&t=120981&p=536860&hilit=AHK+Startup#p536860

You can use for conversion to v2 https://github.com/mmikeww/AHK-v2-script-converter , but anyway, one ends up in docs wondering what the replacement for some function is... and fiddling around in arrays -> maps -> objects.

So I've taken things one at a time from simple. I tweaked a few things here and there, and when it looked like it would be better not to dig into it, I left it in v1. AHK Startup has been a god thing for me for years and one doesn't really have to worry about it too much.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment