Layershellqt

window.cpp
1/*
2 * SPDX-FileCopyrightText: 2021 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6
7#include "window.h"
8#include "../qwaylandlayershellintegration_p.h"
9
10#include <layershellqt_logging.h>
11
12#include <QPointer>
13#include <optional>
14
15#include <QtWaylandClient/private/qwaylandwindow_p.h>
16
17using namespace LayerShellQt;
18
19class LayerShellQt::WindowPrivate
20{
21public:
22 WindowPrivate(QWindow *window)
23 : parentWindow(window)
24 {
25 }
26
27 QWindow *parentWindow;
28 QString scope = QStringLiteral("window");
29 Window::Anchors anchors = {Window::AnchorTop | Window::AnchorBottom | Window::AnchorLeft | Window::AnchorRight};
30 int32_t exclusionZone = 0;
31 Window::Anchor exclusiveEdge = Window::AnchorNone;
32 Window::KeyboardInteractivity keyboardInteractivity = Window::KeyboardInteractivityOnDemand;
33 Window::Layer layer = Window::LayerTop;
34 QMargins margins;
35 QSize desiredSize = QSize(0, 0);
36 Window::ScreenConfiguration screenConfiguration = Window::ScreenFromQWindow;
37 bool closeOnDismissed = true;
38};
39
40static QMap<QWindow *, Window *> s_map;
41
42Window::~Window()
43{
44 s_map.remove(d->parentWindow);
45}
46
47void Window::setAnchors(Anchors anchors)
48{
49 if (d->anchors != anchors) {
50 d->anchors = anchors;
51 Q_EMIT anchorsChanged();
52 }
53}
54
55Window::Anchors Window::anchors() const
56{
57 return d->anchors;
58}
59
60void Window::setExclusiveZone(int32_t zone)
61{
62 if (d->exclusionZone != zone) {
63 d->exclusionZone = zone;
64 Q_EMIT exclusionZoneChanged();
65 }
66}
67
68int32_t Window::exclusionZone() const
69{
70 return d->exclusionZone;
71}
72
73void Window::setExclusiveEdge(Window::Anchor edge)
74{
75 if (d->exclusiveEdge == edge) {
76 return;
77 }
78
79 d->exclusiveEdge = edge;
80 Q_EMIT exclusiveEdgeChanged();
81}
82
83Window::Anchor Window::exclusiveEdge() const
84{
85 return d->exclusiveEdge;
86}
87
88void Window::setMargins(const QMargins &margins)
89{
90 if (d->margins != margins) {
91 d->margins = margins;
92 Q_EMIT marginsChanged();
93 }
94}
95
96QMargins Window::margins() const
97{
98 return d->margins;
99}
100
101void Window::setDesiredSize(const QSize &size)
102{
103 if (size == d->desiredSize) {
104 return;
105 }
106
107 d->desiredSize = size;
108 Q_EMIT desiredSizeChanged();
109}
110
111QSize Window::desiredSize() const
112{
113 return d->desiredSize;
114}
115
116void Window::setKeyboardInteractivity(KeyboardInteractivity interactivity)
117{
118 if (d->keyboardInteractivity != interactivity) {
119 d->keyboardInteractivity = interactivity;
120 Q_EMIT keyboardInteractivityChanged();
121 }
122}
123
124Window::KeyboardInteractivity Window::keyboardInteractivity() const
125{
126 return d->keyboardInteractivity;
127}
128
129void Window::setLayer(Layer layer)
130{
131 if (d->layer != layer) {
132 d->layer = layer;
133 Q_EMIT layerChanged();
134 }
135}
136
137void Window::setScope(const QString &scope)
138{
139 d->scope = scope;
140 // this is static and must be set before the platform window is created
141}
142
143QString Window::scope() const
144{
145 return d->scope;
146}
147
148Window::Layer Window::layer() const
149{
150 return d->layer;
151}
152
153Window::ScreenConfiguration Window::screenConfiguration() const
154{
155 return d->screenConfiguration;
156}
157
158void Window::setScreenConfiguration(Window::ScreenConfiguration screenConfiguration)
159{
160 d->screenConfiguration = screenConfiguration;
161}
162
163bool Window::closeOnDismissed() const
164{
165 return d->closeOnDismissed;
166}
167
168void Window::setCloseOnDismissed(bool close)
169{
170 d->closeOnDismissed = close;
171}
172
173Window::Window(QWindow *window)
174 : QObject(window)
175 , d(new WindowPrivate(window))
176{
177 s_map.insert(d->parentWindow, this);
178
179 window->create();
180
181 auto waylandWindow = dynamic_cast<QtWaylandClient::QWaylandWindow *>(window->handle());
182 if (!waylandWindow) {
183 qCWarning(LAYERSHELLQT) << window << "is not a wayland window. Not creating zwlr_layer_surface";
184 return;
185 }
186
187 static QWaylandLayerShellIntegration *shellIntegration = nullptr;
188 if (!shellIntegration) {
189 shellIntegration = new QWaylandLayerShellIntegration();
190 if (!shellIntegration->initialize(waylandWindow->display())) {
191 delete shellIntegration;
192 shellIntegration = nullptr;
193 qCWarning(LAYERSHELLQT) << "Failed to initialize layer-shell integration, possibly because compositor does not support the layer-shell protocol";
194 return;
195 }
196 }
197
198 waylandWindow->setShellIntegration(shellIntegration);
199}
200
201Window *Window::get(QWindow *window)
202{
203 if (!window) {
204 return nullptr;
205 }
206
207 auto layerShellWindow = s_map.value(window);
208 if (layerShellWindow) {
209 return layerShellWindow;
210 }
211 return new Window(window);
212}
213
214Window *Window::qmlAttachedProperties(QObject *object)
215{
216 return get(qobject_cast<QWindow *>(object));
217}
void close()
QWidget * window(QObject *job)
Q_EMITQ_EMIT
T qobject_cast(QObject *object)
void create(WId window, bool initializeWindow, bool destroyOldWindow)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri May 2 2025 12:06:14 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.