mirror of
https://git.outfoxxed.me/quickshell/quickshell.git
synced 2026-04-10 06:11:54 +10:00
core/window: add parentWindow property to FloatingWindow
This commit is contained in:
parent
ceac3c6cfa
commit
b4e71cb2c0
5 changed files with 161 additions and 2 deletions
|
|
@ -4,6 +4,7 @@ project(quickshell VERSION "0.2.1" LANGUAGES CXX C)
|
|||
set(UNRELEASED_FEATURES
|
||||
"network.2"
|
||||
"colorquant-imagerect"
|
||||
"window-parent"
|
||||
)
|
||||
|
||||
set(QT_MIN_VERSION "6.6.0")
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ set shell id.
|
|||
- Added ext-background-effect window blur support.
|
||||
- Added per-corner radius support to Region.
|
||||
- Added ColorQuantizer region selection.
|
||||
- Added dialog window support to FloatingWindow.
|
||||
|
||||
## Other Changes
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#include <qnamespace.h>
|
||||
#include <qobject.h>
|
||||
#include <qqmlengine.h>
|
||||
#include <qqmllist.h>
|
||||
#include <qqmlinfo.h>
|
||||
#include <qtmetamacros.h>
|
||||
#include <qtypes.h>
|
||||
#include <qwindow.h>
|
||||
|
|
@ -11,6 +11,27 @@
|
|||
#include "proxywindow.hpp"
|
||||
#include "windowinterface.hpp"
|
||||
|
||||
ProxyFloatingWindow::ProxyFloatingWindow(QObject* parent): ProxyWindowBase(parent) {
|
||||
this->bTargetVisible.setBinding([this] {
|
||||
if (!this->bWantsVisible) return false;
|
||||
auto* parent = this->bParentProxyWindow.value();
|
||||
if (!parent) return true;
|
||||
return parent->bindableBackerVisibility().value();
|
||||
});
|
||||
}
|
||||
|
||||
void ProxyFloatingWindow::targetVisibleChanged() {
|
||||
if (this->window && this->bParentProxyWindow) {
|
||||
auto* bw = this->bParentProxyWindow.value()->backingWindow();
|
||||
|
||||
if (bw != this->window->transientParent()) {
|
||||
this->window->setTransientParent(bw);
|
||||
}
|
||||
}
|
||||
|
||||
this->ProxyWindowBase::setVisible(this->bTargetVisible);
|
||||
}
|
||||
|
||||
void ProxyFloatingWindow::connectWindow() {
|
||||
this->ProxyWindowBase::connectWindow();
|
||||
|
||||
|
|
@ -19,6 +40,25 @@ void ProxyFloatingWindow::connectWindow() {
|
|||
this->window->setMaximumSize(this->bMaximumSize);
|
||||
}
|
||||
|
||||
void ProxyFloatingWindow::completeWindow() {
|
||||
this->ProxyWindowBase::completeWindow();
|
||||
|
||||
auto* parent = this->bParentProxyWindow.value();
|
||||
this->window->setTransientParent(parent ? parent->backingWindow() : nullptr);
|
||||
}
|
||||
|
||||
void ProxyFloatingWindow::postCompleteWindow() {
|
||||
this->ProxyWindowBase::setVisible(this->bTargetVisible);
|
||||
}
|
||||
|
||||
void ProxyFloatingWindow::onParentDestroyed() {
|
||||
this->mParentWindow = nullptr;
|
||||
this->bParentProxyWindow = nullptr;
|
||||
emit this->parentWindowChanged();
|
||||
}
|
||||
|
||||
void ProxyFloatingWindow::setVisible(bool visible) { this->bWantsVisible = visible; }
|
||||
|
||||
void ProxyFloatingWindow::trySetWidth(qint32 implicitWidth) {
|
||||
if (!this->window->isVisible()) {
|
||||
this->ProxyWindowBase::trySetWidth(implicitWidth);
|
||||
|
|
@ -46,6 +86,42 @@ void ProxyFloatingWindow::onMaximumSizeChanged() {
|
|||
emit this->maximumSizeChanged();
|
||||
}
|
||||
|
||||
QObject* ProxyFloatingWindow::parentWindow() const { return this->mParentWindow; }
|
||||
|
||||
void ProxyFloatingWindow::setParentWindow(QObject* window) {
|
||||
if (window == this->mParentWindow) return;
|
||||
|
||||
if (this->window && this->window->isVisible()) {
|
||||
qmlWarning(this) << "parentWindow cannot be changed after the window is visible.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->bParentProxyWindow) {
|
||||
QObject::disconnect(this->bParentProxyWindow, nullptr, this, nullptr);
|
||||
}
|
||||
|
||||
if (this->mParentWindow) {
|
||||
QObject::disconnect(this->mParentWindow, nullptr, this, nullptr);
|
||||
}
|
||||
|
||||
this->mParentWindow = nullptr;
|
||||
this->bParentProxyWindow = nullptr;
|
||||
|
||||
if (auto* proxy = ProxyWindowBase::forObject(window)) {
|
||||
this->mParentWindow = window;
|
||||
this->bParentProxyWindow = proxy;
|
||||
|
||||
QObject::connect(
|
||||
this->mParentWindow,
|
||||
&QObject::destroyed,
|
||||
this,
|
||||
&ProxyFloatingWindow::onParentDestroyed
|
||||
);
|
||||
}
|
||||
|
||||
emit this->parentWindowChanged();
|
||||
}
|
||||
|
||||
// FloatingWindowInterface
|
||||
|
||||
FloatingWindowInterface::FloatingWindowInterface(QObject* parent)
|
||||
|
|
@ -57,6 +133,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, &ProxyFloatingWindow::parentWindowChanged, this, &FloatingWindowInterface::parentWindowChanged);
|
||||
QObject::connect(this->window, &ProxyWindowBase::windowConnected, this, &FloatingWindowInterface::onWindowConnected);
|
||||
// clang-format on
|
||||
}
|
||||
|
|
@ -169,3 +246,9 @@ bool FloatingWindowInterface::startSystemResize(Qt::Edges edges) const {
|
|||
if (!qw) return false;
|
||||
return qw->startSystemResize(edges);
|
||||
}
|
||||
|
||||
QObject* FloatingWindowInterface::parentWindow() const { return this->window->parentWindow(); }
|
||||
|
||||
void FloatingWindowInterface::setParentWindow(QObject* window) {
|
||||
this->window->setParentWindow(window);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,9 +16,15 @@ class ProxyFloatingWindow: public ProxyWindowBase {
|
|||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
explicit ProxyFloatingWindow(QObject* parent = nullptr): ProxyWindowBase(parent) {}
|
||||
explicit ProxyFloatingWindow(QObject* parent = nullptr);
|
||||
|
||||
void connectWindow() override;
|
||||
void completeWindow() override;
|
||||
void postCompleteWindow() override;
|
||||
void setVisible(bool visible) override;
|
||||
|
||||
[[nodiscard]] QObject* parentWindow() const;
|
||||
void setParentWindow(QObject* window);
|
||||
|
||||
// Setting geometry while the window is visible makes the content item shrink but not the window
|
||||
// which is awful so we disable it for floating windows.
|
||||
|
|
@ -29,11 +35,28 @@ signals:
|
|||
void minimumSizeChanged();
|
||||
void maximumSizeChanged();
|
||||
void titleChanged();
|
||||
void parentWindowChanged();
|
||||
|
||||
private slots:
|
||||
void onParentDestroyed();
|
||||
|
||||
private:
|
||||
void onMinimumSizeChanged();
|
||||
void onMaximumSizeChanged();
|
||||
void onTitleChanged();
|
||||
void targetVisibleChanged();
|
||||
|
||||
QObject* mParentWindow = nullptr;
|
||||
|
||||
Q_OBJECT_BINDABLE_PROPERTY(ProxyFloatingWindow, ProxyWindowBase*, bParentProxyWindow);
|
||||
Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(ProxyFloatingWindow, bool, bWantsVisible, true);
|
||||
|
||||
Q_OBJECT_BINDABLE_PROPERTY(
|
||||
ProxyFloatingWindow,
|
||||
bool,
|
||||
bTargetVisible,
|
||||
&ProxyFloatingWindow::targetVisibleChanged
|
||||
);
|
||||
|
||||
public:
|
||||
Q_OBJECT_BINDABLE_PROPERTY(
|
||||
|
|
@ -75,6 +98,11 @@ class FloatingWindowInterface: public WindowInterface {
|
|||
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);
|
||||
/// The parent window of this window. Setting this makes the window a child of the parent,
|
||||
/// which affects window stacking behavior.
|
||||
///
|
||||
/// > [!NOTE] This property cannot be changed after the window is visible.
|
||||
Q_PROPERTY(QObject* parentWindow READ parentWindow WRITE setParentWindow NOTIFY parentWindowChanged);
|
||||
// clang-format on
|
||||
QML_NAMED_ELEMENT(FloatingWindow);
|
||||
|
||||
|
|
@ -101,6 +129,9 @@ public:
|
|||
/// Start a system resize operation. Must be called during a pointer press/drag.
|
||||
Q_INVOKABLE [[nodiscard]] bool startSystemResize(Qt::Edges edges) const;
|
||||
|
||||
[[nodiscard]] QObject* parentWindow() const;
|
||||
void setParentWindow(QObject* window);
|
||||
|
||||
signals:
|
||||
void minimumSizeChanged();
|
||||
void maximumSizeChanged();
|
||||
|
|
@ -108,6 +139,7 @@ signals:
|
|||
void minimizedChanged();
|
||||
void maximizedChanged();
|
||||
void fullscreenChanged();
|
||||
void parentWindowChanged();
|
||||
|
||||
private slots:
|
||||
void onWindowConnected();
|
||||
|
|
|
|||
42
src/window/test/manual/parentwindow.qml
Normal file
42
src/window/test/manual/parentwindow.qml
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls.Fusion
|
||||
import Quickshell
|
||||
|
||||
Scope {
|
||||
FloatingWindow {
|
||||
id: control
|
||||
color: contentItem.palette.window
|
||||
ColumnLayout {
|
||||
CheckBox {
|
||||
id: parentCb
|
||||
text: "Show parent"
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
id: dialogCb
|
||||
text: "Show dialog"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FloatingWindow {
|
||||
id: parentw
|
||||
Text {
|
||||
text: "parent"
|
||||
}
|
||||
visible: parentCb.checked
|
||||
color: contentItem.palette.window
|
||||
|
||||
FloatingWindow {
|
||||
id: dialog
|
||||
parentWindow: parentw
|
||||
visible: dialogCb.checked
|
||||
color: contentItem.palette.window
|
||||
|
||||
Text {
|
||||
text: "dialog"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue