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
main.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 Robin Burchell <robin.burchell@viroteck.net>
2// Copyright (C) 2016 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include <QtGui/QCursor>
6#include <QtGui/QPainter>
7#include <QtGui/QPainterPath>
8#include <QtGui/QPalette>
9#include <QtGui/QLinearGradient>
10#include <QtGui/QPainterPath>
11
12#include <qpa/qwindowsysteminterface.h>
13
14#include <QtWaylandClient/private/qwaylanddecorationplugin_p.h>
15#include <QtWaylandClient/private/qwaylandabstractdecoration_p.h>
16#include <QtWaylandClient/private/qwaylandwindow_p.h>
17#include <QtWaylandClient/private/qwaylandshellsurface_p.h>
18
20
21namespace QtWaylandClient {
22
23#define BUTTON_SPACING 5
24#define BUTTON_WIDTH 18
25#define BUTTONS_RIGHT_MARGIN 8
26
34
35class Q_WAYLANDCLIENT_EXPORT QWaylandBradientDecoration : public QWaylandAbstractDecoration
36{
37public:
39protected:
40 QMargins margins(MarginsType marginsType = Full) const override;
41 void paint(QPaintDevice *device) override;
42 bool handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,Qt::MouseButtons b,Qt::KeyboardModifiers mods) override;
43 bool handleTouch(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, QEventPoint::State state, Qt::KeyboardModifiers mods) override;
44private:
45 enum class PointerType {
46 Mouse,
47 Touch
48 };
49
50 void processPointerTop(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods, PointerType type);
51 void processPointerBottom(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods, PointerType type);
52 void processPointerLeft(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods, PointerType type);
53 void processPointerRight(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods, PointerType type);
54 bool clickButton(Qt::MouseButtons b, Button btn);
55
56 QRectF closeButtonRect() const;
57 QRectF maximizeButtonRect() const;
58 QRectF minimizeButtonRect() const;
59
60 QStaticText m_windowTitle;
61 Button m_clicking = None;
62};
63
64
65
73
74QRectF QWaylandBradientDecoration::closeButtonRect() const
75{
76 const int windowRight = waylandWindow()->surfaceSize().width() - margins(ShadowsOnly).right();
77 return QRectF(windowRight - BUTTON_WIDTH - BUTTON_SPACING * 0 - BUTTONS_RIGHT_MARGIN,
79}
80
81QRectF QWaylandBradientDecoration::maximizeButtonRect() const
82{
83 const int windowRight = waylandWindow()->surfaceSize().width() - margins(ShadowsOnly).right();
84 return QRectF(windowRight - BUTTON_WIDTH * 2 - BUTTON_SPACING * 1 - BUTTONS_RIGHT_MARGIN,
86}
87
88QRectF QWaylandBradientDecoration::minimizeButtonRect() const
89{
90 const int windowRight = waylandWindow()->surfaceSize().width() - margins(ShadowsOnly).right();
91 return QRectF(windowRight - BUTTON_WIDTH * 3 - BUTTON_SPACING * 2 - BUTTONS_RIGHT_MARGIN,
93}
94
96{
97 if (marginsType == ShadowsOnly)
98 return QMargins();
99
100 return QMargins(3, 30, 3, 3);
101}
102
104{
105 bool active = window()->handle()->isActive();
108 QRect clips[] =
109 {
110 QRect(wg.left(), wg.top(), wg.width(), margins(ShadowsExcluded).top()),
111 QRect(wg.left(), cg.bottom() + 1, wg.width(), margins(ShadowsExcluded).bottom()),
112 QRect(wg.left(), cg.top(), margins(ShadowsExcluded).left(), cg.height()),
113 QRect(cg.right() + 1, cg.top(), margins(ShadowsExcluded).right(), cg.height())
114 };
115
116 QRect top = clips[0];
117
119 const QColor foregroundColor = palette.color(QPalette::Active, QPalette::WindowText);
120 const QColor backgroundColor = palette.color(QPalette::Active, QPalette::Window);
121 const QColor foregroundInactiveColor = palette.color(QPalette::Disabled, QPalette::WindowText);
122
124 p.setRenderHint(QPainter::Antialiasing);
125
126 // Title bar
127 QPainterPath roundedRect;
128 roundedRect.addRoundedRect(wg, 3, 3);
129 for (int i = 0; i < 4; ++i) {
130 p.save();
131 p.setClipRect(clips[i]);
132 p.fillPath(roundedRect, backgroundColor);
133 p.restore();
134 }
135
136 // Window icon
138 if (!icon.isNull()) {
139 QRectF iconRect(0, 0, 22, 22);
140 iconRect.adjust(margins().left() + BUTTON_SPACING, 4,
141 margins().left() + BUTTON_SPACING, 4),
142 icon.paint(&p, iconRect.toRect());
143 }
144
145 // Window title
146 QString windowTitleText = waylandWindow()->windowTitle();
147 if (!windowTitleText.isEmpty()) {
148 if (m_windowTitle.text() != windowTitleText) {
149 m_windowTitle.setText(windowTitleText);
150 m_windowTitle.prepare();
151 }
152
153 QRect titleBar = top;
154 titleBar.setLeft(margins().left() + BUTTON_SPACING +
155 (icon.isNull() ? 0 : 22 + BUTTON_SPACING));
156 titleBar.setRight(minimizeButtonRect().left() - BUTTON_SPACING);
157
158 p.save();
159 p.setClipRect(titleBar);
160 p.setPen(active ? foregroundColor : foregroundInactiveColor);
161 QSizeF size = m_windowTitle.size();
162 int dx = (top.width() - size.width()) /2;
163 int dy = (top.height()- size.height()) /2;
164 QFont font = p.font();
165 font.setPixelSize(14);
166 p.setFont(font);
167 QPoint windowTitlePoint(top.topLeft().x() + dx,
168 top.topLeft().y() + dy);
169 p.drawStaticText(windowTitlePoint, m_windowTitle);
170 p.restore();
171 }
172
173 QRectF rect;
174
175 // Default pen
176 QPen pen(active ? foregroundColor : foregroundInactiveColor);
177 p.setPen(pen);
178
179 // Close button
180 p.save();
181 rect = closeButtonRect();
182 qreal crossSize = rect.height() / 2.3;
183 QPointF crossCenter(rect.center());
184 QRectF crossRect(crossCenter.x() - crossSize / 2, crossCenter.y() - crossSize / 2, crossSize, crossSize);
185 pen.setWidth(2);
186 p.setPen(pen);
187 p.drawLine(crossRect.topLeft(), crossRect.bottomRight());
188 p.drawLine(crossRect.bottomLeft(), crossRect.topRight());
189 p.restore();
190
191 // Maximize button
192 p.save();
193 p.setRenderHint(QPainter::Antialiasing, false);
194 rect = maximizeButtonRect().adjusted(4, 5, -4, -5);
195 if ((window()->windowStates() & Qt::WindowMaximized)) {
196 qreal inset = 2;
197 QRectF rect1 = rect.adjusted(inset, 0, 0, -inset);
198 QRectF rect2 = rect.adjusted(0, inset, -inset, 0);
199 p.drawRect(rect1);
200 p.setBrush(backgroundColor); // need to cover up some lines from the other rect
201 p.drawRect(rect2);
202 } else {
203 p.drawRect(rect);
204 p.drawLine(rect.left(), rect.top() + 1, rect.right(), rect.top() + 1);
205 }
206 p.restore();
207
208 // Minimize button
209 p.save();
210 p.setRenderHint(QPainter::Antialiasing, false);
211 rect = minimizeButtonRect().adjusted(5, 5, -5, -5);
212 pen.setWidth(2);
213 p.setPen(pen);
214 p.drawLine(rect.bottomLeft(), rect.bottomRight());
215 p.restore();
216}
217
218bool QWaylandBradientDecoration::clickButton(Qt::MouseButtons b, Button btn)
219{
220 if (isLeftClicked(b)) {
221 m_clicking = btn;
222 return false;
223 } else if (isLeftReleased(b)) {
224 if (m_clicking == btn) {
225 m_clicking = None;
226 return true;
227 } else {
228 m_clicking = None;
229 }
230 }
231 return false;
232}
233
234bool QWaylandBradientDecoration::handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
235
236{
238
239 // Figure out what area mouse is in
241 if (local.y() <= margins().top()) {
242 processPointerTop(inputDevice, local, b, mods, PointerType::Mouse);
243 } else if (local.y() >= ss.height() - margins().bottom()) {
244 processPointerBottom(inputDevice, local, b, mods, PointerType::Mouse);
245 } else if (local.x() <= margins().left()) {
246 processPointerLeft(inputDevice, local, b, mods, PointerType::Mouse);
247 } else if (local.x() >= ss.width() - margins().right()) {
248 processPointerRight(inputDevice, local, b, mods, PointerType::Mouse);
249 } else {
250#if QT_CONFIG(cursor)
251 waylandWindow()->restoreMouseCursor(inputDevice);
252#endif
254 return false;
255 }
256
258 return true;
259}
260
261bool QWaylandBradientDecoration::handleTouch(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, QEventPoint::State state, Qt::KeyboardModifiers mods)
262{
265
266 bool handled = state == QEventPoint::Pressed;
267 if (handled) {
268 if (local.y() <= margins().top()) {
269 processPointerTop(inputDevice, local, Qt::LeftButton, mods, PointerType::Touch);
270 } else if (local.y() >= ss.height() - margins().bottom()) {
271 processPointerBottom(inputDevice, local, Qt::LeftButton, mods, PointerType::Touch);
272 } else if (local.x() <= margins().left()) {
273 processPointerLeft(inputDevice, local, Qt::LeftButton, mods, PointerType::Touch);
274 } else if (local.x() >= ss.width() - margins().right()) {
275 processPointerRight(inputDevice, local, Qt::LeftButton, mods, PointerType::Touch);
276 } else {
277 handled = false;
278 }
279 }
280
281 return handled;
282}
283
284void QWaylandBradientDecoration::processPointerTop(QWaylandInputDevice *inputDevice,
285 const QPointF &local,
286 Qt::MouseButtons b,
287 Qt::KeyboardModifiers mods,
289{
290#if !QT_CONFIG(cursor)
291 Q_UNUSED(type);
292#endif
293
295 Q_UNUSED(mods);
296 if (local.y() <= margins().bottom()) {
297 if (local.x() <= margins().left()) {
298 //top left bit
299#if QT_CONFIG(cursor)
300 if (type == PointerType::Mouse)
301 waylandWindow()->setMouseCursor(inputDevice, Qt::SizeFDiagCursor);
302#endif
303 startResize(inputDevice, Qt::TopEdge | Qt::LeftEdge, b);
304 } else if (local.x() >= ss.width() - margins().right()) {
305 //top right bit
306#if QT_CONFIG(cursor)
307 if (type == PointerType::Mouse)
308 waylandWindow()->setMouseCursor(inputDevice, Qt::SizeBDiagCursor);
309#endif
310 startResize(inputDevice, Qt::TopEdge | Qt::RightEdge, b);
311 } else {
312 //top resize bit
313#if QT_CONFIG(cursor)
314 if (type == PointerType::Mouse)
315 waylandWindow()->setMouseCursor(inputDevice, Qt::SplitVCursor);
316#endif
317 startResize(inputDevice, Qt::TopEdge, b);
318 }
319 } else if (local.x() <= margins().left()) {
320 processPointerLeft(inputDevice, local, b, mods, type);
321 } else if (local.x() >= ss.width() - margins().right()) {
322 processPointerRight(inputDevice, local, b, mods, type);
323 } else if (isRightClicked(b)) {
324 showWindowMenu(inputDevice);
325 } else if (closeButtonRect().contains(local)) {
326 if (type == PointerType::Touch || clickButton(b, Close))
328 } else if (maximizeButtonRect().contains(local)) {
329 if (type == PointerType::Touch || clickButton(b, Maximize))
330 window()->setWindowStates(window()->windowStates() ^ Qt::WindowMaximized);
331 } else if (minimizeButtonRect().contains(local)) {
332 if (type == PointerType::Touch || clickButton(b, Minimize))
333 window()->setWindowState(Qt::WindowMinimized);
334 } else {
335#if QT_CONFIG(cursor)
336 if (type == PointerType::Mouse)
337 waylandWindow()->restoreMouseCursor(inputDevice);
338#endif
339 startMove(inputDevice,b);
340 }
341}
342
343void QWaylandBradientDecoration::processPointerBottom(QWaylandInputDevice *inputDevice,
344 const QPointF &local,
345 Qt::MouseButtons b,
346 Qt::KeyboardModifiers mods,
348{
349 Q_UNUSED(mods);
350#if !QT_CONFIG(cursor)
351 Q_UNUSED(type);
352#endif
353
355 if (local.x() <= margins().left()) {
356 //bottom left bit
357#if QT_CONFIG(cursor)
358 if (type == PointerType::Mouse)
359 waylandWindow()->setMouseCursor(inputDevice, Qt::SizeBDiagCursor);
360#endif
361 startResize(inputDevice, Qt::BottomEdge | Qt::LeftEdge, b);
362 } else if (local.x() >= ss.width() - margins().right()) {
363 //bottom right bit
364#if QT_CONFIG(cursor)
365 if (type == PointerType::Mouse)
366 waylandWindow()->setMouseCursor(inputDevice, Qt::SizeFDiagCursor);
367#endif
368 startResize(inputDevice, Qt::BottomEdge | Qt::RightEdge, b);
369 } else {
370 //bottom bit
371#if QT_CONFIG(cursor)
372 if (type == PointerType::Mouse)
373 waylandWindow()->setMouseCursor(inputDevice, Qt::SizeVerCursor);
374#endif
375 startResize(inputDevice, Qt::BottomEdge, b);
376 }
377}
378
379void QWaylandBradientDecoration::processPointerLeft(QWaylandInputDevice *inputDevice,
380 const QPointF &local,
381 Qt::MouseButtons b,
382 Qt::KeyboardModifiers mods,
384{
385 Q_UNUSED(local);
386 Q_UNUSED(mods);
387#if QT_CONFIG(cursor)
388 if (type == PointerType::Mouse)
389 waylandWindow()->setMouseCursor(inputDevice, Qt::SizeHorCursor);
390#else
391 Q_UNUSED(type);
392#endif
393 startResize(inputDevice, Qt::LeftEdge, b);
394}
395
396void QWaylandBradientDecoration::processPointerRight(QWaylandInputDevice *inputDevice,
397 const QPointF &local,
398 Qt::MouseButtons b,
399 Qt::KeyboardModifiers mods,
401{
402 Q_UNUSED(local);
403 Q_UNUSED(mods);
404#if QT_CONFIG(cursor)
405 if (type == PointerType::Mouse)
406 waylandWindow()->setMouseCursor(inputDevice, Qt::SizeHorCursor);
407#else
408 Q_UNUSED(type);
409#endif
410 startResize(inputDevice, Qt::RightEdge, b);
411}
412
420
422{
423 Q_UNUSED(paramList);
424 Q_UNUSED(system);
425 return new QWaylandBradientDecoration();
426}
427
428}
429
431
432#include "main.moc"
IOBluetoothDevice * device
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
State
Specifies the state of this event point.
Definition qeventpoint.h:48
\reentrant
Definition qfont.h:22
void setPixelSize(int)
Sets the font size to pixelSize pixels, with a maxiumum size of an unsigned 16-bit integer.
Definition qfont.cpp:1049
The QIcon class provides scalable icons in different modes and states.
Definition qicon.h:20
void paint(QPainter *painter, const QRect &rect, Qt::Alignment alignment=Qt::AlignCenter, Mode mode=Normal, State state=Off) const
Uses the painter to paint the icon with specified alignment, required mode, and state into the rectan...
Definition qicon.cpp:977
bool isNull() const
Returns true if the icon is empty; otherwise returns false.
Definition qicon.cpp:1019
\inmodule QtCore
Definition qmargins.h:24
constexpr int right() const noexcept
Returns the right margin.
Definition qmargins.h:112
\inmodule QtGui
void addRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode=Qt::AbsoluteSize)
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
@ Antialiasing
Definition qpainter.h:52
The QPalette class contains color groups for each widget state.
Definition qpalette.h:19
@ Disabled
Definition qpalette.h:49
@ WindowText
Definition qpalette.h:51
\inmodule QtGui
Definition qpen.h:28
void setWidth(int width)
Sets the pen width to the given width in pixels with integer precision.
Definition qpen.cpp:592
virtual bool isActive() const
Returns true if the window should appear active from a style perspective.
\inmodule QtCore\reentrant
Definition qpoint.h:217
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:343
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:348
\inmodule QtCore\reentrant
Definition qpoint.h:25
\inmodule QtCore\reentrant
Definition qrect.h:484
constexpr QRectF adjusted(qreal x1, qreal y1, qreal x2, qreal y2) const noexcept
Returns a new rectangle with dx1, dy1, dx2 and dy2 added respectively to the existing coordinates of ...
Definition qrect.h:813
constexpr qreal left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
Definition qrect.h:497
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr int height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:239
constexpr int bottom() const noexcept
Returns the y-coordinate of the rectangle's bottom edge.
Definition qrect.h:182
constexpr QRect marginsRemoved(const QMargins &margins) const noexcept
Removes the margins from the rectangle, shrinking it.
Definition qrect.h:454
constexpr void setRight(int pos) noexcept
Sets the right edge of the rectangle to the given x coordinate.
Definition qrect.h:197
constexpr int top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
Definition qrect.h:176
constexpr void setLeft(int pos) noexcept
Sets the left edge of the rectangle to the given x coordinate.
Definition qrect.h:191
constexpr int right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
Definition qrect.h:179
\inmodule QtCore
Definition qsize.h:208
\inmodule QtCore
Definition qsize.h:25
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:130
The QStaticText class enables optimized drawing of text when the text and its layout is updated rarel...
Definition qstatictext.h:21
void setText(const QString &text)
Sets the text of the QStaticText to text.
void prepare(const QTransform &matrix=QTransform(), const QFont &font=QFont())
Prepares the QStaticText object for being painted with the given matrix and the given font to avoid o...
void setTextFormat(Qt::TextFormat textFormat)
Sets the text format of the QStaticText to textFormat.
QSizeF size() const
Returns the size of the bounding rect for this QStaticText.
void setTextOption(const QTextOption &textOption)
Sets the text option structure that controls the layout process to the given textOption.
QString text() const
Returns the text of the QStaticText.
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
\reentrant
Definition qtextoption.h:18
static bool handleCloseEvent(QWindow *window)
bool isRightClicked(Qt::MouseButtons newMouseButtonState)
void startResize(QWaylandInputDevice *inputDevice, Qt::Edges edges, Qt::MouseButtons buttons)
bool isLeftClicked(Qt::MouseButtons newMouseButtonState)
void showWindowMenu(QWaylandInputDevice *inputDevice)
bool isLeftReleased(Qt::MouseButtons newMouseButtonState)
void startMove(QWaylandInputDevice *inputDevice, Qt::MouseButtons buttons)
QWaylandAbstractDecoration * create(const QString &, const QStringList &) override
Definition main.cpp:421
void paint(QPaintDevice *device) override
Definition main.cpp:103
bool handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods) override
Definition main.cpp:234
bool handleTouch(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, QEventPoint::State state, Qt::KeyboardModifiers mods) override
Definition main.cpp:261
QMargins margins(MarginsType marginsType=Full) const override
Definition main.cpp:95
QSize surfaceSize() const
Size, with decorations (including including eventual shadows) in wl_surface coordinates.
QPainter paint
rect
[4]
else opt state
[0]
const QStyleOptionButton * btn
[3]
Combined button and popup list for selecting options.
@ WindowMinimized
Definition qnamespace.h:253
@ WindowMaximized
Definition qnamespace.h:254
@ AlignVCenter
Definition qnamespace.h:155
@ AlignHCenter
Definition qnamespace.h:148
@ LeftButton
Definition qnamespace.h:58
@ PlainText
@ SizeHorCursor
@ SizeVerCursor
@ SizeFDiagCursor
@ SplitVCursor
@ SizeBDiagCursor
@ RightEdge
@ TopEdge
@ BottomEdge
@ LeftEdge
@ None
Definition qhash.cpp:531
static bool contains(const QJsonArray &haystack, unsigned needle)
Definition qopengl.cpp:116
GLboolean GLboolean GLboolean b
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLdouble GLdouble GLdouble GLdouble top
GLdouble GLdouble right
GLint left
GLenum type
GLint GLint bottom
GLfloat GLfloat p
[1]
GLuint GLenum option
#define Q_OBJECT
#define Q_PLUGIN_METADATA(x)
#define Q_UNUSED(x)
#define BUTTON_SPACING
Definition main.cpp:23
#define BUTTONS_RIGHT_MARGIN
Definition main.cpp:25
#define BUTTON_WIDTH
Definition main.cpp:24
double qreal
Definition qtypes.h:187
PointerType
Definition qwasmevent.h:40
#define QWaylandDecorationFactoryInterface_iid
view create()
QJSValue global