Fix mouse scrolling on visible/hidden tabs

This commit is contained in:
Quang Nguyễn Minh
2026-08-13 23:30:34 +07:00
parent 33a60a4348
commit a0d7717ab6
10 changed files with 231 additions and 0 deletions
+31
View File
@@ -16,6 +16,7 @@
#include <QtWidgets/QWidgetAction>
#include <QtCore/QSettings>
#include <QtCore/QDebug>
#include <QtGui/QWheelEvent>
#include <QWidgetAction>
@@ -112,6 +113,10 @@ SeerCommandLogsWidget::SeerCommandLogsWidget (QWidget* parent) : QWidget(parent)
QObject::connect(helpToolButton, &QToolButton::clicked, this, &SeerCommandLogsWidget::handleHelpToolButtonClicked);
QObject::connect(macroButtonGroup, &QButtonGroup::buttonClicked, this, &SeerCommandLogsWidget::handleMacroToolButtonClicked);
QObject::connect(qApp, &QCoreApplication::aboutToQuit, this, &SeerCommandLogsWidget::handleAboutToQuit);
// Install event filter to swallow wheel events on the tab bar if the number of tabs is greater than the number of visible tabs.
SeerCommandLogsEventFilter* eventFilterHandler = new SeerCommandLogsEventFilter(logsTabWidget, this);
logsTabWidget->tabBar()->installEventFilter(eventFilterHandler);
}
SeerCommandLogsWidget::~SeerCommandLogsWidget () {
@@ -766,3 +771,29 @@ void SeerCommandLogsWidget::handleTabsContextMenuButtonClicked() {
QDetachTabWidget* SeerCommandLogsWidget::logsTabWidgetInstance () {
return logsTabWidget;
}
bool SeerCommandLogsEventFilter::eventFilter(QObject *watched, QEvent *event) {
if (event->type() == QEvent::Wheel) {
// Count the number of visible tabs.
int visibleCount = 0;
for (int i=0; i<_tabWidget->count(); i++) {
if (_tabWidget->isTabVisible(i)) {
visibleCount++;
}
}
int index = _tabWidget->currentIndex();
QWheelEvent* wheelEvent = static_cast<QWheelEvent*>(event);
// Swallow the wheel event only if it would move past the last visible tab, to avoid landing on a hidden one.
if (wheelEvent->angleDelta().y() < 0 && index >= visibleCount - 1) {
return true;
}
}
return QObject::eventFilter(watched, event);
}
+16
View File
@@ -14,6 +14,7 @@
#include "SeerPrintpointsBrowserWidget.h"
#include "SeerCheckpointsBrowserWidget.h"
#include <QtWidgets/QWidget>
#include <QtWidgets/QTabWidget>
#include "ui_SeerCommandLogsWidget.h"
@@ -97,3 +98,18 @@ class SeerCommandLogsWidget : public QWidget, protected Ui::SeerCommandLogsWidge
SeerSeerLogWidget* _seerOutputLog;
};
class SeerCommandLogsEventFilter : public QObject {
Q_OBJECT
public:
explicit SeerCommandLogsEventFilter(QTabWidget* tabWidget, QObject *parent = nullptr) : QObject(parent), _tabWidget(tabWidget) {}
~SeerCommandLogsEventFilter() = default;
protected:
bool eventFilter (QObject *watched, QEvent *event) override;
private:
QTabWidget* _tabWidget;
};
@@ -12,6 +12,7 @@
#include <QtGui/QIcon>
#include <QtCore/QSettings>
#include <QtCore/QDebug>
#include <QtGui/QWheelEvent>
SeerSourceSymbolLibraryManagerWidget::SeerSourceSymbolLibraryManagerWidget (QWidget* parent) : QWidget(parent) {
@@ -70,6 +71,10 @@ SeerSourceSymbolLibraryManagerWidget::SeerSourceSymbolLibraryManagerWidget (QWid
QObject::connect(helpToolButton, &QToolButton::clicked, this, &SeerSourceSymbolLibraryManagerWidget::handleHelpToolButtonClicked);
QObject::connect(tabWidget->tabBar(), &QTabBar::tabMoved, this, &SeerSourceSymbolLibraryManagerWidget::handleTabMoved);
QObject::connect(tabWidget->tabBar(), &QTabBar::currentChanged, this, &SeerSourceSymbolLibraryManagerWidget::handleTabChanged);
// Install event filter to swallow wheel events on the tab bar if the number of tabs is greater than the number of visible tabs.
SeerSourceSymbolLibraryEventFilter* eventFilterHandler = new SeerSourceSymbolLibraryEventFilter(tabWidget, this);
tabWidget->tabBar()->installEventFilter(eventFilterHandler);
}
SeerSourceSymbolLibraryManagerWidget::~SeerSourceSymbolLibraryManagerWidget () {
@@ -289,3 +294,27 @@ void SeerSourceSymbolLibraryManagerWidget::handleTabsContextMenuButtonClicked()
contextMenu.exec(QCursor::pos());
}
bool SeerSourceSymbolLibraryEventFilter::eventFilter(QObject *watched, QEvent *event) {
if (event->type() == QEvent::Wheel) {
// Count the number of visible tabs.
int visibleCount = 0;
for (int i=0; i<_tabWidget->count(); i++) {
if (_tabWidget->isTabVisible(i)) {
visibleCount++;
}
}
int index = _tabWidget->currentIndex();
QWheelEvent* wheelEvent = static_cast<QWheelEvent*>(event);
// Swallow the wheel event only if it would move past the last visible tab, to avoid landing on a hidden one.
if (wheelEvent->angleDelta().y() < 0 && index >= visibleCount - 1) {
return true;
}
}
return QObject::eventFilter(watched, event);
}
@@ -13,6 +13,7 @@
#include "SeerSkipBrowserWidget.h"
#include <QtWidgets/QWidget>
#include <QtWidgets/QTabWidget>
#include "ui_SeerSourceSymbolLibraryManagerWidget.h"
@@ -54,3 +55,17 @@ class SeerSourceSymbolLibraryManagerWidget : public QWidget, protected Ui::SeerS
QTabWidget* _dumpTab;
};
class SeerSourceSymbolLibraryEventFilter : public QObject {
Q_OBJECT
public:
explicit SeerSourceSymbolLibraryEventFilter(QTabWidget* tabWidget, QObject *parent = nullptr) : QObject(parent), _tabWidget(tabWidget) {}
~SeerSourceSymbolLibraryEventFilter() = default;
protected:
bool eventFilter (QObject *watched, QEvent *event) override;
private:
QTabWidget* _tabWidget;
};
+30
View File
@@ -13,6 +13,7 @@
#include <QtGui/QIcon>
#include <QtCore/QSettings>
#include <QtCore/QDebug>
#include <QtGui/QWheelEvent>
SeerStackManagerWidget::SeerStackManagerWidget (QWidget* parent) : QWidget(parent) {
@@ -65,6 +66,10 @@ SeerStackManagerWidget::SeerStackManagerWidget (QWidget* parent) : QWidget(paren
QObject::connect(helpToolButton, &QToolButton::clicked, this, &SeerStackManagerWidget::handleHelpToolButtonClicked);
QObject::connect(tabWidget->tabBar(), &QTabBar::tabMoved, this, &SeerStackManagerWidget::handleTabMoved);
QObject::connect(tabWidget->tabBar(), &QTabBar::currentChanged, this, &SeerStackManagerWidget::handleTabChanged);
// Install event filter to swallow wheel events on the tab bar if the number of tabs is greater than the number of visible tabs.
SeerStackManagerEventFilter* eventFilterHandler = new SeerStackManagerEventFilter(tabWidget, this);
tabWidget->tabBar()->installEventFilter(eventFilterHandler);
}
SeerStackManagerWidget::~SeerStackManagerWidget () {
@@ -330,4 +335,29 @@ void SeerStackManagerWidget::handleTabsContextMenuButtonClicked() {
contextMenu.exec(QCursor::pos());
}
bool SeerStackManagerEventFilter::eventFilter(QObject *watched, QEvent *event) {
if (event->type() == QEvent::Wheel) {
// Count the number of visible tabs.
int visibleCount = 0;
for (int i=0; i<_tabWidget->count(); i++) {
if (_tabWidget->isTabVisible(i)) {
visibleCount++;
}
}
int index = _tabWidget->currentIndex();
QWheelEvent* wheelEvent = static_cast<QWheelEvent*>(event);
// Swallow the wheel event only if it would move past the last visible tab, to avoid landing on a hidden one.
if (wheelEvent->angleDelta().y() < 0 && index >= visibleCount - 1) {
return true;
}
}
return QObject::eventFilter(watched, event);
}
+16
View File
@@ -10,6 +10,7 @@
#include "SeerStackDumpBrowserWidget.h"
#include <QtWidgets/QWidget>
#include <QtWidgets/QTabWidget>
#include "ui_SeerStackManagerWidget.h"
@@ -53,3 +54,18 @@ class SeerStackManagerWidget : public QWidget, protected Ui::SeerStackManagerWid
SeerStackDumpBrowserWidget* _stackDumpBrowserWidget;
};
class SeerStackManagerEventFilter : public QObject {
Q_OBJECT
public:
explicit SeerStackManagerEventFilter(QTabWidget* tabWidget, QObject *parent = nullptr) : QObject(parent), _tabWidget(tabWidget) {}
~SeerStackManagerEventFilter() = default;
protected:
bool eventFilter (QObject *watched, QEvent *event) override;
private:
QTabWidget* _tabWidget;
};
+31
View File
@@ -14,6 +14,7 @@
#include <QtCore/QFile>
#include <QtCore/QSettings>
#include <QtCore/QDebug>
#include <QtGui/QWheelEvent>
SeerThreadManagerWidget::SeerThreadManagerWidget (QWidget* parent) : QWidget(parent) {
@@ -69,6 +70,10 @@ SeerThreadManagerWidget::SeerThreadManagerWidget (QWidget* parent) : QWidget(par
QObject::connect(forkFollowsComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &SeerThreadManagerWidget::handleForkFollowComboBox);
QObject::connect(tabWidget->tabBar(), &QTabBar::tabMoved, this, &SeerThreadManagerWidget::handleTabMoved);
QObject::connect(tabWidget->tabBar(), &QTabBar::currentChanged, this, &SeerThreadManagerWidget::handleTabChanged);
// Install event filter to swallow wheel events on the tab bar if the number of tabs is greater than the number of visible tabs.
SeerThreadManagerEventFilter* eventFilterHandler = new SeerThreadManagerEventFilter(tabWidget, this);
tabWidget->tabBar()->installEventFilter(eventFilterHandler);
}
SeerThreadManagerWidget::~SeerThreadManagerWidget () {
@@ -323,3 +328,29 @@ void SeerThreadManagerWidget::handleTabsContextMenuButtonClicked() {
contextMenu.exec(QCursor::pos());
}
bool SeerThreadManagerEventFilter::eventFilter(QObject *watched, QEvent *event) {
if (event->type() == QEvent::Wheel) {
// Count the number of visible tabs.
int visibleCount = 0;
for (int i=0; i<_tabWidget->count(); i++) {
if (_tabWidget->isTabVisible(i)) {
visibleCount++;
}
}
int index = _tabWidget->currentIndex();
QWheelEvent* wheelEvent = static_cast<QWheelEvent*>(event);
// Swallow the wheel event only if it would move past the last visible tab, to avoid landing on a hidden one.
if (wheelEvent->angleDelta().y() < 0 && index >= visibleCount - 1) {
return true;
}
}
return QObject::eventFilter(watched, event);
}
+16
View File
@@ -10,6 +10,7 @@
#include "SeerAdaTasksBrowserWidget.h"
#include <QtWidgets/QWidget>
#include <QtWidgets/QTabWidget>
#include "ui_SeerThreadManagerWidget.h"
@@ -62,3 +63,18 @@ class SeerThreadManagerWidget : public QWidget, protected Ui::SeerThreadManagerW
SeerAdaTasksBrowserWidget* _adaTasksBrowserWidget;
};
class SeerThreadManagerEventFilter : public QObject {
Q_OBJECT
public:
explicit SeerThreadManagerEventFilter(QTabWidget* tabWidget, QObject *parent = nullptr) : QObject(parent), _tabWidget(tabWidget) {}
~SeerThreadManagerEventFilter() = default;
protected:
bool eventFilter (QObject *watched, QEvent *event) override;
private:
QTabWidget* _tabWidget;
};
+31
View File
@@ -12,6 +12,7 @@
#include <QtGui/QIcon>
#include <QtCore/QSettings>
#include <QtCore/QDebug>
#include <QtGui/QWheelEvent>
SeerVariableManagerWidget::SeerVariableManagerWidget (QWidget* parent) : QWidget(parent) {
@@ -66,6 +67,10 @@ SeerVariableManagerWidget::SeerVariableManagerWidget (QWidget* parent) : QWidget
QObject::connect(tabWidget->tabBar(), &QTabBar::currentChanged, this, &SeerVariableManagerWidget::handleTabChanged);
QObject::connect(_variableLoggerBrowserWidget, &SeerVariableLoggerBrowserWidget::raiseTab, this, &SeerVariableManagerWidget::handleRaiseLoggerTab);
QObject::connect(_variableTrackerBrowserWidget, &SeerVariableTrackerBrowserWidget::raiseTab, this, &SeerVariableManagerWidget::handleRaiseTrackerTab);
// Install event filter to swallow wheel events on the tab bar if the number of tabs is greater than the number of visible tabs.
SeerVariableManagerEventFilter* eventFilterHandler = new SeerVariableManagerEventFilter(tabWidget, this);
tabWidget->tabBar()->installEventFilter(eventFilterHandler);
}
SeerVariableManagerWidget::~SeerVariableManagerWidget () {
@@ -290,3 +295,29 @@ void SeerVariableManagerWidget::handleTabsContextMenuButtonClicked() {
contextMenu.exec(QCursor::pos());
}
bool SeerVariableManagerEventFilter::eventFilter(QObject *watched, QEvent *event) {
if (event->type() == QEvent::Wheel) {
// Count the number of visible tabs.
int visibleCount = 0;
for (int i=0; i<_tabWidget->count(); i++) {
if (_tabWidget->isTabVisible(i)) {
visibleCount++;
}
}
int index = _tabWidget->currentIndex();
QWheelEvent* wheelEvent = static_cast<QWheelEvent*>(event);
// Swallow the wheel event only if it would move past the last visible tab, to avoid landing on a hidden one.
if (wheelEvent->angleDelta().y() < 0 && index >= visibleCount - 1) {
return true;
}
}
return QObject::eventFilter(watched, event);
}
+16
View File
@@ -10,6 +10,7 @@
#include "SeerSignalValuesBrowserWidget.h"
#include <QtWidgets/QWidget>
#include <QtWidgets/QTabWidget>
#include "ui_SeerVariableManagerWidget.h"
@@ -46,3 +47,18 @@ class SeerVariableManagerWidget : public QWidget, protected Ui::SeerVariableMana
SeerSignalValuesBrowserWidget* _signalValuesBrowserWidget;
};
class SeerVariableManagerEventFilter : public QObject {
Q_OBJECT
public:
explicit SeerVariableManagerEventFilter(QTabWidget* tabWidget, QObject *parent = nullptr) : QObject(parent), _tabWidget(tabWidget) {}
~SeerVariableManagerEventFilter() = default;
protected:
bool eventFilter (QObject *watched, QEvent *event) override;
private:
QTabWidget* _tabWidget;
};