Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qwaylandwlshellsurface.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#include <QtWaylandClient/private/qwaylanddisplay_p.h>
7#include <QtWaylandClient/private/qwaylandwindow_p.h>
8#include <QtWaylandClient/private/qwaylandinputdevice_p.h>
9#include <QtWaylandClient/private/qwaylandabstractdecoration_p.h>
10#include <QtWaylandClient/private/qwaylandscreen_p.h>
11#include <QtWaylandClient/private/qwaylandextendedsurface_p.h>
12
13#include <QtCore/QDebug>
14
16
17namespace QtWaylandClient {
18
19QWaylandWlShellSurface::QWaylandWlShellSurface(struct ::wl_shell_surface *shell_surface, QWaylandWindow *window)
21 , QtWayland::wl_shell_surface(shell_surface)
22 , m_window(window)
23{
25 m_extendedWindow = new QWaylandExtendedSurface(window);
26
27 Qt::WindowType type = window->window()->type();
28 auto *transientParent = window->transientParent();
29 if (type == Qt::Popup && transientParent && transientParent->wlSurface())
30 setPopup(transientParent, m_window->display()->lastInputDevice(), m_window->display()->lastInputSerial());
31 else if (transientParent && transientParent->wlSurface())
32 updateTransientParent(transientParent->window());
33 else
34 setTopLevel();
35}
36
38{
39 wl_shell_surface_destroy(object());
40 delete m_extendedWindow;
41}
42
43bool QWaylandWlShellSurface::resize(QWaylandInputDevice *inputDevice, Qt::Edges edges)
44{
45 enum resize resizeEdges = convertToResizeEdges(edges);
46 resize(inputDevice->wl_seat(), inputDevice->serial(), resizeEdges);
47 return true;
48}
49
51{
52 move(inputDevice->wl_seat(),
53 inputDevice->serial());
54 return true;
55}
56
58{
59 return QtWayland::wl_shell_surface::set_title(title);
60}
61
63{
64 return QtWayland::wl_shell_surface::set_class(appId);
65}
66
68{
69 if (m_extendedWindow)
70 m_extendedWindow->raise();
71}
72
74{
75 if (m_extendedWindow)
76 m_extendedWindow->lower();
77}
78
79void QWaylandWlShellSurface::setContentOrientationMask(Qt::ScreenOrientations orientation)
80{
81 if (m_extendedWindow)
82 m_extendedWindow->setContentOrientationMask(orientation);
83}
84
86{
87 if (m_extendedWindow)
88 m_extendedWindow->setWindowFlags(flags);
89}
90
92{
93 if (m_extendedWindow)
94 m_extendedWindow->updateGenericProperty(name, value);
95}
96
98{
99 if ((m_pending.states & (Qt::WindowMaximized|Qt::WindowFullScreen))
100 && !(m_applied.states & (Qt::WindowMaximized|Qt::WindowFullScreen))) {
101 m_normalSize = m_window->windowFrameGeometry().size();
102 }
103
104 if (m_pending.states != m_applied.states)
105 m_window->handleWindowStatesChanged(m_pending.states);
106
107 if (!m_pending.size.isEmpty()) {
108 int x = 0;
109 int y = 0;
110 if (m_pending.edges & resize_left)
111 x = m_applied.size.width() - m_pending.size.width();
112 if (m_pending.edges & resize_top)
113 y = m_applied.size.height() - m_pending.size.height();
114 QPoint offset(x, y);
115 m_window->resizeFromApplyConfigure(m_pending.size, offset);
116 } else if (m_pending.size.isValid() && !m_normalSize.isEmpty()) {
117 m_window->resizeFromApplyConfigure(m_normalSize);
118 }
119
120 m_applied = m_pending;
121}
122
124{
125 return !(m_pending.states & Qt::WindowFullScreen);
126}
127
129{
130 // On wl-shell the client is in charge of states, so diff from the pending state
131 Qt::WindowStates changedStates = m_pending.states ^ states;
132 Qt::WindowStates addedStates = changedStates & states;
133
134 if (addedStates & Qt::WindowMinimized)
135 qCWarning(lcQpaWayland) << "Minimizing is not supported on wl-shell. Consider using xdg-shell instead.";
136
137 if (addedStates & Qt::WindowMaximized) {
138 set_maximized(nullptr);
139 m_window->applyConfigureWhenPossible();
140 }
141
142 if (addedStates & Qt::WindowFullScreen) {
143 set_fullscreen(WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, nullptr);
144 m_window->applyConfigureWhenPossible();
145 }
146
147 bool isNormal = !(states & Qt::WindowMaximized) && !(states & Qt::WindowFullScreen);
148 if (isNormal && (changedStates & (Qt::WindowMaximized | Qt::WindowFullScreen))) {
149 setTopLevel(); // set normal window
150 // There's usually no configure event after this, so just clear the rest of the pending
151 // configure here and queue the applyConfigure call
152 m_pending.size = {0, 0};
153 m_pending.edges = resize_none;
154 m_window->applyConfigureWhenPossible();
155 }
156
157 m_pending.states = states & ~Qt::WindowMinimized;
158}
159
160enum QWaylandWlShellSurface::resize QWaylandWlShellSurface::convertToResizeEdges(Qt::Edges edges)
161{
162 return static_cast<enum resize>(
163 ((edges & Qt::TopEdge) ? resize_top : 0)
164 | ((edges & Qt::BottomEdge) ? resize_bottom : 0)
165 | ((edges & Qt::LeftEdge) ? resize_left : 0)
166 | ((edges & Qt::RightEdge) ? resize_right : 0));
167}
168
169void QWaylandWlShellSurface::setTopLevel()
170{
171 set_toplevel();
172}
173
174static inline bool testShowWithoutActivating(const QWindow *window)
175{
176 // QWidget-attribute Qt::WA_ShowWithoutActivating.
177 const QVariant showWithoutActivating = window->property("_q_showWithoutActivating");
178 return showWithoutActivating.isValid() && showWithoutActivating.toBool();
179}
180
181void QWaylandWlShellSurface::updateTransientParent(QWindow *parent)
182{
183 QWaylandWindow *parent_wayland_window = static_cast<QWaylandWindow *>(parent->handle());
184 if (!parent_wayland_window)
185 return;
186
187 // set_transient expects a position relative to the parent
188 QPoint transientPos = m_window->geometry().topLeft(); // this is absolute
189 transientPos -= parent->geometry().topLeft();
190 if (parent_wayland_window->decoration()) {
191 transientPos.setX(transientPos.x() + parent_wayland_window->decoration()->margins().left());
192 transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top());
193 }
194
195 uint32_t flags = 0;
196 Qt::WindowFlags wf = m_window->window()->flags();
197 if (wf.testFlag(Qt::ToolTip)
198 || wf.testFlag(Qt::WindowTransparentForInput)
199 || testShowWithoutActivating(m_window->window()))
200 flags |= WL_SHELL_SURFACE_TRANSIENT_INACTIVE;
201
202 auto *parentSurface = parent_wayland_window->wlSurface();
203 Q_ASSERT(parentSurface);
204 set_transient(parentSurface, transientPos.x(), transientPos.y(), flags);
205}
206
207void QWaylandWlShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, uint serial)
208{
209 QWaylandWindow *parent_wayland_window = parent;
210 if (!parent_wayland_window) {
211 qCWarning(lcQpaWayland) << "setPopup called without a parent window";
212 return;
213 }
214 if (!device) {
215 qCWarning(lcQpaWayland) << "setPopup called without an input device";
216 return;
217 }
218
219 // set_popup expects a position relative to the parent
220 QPoint transientPos = m_window->geometry().topLeft(); // this is absolute
221 transientPos -= parent_wayland_window->geometry().topLeft();
222 if (parent_wayland_window->decoration()) {
223 transientPos.setX(transientPos.x() + parent_wayland_window->decoration()->margins().left());
224 transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top());
225 }
226
227 auto *parentSurface = parent_wayland_window->wlSurface();
228 Q_ASSERT(parentSurface);
229 uint flags = 0;
230 set_popup(device->wl_seat(), serial, parentSurface, transientPos.x(), transientPos.y(), flags);
231}
232
234{
235 pong(serial);
236}
237
239{
240 m_pending.size = QSize(width, height);
241 m_pending.edges = static_cast<enum resize>(edges);
242 if (m_pending.edges && !m_pending.size.isEmpty())
243 m_normalSize = m_pending.size;
244 m_window->applyConfigureWhenPossible();
245}
246
251
252}
253
255
256#include "moc_qwaylandwlshellsurface_p.cpp"
IOBluetoothDevice * device
The QCloseEvent class contains parameters that describe a close event.
Definition qevent.h:562
static void postEvent(QObject *receiver, QEvent *event, int priority=Qt::NormalEventPriority)
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:346
QRect windowFrameGeometry() const
Returns the QWindow frame geometry.
QWindow * window() const
Returns the window which belongs to the QPlatformWindow.
virtual QRect geometry() const
Returns the current geometry of a window.
\inmodule QtCore\reentrant
Definition qpoint.h:25
constexpr QSize size() const noexcept
Returns the size of the rectangle.
Definition qrect.h:242
\inmodule QtCore
Definition qsize.h:25
constexpr bool isEmpty() const noexcept
Returns true if either of the width and height is less than or equal to 0; otherwise returns false.
Definition qsize.h:124
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
\inmodule QtCore
Definition qvariant.h:65
bool isValid() const
Returns true if the storage type of this variant is not QMetaType::UnknownType; otherwise returns fal...
Definition qvariant.h:714
bool toBool() const
Returns the variant as a bool if the variant has userType() Bool.
void setPopup(QWaylandSeat *seat, QWaylandSurface *parentSurface, const QPoint &relativeToParent)
QWaylandWlShellSurface()
Constructs a QWaylandWlShellSurface.
\inmodule QtGui
Definition qwindow.h:63
Qt::WindowFlags flags
the window flags of the window
Definition qwindow.h:79
QtWayland::qt_surface_extension * windowExtension() const
QWaylandInputDevice * lastInputDevice() const
void setContentOrientationMask(Qt::ScreenOrientations mask)
Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags)
void updateGenericProperty(const QString &name, const QVariant &value)
void handleWindowStatesChanged(Qt::WindowStates states)
QWaylandWindow * transientParent() const
QWaylandDisplay * display() const
void resizeFromApplyConfigure(const QSize &sizeWithMargins, const QPoint &offset={0, 0})
void shell_surface_configure(uint32_t edges, int32_t width, int32_t height) override
bool resize(QWaylandInputDevice *inputDevice, Qt::Edges edges) override
void setAppId(const QString &appId) override
void shell_surface_ping(uint32_t serial) override
void sendProperty(const QString &name, const QVariant &value) override
void setWindowFlags(Qt::WindowFlags flags) override
void setTitle(const QString &title) override
bool move(QWaylandInputDevice *inputDevice) override
void setContentOrientationMask(Qt::ScreenOrientations orientation) override
void requestWindowStates(Qt::WindowStates states) override
Combined button and popup list for selecting options.
static bool testShowWithoutActivating(const QWindow *window)
Definition qcompare.h:63
@ WindowFullScreen
Definition qnamespace.h:255
@ WindowMinimized
Definition qnamespace.h:253
@ WindowMaximized
Definition qnamespace.h:254
@ TopEdge
WindowType
Definition qnamespace.h:205
@ ToolTip
Definition qnamespace.h:213
@ Popup
Definition qnamespace.h:211
@ WindowTransparentForInput
Definition qnamespace.h:234
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qCWarning(category,...)
GLint GLint GLint GLint GLint x
[0]
GLint GLsizei GLsizei height
GLint GLsizei width
GLenum type
GLbitfield flags
GLenum GLuint GLintptr offset
GLuint name
GLint y
GLuint * states
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
unsigned int uint
Definition qtypes.h:34
QString title
[35]
aWidget window() -> setWindowTitle("New Window Title")
[2]