Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qwaylandadwaitadecoration_p.h
Go to the documentation of this file.
1// Copyright (C) 2023 Jan Grulich <jgrulich@redhat.com>
2// Copyright (C) 2023 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// Qt-Security score:significant reason:default
5
6#ifndef QWAYLANDADWAITADECORATION_P_H
7#define QWAYLANDADWAITADECORATION_P_H
8
9#include <QtWaylandClient/private/qwaylandabstractdecoration_p.h>
10
11#include <QtGui/qcolor.h>
12#include <QtGui/qfont.h>
13#include <QtGui/qstatictext.h>
14
15#include <QtCore/QDateTime>
16#include <QtCore/qflags.h>
17#include <QtCore/qmap.h>
18#include <QtCore/qpoint.h>
19#include <QtCore/qstring.h>
20
21#include <memory>
22
23QT_BEGIN_NAMESPACE
24
25class QDBusVariant;
26class QPainter;
27
28namespace QtWaylandClient {
29
30//
31// INFO
32// -------------
33//
34// This is a Qt decoration plugin implementing Adwaita-like (GNOME) client-side
35// window decorations. It uses xdg-desktop-portal to get the user configuration.
36// This plugin was originally part of QGnomePlatform and later made a separate
37// project named QAdwaitaDecorations.
38//
39// INFO: How SVG icons are used here?
40// We try to find an SVG icon for a particular button from the current icon theme.
41// This icon is then opened as a file, it's content saved and later loaded to be
42// painted with QSvgRenderer, but before it's painted, we try to find following
43// patterns:
44// 1) fill=[\"']#[0-9A-F]{6}[\"']
45// 2) fill:#[0-9A-F]{6}
46// 3) fill=[\"']currentColor[\"']
47// The color in this case doesn't match the theme and is replaced by Foreground color.
48//
49// FIXME/TODO:
50// This plugin currently have all the colors for the decorations hardcoded.
51// There might be a way to get these from GTK/libadwaita (not sure), but problem is
52// we want Gtk4 version and using Gtk4 together with QGtk3Theme from QtBase that links
53// to Gtk3 will not work out. Possibly in future we can make a QGtk4Theme providing us
54// what we need to paint the decorations without having to deal with the colors ourself.
55//
56// TODO: Implement shadows
57
58
60{
62public:
75
76 enum Placement {
77 Left = 0,
79 };
80
81 enum Button {
82 None = 0x0,
83 Close = 0x1,
84 Minimize = 0x02,
85 Maximize = 0x04
86 };
88
95
97 virtual ~QWaylandAdwaitaDecoration() = default;
98
99protected:
100 QMargins margins(MarginsType marginsType = Full) const override;
101 void paint(QPaintDevice *device) override;
102 bool handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,
103 Qt::MouseButtons b, Qt::KeyboardModifiers mods) override;
104 bool handleTouch(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,
105 QEventPoint::State state, Qt::KeyboardModifiers mods) override;
106
107private Q_SLOTS:
108 void settingChanged(const QString &group, const QString &key, const QDBusVariant &value);
109
110private:
111 // Makes a call to xdg-desktop-portal (Settings) to load initial configuration
112 void loadConfiguration();
113 // Updates color scheme from light to dark and vice-versa
114 void updateColors(bool isDark);
115 // Updates titlebar layout with position and button order
116 void updateTitlebarLayout(const QString &layout);
117
118 // Returns a bounding rect for a given button type
119 QRectF buttonRect(Button button) const;
120 // Draw given button type using SVG icon (when found) or fallback to QPixmap icon
121 void drawButton(Button button, QPainter *painter);
122
123 // Returns color for given type and button
124 QColor color(ColorType type, Button button = None);
125
126 // Returns whether the left button was clicked i.e. pressed and released
127 bool clickButton(Qt::MouseButtons b, Button btn);
128 // Returns whether the left button was double-clicked
129 bool doubleClickButton(Qt::MouseButtons b, const QPointF &local, const QDateTime &currentTime);
130 // Updates button hover state
131 void updateButtonHoverState(Button hoveredButton);
132
133 void processMouseTop(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,
134 Qt::KeyboardModifiers mods);
135 void processMouseBottom(QWaylandInputDevice *inputDevice, const QPointF &local,
136 Qt::MouseButtons b, Qt::KeyboardModifiers mods);
137 void processMouseLeft(QWaylandInputDevice *inputDevice, const QPointF &local,
138 Qt::MouseButtons b, Qt::KeyboardModifiers mods);
139 void processMouseRight(QWaylandInputDevice *inputDevice, const QPointF &local,
140 Qt::MouseButtons b, Qt::KeyboardModifiers mods);
141 // Request to repaint the decorations. This will be invoked when button hover changes or
142 // when there is a setting change (e.g. layout change).
143 void requestRepaint() const;
144
145 // Button states
146 Button m_clicking = None;
147 Buttons m_hoveredButtons = None;
148 QDateTime m_lastButtonClick;
149 QPointF m_lastButtonClickPosition;
150
151 // Configuration
152 QMap<Button, uint> m_buttons;
153 QMap<ColorType, QColor> m_colors;
154 QMap<ButtonIcon, QString> m_icons;
155 std::unique_ptr<QFont> m_font;
156 Placement m_placement = Right;
157
158 QStaticText m_windowTitle;
159};
160Q_DECLARE_OPERATORS_FOR_FLAGS(QWaylandAdwaitaDecoration::Buttons)
161
162} // namespace QtWaylandClient
163
164QT_END_NAMESPACE
165
166#endif // QWAYLANDADWAITADECORATION_P_H
friend class QPainter
bool handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods) override
bool handleTouch(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, QEventPoint::State state, Qt::KeyboardModifiers mods) override
QMargins margins(MarginsType marginsType=Full) const override
Combined button and popup list for selecting options.