forked from quickshell/quickshell
refactor(wayland): start factoring wayland out of ShellWindow
This commit is contained in:
parent
55bcae4d62
commit
5bbd0333ef
|
@ -40,6 +40,7 @@ qt_add_executable(quickshell
|
||||||
src/cpp/watcher.cpp
|
src/cpp/watcher.cpp
|
||||||
src/cpp/region.cpp
|
src/cpp/region.cpp
|
||||||
src/cpp/persistentprops.cpp
|
src/cpp/persistentprops.cpp
|
||||||
|
src/cpp/shellwindow.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
qt_add_qml_module(quickshell URI QuickShell)
|
qt_add_qml_module(quickshell URI QuickShell)
|
||||||
|
|
|
@ -12,56 +12,67 @@
|
||||||
#include <qwindow.h>
|
#include <qwindow.h>
|
||||||
|
|
||||||
#include "proxywindow.hpp"
|
#include "proxywindow.hpp"
|
||||||
|
#include "shellwindow.hpp"
|
||||||
|
|
||||||
void ProxyShellWindow::setupWindow() {
|
WaylandShellWindow::WaylandShellWindow(QObject* parent):
|
||||||
|
ProxyShellWindow(parent), mWayland(new WaylandShellWindowExtensions(this)) {}
|
||||||
|
|
||||||
|
void WaylandShellWindow::setupWindow() {
|
||||||
this->shellWindow = LayerShellQt::Window::get(this->window);
|
this->shellWindow = LayerShellQt::Window::get(this->window);
|
||||||
|
|
||||||
this->ProxyWindowBase::setupWindow();
|
this->ProxyShellWindow::setupWindow();
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
QObject::connect(this->shellWindow, &LayerShellQt::Window::anchorsChanged, this, &ProxyShellWindow::anchorsChanged);
|
QObject::connect(this->shellWindow, &LayerShellQt::Window::anchorsChanged, this, &ProxyShellWindow::anchorsChanged);
|
||||||
QObject::connect(this->shellWindow, &LayerShellQt::Window::marginsChanged, this, &ProxyShellWindow::marginsChanged);
|
QObject::connect(this->shellWindow, &LayerShellQt::Window::marginsChanged, this, &ProxyShellWindow::marginsChanged);
|
||||||
QObject::connect(this->shellWindow, &LayerShellQt::Window::layerChanged, this, &ProxyShellWindow::layerChanged);
|
|
||||||
QObject::connect(this->shellWindow, &LayerShellQt::Window::keyboardInteractivityChanged, this, &ProxyShellWindow::keyboardFocusChanged);
|
|
||||||
|
|
||||||
QObject::connect(this->window, &QWindow::widthChanged, this, &ProxyShellWindow::updateExclusionZone);
|
QObject::connect(
|
||||||
QObject::connect(this->window, &QWindow::heightChanged, this, &ProxyShellWindow::updateExclusionZone);
|
this->shellWindow, &LayerShellQt::Window::layerChanged,
|
||||||
QObject::connect(this, &ProxyShellWindow::anchorsChanged, this, &ProxyShellWindow::updateExclusionZone);
|
this->mWayland, &WaylandShellWindowExtensions::layerChanged
|
||||||
QObject::connect(this, &ProxyShellWindow::marginsChanged, this, &ProxyShellWindow::updateExclusionZone);
|
);
|
||||||
|
QObject::connect(
|
||||||
|
this->shellWindow, &LayerShellQt::Window::keyboardInteractivityChanged,
|
||||||
|
this->mWayland, &WaylandShellWindowExtensions::keyboardFocusChanged
|
||||||
|
);
|
||||||
|
|
||||||
|
QObject::connect(this->window, &QWindow::widthChanged, this, &WaylandShellWindow::updateExclusionZone);
|
||||||
|
QObject::connect(this->window, &QWindow::heightChanged, this, &WaylandShellWindow::updateExclusionZone);
|
||||||
|
QObject::connect(this, &ProxyShellWindow::anchorsChanged, this, &WaylandShellWindow::updateExclusionZone);
|
||||||
|
QObject::connect(this, &ProxyShellWindow::marginsChanged, this, &WaylandShellWindow::updateExclusionZone);
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
this->setAnchors(this->mAnchors);
|
this->setAnchors(this->mAnchors);
|
||||||
this->setMargins(this->mMargins);
|
this->setMargins(this->mMargins);
|
||||||
this->setExclusionMode(this->mExclusionMode); // also sets exclusion zone
|
this->setExclusionMode(this->mExclusionMode); // also sets exclusion zone
|
||||||
this->setLayer(this->mLayer);
|
this->mWayland->setLayer(this->mLayer);
|
||||||
this->shellWindow->setScope(this->mScope);
|
this->shellWindow->setScope(this->mScope);
|
||||||
this->setKeyboardFocus(this->mKeyboardFocus);
|
this->mWayland->setKeyboardFocus(this->mKeyboardFocus);
|
||||||
|
|
||||||
this->connected = true;
|
this->connected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QQuickWindow* ProxyShellWindow::disownWindow() {
|
QQuickWindow* WaylandShellWindow::disownWindow() {
|
||||||
QObject::disconnect(this->shellWindow, nullptr, this, nullptr);
|
QObject::disconnect(this->shellWindow, nullptr, this, nullptr);
|
||||||
return this->ProxyWindowBase::disownWindow();
|
return this->ProxyWindowBase::disownWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProxyShellWindow::setWidth(qint32 width) {
|
void WaylandShellWindow::setWidth(qint32 width) {
|
||||||
this->mWidth = width;
|
this->mWidth = width;
|
||||||
|
|
||||||
// only update the actual size if not blocked by anchors
|
// only update the actual size if not blocked by anchors
|
||||||
auto anchors = this->anchors();
|
auto anchors = this->anchors();
|
||||||
if (!anchors.mLeft || !anchors.mRight) this->ProxyWindowBase::setWidth(width);
|
if (!anchors.mLeft || !anchors.mRight) this->ProxyShellWindow::setWidth(width);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProxyShellWindow::setHeight(qint32 height) {
|
void WaylandShellWindow::setHeight(qint32 height) {
|
||||||
this->mHeight = height;
|
this->mHeight = height;
|
||||||
|
|
||||||
// only update the actual size if not blocked by anchors
|
// only update the actual size if not blocked by anchors
|
||||||
auto anchors = this->anchors();
|
auto anchors = this->anchors();
|
||||||
if (!anchors.mTop || !anchors.mBottom) this->ProxyWindowBase::setHeight(height);
|
if (!anchors.mTop || !anchors.mBottom) this->ProxyShellWindow::setHeight(height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProxyShellWindow::setAnchors(Anchors anchors) {
|
void WaylandShellWindow::setAnchors(Anchors anchors) {
|
||||||
if (this->window == nullptr) {
|
if (this->window == nullptr) {
|
||||||
this->mAnchors = anchors;
|
this->mAnchors = anchors;
|
||||||
return;
|
return;
|
||||||
|
@ -79,7 +90,7 @@ void ProxyShellWindow::setAnchors(Anchors anchors) {
|
||||||
this->shellWindow->setAnchors(lsAnchors);
|
this->shellWindow->setAnchors(lsAnchors);
|
||||||
}
|
}
|
||||||
|
|
||||||
Anchors ProxyShellWindow::anchors() const {
|
Anchors WaylandShellWindow::anchors() const {
|
||||||
if (this->window == nullptr) return this->mAnchors;
|
if (this->window == nullptr) return this->mAnchors;
|
||||||
|
|
||||||
auto lsAnchors = this->shellWindow->anchors();
|
auto lsAnchors = this->shellWindow->anchors();
|
||||||
|
@ -93,7 +104,7 @@ Anchors ProxyShellWindow::anchors() const {
|
||||||
return anchors;
|
return anchors;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProxyShellWindow::setExclusiveZone(qint32 zone) {
|
void WaylandShellWindow::setExclusiveZone(qint32 zone) {
|
||||||
if (zone < 0) zone = 0;
|
if (zone < 0) zone = 0;
|
||||||
if (this->connected && zone == this->mExclusionZone) return;
|
if (this->connected && zone == this->mExclusionZone) return;
|
||||||
this->mExclusionZone = zone;
|
this->mExclusionZone = zone;
|
||||||
|
@ -104,14 +115,14 @@ void ProxyShellWindow::setExclusiveZone(qint32 zone) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qint32 ProxyShellWindow::exclusiveZone() const {
|
qint32 WaylandShellWindow::exclusiveZone() const {
|
||||||
if (this->window == nullptr) return this->mExclusionZone;
|
if (this->window == nullptr) return this->mExclusionZone;
|
||||||
else return this->shellWindow->exclusionZone();
|
else return this->shellWindow->exclusionZone();
|
||||||
}
|
}
|
||||||
|
|
||||||
ExclusionMode::Enum ProxyShellWindow::exclusionMode() const { return this->mExclusionMode; }
|
ExclusionMode::Enum WaylandShellWindow::exclusionMode() const { return this->mExclusionMode; }
|
||||||
|
|
||||||
void ProxyShellWindow::setExclusionMode(ExclusionMode::Enum exclusionMode) {
|
void WaylandShellWindow::setExclusionMode(ExclusionMode::Enum exclusionMode) {
|
||||||
if (this->connected && exclusionMode == this->mExclusionMode) return;
|
if (this->connected && exclusionMode == this->mExclusionMode) return;
|
||||||
this->mExclusionMode = exclusionMode;
|
this->mExclusionMode = exclusionMode;
|
||||||
|
|
||||||
|
@ -128,7 +139,7 @@ void ProxyShellWindow::setExclusionMode(ExclusionMode::Enum exclusionMode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProxyShellWindow::setMargins(Margins margins) {
|
void WaylandShellWindow::setMargins(Margins margins) {
|
||||||
if (this->window == nullptr) this->mMargins = margins;
|
if (this->window == nullptr) this->mMargins = margins;
|
||||||
else {
|
else {
|
||||||
auto lsMargins = QMargins(margins.mLeft, margins.mTop, margins.mRight, margins.mBottom);
|
auto lsMargins = QMargins(margins.mLeft, margins.mTop, margins.mRight, margins.mBottom);
|
||||||
|
@ -136,7 +147,7 @@ void ProxyShellWindow::setMargins(Margins margins) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Margins ProxyShellWindow::margins() const {
|
Margins WaylandShellWindow::margins() const {
|
||||||
if (this->window == nullptr) return this->mMargins;
|
if (this->window == nullptr) return this->mMargins;
|
||||||
auto lsMargins = this->shellWindow->margins();
|
auto lsMargins = this->shellWindow->margins();
|
||||||
|
|
||||||
|
@ -149,9 +160,9 @@ Margins ProxyShellWindow::margins() const {
|
||||||
return margins;
|
return margins;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProxyShellWindow::setLayer(Layer::Enum layer) {
|
void WaylandShellWindowExtensions::setLayer(Layer::Enum layer) {
|
||||||
if (this->window == nullptr) {
|
if (this->window->window == nullptr) {
|
||||||
this->mLayer = layer;
|
this->window->mLayer = layer;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,14 +177,14 @@ void ProxyShellWindow::setLayer(Layer::Enum layer) {
|
||||||
}
|
}
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
this->shellWindow->setLayer(lsLayer);
|
this->window->shellWindow->setLayer(lsLayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
Layer::Enum ProxyShellWindow::layer() const {
|
Layer::Enum WaylandShellWindowExtensions::layer() const {
|
||||||
if (this->window == nullptr) return this->mLayer;
|
if (this->window->window == nullptr) return this->window->mLayer;
|
||||||
|
|
||||||
auto layer = Layer::Top;
|
auto layer = Layer::Top;
|
||||||
auto lsLayer = this->shellWindow->layer();
|
auto lsLayer = this->window->shellWindow->layer();
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
switch (lsLayer) {
|
switch (lsLayer) {
|
||||||
|
@ -187,19 +198,19 @@ Layer::Enum ProxyShellWindow::layer() const {
|
||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProxyShellWindow::setScope(const QString& scope) {
|
void WaylandShellWindowExtensions::setScope(const QString& scope) {
|
||||||
if (this->window == nullptr) this->mScope = scope;
|
if (this->window->window == nullptr) this->window->mScope = scope;
|
||||||
else this->shellWindow->setScope(scope);
|
else this->window->shellWindow->setScope(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ProxyShellWindow::scope() const {
|
QString WaylandShellWindowExtensions::scope() const {
|
||||||
if (this->window == nullptr) return this->mScope;
|
if (this->window->window == nullptr) return this->window->mScope;
|
||||||
else return this->shellWindow->scope();
|
else return this->window->shellWindow->scope();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProxyShellWindow::setKeyboardFocus(KeyboardFocus::Enum focus) {
|
void WaylandShellWindowExtensions::setKeyboardFocus(KeyboardFocus::Enum focus) {
|
||||||
if (this->window == nullptr) {
|
if (this->window->window == nullptr) {
|
||||||
this->mKeyboardFocus = focus;
|
this->window->mKeyboardFocus = focus;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,14 +224,14 @@ void ProxyShellWindow::setKeyboardFocus(KeyboardFocus::Enum focus) {
|
||||||
}
|
}
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
this->shellWindow->setKeyboardInteractivity(lsFocus);
|
this->window->shellWindow->setKeyboardInteractivity(lsFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyboardFocus::Enum ProxyShellWindow::keyboardFocus() const {
|
KeyboardFocus::Enum WaylandShellWindowExtensions::keyboardFocus() const {
|
||||||
if (this->window == nullptr) return this->mKeyboardFocus;
|
if (this->window->window == nullptr) return this->window->mKeyboardFocus;
|
||||||
|
|
||||||
auto focus = KeyboardFocus::None;
|
auto focus = KeyboardFocus::None;
|
||||||
auto lsFocus = this->shellWindow->keyboardInteractivity();
|
auto lsFocus = this->window->shellWindow->keyboardInteractivity();
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
switch (lsFocus) {
|
switch (lsFocus) {
|
||||||
|
@ -233,9 +244,9 @@ KeyboardFocus::Enum ProxyShellWindow::keyboardFocus() const {
|
||||||
return focus;
|
return focus;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProxyShellWindow::setScreenConfiguration(ScreenConfiguration::Enum configuration) {
|
void WaylandShellWindowExtensions::setScreenConfiguration(ScreenConfiguration::Enum configuration) {
|
||||||
if (this->window == nullptr) {
|
if (this->window->window == nullptr) {
|
||||||
this->mScreenConfiguration = configuration;
|
this->window->mScreenConfiguration = configuration;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,14 +259,14 @@ void ProxyShellWindow::setScreenConfiguration(ScreenConfiguration::Enum configur
|
||||||
}
|
}
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
this->shellWindow->setScreenConfiguration(lsConfiguration);
|
this->window->shellWindow->setScreenConfiguration(lsConfiguration);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenConfiguration::Enum ProxyShellWindow::screenConfiguration() const {
|
ScreenConfiguration::Enum WaylandShellWindowExtensions::screenConfiguration() const {
|
||||||
if (this->window == nullptr) return this->mScreenConfiguration;
|
if (this->window->window == nullptr) return this->window->mScreenConfiguration;
|
||||||
|
|
||||||
auto configuration = ScreenConfiguration::Window;
|
auto configuration = ScreenConfiguration::Window;
|
||||||
auto lsConfiguration = this->shellWindow->screenConfiguration();
|
auto lsConfiguration = this->window->shellWindow->screenConfiguration();
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
switch (lsConfiguration) {
|
switch (lsConfiguration) {
|
||||||
|
@ -267,7 +278,7 @@ ScreenConfiguration::Enum ProxyShellWindow::screenConfiguration() const {
|
||||||
return configuration;
|
return configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProxyShellWindow::updateExclusionZone() {
|
void WaylandShellWindow::updateExclusionZone() {
|
||||||
if (this->window != nullptr && this->exclusionMode() == ExclusionMode::Auto) {
|
if (this->window != nullptr && this->exclusionMode() == ExclusionMode::Auto) {
|
||||||
auto anchors = this->anchors();
|
auto anchors = this->anchors();
|
||||||
|
|
||||||
|
|
|
@ -3,62 +3,10 @@
|
||||||
#include <LayerShellQt/window.h>
|
#include <LayerShellQt/window.h>
|
||||||
#include <qobject.h>
|
#include <qobject.h>
|
||||||
#include <qqmlintegration.h>
|
#include <qqmlintegration.h>
|
||||||
#include <qqmllist.h>
|
|
||||||
#include <qquickwindow.h>
|
|
||||||
#include <qscreen.h>
|
|
||||||
#include <qtmetamacros.h>
|
#include <qtmetamacros.h>
|
||||||
#include <qtypes.h>
|
#include <qtypes.h>
|
||||||
#include <qvariant.h>
|
|
||||||
#include <qwindow.h>
|
|
||||||
|
|
||||||
#include "proxywindow.hpp"
|
#include "shellwindow.hpp"
|
||||||
|
|
||||||
class Anchors {
|
|
||||||
Q_GADGET;
|
|
||||||
Q_PROPERTY(bool left MEMBER mLeft);
|
|
||||||
Q_PROPERTY(bool right MEMBER mRight);
|
|
||||||
Q_PROPERTY(bool top MEMBER mTop);
|
|
||||||
Q_PROPERTY(bool bottom MEMBER mBottom);
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool mLeft = false;
|
|
||||||
bool mRight = false;
|
|
||||||
bool mTop = false;
|
|
||||||
bool mBottom = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Margins {
|
|
||||||
Q_GADGET;
|
|
||||||
Q_PROPERTY(qint32 left MEMBER mLeft);
|
|
||||||
Q_PROPERTY(qint32 right MEMBER mRight);
|
|
||||||
Q_PROPERTY(qint32 top MEMBER mTop);
|
|
||||||
Q_PROPERTY(qint32 bottom MEMBER mBottom);
|
|
||||||
|
|
||||||
public:
|
|
||||||
qint32 mLeft = 0;
|
|
||||||
qint32 mRight = 0;
|
|
||||||
qint32 mTop = 0;
|
|
||||||
qint32 mBottom = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace ExclusionMode { // NOLINT
|
|
||||||
Q_NAMESPACE;
|
|
||||||
QML_ELEMENT;
|
|
||||||
|
|
||||||
enum Enum {
|
|
||||||
/// Respect the exclusion zone of other shell layers and optionally set one
|
|
||||||
Normal = 0,
|
|
||||||
/// Ignore exclusion zones of other shell layers. You cannot set an exclusion zone in this mode.
|
|
||||||
Ignore = 1,
|
|
||||||
/// Decide the exclusion zone based on the window dimensions and anchors.
|
|
||||||
///
|
|
||||||
/// Will attempt to reseve exactly enough space for the window and its margins if
|
|
||||||
/// exactly 3 anchors are connected.
|
|
||||||
Auto = 2,
|
|
||||||
};
|
|
||||||
Q_ENUM_NS(Enum);
|
|
||||||
|
|
||||||
} // namespace ExclusionMode
|
|
||||||
|
|
||||||
namespace Layer { // NOLINT
|
namespace Layer { // NOLINT
|
||||||
Q_NAMESPACE;
|
Q_NAMESPACE;
|
||||||
|
@ -109,78 +57,69 @@ Q_ENUM_NS(Enum);
|
||||||
|
|
||||||
} // namespace ScreenConfiguration
|
} // namespace ScreenConfiguration
|
||||||
|
|
||||||
///! Decorationless window attached to screen edges by anchors.
|
class WaylandShellWindowExtensions;
|
||||||
/// Decorationless window attached to screen edges by anchors.
|
|
||||||
///
|
class WaylandShellWindow: public ProxyShellWindow {
|
||||||
/// #### Example
|
Q_OBJECT;
|
||||||
/// The following snippet creates a white bar attached to the bottom of [TODO] screen.
|
Q_PROPERTY(WaylandShellWindowExtensions* wayland MEMBER mWayland CONSTANT);
|
||||||
///
|
QML_NAMED_ELEMENT(ShellWindow);
|
||||||
/// ```qml
|
|
||||||
/// ShellWindow {
|
public:
|
||||||
/// anchors {
|
explicit WaylandShellWindow(QObject* parent = nullptr);
|
||||||
/// left: true
|
|
||||||
/// bottom: true
|
WaylandShellWindowExtensions* wayland();
|
||||||
/// right: true
|
|
||||||
/// }
|
void setupWindow() override;
|
||||||
///
|
QQuickWindow* disownWindow() override;
|
||||||
/// Text {
|
|
||||||
/// anchors.horizontalCenter: parent.horizontalCenter
|
void setWidth(qint32 width) override;
|
||||||
/// anchors.verticalCenter: parent.verticalCenter
|
void setHeight(qint32 height) override;
|
||||||
/// text: "Hello!"
|
|
||||||
/// }
|
void setAnchors(Anchors anchors) override;
|
||||||
/// }
|
[[nodiscard]] Anchors anchors() const override;
|
||||||
/// ```
|
|
||||||
class ProxyShellWindow: public ProxyWindowBase {
|
void setExclusiveZone(qint32 zone) override;
|
||||||
// clang-format off
|
[[nodiscard]] qint32 exclusiveZone() const override;
|
||||||
|
|
||||||
|
void setExclusionMode(ExclusionMode::Enum exclusionMode) override;
|
||||||
|
[[nodiscard]] ExclusionMode::Enum exclusionMode() const override;
|
||||||
|
|
||||||
|
void setMargins(Margins margins) override;
|
||||||
|
[[nodiscard]] Margins margins() const override;
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void updateExclusionZone();
|
||||||
|
|
||||||
|
private:
|
||||||
|
WaylandShellWindowExtensions* mWayland = nullptr;
|
||||||
|
|
||||||
|
LayerShellQt::Window* shellWindow = nullptr;
|
||||||
|
Layer::Enum mLayer = Layer::Top;
|
||||||
|
QString mScope;
|
||||||
|
KeyboardFocus::Enum mKeyboardFocus = KeyboardFocus::None;
|
||||||
|
ScreenConfiguration::Enum mScreenConfiguration = ScreenConfiguration::Window;
|
||||||
|
|
||||||
|
bool connected = false;
|
||||||
|
|
||||||
|
friend class WaylandShellWindowExtensions;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WaylandShellWindowExtensions: public QObject {
|
||||||
Q_OBJECT;
|
Q_OBJECT;
|
||||||
/// Anchors attach a shell window to the sides of the screen.
|
|
||||||
/// By default all anchors are disabled to avoid blocking the entire screen due to a misconfiguration.
|
|
||||||
///
|
|
||||||
/// > [!INFO] When two opposite anchors are attached at the same time, the corrosponding dimension
|
|
||||||
/// > (width or height) will be forced to equal the screen width/height.
|
|
||||||
/// > Margins can be used to create anchored windows that are also disconnected from the monitor sides.
|
|
||||||
Q_PROPERTY(Anchors anchors READ anchors WRITE setAnchors NOTIFY anchorsChanged);
|
|
||||||
/// The amount of space reserved for the shell layer relative to its anchors.
|
|
||||||
///
|
|
||||||
/// > [!INFO] Some systems will require exactly 3 anchors to be attached for the exclusion zone to take
|
|
||||||
/// > effect.
|
|
||||||
Q_PROPERTY(qint32 exclusionZone READ exclusiveZone WRITE setExclusiveZone NOTIFY exclusionZoneChanged);
|
|
||||||
/// Defaults to `ExclusionMode.Normal`.
|
|
||||||
Q_PROPERTY(ExclusionMode::Enum exclusionMode READ exclusionMode WRITE setExclusionMode NOTIFY exclusionModeChanged);
|
|
||||||
/// Offsets from the sides of the screen.
|
|
||||||
///
|
|
||||||
/// > [!INFO] Only applies to edges with anchors
|
|
||||||
Q_PROPERTY(Margins margins READ margins WRITE setMargins NOTIFY marginsChanged);
|
|
||||||
/// The shell layer the window sits in. Defaults to `Layer.Top`.
|
/// The shell layer the window sits in. Defaults to `Layer.Top`.
|
||||||
Q_PROPERTY(Layer::Enum layer READ layer WRITE setLayer NOTIFY layerChanged);
|
Q_PROPERTY(Layer::Enum layer READ layer WRITE setLayer NOTIFY layerChanged);
|
||||||
Q_PROPERTY(QString scope READ scope WRITE setScope);
|
Q_PROPERTY(QString scope READ scope WRITE setScope);
|
||||||
/// The degree of keyboard focus taken. Defaults to `KeyboardFocus.None`.
|
/// The degree of keyboard focus taken. Defaults to `KeyboardFocus.None`.
|
||||||
Q_PROPERTY(KeyboardFocus::Enum keyboardFocus READ keyboardFocus WRITE setKeyboardFocus NOTIFY keyboardFocusChanged);
|
Q_PROPERTY(KeyboardFocus::Enum keyboardFocus READ keyboardFocus WRITE setKeyboardFocus NOTIFY
|
||||||
Q_PROPERTY(ScreenConfiguration::Enum screenConfiguration READ screenConfiguration WRITE setScreenConfiguration);
|
keyboardFocusChanged);
|
||||||
QML_NAMED_ELEMENT(ShellWindow);
|
Q_PROPERTY(ScreenConfiguration::Enum screenConfiguration READ screenConfiguration WRITE
|
||||||
// clang-format on
|
setScreenConfiguration);
|
||||||
|
QML_ELEMENT;
|
||||||
|
QML_UNCREATABLE("WaylandShellWindowExtensions cannot be created");
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void setupWindow() override;
|
explicit WaylandShellWindowExtensions(WaylandShellWindow* window):
|
||||||
QQuickWindow* disownWindow() override;
|
QObject(window), window(window) {}
|
||||||
|
|
||||||
QQmlListProperty<QObject> data();
|
|
||||||
|
|
||||||
void setWidth(qint32 width) override;
|
|
||||||
|
|
||||||
void setHeight(qint32 height) override;
|
|
||||||
|
|
||||||
void setAnchors(Anchors anchors);
|
|
||||||
[[nodiscard]] Anchors anchors() const;
|
|
||||||
|
|
||||||
void setExclusiveZone(qint32 zone);
|
|
||||||
[[nodiscard]] qint32 exclusiveZone() const;
|
|
||||||
|
|
||||||
void setExclusionMode(ExclusionMode::Enum exclusionMode);
|
|
||||||
[[nodiscard]] ExclusionMode::Enum exclusionMode() const;
|
|
||||||
|
|
||||||
void setMargins(Margins margins);
|
|
||||||
[[nodiscard]] Margins margins() const;
|
|
||||||
|
|
||||||
void setLayer(Layer::Enum layer);
|
void setLayer(Layer::Enum layer);
|
||||||
[[nodiscard]] Layer::Enum layer() const;
|
[[nodiscard]] Layer::Enum layer() const;
|
||||||
|
@ -195,26 +134,11 @@ public:
|
||||||
[[nodiscard]] ScreenConfiguration::Enum screenConfiguration() const;
|
[[nodiscard]] ScreenConfiguration::Enum screenConfiguration() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void anchorsChanged();
|
|
||||||
void marginsChanged();
|
|
||||||
void exclusionZoneChanged();
|
|
||||||
void exclusionModeChanged();
|
|
||||||
void layerChanged();
|
void layerChanged();
|
||||||
void keyboardFocusChanged();
|
void keyboardFocusChanged();
|
||||||
|
|
||||||
private slots:
|
|
||||||
void updateExclusionZone();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LayerShellQt::Window* shellWindow = nullptr;
|
WaylandShellWindow* window;
|
||||||
ExclusionMode::Enum mExclusionMode = ExclusionMode::Normal;
|
|
||||||
qint32 mExclusionZone = 0;
|
|
||||||
Anchors mAnchors;
|
|
||||||
Margins mMargins;
|
|
||||||
Layer::Enum mLayer = Layer::Top;
|
|
||||||
QString mScope;
|
|
||||||
KeyboardFocus::Enum mKeyboardFocus = KeyboardFocus::None;
|
|
||||||
ScreenConfiguration::Enum mScreenConfiguration = ScreenConfiguration::Window;
|
|
||||||
|
|
||||||
bool connected = false;
|
friend class WaylandShellWindow;
|
||||||
};
|
};
|
||||||
|
|
1
src/cpp/shellwindow.cpp
Normal file
1
src/cpp/shellwindow.cpp
Normal file
|
@ -0,0 +1 @@
|
||||||
|
#include "shellwindow.hpp" // NOLINT
|
134
src/cpp/shellwindow.hpp
Normal file
134
src/cpp/shellwindow.hpp
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <qobject.h>
|
||||||
|
#include <qqmlintegration.h>
|
||||||
|
#include <qqmllist.h>
|
||||||
|
#include <qquickwindow.h>
|
||||||
|
#include <qscreen.h>
|
||||||
|
#include <qtmetamacros.h>
|
||||||
|
#include <qtypes.h>
|
||||||
|
#include <qvariant.h>
|
||||||
|
#include <qwindow.h>
|
||||||
|
|
||||||
|
#include "proxywindow.hpp"
|
||||||
|
|
||||||
|
class Anchors {
|
||||||
|
Q_GADGET;
|
||||||
|
Q_PROPERTY(bool left MEMBER mLeft);
|
||||||
|
Q_PROPERTY(bool right MEMBER mRight);
|
||||||
|
Q_PROPERTY(bool top MEMBER mTop);
|
||||||
|
Q_PROPERTY(bool bottom MEMBER mBottom);
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool mLeft = false;
|
||||||
|
bool mRight = false;
|
||||||
|
bool mTop = false;
|
||||||
|
bool mBottom = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Margins {
|
||||||
|
Q_GADGET;
|
||||||
|
Q_PROPERTY(qint32 left MEMBER mLeft);
|
||||||
|
Q_PROPERTY(qint32 right MEMBER mRight);
|
||||||
|
Q_PROPERTY(qint32 top MEMBER mTop);
|
||||||
|
Q_PROPERTY(qint32 bottom MEMBER mBottom);
|
||||||
|
|
||||||
|
public:
|
||||||
|
qint32 mLeft = 0;
|
||||||
|
qint32 mRight = 0;
|
||||||
|
qint32 mTop = 0;
|
||||||
|
qint32 mBottom = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace ExclusionMode { // NOLINT
|
||||||
|
Q_NAMESPACE;
|
||||||
|
QML_ELEMENT;
|
||||||
|
|
||||||
|
enum Enum {
|
||||||
|
/// Respect the exclusion zone of other shell layers and optionally set one
|
||||||
|
Normal = 0,
|
||||||
|
/// Ignore exclusion zones of other shell layers. You cannot set an exclusion zone in this mode.
|
||||||
|
Ignore = 1,
|
||||||
|
/// Decide the exclusion zone based on the window dimensions and anchors.
|
||||||
|
///
|
||||||
|
/// Will attempt to reseve exactly enough space for the window and its margins if
|
||||||
|
/// exactly 3 anchors are connected.
|
||||||
|
Auto = 2,
|
||||||
|
};
|
||||||
|
Q_ENUM_NS(Enum);
|
||||||
|
|
||||||
|
} // namespace ExclusionMode
|
||||||
|
|
||||||
|
///! Decorationless window attached to screen edges by anchors.
|
||||||
|
/// Decorationless window attached to screen edges by anchors.
|
||||||
|
///
|
||||||
|
/// #### Example
|
||||||
|
/// The following snippet creates a white bar attached to the bottom of the screen.
|
||||||
|
///
|
||||||
|
/// ```qml
|
||||||
|
/// ShellWindow {
|
||||||
|
/// anchors {
|
||||||
|
/// left: true
|
||||||
|
/// bottom: true
|
||||||
|
/// right: true
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// Text {
|
||||||
|
/// anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
/// anchors.verticalCenter: parent.verticalCenter
|
||||||
|
/// text: "Hello!"
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
class ProxyShellWindow: public ProxyWindowBase {
|
||||||
|
// clang-format off
|
||||||
|
Q_OBJECT;
|
||||||
|
/// Anchors attach a shell window to the sides of the screen.
|
||||||
|
/// By default all anchors are disabled to avoid blocking the entire screen due to a misconfiguration.
|
||||||
|
///
|
||||||
|
/// > [!INFO] When two opposite anchors are attached at the same time, the corrosponding dimension
|
||||||
|
/// > (width or height) will be forced to equal the screen width/height.
|
||||||
|
/// > Margins can be used to create anchored windows that are also disconnected from the monitor sides.
|
||||||
|
Q_PROPERTY(Anchors anchors READ anchors WRITE setAnchors NOTIFY anchorsChanged);
|
||||||
|
/// The amount of space reserved for the shell layer relative to its anchors.
|
||||||
|
///
|
||||||
|
/// > [!INFO] Some systems will require exactly 3 anchors to be attached for the exclusion zone to take
|
||||||
|
/// > effect.
|
||||||
|
Q_PROPERTY(qint32 exclusionZone READ exclusiveZone WRITE setExclusiveZone NOTIFY exclusionZoneChanged);
|
||||||
|
/// Defaults to `ExclusionMode.Normal`.
|
||||||
|
Q_PROPERTY(ExclusionMode::Enum exclusionMode READ exclusionMode WRITE setExclusionMode NOTIFY exclusionModeChanged);
|
||||||
|
/// Offsets from the sides of the screen.
|
||||||
|
///
|
||||||
|
/// > [!INFO] Only applies to edges with anchors
|
||||||
|
Q_PROPERTY(Margins margins READ margins WRITE setMargins NOTIFY marginsChanged);
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ProxyShellWindow(QObject* parent = nullptr): ProxyWindowBase(parent) {}
|
||||||
|
|
||||||
|
QQmlListProperty<QObject> data();
|
||||||
|
|
||||||
|
virtual void setAnchors(Anchors anchors) = 0;
|
||||||
|
[[nodiscard]] virtual Anchors anchors() const = 0;
|
||||||
|
|
||||||
|
virtual void setExclusiveZone(qint32 zone) = 0;
|
||||||
|
[[nodiscard]] virtual qint32 exclusiveZone() const = 0;
|
||||||
|
|
||||||
|
virtual void setExclusionMode(ExclusionMode::Enum exclusionMode) = 0;
|
||||||
|
[[nodiscard]] virtual ExclusionMode::Enum exclusionMode() const = 0;
|
||||||
|
|
||||||
|
virtual void setMargins(Margins margins) = 0;
|
||||||
|
[[nodiscard]] virtual Margins margins() const = 0;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void anchorsChanged();
|
||||||
|
void marginsChanged();
|
||||||
|
void exclusionZoneChanged();
|
||||||
|
void exclusionModeChanged();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ExclusionMode::Enum mExclusionMode = ExclusionMode::Normal;
|
||||||
|
qint32 mExclusionZone = 0;
|
||||||
|
Anchors mAnchors;
|
||||||
|
Margins mMargins;
|
||||||
|
};
|
Loading…
Reference in a new issue