From c09979d51169c9f84a85429c6c9960fe03dbfef1 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
Date: Thu, 21 Nov 2024 19:38:55 +0000
Subject: [PATCH] deploy: 7fb455e856a1d5067bae96a727cd1e27a6af9ff3
---
catalog.json | 6 +-
changelogs/chrome-wheel-scroll-tabs.md | 5 +
mods/chrome-wheel-scroll-tabs.wh.cpp | 140 ++++++++++++++++++++-----
updates.atom | 29 ++---
4 files changed, 135 insertions(+), 45 deletions(-)
diff --git a/catalog.json b/catalog.json
index bfacf7b30..8e63056ef 100644
--- a/catalog.json
+++ b/catalog.json
@@ -265,13 +265,13 @@
"published": 1646604429000,
"rating": 10,
"ratingUsers": 57,
- "updated": 1672509589000,
+ "updated": 1732217907000,
"users": 4510
},
"featured": true,
"metadata": {
"author": "m417z",
- "compilerOptions": "-lcomctl32",
+ "compilerOptions": "-lcomctl32 -lgdi32",
"description": "Use the mouse wheel while hovering over the tab bar to switch between tabs",
"github": "https://github.com/m417z",
"homepage": "https://m417z.com/",
@@ -283,7 +283,7 @@
],
"name": "Chrome/Edge scroll tabs with mouse wheel",
"twitter": "https://twitter.com/m417z",
- "version": "1.0.3"
+ "version": "1.1"
}
},
"classic-browser-fix": {
diff --git a/changelogs/chrome-wheel-scroll-tabs.md b/changelogs/chrome-wheel-scroll-tabs.md
index ee2b2f7bc..e81ff7a5e 100644
--- a/changelogs/chrome-wheel-scroll-tabs.md
+++ b/changelogs/chrome-wheel-scroll-tabs.md
@@ -1,3 +1,8 @@
+## 1.1 ([Nov 21, 2024](https://github.com/ramensoftware/windhawk-mods/blob/7fb455e856a1d5067bae96a727cd1e27a6af9ff3/mods/chrome-wheel-scroll-tabs.wh.cpp))
+
+* Added an option to switch between tabs when the mouse's horizontal scroll wheel is tilted or rotated.
+* Fixed the border around the web content in Edge triggering the tab scrolling.
+
## 1.0.3 ([Dec 31, 2022](https://github.com/ramensoftware/windhawk-mods/blob/c323dbab16d3ed2e63b923a87b325278ff43e767/mods/chrome-wheel-scroll-tabs.wh.cpp))
* Fix scrolling in Edge with the find bar open.
diff --git a/mods/chrome-wheel-scroll-tabs.wh.cpp b/mods/chrome-wheel-scroll-tabs.wh.cpp
index 7016717f0..fd246eb12 100644
--- a/mods/chrome-wheel-scroll-tabs.wh.cpp
+++ b/mods/chrome-wheel-scroll-tabs.wh.cpp
@@ -2,7 +2,7 @@
// @id chrome-wheel-scroll-tabs
// @name Chrome/Edge scroll tabs with mouse wheel
// @description Use the mouse wheel while hovering over the tab bar to switch between tabs
-// @version 1.0.3
+// @version 1.1
// @author m417z
// @github https://github.com/m417z
// @twitter https://twitter.com/m417z
@@ -11,9 +11,17 @@
// @include msedge.exe
// @include opera.exe
// @include brave.exe
-// @compilerOptions -lcomctl32
+// @compilerOptions -lcomctl32 -lgdi32
// ==/WindhawkMod==
+// Source code is published under The GNU General Public License v3.0.
+//
+// For bug reports and feature requests, please open an issue here:
+// https://github.com/ramensoftware/windhawk-mods/issues
+//
+// For pull requests, development takes place here:
+// https://github.com/m417z/my-windhawk-mods
+
// ==WindhawkModReadme==
/*
# Chrome/Edge scroll tabs with mouse wheel
@@ -30,15 +38,23 @@ Currently supported browsers: Google Chrome, Microsoft Edge, Opera, Brave.
/*
- reverseScrollingDirection: false
$name: Reverse Scrolling Direction
+- horizontalScrolling: false
+ $name: Horizontal scrolling
+ $description: >-
+ Switch between tabs when the mouse's horizontal scroll wheel is tilted or
+ rotated
*/
// ==/WindhawkModSettings==
#include
+#include
struct {
bool reverseScrollingDirection;
+ bool horizontalScrolling;
} g_settings;
+bool g_isEdge;
DWORD g_uiThreadId;
DWORD g_lastScrollTime;
HWND g_lastScrollWnd;
@@ -56,6 +72,32 @@ struct SET_WINDOW_SUBCLASS_FROM_ANY_THREAD_PARAM {
BOOL result;
};
+UINT GetDpiForWindowWithFallback(HWND hWnd) {
+ using GetDpiForWindow_t = UINT(WINAPI*)(HWND hwnd);
+ static GetDpiForWindow_t pGetDpiForWindow = []() {
+ HMODULE hUser32 = GetModuleHandle(L"user32.dll");
+ if (hUser32) {
+ return (GetDpiForWindow_t)GetProcAddress(hUser32,
+ "GetDpiForWindow");
+ }
+
+ return (GetDpiForWindow_t) nullptr;
+ }();
+
+ UINT dpi = 96;
+ if (pGetDpiForWindow) {
+ dpi = pGetDpiForWindow(hWnd);
+ } else {
+ HDC hdc = GetDC(nullptr);
+ if (hdc) {
+ dpi = GetDeviceCaps(hdc, LOGPIXELSX);
+ ReleaseDC(nullptr, hdc);
+ }
+ }
+
+ return dpi;
+}
+
LRESULT CALLBACK CallWndProcForWindowSubclass(int nCode,
WPARAM wParam,
LPARAM lParam) {
@@ -97,26 +139,56 @@ BOOL SetWindowSubclassFromAnyThread(HWND hWnd,
param.uIdSubclass = uIdSubclass;
param.dwRefData = dwRefData;
param.result = FALSE;
- SendMessage(hWnd, g_subclassRegisteredMsg, TRUE, (WPARAM)¶m);
+ SendMessage(hWnd, g_subclassRegisteredMsg, TRUE, (LPARAM)¶m);
UnhookWindowsHookEx(hook);
return param.result;
}
-bool OnMouseWheel(HWND hWnd, short delta) {
+bool OnMouseWheel(HWND hWnd, WORD keys, short delta, int xPos, int yPos) {
+ if (keys) {
+ return false;
+ }
+
+ switch (SendMessage(hWnd, WM_NCHITTEST, 0, MAKELPARAM(xPos, yPos))) {
+ case HTCLIENT:
+ case HTCAPTION:
+ case HTSYSMENU:
+ case HTMINBUTTON:
+ case HTMAXBUTTON:
+ case HTCLOSE:
+ break;
+
+ default:
+ return false;
+ }
+
HWND hForegroundWnd = GetForegroundWindow();
if (!hForegroundWnd || GetAncestor(hForegroundWnd, GA_ROOTOWNER) != hWnd) {
g_lastScrollWnd = nullptr;
return false;
}
- if (GetKeyState(VK_CONTROL) < 0 || GetKeyState(VK_MENU) < 0 ||
- GetKeyState(VK_SHIFT) < 0 || GetKeyState(VK_PRIOR) < 0 ||
+ if (GetKeyState(VK_MENU) < 0 || GetKeyState(VK_LWIN) < 0 ||
+ GetKeyState(VK_RWIN) < 0 || GetKeyState(VK_PRIOR) < 0 ||
GetKeyState(VK_NEXT) < 0) {
return false;
}
+ // Edge has a thin border around the web content which triggers the tab
+ // scrolling. Ignore events which are very close to the window borders.
+ if (g_isEdge) {
+ UINT dpi = GetDpiForWindowWithFallback(hWnd);
+ RECT rect{};
+ GetWindowRect(hWnd, &rect);
+ if (MulDiv(xPos - rect.left, 96, dpi) <= 15 ||
+ MulDiv(rect.right - xPos, 96, dpi) <= 15 ||
+ MulDiv(rect.bottom - yPos, 96, dpi) <= 15) {
+ return false;
+ }
+ }
+
if (hWnd == g_lastScrollWnd &&
GetTickCount() - g_lastScrollTime < 1000 * 5) {
delta += g_lastScrollDeltaRemainder;
@@ -125,18 +197,14 @@ bool OnMouseWheel(HWND hWnd, short delta) {
int clicks = delta / WHEEL_DELTA;
Wh_Log(L"%d clicks (delta=%d)", clicks, delta);
- if (g_settings.reverseScrollingDirection) {
- clicks = -clicks;
- }
-
- WORD key = VK_PRIOR;
+ WORD key = VK_NEXT;
if (clicks < 0) {
clicks = -clicks;
- key = VK_NEXT;
+ key = VK_PRIOR;
}
INPUT* input = new INPUT[clicks * 2 + 2];
- for (size_t i = 0; i < clicks * 2 + 2; i++) {
+ for (int i = 0; i < clicks * 2 + 2; i++) {
input[i].type = INPUT_KEYBOARD;
input[i].ki.wScan = 0;
input[i].ki.time = 0;
@@ -146,7 +214,7 @@ bool OnMouseWheel(HWND hWnd, short delta) {
input[0].ki.wVk = VK_CONTROL;
input[0].ki.dwFlags = 0;
- for (size_t i = 0; i < clicks; i++) {
+ for (int i = 0; i < clicks; i++) {
input[1 + i * 2].ki.wVk = key;
input[1 + i * 2].ki.dwFlags = 0;
input[1 + i * 2 + 1].ki.wVk = key;
@@ -173,26 +241,39 @@ LRESULT CALLBACK BrowserWindowSubclassProc(_In_ HWND hWnd,
_In_ LPARAM lParam,
_In_ UINT_PTR uIdSubclass,
_In_ DWORD_PTR dwRefData) {
+ if (uMsg == WM_NCDESTROY || (uMsg == g_subclassRegisteredMsg && !wParam)) {
+ RemoveWindowSubclass(hWnd, BrowserWindowSubclassProc, 0);
+ }
+
switch (uMsg) {
case WM_MOUSEWHEEL:
- switch (SendMessage(hWnd, WM_NCHITTEST, 0, lParam)) {
- case HTCLIENT:
- case HTCAPTION:
- case HTSYSMENU:
- case HTMINBUTTON:
- case HTMAXBUTTON:
- case HTCLOSE:
- if (OnMouseWheel(hWnd, GET_WHEEL_DELTA_WPARAM(wParam))) {
- return 0;
- }
+ case WM_MOUSEHWHEEL: {
+ WORD fwKeys = GET_KEYSTATE_WPARAM(wParam);
+ short zDelta = GET_WHEEL_DELTA_WPARAM(wParam);
+ int xPos = GET_X_LPARAM(lParam);
+ int yPos = GET_Y_LPARAM(lParam);
+
+ if (uMsg == WM_MOUSEHWHEEL) {
+ if (!g_settings.horizontalScrolling) {
break;
+ }
+
+ // For horizontal scrolling, a large delta value might be posted
+ // for a single click (e.g. 480). Limit the value to 120.
+ if (zDelta < -120) {
+ zDelta = -120;
+ } else if (zDelta > 120) {
+ zDelta = 120;
+ }
+ } else if (!g_settings.reverseScrollingDirection) {
+ zDelta = -zDelta;
}
- break;
- default:
- if (uMsg == g_subclassRegisteredMsg && !wParam)
- RemoveWindowSubclass(hWnd, BrowserWindowSubclassProc, 0);
+ if (OnMouseWheel(hWnd, fwKeys, zDelta, xPos, yPos)) {
+ return 0;
+ }
break;
+ }
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
@@ -289,6 +370,7 @@ HWND WINAPI CreateWindowExWHook(DWORD dwExStyle,
void LoadSettings() {
g_settings.reverseScrollingDirection =
Wh_GetIntSetting(L"reverseScrollingDirection");
+ g_settings.horizontalScrolling = Wh_GetIntSetting(L"horizontalScrolling");
}
BOOL Wh_ModInit() {
@@ -296,6 +378,8 @@ BOOL Wh_ModInit() {
LoadSettings();
+ g_isEdge = !!GetModuleHandle(L"msedge.exe");
+
Wh_SetFunctionHook((void*)CreateWindowExW, (void*)CreateWindowExWHook,
(void**)&pOriginalCreateWindowExW);
diff --git a/updates.atom b/updates.atom
index 887437007..33afffc19 100644
--- a/updates.atom
+++ b/updates.atom
@@ -2,12 +2,26 @@
https://windhawk.net/Windhawk Mod Updates
- 2024-11-21T11:02:33.000Z
+ 2024-11-21T19:38:27.000Zhttps://github.com/jpmonette/feedUpdates in the official collection of Windhawk modshttps://windhawk.net/favicon.icoRamen Software
+
+
+ https://windhawk.net/mods/chrome-wheel-scroll-tabs#7fb455e856a1d5067bae96a727cd1e27a6af9ff3
+
+ 2024-11-21T19:38:27.000Z
+
+
Added an option to switch between tabs when the mouse's horizontal scroll wheel is tilted or rotated.
+
Fixed the border around the web content in Edge triggering the tab scrolling.
+]]>
+
+ m417z
+ https://github.com/m417z
+
+ https://windhawk.net/mods/classic-browser-fix#f646116532b0fbd44766c91c0c4d9ca824647ee6
@@ -265,19 +279,6 @@ center, etc. to another monitor.
2024-11-08T23:35:10.000Z
Added an option to mix files and folders when sorting by size.
The integration with Everything was rewritten and is now faster (about x6 speedup), more stable (occasional hangs were fixed), and more robust overall.