Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qxcbconnection.h
Go to the documentation of this file.
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 QXCBCONNECTION_H
5#define QXCBCONNECTION_H
6
7#include <xcb/xcb.h>
8#include <xcb/randr.h>
9
10#include <QtCore/QTimer>
11#include <QtGui/qpointingdevice.h>
12#include <QtGui/private/qtguiglobal_p.h>
13#include "qxcbexport.h"
14#include <QHash>
15#include <QList>
16#include <qpa/qwindowsysteminterface.h>
17#include <QtCore/QLoggingCategory>
18#include <QtCore/private/qglobal_p.h>
19
20#include "qxcbeventqueue.h"
22
23#if QT_CONFIG(tabletevent)
24#include <QTabletEvent>
25#endif
26
28
30Q_DECLARE_LOGGING_CATEGORY(lcQpaXInputDevices)
31Q_DECLARE_LOGGING_CATEGORY(lcQpaXInputEvents)
35Q_DECLARE_LOGGING_CATEGORY(lcQpaKeyboard)
36Q_DECLARE_LOGGING_CATEGORY(lcQpaClipboard)
38Q_DECLARE_LOGGING_CATEGORY(lcQpaEventReader)
39
41class QXcbScreen;
42class QXcbWindow;
43class QXcbDrag;
44class QXcbKeyboard;
47class QXcbClipboard;
48class QXcbWMSupport;
52
54{
55public:
57 virtual bool handleNativeEvent(xcb_generic_event_t *) { return false; }
58
59 virtual void handleExposeEvent(const xcb_expose_event_t *) {}
60 virtual void handleClientMessageEvent(const xcb_client_message_event_t *) {}
61 virtual void handleConfigureNotifyEvent(const xcb_configure_notify_event_t *) {}
62 virtual void handleMapNotifyEvent(const xcb_map_notify_event_t *) {}
63 virtual void handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *) {}
64 virtual void handleDestroyNotifyEvent(const xcb_destroy_notify_event_t *) {}
65 virtual void handleButtonPressEvent(const xcb_button_press_event_t *) {}
66 virtual void handleButtonReleaseEvent(const xcb_button_release_event_t *) {}
67 virtual void handleMotionNotifyEvent(const xcb_motion_notify_event_t *) {}
68 virtual void handleEnterNotifyEvent(const xcb_enter_notify_event_t *) {}
69 virtual void handleLeaveNotifyEvent(const xcb_leave_notify_event_t *) {}
70 virtual void handleFocusInEvent(const xcb_focus_in_event_t *) {}
71 virtual void handleFocusOutEvent(const xcb_focus_out_event_t *) {}
72 virtual void handlePropertyNotifyEvent(const xcb_property_notify_event_t *) {}
74 virtual void handleXIEnterLeave(xcb_ge_event_t *) {}
75 virtual QXcbWindow *toWindow() { return nullptr; }
76};
77
79
81{
82public:
84
85 QXcbWindow *window() const { return m_window; }
86 void invalidate();
87
88private:
89 QXcbWindow *m_window;
90};
91
93{
95public:
96 QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName = nullptr);
98
99 QXcbConnection *connection() const { return const_cast<QXcbConnection *>(this); }
100 QXcbEventQueue *eventQueue() const { return m_eventQueue; }
101
102 const QList<QXcbVirtualDesktop *> &virtualDesktops() const { return m_virtualDesktops; }
103 const QList<QXcbScreen *> &screens() const { return m_screens; }
105 return m_virtualDesktops.value(primaryScreenNumber());
106 }
107 QXcbScreen *primaryScreen() const;
108
109 const xcb_format_t *formatForDepth(uint8_t depth) const;
110
112 {
113 if (!hasShm())
114 return false; // The non-Shm path does its own swapping
115#if Q_BYTE_ORDER == Q_BIG_ENDIAN
116 return setup()->image_byte_order != XCB_IMAGE_ORDER_MSB_FIRST;
117#else
118 return setup()->image_byte_order != XCB_IMAGE_ORDER_LSB_FIRST;
119#endif
120 }
121
122 QXcbKeyboard *keyboard() const { return m_keyboard; }
123
124#ifndef QT_NO_CLIPBOARD
125 QXcbClipboard *clipboard() const { return m_clipboard; }
126#endif
127#if QT_CONFIG(draganddrop)
128 QXcbDrag *drag() const { return m_drag; }
129#endif
130
131 QXcbWMSupport *wmSupport() const { return m_wmSupport.data(); }
132 xcb_window_t rootWindow();
133 xcb_window_t clientLeader();
134
135 bool hasDefaultVisualId() const { return m_defaultVisualId != UINT_MAX; }
136 xcb_visualid_t defaultVisualId() const { return m_defaultVisualId; }
137
138 void sync();
139
140 void handleXcbError(xcb_generic_error_t *error);
141 void printXcbError(const char *message, xcb_generic_error_t *error);
142 void handleXcbEvent(xcb_generic_event_t *event);
143 void printXcbEvent(const QLoggingCategory &log, const char *message,
144 xcb_generic_event_t *event) const;
145
146 void addWindowEventListener(xcb_window_t id, QXcbWindowEventListener *eventListener);
147 void removeWindowEventListener(xcb_window_t id);
148 QXcbWindowEventListener *windowEventListenerFromId(xcb_window_t id);
149 QXcbWindow *platformWindowFromId(xcb_window_t id);
150
151 inline xcb_timestamp_t time() const { return m_time; }
152 inline void setTime(xcb_timestamp_t t) { if (timeGreaterThan(t, m_time)) m_time = t; }
153
154 inline xcb_timestamp_t netWmUserTime() const { return m_netWmUserTime; }
155 inline void setNetWmUserTime(xcb_timestamp_t t) { if (timeGreaterThan(t, m_netWmUserTime)) m_netWmUserTime = t; }
156
157 xcb_timestamp_t getTimestamp();
158 xcb_window_t selectionOwner(xcb_atom_t atom) const;
159 xcb_window_t qtSelectionOwner();
160
161 void setButtonState(Qt::MouseButton button, bool down);
162 Qt::MouseButtons buttonState() const { return m_buttonState; }
163 Qt::MouseButton button() const { return m_button; }
164 Qt::MouseButton translateMouseButton(xcb_button_t s);
165
166 QXcbWindow *focusWindow() const { return m_focusWindow; }
167 void setFocusWindow(QWindow *);
168 QXcbWindow *mouseGrabber() const { return m_mouseGrabber; }
169 void setMouseGrabber(QXcbWindow *);
170 QXcbWindow *mousePressWindow() const { return m_mousePressWindow; }
171 void setMousePressWindow(QXcbWindow *);
172
173 QByteArray startupId() const;
174 void setStartupId(const QByteArray &nextId);
175
176 void grabServer();
177 void ungrabServer();
178
179 QString windowManagerName() const;
180
181 QXcbNativeInterface *nativeInterface() const { return m_nativeInterface; }
182
184
185 Qt::MouseButtons queryMouseButtons() const;
186 Qt::KeyboardModifiers queryKeyboardModifiers() const;
187
188 bool isUserInputEvent(xcb_generic_event_t *event) const;
189
190 void xi2SelectStateEvents();
191 void xi2SelectDeviceEvents(xcb_window_t window);
192 bool xi2SetMouseGrabEnabled(xcb_window_t w, bool grab);
193
194 Qt::MouseButton xiToQtMouseButton(uint32_t b);
195 void xi2UpdateScrollingDevices();
196 bool isTouchScreen(int id);
197
198 bool startSystemMoveResizeForTouch(xcb_window_t window, int edges);
199 void abortSystemMoveResize(xcb_window_t window);
200 bool isDuringSystemMoveResize() const;
201 void setDuringSystemMoveResize(bool during);
202
203 bool canGrab() const { return m_canGrabServer; }
204
205 QXcbGlIntegration *glIntegration() const;
206
207 void flush() { xcb_flush(xcb_connection()); }
208 void processXcbEvents(QEventLoop::ProcessEventsFlags flags);
209
210 QTimer &focusInTimer() { return m_focusInTimer; }
211
212protected:
213 bool event(QEvent *e) override;
214
215private:
216 void xrandrSelectEvents();
217 QXcbScreen* findScreenForCrtc(xcb_window_t rootWindow, xcb_randr_crtc_t crtc) const;
218 QXcbScreen* findScreenForOutput(xcb_window_t rootWindow, xcb_randr_output_t output) const;
219 QXcbVirtualDesktop* virtualDesktopForRootWindow(xcb_window_t rootWindow) const;
220 void updateScreens(const xcb_randr_notify_event_t *event);
221 bool checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output);
222 void updateScreen(QXcbScreen *screen, const xcb_randr_output_change_t &outputChange);
223 QXcbScreen *createScreen(QXcbVirtualDesktop *virtualDesktop,
224 const xcb_randr_output_change_t &outputChange,
225 xcb_randr_get_output_info_reply_t *outputInfo);
226 void destroyScreen(QXcbScreen *screen);
227 void initializeScreens(bool initialized);
228 void initializeScreensWithoutXRandR(xcb_screen_iterator_t *it, int screenNumber, QXcbScreen **primaryScreen);
229 void initializeScreensFromOutput(xcb_screen_iterator_t *it, int screenNumber, QXcbScreen **primaryScreen);
230
231 void updateScreen_monitor(QXcbScreen *screen, xcb_randr_monitor_info_t *monitorInfo, xcb_timestamp_t timestamp = XCB_NONE);
232 QXcbScreen *createScreen_monitor(QXcbVirtualDesktop *virtualDesktop,
233 xcb_randr_monitor_info_t *monitorInfo, xcb_timestamp_t timestamp = XCB_NONE);
234 QXcbVirtualDesktop* virtualDesktopForNumber(int n) const;
235 QXcbScreen* findScreenForMonitorInfo(const QList<QPlatformScreen *> &screens, xcb_randr_monitor_info_t *monitorInfo);
236 void initializeScreensFromMonitor(xcb_screen_iterator_t *it, int screenNumber, QXcbScreen **primaryScreen, bool initialized);
237
238 bool compressEvent(xcb_generic_event_t *event) const;
239 inline bool timeGreaterThan(xcb_timestamp_t a, xcb_timestamp_t b) const
240 { return static_cast<int32_t>(a - b) > 0 || b == XCB_CURRENT_TIME; }
241
242 void xi2SetupSlavePointerDevice(void *info, bool removeExisting = true, QPointingDevice *master = nullptr);
243 void xi2SetupDevices();
244 // TODO get rid of this: store minimal necessary info in a subclass of QPointingDevicePrivate
245 struct TouchDeviceData {
246 QPointingDevice *qtTouchDevice = nullptr;
248 QHash<int, QPointF> pointPressedPosition; // in screen coordinates where each point was pressed
250 double min = 0;
251 double max = 0;
252 int number = -1;
254 };
255 QList<ValuatorClassInfo> valuatorInfo;
256
257 // Stuff that is relevant only for touchpads
258 QPointF firstPressedPosition; // in screen coordinates where the first point was pressed
259 QPointF firstPressedNormalPosition; // device coordinates (0 to 1, 0 to 1) where the first point was pressed
260 QSizeF size; // device size in mm
261 bool providesTouchOrientation = false;
262 };
263 TouchDeviceData *populateTouchDevices(void *info, QXcbScrollingDevicePrivate *scrollingDeviceP, bool *used = nullptr);
264 TouchDeviceData *touchDeviceForId(int id);
265 void xi2HandleEvent(xcb_ge_event_t *event);
266 void xi2HandleGesturePinchEvent(void *event);
267 void xi2HandleGestureSwipeEvent(void *event);
268 void xi2HandleHierarchyEvent(void *event);
269 void xi2HandleDeviceChangedEvent(void *event);
270 void xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindow);
271#if QT_CONFIG(tabletevent)
272 // TODO get rid of this: store minimal necessary info in a subclass of QXcbScrollingDevice (some tablets can scroll)
273 struct TabletData {
274 int deviceId = 0;
278 Qt::MouseButtons buttons;
279 qint64 serialId = 0;
280 bool inProximity = false;
281 struct ValuatorClassInfo {
282 double minVal = 0;
283 double maxVal = 0;
284 double curVal = 0;
285 int number = -1;
286 };
288 };
289 friend class QTypeInfo<TabletData>;
290 friend class QTypeInfo<TabletData::ValuatorClassInfo>;
291 bool xi2HandleTabletEvent(const void *event, TabletData *tabletData);
292 void xi2ReportTabletEvent(const void *event, TabletData *tabletData);
293 QList<TabletData> m_tabletData;
294 TabletData *tabletDataForDevice(int id);
295#endif // QT_CONFIG(tabletevent)
296 void xi2HandleScrollEvent(void *event, const QPointingDevice *scrollingDevice);
297 void xi2UpdateScrollingDevice(QInputDevice *scrollingDevice);
298 QXcbScrollingDevice *scrollingDeviceForId(int id);
299
300 static bool xi2GetValuatorValueIfSet(const void *event, int valuatorNum, double *value);
301
302 QHash<int, TouchDeviceData> m_touchDevices;
303
304 struct StartSystemMoveResizeInfo {
305 xcb_window_t window = XCB_NONE;
306 uint16_t deviceid;
307 uint32_t pointid;
308 int edges;
309 } m_startSystemMoveResizeInfo;
310 bool m_duringSystemMoveResize;
311
312 const bool m_canGrabServer;
313 const xcb_visualid_t m_defaultVisualId;
314
315 QList<QXcbVirtualDesktop *> m_virtualDesktops;
316 QList<QXcbScreen *> m_screens;
317
318 xcb_timestamp_t m_time = XCB_CURRENT_TIME;
319 xcb_timestamp_t m_netWmUserTime = XCB_CURRENT_TIME;
320
321 QXcbKeyboard *m_keyboard = nullptr;
322#ifndef QT_NO_CLIPBOARD
323 QXcbClipboard *m_clipboard = nullptr;
324#endif
325#if QT_CONFIG(draganddrop)
326 QXcbDrag *m_drag = nullptr;
327#endif
329 QXcbNativeInterface *m_nativeInterface = nullptr;
330
331 QXcbEventQueue *m_eventQueue = nullptr;
332
333 WindowMapper m_mapper;
334
335 Qt::MouseButtons m_buttonState;
336 Qt::MouseButton m_button = Qt::NoButton;
337
338 QXcbWindow *m_focusWindow = nullptr;
339 QXcbWindow *m_mouseGrabber = nullptr;
340 QXcbWindow *m_mousePressWindow = nullptr;
341
342#if QT_CONFIG(gestures)
343 qreal m_lastPinchScale = 0;
344#endif
345
346 xcb_window_t m_clientLeader = 0;
347 QByteArray m_startupId;
348 QXcbSystemTrayTracker *m_systemTrayTracker = nullptr;
349 mutable QXcbGlIntegration *m_glIntegration = nullptr;
350 mutable bool m_glIntegrationInitialized = false;
351 bool m_xiGrab = false;
352 QList<int> m_xiMasterPointerIds;
353 QList<int> m_xiSlavePointerIds;
354
355 xcb_window_t m_qtSelectionOwner = 0;
356
357 friend class QXcbEventQueue;
358
359 QTimer m_focusInTimer;
360
361};
362#if QT_CONFIG(tabletevent)
363Q_DECLARE_TYPEINFO(QXcbConnection::TabletData::ValuatorClassInfo, Q_PRIMITIVE_TYPE);
364Q_DECLARE_TYPEINFO(QXcbConnection::TabletData, Q_RELOCATABLE_TYPE);
365#endif
366
368{
369public:
372 void release();
373private:
374 QXcbConnection *m_connection;
375};
376
377// The xcb_send_event() requires all events to have 32 bytes. It calls memcpy() on the
378// passed in event. If the passed in event is less than 32 bytes, memcpy() reaches into
379// unrelated memory.
380template <typename T>
381struct alignas(32) q_padded_xcb_event : T { };
382
384
385#endif
\inmodule QtCore
Definition qbytearray.h:57
\inmodule QtCore
Definition qcoreevent.h:45
\inmodule QtCore
Definition qhash.h:818
DeviceType
This enum represents the type of device that generated a QPointerEvent.
Definition qlist.h:74
\inmodule QtCore
\inmodule QtCore\reentrant
Definition qpoint.h:214
The QPointingDevice class describes a device from which mouse, touch or tablet events originate.
PointerType
This enum represents what is interacting with the pointing device.
\inmodule QtCore
\inmodule QtCore
Definition qsize.h:207
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
\inmodule QtCore
Definition qtimer.h:20
\inmodule QtGui
Definition qwindow.h:63
xcb_connection_t * xcb_connection() const
const xcb_setup_t * setup() const
QXcbKeyboard * keyboard() const
QTimer & focusInTimer()
QXcbWindow * mouseGrabber() const
QXcbWindow * mousePressWindow() const
Qt::MouseButtons buttonState() const
void setTime(xcb_timestamp_t t)
QXcbConnection * connection() const
xcb_visualid_t defaultVisualId() const
QXcbWindow * focusWindow() const
bool canGrab() const
void setNetWmUserTime(xcb_timestamp_t t)
bool hasDefaultVisualId() const
bool imageNeedsEndianSwap() const
xcb_timestamp_t time() const
QXcbWMSupport * wmSupport() const
QXcbVirtualDesktop * primaryVirtualDesktop() const
const QList< QXcbVirtualDesktop * > & virtualDesktops() const
QXcbEventQueue * eventQueue() const
const QList< QXcbScreen * > & screens() const
Qt::MouseButton button() const
QXcbNativeInterface * nativeInterface() const
xcb_timestamp_t netWmUserTime() const
QXcbClipboard * clipboard() const
QXcbWindow * window() const
QXcbSyncWindowRequest(QXcbWindow *w)
virtual void handleConfigureNotifyEvent(const xcb_configure_notify_event_t *)
virtual void handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *)
virtual void handleXIMouseEvent(xcb_ge_event_t *, Qt::MouseEventSource=Qt::MouseEventNotSynthesized)
virtual void handleButtonPressEvent(const xcb_button_press_event_t *)
virtual void handleEnterNotifyEvent(const xcb_enter_notify_event_t *)
virtual void handleMapNotifyEvent(const xcb_map_notify_event_t *)
virtual void handleClientMessageEvent(const xcb_client_message_event_t *)
virtual void handleDestroyNotifyEvent(const xcb_destroy_notify_event_t *)
virtual void handleXIEnterLeave(xcb_ge_event_t *)
virtual void handleMotionNotifyEvent(const xcb_motion_notify_event_t *)
virtual void handleLeaveNotifyEvent(const xcb_leave_notify_event_t *)
virtual void handleButtonReleaseEvent(const xcb_button_release_event_t *)
virtual void handleExposeEvent(const xcb_expose_event_t *)
virtual void handleFocusOutEvent(const xcb_focus_out_event_t *)
virtual void handleFocusInEvent(const xcb_focus_in_event_t *)
virtual void handlePropertyNotifyEvent(const xcb_property_notify_event_t *)
virtual bool handleNativeEvent(xcb_generic_event_t *)
virtual QXcbWindow * toWindow()
QPushButton * button
[2]
double e
QSet< QString >::iterator it
Combined button and popup list for selecting options.
MouseButton
Definition qnamespace.h:55
@ NoButton
Definition qnamespace.h:56
MouseEventSource
@ MouseEventNotSynthesized
static bool isUserInputEvent(NSEvent *event)
static QString displayName(CGDirectDisplayID displayID)
#define Q_NODISCARD_CTOR
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
DBusConnection const char DBusError * error
DBusConnection * connection
#define Q_DECLARE_LOGGING_CATEGORY(name)
GLboolean GLboolean GLboolean b
GLint GLenum GLsizei GLsizei GLsizei depth
GLfloat GLfloat GLfloat w
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLbitfield flags
GLuint GLsizei const GLchar * message
GLuint name
GLfloat n
struct _cl_event * event
GLdouble GLdouble t
Definition qopenglext.h:243
GLdouble s
[6]
Definition qopenglext.h:235
QScreen * screen
[1]
Definition main.cpp:29
#define Q_OBJECT
@ Q_PRIMITIVE_TYPE
Definition qtypeinfo.h:144
@ Q_RELOCATABLE_TYPE
Definition qtypeinfo.h:145
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
Definition qtypeinfo.h:163
long long qint64
Definition qtypes.h:55
double qreal
Definition qtypes.h:92
QT_BEGIN_NAMESPACE typedef uchar * output
static uint nextId
static Qt::MouseButtons queryMouseButtons()
static QPointingDevice::PointerType pointerType(unsigned currentCursor)
QHash< xcb_window_t, QXcbWindowEventListener * > WindowMapper
#define Q_XCB_EXPORT
Definition qxcbexport.h:14
static QXcbSystemTrayTracker * systemTrayTracker(const QScreen *s)
QFileInfo info(fileName)
[8]
aWidget window() -> setWindowTitle("New Window Title")
[2]
Definition moc.h:24