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:
76
77 enum Placement {
78 Left = 0,
80 };
81
82 enum Button {
83 None = 0x0,
84 Close = 0x1,
85 Minimize = 0x02,
86 Maximize = 0x04
87 };
89
96
98 virtual ~QWaylandAdwaitaDecoration() = default;
99
100protected:
101 QMargins margins(MarginsType marginsType = Full) const override;
102 void paint(QPaintDevice *device) override;
103 bool handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,
104 Qt::MouseButtons b, Qt::KeyboardModifiers mods) override;
105 bool handleTouch(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,
106 QEventPoint::State state, Qt::KeyboardModifiers mods) override;
107
108private Q_SLOTS:
109 void settingChanged(const QString &group, const QString &key, const QDBusVariant &value);
110
111private:
112 // Makes a call to xdg-desktop-portal (Settings) to load initial configuration
113 void loadConfiguration();
114 // Updates color scheme from light to dark and vice-versa
115 void updateColors(bool isDark);
116 // Updates titlebar layout with position and button order
117 void updateTitlebarLayout(const QString &layout);
118
119 // Returns a bounding rect for a given button type
120 QRectF buttonRect(Button button) const;
121 // Draw given button type using SVG icon (when found) or fallback to QPixmap icon
122 void drawButton(Button button, QPainter *painter);
123
124 // Returns color for given type and button
125 QColor color(ColorType type, Button button = None);
126
127 // Returns whether the left button was clicked i.e. pressed and released
128 bool clickButton(Qt::MouseButtons b, Button btn);
129 // Returns whether the left button was double-clicked
130 bool doubleClickButton(Qt::MouseButtons b, const QPointF &local, const QDateTime &currentTime);
131 // Updates button hover state
132 void updateButtonHoverState(Button hoveredButton);
133
134 void processMouseTop(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,
135 Qt::KeyboardModifiers mods);
136 void processMouseBottom(QWaylandInputDevice *inputDevice, const QPointF &local,
137 Qt::MouseButtons b, Qt::KeyboardModifiers mods);
138 void processMouseLeft(QWaylandInputDevice *inputDevice, const QPointF &local,
139 Qt::MouseButtons b, Qt::KeyboardModifiers mods);
140 void processMouseRight(QWaylandInputDevice *inputDevice, const QPointF &local,
141 Qt::MouseButtons b, Qt::KeyboardModifiers mods);
142 // Request to repaint the decorations. This will be invoked when button hover changes or
143 // when there is a setting change (e.g. layout change).
144 void requestRepaint() const;
145
146 // Button states
147 Button m_clicking = None;
148 Buttons m_hoveredButtons = None;
149 QDateTime m_lastButtonClick;
150 QPointF m_lastButtonClickPosition;
151
152 // Configuration
153 QMap<Button, uint> m_buttons;
154 QMap<ColorType, QColor> m_colors;
155 QMap<ButtonIcon, QString> m_icons;
156 std::unique_ptr<QFont> m_font;
157 Placement m_placement = Right;
158
159 QStaticText m_windowTitle;
160};
161Q_DECLARE_OPERATORS_FOR_FLAGS(QWaylandAdwaitaDecoration::Buttons)
162
163} // namespace QtWaylandClient
164
165QT_END_NAMESPACE
166
167#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.