Implement empty-area drag.

Uses Qt 5.15's new QWindow::startSystemMove() to implement empty-area
drag, which allows the user to click and drag any empty area on the
menubar, toolbar, or tabbar to move the window around.
This commit is contained in:
Janek Bevendorff 2020-12-22 01:03:39 +01:00 committed by Jonathan White
parent cd0084f21c
commit 37dab85df7
2 changed files with 63 additions and 0 deletions

View File

@ -503,6 +503,14 @@ MainWindow::MainWindow()
connect(m_ui->actionOnlineHelp, SIGNAL(triggered()), SLOT(openOnlineHelp())); connect(m_ui->actionOnlineHelp, SIGNAL(triggered()), SLOT(openOnlineHelp()));
connect(m_ui->actionKeyboardShortcuts, SIGNAL(triggered()), SLOT(openKeyboardShortcuts())); connect(m_ui->actionKeyboardShortcuts, SIGNAL(triggered()), SLOT(openKeyboardShortcuts()));
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
// Install event filter for empty-area drag
auto* eventFilter = new MainWindowEventFilter(this);
m_ui->menubar->installEventFilter(eventFilter);
m_ui->toolBar->installEventFilter(eventFilter);
m_ui->tabWidget->tabBar()->installEventFilter(eventFilter);
#endif
#ifdef Q_OS_MACOS #ifdef Q_OS_MACOS
setUnifiedTitleAndToolBarOnMac(true); setUnifiedTitleAndToolBarOnMac(true);
#endif #endif
@ -1798,3 +1806,44 @@ void MainWindow::initViewMenu()
config()->set(Config::GUI_HidePasswords, checked); config()->set(Config::GUI_HidePasswords, checked);
}); });
} }
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
MainWindowEventFilter::MainWindowEventFilter(QObject* parent)
: QObject(parent)
{
}
/**
* MainWindow event filter to initiate empty-area drag on the toolbar, menubar, and tabbar.
*/
bool MainWindowEventFilter::eventFilter(QObject* watched, QEvent* event)
{
auto* mainWindow = getMainWindow();
if (!mainWindow || !mainWindow->m_ui) {
return QObject::eventFilter(watched, event);
}
if (event->type() == QEvent::MouseButtonPress) {
if (watched == mainWindow->m_ui->menubar) {
mainWindow->windowHandle()->startSystemMove();
// Continue processing events, so menus keep working.
return false;
} else if (watched == mainWindow->m_ui->toolBar) {
if (!mainWindow->m_ui->toolBar->isMovable() || mainWindow->m_ui->toolBar->cursor() != Qt::SizeAllCursor) {
mainWindow->windowHandle()->startSystemMove();
return false;
}
} else if (watched == mainWindow->m_ui->tabWidget->tabBar()) {
auto* m = static_cast<QMouseEvent*>(event);
if (mainWindow->m_ui->tabWidget->tabBar()->tabAt(m->pos()) == -1) {
mainWindow->windowHandle()->startSystemMove();
return true;
}
}
}
return QObject::eventFilter(watched, event);
}
#endif

View File

@ -35,6 +35,7 @@ namespace Ui
class InactivityTimer; class InactivityTimer;
class SearchWidget; class SearchWidget;
class MainWindowEventFilter;
class MainWindow : public QMainWindow class MainWindow : public QMainWindow
{ {
@ -182,8 +183,21 @@ private:
QTimer m_updateCheckTimer; QTimer m_updateCheckTimer;
QTimer m_trayIconTriggerTimer; QTimer m_trayIconTriggerTimer;
QSystemTrayIcon::ActivationReason m_trayIconTriggerReason; QSystemTrayIcon::ActivationReason m_trayIconTriggerReason;
friend class MainWindowEventFilter;
}; };
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
class MainWindowEventFilter : public QObject
{
Q_OBJECT
public:
explicit MainWindowEventFilter(QObject* parent);
bool eventFilter(QObject* watched, QEvent* event) override;
};
#endif
/** /**
* Return instance of MainWindow created on app load * Return instance of MainWindow created on app load
* non-gui instances will return nullptr * non-gui instances will return nullptr