mirror of
https://git.outfoxxed.me/quickshell/quickshell.git
synced 2026-04-10 06:11:54 +10:00
wm: add WindowManager module with ext-workspace support
This commit is contained in:
parent
9e8eecf2b8
commit
6705e2da77
22 changed files with 1337 additions and 0 deletions
20
src/windowmanager/CMakeLists.txt
Normal file
20
src/windowmanager/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
qt_add_library(quickshell-windowmanager STATIC
|
||||
screenprojection.cpp
|
||||
windowmanager.cpp
|
||||
windowset.cpp
|
||||
)
|
||||
|
||||
qt_add_qml_module(quickshell-windowmanager
|
||||
URI Quickshell.WindowManager
|
||||
VERSION 0.1
|
||||
DEPENDENCIES QtQuick
|
||||
)
|
||||
|
||||
qs_add_module_deps_light(quickshell-windowmanager Quickshell)
|
||||
|
||||
install_qml_module(quickshell-windowmanager)
|
||||
|
||||
qs_module_pch(quickshell-windowmanager SET large)
|
||||
|
||||
target_link_libraries(quickshell-windowmanager PRIVATE Qt::Quick)
|
||||
target_link_libraries(quickshell PRIVATE quickshell-windowmanagerplugin)
|
||||
10
src/windowmanager/module.md
Normal file
10
src/windowmanager/module.md
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
name = "Quickshell.WindowManager"
|
||||
description = "Window manager interface"
|
||||
headers = [
|
||||
"windowmanager.hpp",
|
||||
"windowset.hpp",
|
||||
"screenprojection.hpp",
|
||||
]
|
||||
-----
|
||||
Currently only supports the [ext-workspace-v1](https://wayland.app/protocols/ext-workspace-v1) wayland protocol.
|
||||
Support will be expanded in future releases.
|
||||
30
src/windowmanager/screenprojection.cpp
Normal file
30
src/windowmanager/screenprojection.cpp
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#include "screenprojection.hpp"
|
||||
|
||||
#include <qlist.h>
|
||||
#include <qobject.h>
|
||||
#include <qscreen.h>
|
||||
|
||||
#include "windowmanager.hpp"
|
||||
#include "windowset.hpp"
|
||||
|
||||
namespace qs::wm {
|
||||
|
||||
ScreenProjection::ScreenProjection(QScreen* screen, QObject* parent)
|
||||
: WindowsetProjection(parent)
|
||||
, mScreen(screen) {
|
||||
this->bQScreens = {screen};
|
||||
this->bWindowsets.setBinding([this]() {
|
||||
QList<Windowset*> result;
|
||||
for (auto* ws: WindowManager::instance()->bindableWindowsets().value()) {
|
||||
auto* proj = ws->bindableProjection().value();
|
||||
if (proj && proj->bindableQScreens().value().contains(this->mScreen)) {
|
||||
result.append(ws);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
QScreen* ScreenProjection::screen() const { return this->mScreen; }
|
||||
|
||||
} // namespace qs::wm
|
||||
34
src/windowmanager/screenprojection.hpp
Normal file
34
src/windowmanager/screenprojection.hpp
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
|
||||
#include <qobject.h>
|
||||
#include <qqmlintegration.h>
|
||||
#include <qscreen.h>
|
||||
#include <qtmetamacros.h>
|
||||
|
||||
#include "windowset.hpp"
|
||||
|
||||
namespace qs::wm {
|
||||
|
||||
///! WindowsetProjection covering one specific screen.
|
||||
/// A ScreenProjection is a special type of @@WindowsetProjection which aggregates
|
||||
/// all windowsets across all projections covering a specific screen.
|
||||
///
|
||||
/// When used with @@Windowset.setProjection(), an arbitrary projection on the screen
|
||||
/// will be picked. Usually there is only one.
|
||||
///
|
||||
/// Use @@WindowManager.screenProjection() to get a ScreenProjection for a given screen.
|
||||
class ScreenProjection: public WindowsetProjection {
|
||||
Q_OBJECT;
|
||||
QML_ELEMENT;
|
||||
QML_UNCREATABLE("");
|
||||
|
||||
public:
|
||||
ScreenProjection(QScreen* screen, QObject* parent);
|
||||
|
||||
[[nodiscard]] QScreen* screen() const;
|
||||
|
||||
private:
|
||||
QScreen* mScreen;
|
||||
};
|
||||
|
||||
} // namespace qs::wm
|
||||
86
src/windowmanager/test/manual/WorkspaceDelegate.qml
Normal file
86
src/windowmanager/test/manual/WorkspaceDelegate.qml
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls.Fusion
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.WindowManager
|
||||
|
||||
WrapperRectangle {
|
||||
id: delegate
|
||||
required property Windowset modelData;
|
||||
color: modelData.active ? "green" : "gray"
|
||||
|
||||
ColumnLayout {
|
||||
Label { text: delegate.modelData.toString() }
|
||||
Label { text: `Id: ${delegate.modelData.id} Name: ${delegate.modelData.name}` }
|
||||
Label { text: `Coordinates: ${delegate.modelData.coordinates.toString()}`}
|
||||
|
||||
RowLayout {
|
||||
Label { text: "Group:" }
|
||||
ComboBox {
|
||||
Layout.fillWidth: true
|
||||
implicitContentWidthPolicy: ComboBox.WidestText
|
||||
enabled: delegate.modelData.canSetProjection
|
||||
model: [...WindowManager.windowsetProjections].map(w => w.toString())
|
||||
currentIndex: WindowManager.windowsetProjections.indexOf(delegate.modelData.projection)
|
||||
onActivated: i => delegate.modelData.setProjection(WindowManager.windowsetProjections[i])
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Label { text: "Screen:" }
|
||||
ComboBox {
|
||||
Layout.fillWidth: true
|
||||
implicitContentWidthPolicy: ComboBox.WidestText
|
||||
enabled: delegate.modelData.canSetProjection
|
||||
model: [...Quickshell.screens].map(w => w.name)
|
||||
currentIndex: Quickshell.screens.indexOf(delegate.modelData.projection.screens[0])
|
||||
onActivated: i => delegate.modelData.setProjection(WindowManager.screenProjection(Quickshell.screens[i]))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RowLayout {
|
||||
DisplayCheckBox {
|
||||
text: "Active"
|
||||
checked: delegate.modelData.active
|
||||
}
|
||||
|
||||
DisplayCheckBox {
|
||||
text: "Urgent"
|
||||
checked: delegate.modelData.urgent
|
||||
}
|
||||
|
||||
DisplayCheckBox {
|
||||
text: "Should Display"
|
||||
checked: delegate.modelData.shouldDisplay
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Button {
|
||||
text: "Activate"
|
||||
enabled: delegate.modelData.canActivate
|
||||
onClicked: delegate.modelData.activate()
|
||||
}
|
||||
|
||||
Button {
|
||||
text: "Deactivate"
|
||||
enabled: delegate.modelData.canDeactivate
|
||||
onClicked: delegate.modelData.deactivate()
|
||||
}
|
||||
|
||||
Button {
|
||||
text: "Remove"
|
||||
enabled: delegate.modelData.canRemove
|
||||
onClicked: delegate.modelData.remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component DisplayCheckBox: CheckBox {
|
||||
enabled: false
|
||||
palette.disabled.text: parent.palette.active.text
|
||||
palette.disabled.windowText: parent.palette.active.windowText
|
||||
}
|
||||
}
|
||||
45
src/windowmanager/test/manual/screenproj.qml
Normal file
45
src/windowmanager/test/manual/screenproj.qml
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls.Fusion
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.WindowManager
|
||||
|
||||
FloatingWindow {
|
||||
ScrollView {
|
||||
anchors.fill: parent
|
||||
|
||||
ColumnLayout {
|
||||
Repeater {
|
||||
model: Quickshell.screens
|
||||
|
||||
WrapperRectangle {
|
||||
id: delegate
|
||||
required property ShellScreen modelData
|
||||
color: "slategray"
|
||||
margin: 5
|
||||
|
||||
ColumnLayout {
|
||||
Label { text: `Screen: ${delegate.modelData.name}` }
|
||||
|
||||
Repeater {
|
||||
model: ScriptModel {
|
||||
values: WindowManager.screenProjection(delegate.modelData).windowsets
|
||||
}
|
||||
|
||||
WorkspaceDelegate {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: ScriptModel {
|
||||
values: WindowManager.windowsets.filter(w => w.projection == null)
|
||||
}
|
||||
|
||||
WorkspaceDelegate {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
46
src/windowmanager/test/manual/workspaces.qml
Normal file
46
src/windowmanager/test/manual/workspaces.qml
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls.Fusion
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.WindowManager
|
||||
|
||||
FloatingWindow {
|
||||
ScrollView {
|
||||
anchors.fill: parent
|
||||
|
||||
ColumnLayout {
|
||||
Repeater {
|
||||
model: WindowManager.windowsetProjections
|
||||
|
||||
WrapperRectangle {
|
||||
id: delegate
|
||||
required property WindowsetProjection modelData
|
||||
color: "slategray"
|
||||
margin: 5
|
||||
|
||||
ColumnLayout {
|
||||
Label { text: delegate.modelData.toString() }
|
||||
Label { text: `Screens: ${delegate.modelData.screens.map(s => s.name)}` }
|
||||
|
||||
Repeater {
|
||||
model: ScriptModel {
|
||||
values: delegate.modelData.windowsets
|
||||
}
|
||||
|
||||
WorkspaceDelegate {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: ScriptModel {
|
||||
values: WindowManager.windowsets.filter(w => w.projection == null)
|
||||
}
|
||||
|
||||
WorkspaceDelegate {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
41
src/windowmanager/windowmanager.cpp
Normal file
41
src/windowmanager/windowmanager.cpp
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#include "windowmanager.hpp"
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
#include <qobject.h>
|
||||
|
||||
#include "../core/qmlscreen.hpp"
|
||||
#include "screenprojection.hpp"
|
||||
|
||||
namespace qs::wm {
|
||||
|
||||
std::function<WindowManager*()> WindowManager::provider;
|
||||
|
||||
void WindowManager::setProvider(std::function<WindowManager*()> provider) {
|
||||
WindowManager::provider = std::move(provider);
|
||||
}
|
||||
|
||||
WindowManager* WindowManager::instance() {
|
||||
static auto* instance = WindowManager::provider();
|
||||
return instance;
|
||||
}
|
||||
|
||||
ScreenProjection* WindowManager::screenProjection(QuickshellScreenInfo* screen) {
|
||||
auto* qscreen = screen->screen;
|
||||
auto it = this->mScreenProjections.find(qscreen);
|
||||
if (it != this->mScreenProjections.end()) {
|
||||
return *it;
|
||||
}
|
||||
|
||||
auto* projection = new ScreenProjection(qscreen, this);
|
||||
this->mScreenProjections.insert(qscreen, projection);
|
||||
|
||||
QObject::connect(qscreen, &QObject::destroyed, this, [this, projection, qscreen]() {
|
||||
this->mScreenProjections.remove(qscreen);
|
||||
delete projection;
|
||||
});
|
||||
|
||||
return projection;
|
||||
}
|
||||
|
||||
} // namespace qs::wm
|
||||
91
src/windowmanager/windowmanager.hpp
Normal file
91
src/windowmanager/windowmanager.hpp
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <qhash.h>
|
||||
#include <qlist.h>
|
||||
#include <qobject.h>
|
||||
#include <qproperty.h>
|
||||
#include <qqmlintegration.h>
|
||||
#include <qscreen.h>
|
||||
#include <qtmetamacros.h>
|
||||
|
||||
#include "../core/qmlscreen.hpp"
|
||||
#include "screenprojection.hpp"
|
||||
#include "windowset.hpp"
|
||||
|
||||
namespace qs::wm {
|
||||
|
||||
class WindowManager: public QObject {
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
static void setProvider(std::function<WindowManager*()> provider);
|
||||
static WindowManager* instance();
|
||||
|
||||
Q_INVOKABLE ScreenProjection* screenProjection(QuickshellScreenInfo* screen);
|
||||
|
||||
[[nodiscard]] QBindable<QList<Windowset*>> bindableWindowsets() const {
|
||||
return &this->bWindowsets;
|
||||
}
|
||||
|
||||
[[nodiscard]] QBindable<QList<WindowsetProjection*>> bindableWindowsetProjections() const {
|
||||
return &this->bWindowsetProjections;
|
||||
}
|
||||
|
||||
signals:
|
||||
void windowsetsChanged();
|
||||
void windowsetProjectionsChanged();
|
||||
|
||||
public:
|
||||
Q_OBJECT_BINDABLE_PROPERTY(
|
||||
WindowManager,
|
||||
QList<Windowset*>,
|
||||
bWindowsets,
|
||||
&WindowManager::windowsetsChanged
|
||||
);
|
||||
|
||||
Q_OBJECT_BINDABLE_PROPERTY(
|
||||
WindowManager,
|
||||
QList<WindowsetProjection*>,
|
||||
bWindowsetProjections,
|
||||
&WindowManager::windowsetProjectionsChanged
|
||||
);
|
||||
|
||||
private:
|
||||
static std::function<WindowManager*()> provider;
|
||||
QHash<QScreen*, ScreenProjection*> mScreenProjections;
|
||||
};
|
||||
|
||||
///! Window management interfaces exposed by the window manager.
|
||||
class WindowManagerQml: public QObject {
|
||||
Q_OBJECT;
|
||||
QML_NAMED_ELEMENT(WindowManager);
|
||||
QML_SINGLETON;
|
||||
// clang-format off
|
||||
/// All windowsets tracked by the WM across all projections.
|
||||
Q_PROPERTY(QList<Windowset*> windowsets READ default BINDABLE bindableWindowsets);
|
||||
/// All windowset projections tracked by the WM. Does not include
|
||||
/// internal projections from @@screenProjection().
|
||||
Q_PROPERTY(QList<WindowsetProjection*> windowsetProjections READ default BINDABLE bindableWindowsetProjections);
|
||||
// clang-format on
|
||||
|
||||
public:
|
||||
/// Returns an internal WindowsetProjection that covers a single screen and contains all
|
||||
/// windowsets on that screen, regardless of the WM-specified projection. Depending on
|
||||
/// how the WM lays out its actual projections, multiple ScreenProjections may contain
|
||||
/// the same Windowsets.
|
||||
Q_INVOKABLE static ScreenProjection* screenProjection(QuickshellScreenInfo* screen) {
|
||||
return WindowManager::instance()->screenProjection(screen);
|
||||
}
|
||||
|
||||
[[nodiscard]] static QBindable<QList<Windowset*>> bindableWindowsets() {
|
||||
return WindowManager::instance()->bindableWindowsets();
|
||||
}
|
||||
|
||||
[[nodiscard]] static QBindable<QList<WindowsetProjection*>> bindableWindowsetProjections() {
|
||||
return WindowManager::instance()->bindableWindowsetProjections();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace qs::wm
|
||||
45
src/windowmanager/windowset.cpp
Normal file
45
src/windowmanager/windowset.cpp
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#include "windowset.hpp"
|
||||
|
||||
#include <qlist.h>
|
||||
#include <qlogging.h>
|
||||
#include <qloggingcategory.h>
|
||||
#include <qobject.h>
|
||||
|
||||
#include "../core/qmlglobal.hpp"
|
||||
#include "windowmanager.hpp"
|
||||
|
||||
namespace qs::wm {
|
||||
|
||||
Q_LOGGING_CATEGORY(logWorkspace, "quickshell.wm.workspace", QtWarningMsg);
|
||||
|
||||
void Windowset::activate() { qCCritical(logWorkspace) << this << "cannot be activated"; }
|
||||
void Windowset::deactivate() { qCCritical(logWorkspace) << this << "cannot be deactivated"; }
|
||||
void Windowset::remove() { qCCritical(logWorkspace) << this << "cannot be removed"; }
|
||||
|
||||
void Windowset::setProjection(WindowsetProjection* /*projection*/) {
|
||||
qCCritical(logWorkspace) << this << "cannot be assigned to a projection";
|
||||
}
|
||||
|
||||
WindowsetProjection::WindowsetProjection(QObject* parent): QObject(parent) {
|
||||
this->bWindowsets.setBinding([this] {
|
||||
QList<Windowset*> result;
|
||||
for (auto* ws: WindowManager::instance()->bindableWindowsets().value()) {
|
||||
if (ws->bindableProjection().value() == this) {
|
||||
result.append(ws);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
});
|
||||
|
||||
this->bScreens.setBinding([this] {
|
||||
QList<QuickshellScreenInfo*> screens;
|
||||
|
||||
for (auto* screen: this->bQScreens.value()) {
|
||||
screens.append(QuickshellTracked::instance()->screenInfo(screen));
|
||||
}
|
||||
|
||||
return screens;
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace qs::wm
|
||||
175
src/windowmanager/windowset.hpp
Normal file
175
src/windowmanager/windowset.hpp
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
#pragma once
|
||||
|
||||
#include <qcontainerfwd.h>
|
||||
#include <qlist.h>
|
||||
#include <qloggingcategory.h>
|
||||
#include <qobject.h>
|
||||
#include <qproperty.h>
|
||||
#include <qqmlintegration.h>
|
||||
#include <qscreen.h>
|
||||
#include <qtmetamacros.h>
|
||||
#include <qtypes.h>
|
||||
|
||||
class QuickshellScreenInfo;
|
||||
|
||||
namespace qs::wm {
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(logWorkspace);
|
||||
|
||||
class WindowsetProjection;
|
||||
|
||||
///! A group of windows worked with by a user, usually known as a Workspace or Tag.
|
||||
/// A Windowset is a generic type that encompasses both "Workspaces" and "Tags" in window managers.
|
||||
/// Because the definition encompasses both you may not necessarily need all features.
|
||||
class Windowset: public QObject {
|
||||
Q_OBJECT;
|
||||
QML_ELEMENT;
|
||||
QML_UNCREATABLE("");
|
||||
// clang-format off
|
||||
/// A persistent internal identifier for the windowset. This property should be identical
|
||||
/// across restarts and destruction/recreation of a windowset.
|
||||
Q_PROPERTY(QString id READ default NOTIFY idChanged BINDABLE bindableId);
|
||||
/// Human readable name of the windowset.
|
||||
Q_PROPERTY(QString name READ default NOTIFY nameChanged BINDABLE bindableName);
|
||||
/// Coordinates of the workspace, represented as an N-dimensional array. Most WMs
|
||||
/// will only expose one coordinate. If more than one is exposed, the first is
|
||||
/// conventionally X, the second Y, and the third Z.
|
||||
Q_PROPERTY(QList<qint32> coordinates READ default NOTIFY coordinatesChanged BINDABLE bindableCoordinates);
|
||||
/// True if the windowset is currently active. In a workspace based WM, this means the
|
||||
/// represented workspace is current. In a tag based WM, this means the represented tag
|
||||
/// is active.
|
||||
Q_PROPERTY(bool active READ default NOTIFY activeChanged BINDABLE bindableActive);
|
||||
/// The projection this windowset is a member of. A projection is the set of screens covered by
|
||||
/// a windowset.
|
||||
Q_PROPERTY(WindowsetProjection* projection READ default NOTIFY projectionChanged BINDABLE bindableProjection);
|
||||
/// If false, this windowset should generally be hidden from workspace pickers.
|
||||
Q_PROPERTY(bool shouldDisplay READ default NOTIFY shouldDisplayChanged BINDABLE bindableShouldDisplay);
|
||||
/// If true, a window in this windowset has been marked as urgent.
|
||||
Q_PROPERTY(bool urgent READ default NOTIFY urgentChanged BINDABLE bindableUrgent);
|
||||
/// If true, the windowset can be activated. In a workspace based WM, this will make the workspace
|
||||
/// current, in a tag based wm, the tag will be activated.
|
||||
Q_PROPERTY(bool canActivate READ default NOTIFY canActivateChanged BINDABLE bindableCanActivate);
|
||||
/// If true, the windowset can be deactivated. In a workspace based WM, deactivation is usually implicit
|
||||
/// and based on activation of another workspace.
|
||||
Q_PROPERTY(bool canDeactivate READ default NOTIFY canDeactivateChanged BINDABLE bindableCanDeactivate);
|
||||
/// If true, the windowset can be removed. This may be done implicitly by the WM as well.
|
||||
Q_PROPERTY(bool canRemove READ default NOTIFY canRemoveChanged BINDABLE bindableCanRemove);
|
||||
/// If true, the windowset can be moved to a different projection.
|
||||
Q_PROPERTY(bool canSetProjection READ default NOTIFY canSetProjectionChanged BINDABLE bindableCanSetProjection);
|
||||
// clang-format on
|
||||
|
||||
public:
|
||||
explicit Windowset(QObject* parent): QObject(parent) {}
|
||||
|
||||
/// Activate the windowset, making it the current workspace on a workspace based WM, or activating
|
||||
/// the tag on a tag based WM. Requires @@canActivate.
|
||||
Q_INVOKABLE virtual void activate();
|
||||
/// Deactivate the windowset, hiding it. Requires @@canDeactivate.
|
||||
Q_INVOKABLE virtual void deactivate();
|
||||
/// Remove or destroy the windowset. Requires @@canRemove.
|
||||
Q_INVOKABLE virtual void remove();
|
||||
/// Move the windowset to a different projection. A projection represents the set of screens
|
||||
/// a workspace spans. Requires @@canSetProjection.
|
||||
Q_INVOKABLE virtual void setProjection(WindowsetProjection* projection);
|
||||
|
||||
[[nodiscard]] QBindable<QString> bindableId() const { return &this->bId; }
|
||||
[[nodiscard]] QBindable<QString> bindableName() const { return &this->bName; }
|
||||
[[nodiscard]] QBindable<QList<qint32>> bindableCoordinates() const { return &this->bCoordinates; }
|
||||
[[nodiscard]] QBindable<bool> bindableActive() const { return &this->bActive; }
|
||||
|
||||
[[nodiscard]] QBindable<WindowsetProjection*> bindableProjection() const {
|
||||
return &this->bProjection;
|
||||
}
|
||||
|
||||
[[nodiscard]] QBindable<bool> bindableShouldDisplay() const { return &this->bShouldDisplay; }
|
||||
[[nodiscard]] QBindable<bool> bindableUrgent() const { return &this->bUrgent; }
|
||||
[[nodiscard]] QBindable<bool> bindableCanActivate() const { return &this->bCanActivate; }
|
||||
[[nodiscard]] QBindable<bool> bindableCanDeactivate() const { return &this->bCanDeactivate; }
|
||||
[[nodiscard]] QBindable<bool> bindableCanRemove() const { return &this->bCanRemove; }
|
||||
|
||||
[[nodiscard]] QBindable<bool> bindableCanSetProjection() const {
|
||||
return &this->bCanSetProjection;
|
||||
}
|
||||
|
||||
signals:
|
||||
void idChanged();
|
||||
void nameChanged();
|
||||
void coordinatesChanged();
|
||||
void activeChanged();
|
||||
void projectionChanged();
|
||||
void shouldDisplayChanged();
|
||||
void urgentChanged();
|
||||
void canActivateChanged();
|
||||
void canDeactivateChanged();
|
||||
void canRemoveChanged();
|
||||
void canSetProjectionChanged();
|
||||
|
||||
protected:
|
||||
// clang-format off
|
||||
Q_OBJECT_BINDABLE_PROPERTY(Windowset, QString, bId, &Windowset::idChanged);
|
||||
Q_OBJECT_BINDABLE_PROPERTY(Windowset, QString, bName, &Windowset::nameChanged);
|
||||
Q_OBJECT_BINDABLE_PROPERTY(Windowset, QList<qint32>, bCoordinates);
|
||||
Q_OBJECT_BINDABLE_PROPERTY(Windowset, bool, bActive, &Windowset::activeChanged);
|
||||
Q_OBJECT_BINDABLE_PROPERTY(Windowset, WindowsetProjection*, bProjection, &Windowset::projectionChanged);
|
||||
Q_OBJECT_BINDABLE_PROPERTY(Windowset, bool, bShouldDisplay, &Windowset::shouldDisplayChanged);
|
||||
Q_OBJECT_BINDABLE_PROPERTY(Windowset, bool, bUrgent, &Windowset::urgentChanged);
|
||||
Q_OBJECT_BINDABLE_PROPERTY(Windowset, bool, bCanActivate, &Windowset::canActivateChanged);
|
||||
Q_OBJECT_BINDABLE_PROPERTY(Windowset, bool, bCanDeactivate, &Windowset::canDeactivateChanged);
|
||||
Q_OBJECT_BINDABLE_PROPERTY(Windowset, bool, bCanRemove, &Windowset::canRemoveChanged);
|
||||
Q_OBJECT_BINDABLE_PROPERTY(Windowset, bool, bCanSetProjection, &Windowset::canSetProjectionChanged);
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
///! A space occupiable by a Windowset.
|
||||
/// A WindowsetProjection represents a space that can be occupied by one or more @@Windowset$s.
|
||||
/// The space is one or more screens. Multiple projections may occupy the same screens.
|
||||
///
|
||||
/// @@WindowManager.screenProjection() can be used to get a projection representing all
|
||||
/// @@Windowset$s on a given screen regardless of the WM's actual projection layout.
|
||||
class WindowsetProjection: public QObject {
|
||||
Q_OBJECT;
|
||||
QML_ELEMENT;
|
||||
QML_UNCREATABLE("");
|
||||
// clang-format off
|
||||
/// Screens the windowset projection spans, often a single screen or all screens.
|
||||
Q_PROPERTY(QList<QuickshellScreenInfo*> screens READ default NOTIFY screensChanged BINDABLE bindableScreens);
|
||||
/// Windowsets that are currently present on the projection.
|
||||
Q_PROPERTY(QList<Windowset*> windowsets READ default NOTIFY windowsetsChanged BINDABLE bindableWindowsets);
|
||||
// clang-format on
|
||||
|
||||
public:
|
||||
explicit WindowsetProjection(QObject* parent);
|
||||
|
||||
[[nodiscard]] QBindable<QList<QuickshellScreenInfo*>> bindableScreens() const {
|
||||
return &this->bScreens;
|
||||
}
|
||||
|
||||
[[nodiscard]] QBindable<QList<QScreen*>> bindableQScreens() const { return &this->bQScreens; }
|
||||
|
||||
[[nodiscard]] QBindable<QList<Windowset*>> bindableWindowsets() const {
|
||||
return &this->bWindowsets;
|
||||
}
|
||||
|
||||
signals:
|
||||
void screensChanged();
|
||||
void windowsetsChanged();
|
||||
|
||||
protected:
|
||||
Q_OBJECT_BINDABLE_PROPERTY(WindowsetProjection, QList<QScreen*>, bQScreens);
|
||||
|
||||
Q_OBJECT_BINDABLE_PROPERTY(
|
||||
WindowsetProjection,
|
||||
QList<QuickshellScreenInfo*>,
|
||||
bScreens,
|
||||
&WindowsetProjection::screensChanged
|
||||
);
|
||||
|
||||
Q_OBJECT_BINDABLE_PROPERTY(
|
||||
WindowsetProjection,
|
||||
QList<Windowset*>,
|
||||
bWindowsets,
|
||||
&WindowsetProjection::windowsetsChanged
|
||||
);
|
||||
};
|
||||
|
||||
} // namespace qs::wm
|
||||
Loading…
Add table
Add a link
Reference in a new issue