From fb375e149b025aadae677aaec701ba25fa338bcf Mon Sep 17 00:00:00 2001 From: pajlada Date: Thu, 13 Mar 2025 22:20:03 +0100 Subject: [PATCH] refactor: some mini feature changes in BaseWindow (#6074) --- CHANGELOG.md | 1 + src/singletons/WindowManager.cpp | 8 +- src/util/InitUpdateButton.cpp | 1 - src/widgets/AccountSwitchPopup.cpp | 20 +++-- src/widgets/AccountSwitchPopup.hpp | 1 - src/widgets/BaseWindow.cpp | 78 ++++++++++--------- src/widgets/BaseWindow.hpp | 32 ++++++-- src/widgets/DraggablePopup.cpp | 6 +- src/widgets/dialogs/UpdateDialog.cpp | 2 + .../dialogs/switcher/QuickSwitcherPopup.cpp | 5 +- 10 files changed, 86 insertions(+), 68 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8202ec62..4b8a6041 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -71,6 +71,7 @@ - Dev: Refactored some settings styles/APIs. (#6023) - Dev: Added snapshot tests for EventSub. (#5965) - Dev: Updated crashpad. (#6026) +- Dev: Mini feature refactor of BaseWindow. (#6074) - Dev: Removed dead code and some MSVC warnings. (#6024) - Dev: Added check if WEBP is supported. (#6073) diff --git a/src/singletons/WindowManager.cpp b/src/singletons/WindowManager.cpp index e07e6792..632c2f7c 100644 --- a/src/singletons/WindowManager.cpp +++ b/src/singletons/WindowManager.cpp @@ -88,20 +88,14 @@ void WindowManager::showSettingsDialog(QWidget *parent, void WindowManager::showAccountSelectPopup(QPoint point) { - // static QWidget *lastFocusedWidget = nullptr; - static AccountSwitchPopup *w = new AccountSwitchPopup(); + static auto *w = new AccountSwitchPopup; if (w->hasFocus()) { w->hide(); - // if (lastFocusedWidget) { - // lastFocusedWidget->setFocus(); - // } return; } - // lastFocusedWidget = this->focusWidget(); - w->refresh(); w->moveTo(point - QPoint(30, 0), widgets::BoundsChecking::CursorPosition); diff --git a/src/util/InitUpdateButton.cpp b/src/util/InitUpdateButton.cpp index 8636a85f..4f81b96e 100644 --- a/src/util/InitUpdateButton.cpp +++ b/src/util/InitUpdateButton.cpp @@ -14,7 +14,6 @@ void initUpdateButton(Button &button, // show update prompt when clicking the button QObject::connect(&button, &Button::leftClicked, [&button] { auto *dialog = new UpdateDialog(); - dialog->setActionOnFocusLoss(BaseWindow::Delete); auto globalPoint = button.mapToGlobal( QPoint(int(-100 * button.scale()), button.height())); diff --git a/src/widgets/AccountSwitchPopup.cpp b/src/widgets/AccountSwitchPopup.cpp index f94b94f7..a3d47512 100644 --- a/src/widgets/AccountSwitchPopup.cpp +++ b/src/widgets/AccountSwitchPopup.cpp @@ -14,13 +14,16 @@ namespace chatterino { using namespace literals; AccountSwitchPopup::AccountSwitchPopup(QWidget *parent) - : BaseWindow({BaseWindow::TopMost, BaseWindow::Frameless, - BaseWindow::DisableLayoutSave}, - parent) + : BaseWindow( + { + BaseWindow::TopMost, + BaseWindow::Frameless, + BaseWindow::DisableLayoutSave, + BaseWindow::LinuxPopup, + }, + parent) { -#ifdef Q_OS_LINUX - this->setWindowFlag(Qt::Popup); -#endif + this->focusOutAction = FocusOutAction::Hide; this->setContentsMargins(0, 0, 0, 0); @@ -92,11 +95,6 @@ void AccountSwitchPopup::refresh() this->ui_.accountSwitchWidget->refresh(); } -void AccountSwitchPopup::focusOutEvent(QFocusEvent *) -{ - this->hide(); -} - void AccountSwitchPopup::paintEvent(QPaintEvent *) { QPainter painter(this); diff --git a/src/widgets/AccountSwitchPopup.hpp b/src/widgets/AccountSwitchPopup.hpp index 68d7b69b..59dfaaab 100644 --- a/src/widgets/AccountSwitchPopup.hpp +++ b/src/widgets/AccountSwitchPopup.hpp @@ -18,7 +18,6 @@ public: void refresh(); protected: - void focusOutEvent(QFocusEvent *event) final; void paintEvent(QPaintEvent *event) override; void themeChangedEvent() override; diff --git a/src/widgets/BaseWindow.cpp b/src/widgets/BaseWindow.cpp index 962fa528..27d52113 100644 --- a/src/widgets/BaseWindow.cpp +++ b/src/widgets/BaseWindow.cpp @@ -210,6 +210,13 @@ Qt::WindowFlags windowFlagsFor(FlagsEnum flags) out.setFlag(Qt::WindowStaysOnTopHint, flags.has(BaseWindow::TopMost)); out.setFlag(Qt::FramelessWindowHint, flags.has(BaseWindow::Frameless)); +#ifdef Q_OS_LINUX + if (flags.has(BaseWindow::LinuxPopup)) + { + out.setFlag(Qt::Popup); + } +#endif + return out; } @@ -449,16 +456,6 @@ bool BaseWindow::isTopMost() const return this->isTopMost_ || this->flags_.has(TopMost); } -void BaseWindow::setActionOnFocusLoss(ActionOnFocusLoss value) -{ - this->actionOnFocusLoss_ = value; -} - -BaseWindow::ActionOnFocusLoss BaseWindow::getActionOnFocusLoss() const -{ - return this->actionOnFocusLoss_; -} - QWidget *BaseWindow::getLayoutContainer() { if (this->hasCustomWindowFrame()) @@ -521,10 +518,26 @@ void BaseWindow::themeChangedEvent() bool BaseWindow::event(QEvent *event) { - if (event->type() == - QEvent::WindowDeactivate /*|| event->type() == QEvent::FocusOut*/) + if (event->type() == QEvent::WindowDeactivate) { - this->onFocusLost(); + switch (this->windowDeactivateAction) + { + case WindowDeactivateAction::Delete: + this->deleteLater(); + break; + + case WindowDeactivateAction::Close: + this->close(); + break; + + case WindowDeactivateAction::Hide: + this->hide(); + break; + + case WindowDeactivateAction::Nothing: + default: + break; + } } #if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0) @@ -571,29 +584,6 @@ void BaseWindow::wheelEvent(QWheelEvent *event) } } -void BaseWindow::onFocusLost() -{ - switch (this->getActionOnFocusLoss()) - { - case Delete: { - this->deleteLater(); - } - break; - - case Close: { - this->close(); - } - break; - - case Hide: { - this->hide(); - } - break; - - default:; - } -} - void BaseWindow::mousePressEvent(QMouseEvent *event) { #ifndef Q_OS_WIN @@ -660,6 +650,22 @@ void BaseWindow::mouseMoveEvent(QMouseEvent *event) BaseWidget::mouseMoveEvent(event); } +void BaseWindow::focusOutEvent(QFocusEvent *event) +{ + switch (this->focusOutAction) + { + case FocusOutAction::Hide: + this->hide(); + break; + + case FocusOutAction::None: + default: + break; + } + + BaseWidget::focusOutEvent(event); +} + TitleBarButton *BaseWindow::addTitleBarButton(const TitleBarButtonStyle &style, std::function onClicked) { diff --git a/src/widgets/BaseWindow.hpp b/src/widgets/BaseWindow.hpp index cc736ba5..919ab893 100644 --- a/src/widgets/BaseWindow.hpp +++ b/src/widgets/BaseWindow.hpp @@ -38,9 +38,10 @@ public: DisableLayoutSave = 1 << 7, BoundsCheckOnShow = 1 << 8, ClearBuffersOnDpiChange = 1 << 9, - }; - enum ActionOnFocusLoss { Nothing, Delete, Close, Hide }; + /// special flag that enables the Qt::Popup flag on Linux + LinuxPopup = 1 << 10, + }; explicit BaseWindow(FlagsEnum flags_ = None, QWidget *parent = nullptr); @@ -55,9 +56,6 @@ public: std::function onClicked); EffectLabel *addTitleBarLabel(std::function onClicked); - void setActionOnFocusLoss(ActionOnFocusLoss value); - ActionOnFocusLoss getActionOnFocusLoss() const; - void moveTo(QPoint point, widgets::BoundsChecking mode); /** @@ -93,6 +91,25 @@ Q_SIGNALS: void topMostChanged(bool topMost); protected: + enum class FocusOutAction : std::uint8_t { + None, + Hide, + }; + + /// focusOutAction is used when the `FocusOut` event is fired + FocusOutAction focusOutAction = FocusOutAction::None; + + enum class WindowDeactivateAction : std::uint8_t { + Nothing, + Delete, + Close, + Hide, + }; + + /// This action is used when the `WindowDeactivate` event is fired + WindowDeactivateAction windowDeactivateAction = + WindowDeactivateAction::Nothing; + #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) bool nativeEvent(const QByteArray &eventType, void *message, qintptr *result) override; @@ -118,6 +135,9 @@ protected: void mousePressEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; + + void focusOutEvent(QFocusEvent *event) override; + QPointF movingRelativePos; bool moving{}; @@ -132,7 +152,6 @@ private: void calcButtonsSizes(); void drawCustomWindowFrame(QPainter &painter); - void onFocusLost(); static void applyScaleRecursive(QObject *root, float scale); @@ -148,7 +167,6 @@ private: #endif bool enableCustomFrame_; - ActionOnFocusLoss actionOnFocusLoss_ = Nothing; bool frameless_; bool shown_ = false; FlagsEnum flags_; diff --git a/src/widgets/DraggablePopup.cpp b/src/widgets/DraggablePopup.cpp index b680e35b..95543220 100644 --- a/src/widgets/DraggablePopup.cpp +++ b/src/widgets/DraggablePopup.cpp @@ -47,7 +47,7 @@ DraggablePopup::DraggablePopup(bool closeAutomatically, QWidget *parent) { if (closeAutomatically) { - this->setActionOnFocusLoss(BaseWindow::Delete); + this->windowDeactivateAction = WindowDeactivateAction::Delete; } else { @@ -108,12 +108,12 @@ void DraggablePopup::togglePinned() this->isPinned_ = !isPinned_; if (isPinned_) { - this->setActionOnFocusLoss(BaseWindow::Nothing); + this->windowDeactivateAction = WindowDeactivateAction::Nothing; this->pinButton_->setPixmap(getResources().buttons.pinEnabled); } else { - this->setActionOnFocusLoss(BaseWindow::Delete); + this->windowDeactivateAction = WindowDeactivateAction::Delete; this->pinButton_->setPixmap(getTheme()->buttons.pin); } } diff --git a/src/widgets/dialogs/UpdateDialog.cpp b/src/widgets/dialogs/UpdateDialog.cpp index a1084b2a..a43f6e4e 100644 --- a/src/widgets/dialogs/UpdateDialog.cpp +++ b/src/widgets/dialogs/UpdateDialog.cpp @@ -15,6 +15,8 @@ UpdateDialog::UpdateDialog() : BaseWindow({BaseWindow::Frameless, BaseWindow::TopMost, BaseWindow::EnableCustomFrame, BaseWindow::DisableLayoutSave}) { + this->windowDeactivateAction = WindowDeactivateAction::Delete; + auto layout = LayoutCreator(this).setLayoutType(); diff --git a/src/widgets/dialogs/switcher/QuickSwitcherPopup.cpp b/src/widgets/dialogs/switcher/QuickSwitcherPopup.cpp index b0294c45..bed8eaa5 100644 --- a/src/widgets/dialogs/switcher/QuickSwitcherPopup.cpp +++ b/src/widgets/dialogs/switcher/QuickSwitcherPopup.cpp @@ -48,8 +48,9 @@ QuickSwitcherPopup::QuickSwitcherPopup(Window *parent) , switcherModel_(this) , window(parent) { - this->setWindowFlag(Qt::Dialog); - this->setActionOnFocusLoss(BaseWindow::ActionOnFocusLoss::Delete); + assert(this->windowFlags().testFlag(Qt::Dialog)); + + this->windowDeactivateAction = WindowDeactivateAction::Delete; this->setMinimumSize(QuickSwitcherPopup::MINIMUM_SIZE); this->initWidgets();