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