From 3918290c1bcd93ed81291844d9f1ed146672dbfc Mon Sep 17 00:00:00 2001 From: bbedward Date: Wed, 26 Nov 2025 09:54:32 -0500 Subject: [PATCH] core/window: add min/max/fullscreen properties, and move/resize fns to FloatingWindow --- changelog/next.md | 2 + src/window/floatingwindow.cpp | 103 ++++++++++++++++++++++++++++++++++ src/window/floatingwindow.hpp | 38 ++++++++++++- 3 files changed, 140 insertions(+), 3 deletions(-) diff --git a/changelog/next.md b/changelog/next.md index 225a3f9..9d8dd04 100644 --- a/changelog/next.md +++ b/changelog/next.md @@ -16,6 +16,8 @@ set shell id. - Added support for wayland idle timeouts. - Added support for inhibiting wayland compositor shortcuts for focused windows. - Added the ability to override Quickshell.cacheDir with a custom path. +- Added minimized, maximized, and fullscreen properties to FloatingWindow. +- Added the ability to handle move and resize events to FloatingWindow. ## Other Changes diff --git a/src/window/floatingwindow.cpp b/src/window/floatingwindow.cpp index 0b9e9b1..a0c9fdd 100644 --- a/src/window/floatingwindow.cpp +++ b/src/window/floatingwindow.cpp @@ -1,10 +1,12 @@ #include "floatingwindow.hpp" +#include #include #include #include #include #include +#include #include "proxywindow.hpp" #include "windowinterface.hpp" @@ -55,6 +57,7 @@ FloatingWindowInterface::FloatingWindowInterface(QObject* parent) QObject::connect(this->window, &ProxyFloatingWindow::titleChanged, this, &FloatingWindowInterface::titleChanged); QObject::connect(this->window, &ProxyFloatingWindow::minimumSizeChanged, this, &FloatingWindowInterface::minimumSizeChanged); QObject::connect(this->window, &ProxyFloatingWindow::maximumSizeChanged, this, &FloatingWindowInterface::maximumSizeChanged); + QObject::connect(this->window, &ProxyWindowBase::windowConnected, this, &FloatingWindowInterface::onWindowConnected); // clang-format on } @@ -66,3 +69,103 @@ void FloatingWindowInterface::onReload(QObject* oldInstance) { } ProxyWindowBase* FloatingWindowInterface::proxyWindow() const { return this->window; } + +void FloatingWindowInterface::onWindowConnected() { + auto* qw = this->window->backingWindow(); + if (qw) { + QObject::connect( + qw, + &QWindow::windowStateChanged, + this, + &FloatingWindowInterface::onWindowStateChanged + ); + this->setMinimized(this->mMinimized); + this->setMaximized(this->mMaximized); + this->setFullscreen(this->mFullscreen); + this->onWindowStateChanged(); + } +} + +void FloatingWindowInterface::onWindowStateChanged() { + auto* qw = this->window->backingWindow(); + auto states = qw ? qw->windowStates() : Qt::WindowStates(); + + auto minimized = states.testFlag(Qt::WindowMinimized); + auto maximized = states.testFlag(Qt::WindowMaximized); + auto fullscreen = states.testFlag(Qt::WindowFullScreen); + + if (minimized != this->mWasMinimized) { + this->mWasMinimized = minimized; + emit this->minimizedChanged(); + } + + if (maximized != this->mWasMaximized) { + this->mWasMaximized = maximized; + emit this->maximizedChanged(); + } + + if (fullscreen != this->mWasFullscreen) { + this->mWasFullscreen = fullscreen; + emit this->fullscreenChanged(); + } +} + +bool FloatingWindowInterface::isMinimized() const { + auto* qw = this->window->backingWindow(); + if (!qw) return this->mWasMinimized; + return qw->windowStates().testFlag(Qt::WindowMinimized); +} + +void FloatingWindowInterface::setMinimized(bool minimized) { + this->mMinimized = minimized; + + if (auto* qw = this->window->backingWindow()) { + auto states = qw->windowStates(); + states.setFlag(Qt::WindowMinimized, minimized); + qw->setWindowStates(states); + } +} + +bool FloatingWindowInterface::isMaximized() const { + auto* qw = this->window->backingWindow(); + if (!qw) return this->mWasMaximized; + return qw->windowStates().testFlag(Qt::WindowMaximized); +} + +void FloatingWindowInterface::setMaximized(bool maximized) { + this->mMaximized = maximized; + + if (auto* qw = this->window->backingWindow()) { + auto states = qw->windowStates(); + states.setFlag(Qt::WindowMaximized, maximized); + qw->setWindowStates(states); + } +} + +bool FloatingWindowInterface::isFullscreen() const { + auto* qw = this->window->backingWindow(); + if (!qw) return this->mWasFullscreen; + return qw->windowStates().testFlag(Qt::WindowFullScreen); +} + +void FloatingWindowInterface::setFullscreen(bool fullscreen) { + this->mFullscreen = fullscreen; + + if (auto* qw = this->window->backingWindow()) { + auto states = qw->windowStates(); + states.setFlag(Qt::WindowFullScreen, fullscreen); + qw->setWindowStates(states); + } +} + +bool FloatingWindowInterface::startSystemMove() const { + auto* qw = this->window->backingWindow(); + if (!qw) return false; + return qw->startSystemMove(); +} + +bool FloatingWindowInterface::startSystemResize(Qt::Edges edges) const { + auto* qw = this->window->backingWindow(); + if (!qw) return false; + return qw->startSystemResize(edges); +} diff --git a/src/window/floatingwindow.hpp b/src/window/floatingwindow.hpp index f9cd5ce..06b5b9e 100644 --- a/src/window/floatingwindow.hpp +++ b/src/window/floatingwindow.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -68,6 +69,12 @@ class FloatingWindowInterface: public WindowInterface { Q_PROPERTY(QSize minimumSize READ default WRITE default NOTIFY minimumSizeChanged BINDABLE bindableMinimumSize); /// Maximum window size given to the window system. Q_PROPERTY(QSize maximumSize READ default WRITE default NOTIFY maximumSizeChanged BINDABLE bindableMaximumSize); + /// Whether the window is currently minimized. + Q_PROPERTY(bool minimized READ isMinimized WRITE setMinimized NOTIFY minimizedChanged); + /// Whether the window is currently maximized. + Q_PROPERTY(bool maximized READ isMaximized WRITE setMaximized NOTIFY maximizedChanged); + /// Whether the window is currently fullscreen. + Q_PROPERTY(bool fullscreen READ isFullscreen WRITE setFullscreen NOTIFY fullscreenChanged); // clang-format on QML_NAMED_ELEMENT(FloatingWindow); @@ -78,15 +85,40 @@ public: [[nodiscard]] ProxyWindowBase* proxyWindow() const override; - QBindable bindableMinimumSize() { return &this->window->bMinimumSize; } - QBindable bindableMaximumSize() { return &this->window->bMaximumSize; } - QBindable bindableTitle() { return &this->window->bTitle; } + [[nodiscard]] QBindable bindableMinimumSize() { return &this->window->bMinimumSize; } + [[nodiscard]] QBindable bindableMaximumSize() { return &this->window->bMaximumSize; } + [[nodiscard]] QBindable bindableTitle() { return &this->window->bTitle; } + + [[nodiscard]] bool isMinimized() const; + void setMinimized(bool minimized); + [[nodiscard]] bool isMaximized() const; + void setMaximized(bool maximized); + [[nodiscard]] bool isFullscreen() const; + void setFullscreen(bool fullscreen); + + /// Start a system move operation. Must be called during a pointer press/drag. + Q_INVOKABLE [[nodiscard]] bool startSystemMove() const; + /// Start a system resize operation. Must be called during a pointer press/drag. + Q_INVOKABLE [[nodiscard]] bool startSystemResize(Qt::Edges edges) const; signals: void minimumSizeChanged(); void maximumSizeChanged(); void titleChanged(); + void minimizedChanged(); + void maximizedChanged(); + void fullscreenChanged(); + +private slots: + void onWindowConnected(); + void onWindowStateChanged(); private: ProxyFloatingWindow* window; + bool mMinimized = false; + bool mMaximized = false; + bool mFullscreen = false; + bool mWasMinimized = false; + bool mWasMaximized = false; + bool mWasFullscreen = false; };