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
4#ifndef QXCBWINDOW_H
5#define QXCBWINDOW_H
6
7#include <qpa/qplatformwindow.h>
8#include <qpa/qplatformwindow_p.h>
9#include <QtGui/QSurfaceFormat>
10#include <QtGui/QImage>
11
12#include <xcb/xcb.h>
13#include <xcb/sync.h>
14
15#include "qxcbobject.h"
16
17QT_BEGIN_NAMESPACE
18
19class QXcbScreen;
20class QXcbSyncWindowRequest;
21class QIcon;
22
23class Q_XCB_EXPORT QXcbWindow : public QXcbObject, public QXcbWindowEventListener, public QPlatformWindow
24 , public QNativeInterface::Private::QXcbWindow
25{
26public:
27 enum NetWmState {
28 NetWmStateAbove = 0x1,
29 NetWmStateBelow = 0x2,
30 NetWmStateFullScreen = 0x4,
31 NetWmStateMaximizedHorz = 0x8,
32 NetWmStateMaximizedVert = 0x10,
33 NetWmStateModal = 0x20,
34 NetWmStateStaysOnTop = 0x40,
35 NetWmStateDemandsAttention = 0x80,
36 NetWmStateHidden = 0x100
37 };
38
39 Q_DECLARE_FLAGS(NetWmStates, NetWmState)
40
41 enum RecreationReason {
42 RecreationNotNeeded = 0,
43 WindowStaysOnTopHintChanged = 0x1,
44 WindowStaysOnBottomHintChanged = 0x2
45 };
46 Q_DECLARE_FLAGS(RecreationReasons, RecreationReason)
47
48 QXcbWindow(QWindow *window);
49 ~QXcbWindow();
50
51 void setGeometry(const QRect &rect) override;
52
53 QMargins frameMargins() const override;
54
55 void setVisible(bool visible) override;
56 void setWindowFlags(Qt::WindowFlags flags) override;
57 void setWindowState(Qt::WindowStates state) override;
58 WId winId() const override;
59 void setParent(const QPlatformWindow *window) override;
60
61 bool isExposed() const override;
62 bool isEmbedded() const override;
63 QPoint mapToGlobal(const QPoint &pos) const override;
64 QPoint mapFromGlobal(const QPoint &pos) const override;
65
66 void setWindowTitle(const QString &title) override;
67 void setWindowIconText(const QString &title) override;
68 void setWindowIcon(const QIcon &icon) override;
69 void raise() override;
70 void lower() override;
71 void propagateSizeHints() override;
72
73 void requestActivateWindow() override;
74
75 bool setKeyboardGrabEnabled(bool grab) override;
76 bool setMouseGrabEnabled(bool grab) override;
77
78 QSurfaceFormat format() const override;
79
80 bool windowEvent(QEvent *event) override;
81
82 bool startSystemResize(Qt::Edges edges) override;
83 bool startSystemMove() override;
84
85 void setOpacity(qreal level) override;
86 void setMask(const QRegion &region) override;
87
88 void setAlertState(bool enabled) override;
89 bool isAlertState() const override { return m_alertState; }
90
91 xcb_window_t xcb_window() const { return m_window; }
92 uint depth() const { return m_depth; }
93 QImage::Format imageFormat() const { return m_imageFormat; }
94 bool imageNeedsRgbSwap() const { return m_imageRgbSwap; }
95
96 bool handleNativeEvent(xcb_generic_event_t *event) override;
97
98 void handleExposeEvent(const xcb_expose_event_t *event) override;
99 void handleClientMessageEvent(const xcb_client_message_event_t *event) override;
100 void handleConfigureNotifyEvent(const xcb_configure_notify_event_t *event) override;
101 void handleMapNotifyEvent(const xcb_map_notify_event_t *event) override;
102 void handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event) override;
103 void handleButtonPressEvent(const xcb_button_press_event_t *event) override;
104 void handleButtonReleaseEvent(const xcb_button_release_event_t *event) override;
105 void handleMotionNotifyEvent(const xcb_motion_notify_event_t *event) override;
106
107 void handleEnterNotifyEvent(const xcb_enter_notify_event_t *event) override;
108 void handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event) override;
109 void handleFocusInEvent(const xcb_focus_in_event_t *event) override;
110 void handleFocusOutEvent(const xcb_focus_out_event_t *event) override;
111 void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event) override;
112 void handleXIMouseEvent(xcb_ge_event_t *, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized) override;
113 void handleXIEnterLeave(xcb_ge_event_t *) override;
114
115 QXcbWindow *toWindow() override;
116
117 void handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global,
118 Qt::KeyboardModifiers modifiers, QEvent::Type type, Qt::MouseEventSource source);
119
120 void updateNetWmUserTime(xcb_timestamp_t timestamp);
121
122 WindowTypes wmWindowTypes() const;
123 void setWmWindowType(WindowTypes types, Qt::WindowFlags flags);
124 void setWindowType(WindowTypes windowTypes) override { setWmWindowType(types: windowTypes, flags: window()->flags()); }
125 void setWindowRole(const QString &role) override;
126
127 void setParentRelativeBackPixmap();
128 bool requestSystemTrayWindowDock();
129 uint visualId() const override;
130
131 bool needsSync() const;
132
133 void postSyncWindowRequest();
134 void clearSyncWindowRequest() { m_pendingSyncRequest = nullptr; }
135
136 QXcbScreen *xcbScreen() const;
137
138 QPoint lastPointerPosition() const { return m_lastPointerPosition; }
139 QPoint lastPointerGlobalPosition() const { return m_lastPointerGlobalPosition; }
140
141 bool startSystemMoveResize(const QPoint &pos, int edges);
142 void doStartSystemMoveResize(const QPoint &globalPos, int edges);
143
144 static bool isTrayIconWindow(QWindow *window)
145 {
146 return window->objectName() == QLatin1StringView("QSystemTrayIconSysWindow");
147 }
148
149 virtual void create();
150 virtual void destroy();
151
152 static void setWindowTitle(const QXcbConnection *conn, xcb_window_t window, const QString &title);
153 static QString windowTitle(const QXcbConnection *conn, xcb_window_t window);
154
155 int swapInterval() const { return m_swapInterval; }
156 void setSwapInterval(int swapInterval) { m_swapInterval = swapInterval; }
157
158public Q_SLOTS:
159 void updateSyncRequestCounter();
160
161protected:
162 virtual void resolveFormat(const QSurfaceFormat &format) { m_format = format; }
163 virtual const xcb_visualtype_t *createVisual();
164 void setImageFormatForVisual(const xcb_visualtype_t *visual);
165
166 QXcbScreen *parentScreen();
167 QXcbScreen *initialScreen() const;
168
169 void setNetWmState(bool set, xcb_atom_t one, xcb_atom_t two = 0);
170 void setNetWmState(Qt::WindowFlags flags);
171 void setNetWmState(Qt::WindowStates state);
172 void setNetWmStateOnUnmappedWindow();
173 NetWmStates netWmStates();
174
175 void setMotifWmHints(Qt::WindowFlags flags);
176
177 void setTransparentForMouseEvents(bool transparent);
178 void updateDoesNotAcceptFocus(bool doesNotAcceptFocus);
179
180 void sendXEmbedMessage(xcb_window_t window, quint32 message,
181 quint32 detail = 0, quint32 data1 = 0, quint32 data2 = 0);
182 void handleXEmbedMessage(const xcb_client_message_event_t *event);
183
184 void show();
185 void hide();
186
187 bool relayFocusToModalWindow() const;
188 void doFocusIn();
189 void doFocusOut();
190
191 void handleButtonPressEvent(int event_x, int event_y, int root_x, int root_y,
192 int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp,
193 QEvent::Type type, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
194
195 void handleButtonReleaseEvent(int event_x, int event_y, int root_x, int root_y,
196 int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp,
197 QEvent::Type type, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
198
199 void handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y,
200 Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp,
201 QEvent::Type type, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
202
203 void handleEnterNotifyEvent(int event_x, int event_y, int root_x, int root_y,
204 quint8 mode, quint8 detail, xcb_timestamp_t timestamp);
205
206 void handleLeaveNotifyEvent(int root_x, int root_y,
207 quint8 mode, quint8 detail, xcb_timestamp_t timestamp);
208
209 xcb_window_t m_window = 0;
210
211 uint m_depth = 0;
212 QImage::Format m_imageFormat = QImage::Format_ARGB32_Premultiplied;
213 bool m_imageRgbSwap = false;
214
215 xcb_sync_int64_t m_syncValue;
216 xcb_sync_counter_t m_syncCounter = 0;
217
218 Qt::WindowStates m_windowState = Qt::WindowNoState;
219
220 bool m_mapped = false;
221 bool m_transparent = false;
222 bool m_deferredActivation = false;
223 bool m_embedded = false;
224 bool m_alertState = false;
225 bool m_minimized = false;
226 bool m_trayIconWindow = false;
227 xcb_window_t m_netWmUserTimeWindow = XCB_NONE;
228
229 QSurfaceFormat m_format;
230
231 mutable bool m_dirtyFrameMargins = false;
232 mutable QMargins m_frameMargins;
233
234 QRegion m_exposeRegion;
235 QSize m_oldWindowSize;
236 QPoint m_lastPointerPosition;
237 QPoint m_lastPointerGlobalPosition;
238
239 xcb_visualid_t m_visualId = 0;
240 // Last sent state. Initialized to an invalid state, on purpose.
241 Qt::WindowStates m_lastWindowStateEvent = Qt::WindowActive;
242
243 enum SyncState {
244 NoSyncNeeded,
245 SyncReceived,
246 SyncAndConfigureReceived
247 };
248 SyncState m_syncState = NoSyncNeeded;
249
250 QXcbSyncWindowRequest *m_pendingSyncRequest = nullptr;
251 int m_swapInterval = -1;
252
253 qreal m_sizeHintsScaleFactor = 1.0;
254
255 RecreationReasons m_recreationReasons = RecreationNotNeeded;
256};
257
258class QXcbForeignWindow : public QXcbWindow
259{
260public:
261 QXcbForeignWindow(QWindow *window, WId nativeHandle);
262 ~QXcbForeignWindow();
263 bool isForeignWindow() const override { return true; }
264
265protected:
266 void create() override {} // No-op
267};
268
269QList<xcb_rectangle_t> qRegionToXcbRectangleList(const QRegion &region);
270
271QT_END_NAMESPACE
272
273Q_DECLARE_METATYPE(QXcbWindow*)
274
275#endif
276

source code of qtbase/src/plugins/platforms/xcb/qxcbwindow.h