Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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
78typedef QHash<xcb_window_t, QXcbWindowEventListener *> WindowMapper;
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
187 bool isUserInputEvent(xcb_generic_event_t *event) const;
188
189 void xi2SelectStateEvents();
190 void xi2SelectDeviceEvents(xcb_window_t window);
191 bool xi2SetMouseGrabEnabled(xcb_window_t w, bool grab);
192
193 Qt::MouseButton xiToQtMouseButton(uint32_t b);
194 void xi2UpdateScrollingDevices();
195 bool isTouchScreen(int id);
196
197 bool startSystemMoveResizeForTouch(xcb_window_t window, int edges);
198 void abortSystemMoveResize(xcb_window_t window);
199 bool isDuringSystemMoveResize() const;
200 void setDuringSystemMoveResize(bool during);
201
202 bool canGrab() const { return m_canGrabServer; }
203
204 QXcbGlIntegration *glIntegration() const;
205
206 void flush() { xcb_flush(xcb_connection()); }
207 void processXcbEvents(QEventLoop::ProcessEventsFlags flags);
208
209 QTimer &focusInTimer() { return m_focusInTimer; }
210
211protected:
212 bool event(QEvent *e) override;
213
214private:
215 void xrandrSelectEvents();
216 QXcbScreen* findScreenForCrtc(xcb_window_t rootWindow, xcb_randr_crtc_t crtc) const;
217 QXcbScreen* findScreenForOutput(xcb_window_t rootWindow, xcb_randr_output_t output) const;
218 QXcbVirtualDesktop* virtualDesktopForRootWindow(xcb_window_t rootWindow) const;
219 void updateScreens(const xcb_randr_notify_event_t *event);
220 bool checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output);
221 void updateScreen(QXcbScreen *screen, const xcb_randr_output_change_t &outputChange);
222 QXcbScreen *createScreen(QXcbVirtualDesktop *virtualDesktop,
223 const xcb_randr_output_change_t &outputChange,
224 xcb_randr_get_output_info_reply_t *outputInfo);
225 void destroyScreen(QXcbScreen *screen);
226 void initializeScreens(bool initialized);
227 void initializeScreensWithoutXRandR(xcb_screen_iterator_t *it, int screenNumber, QXcbScreen **primaryScreen);
228 void initializeScreensFromOutput(xcb_screen_iterator_t *it, int screenNumber, QXcbScreen **primaryScreen);
229
230 void updateScreen_monitor(QXcbScreen *screen, xcb_randr_monitor_info_t *monitorInfo, xcb_timestamp_t timestamp = XCB_NONE);
231 QXcbScreen *createScreen_monitor(QXcbVirtualDesktop *virtualDesktop,
232 xcb_randr_monitor_info_t *monitorInfo, xcb_timestamp_t timestamp = XCB_NONE);
233 QXcbVirtualDesktop* virtualDesktopForNumber(int n) const;
234 QXcbScreen* findScreenForMonitorInfo(const QList<QPlatformScreen *> &screens, xcb_randr_monitor_info_t *monitorInfo);
235 void initializeScreensFromMonitor(xcb_screen_iterator_t *it, int screenNumber, QXcbScreen **primaryScreen, bool initialized);
236
237 bool compressEvent(xcb_generic_event_t *event) const;
238 inline bool timeGreaterThan(xcb_timestamp_t a, xcb_timestamp_t b) const
239 { return static_cast<int32_t>(a - b) > 0 || b == XCB_CURRENT_TIME; }
240
241 void xi2SetupSlavePointerDevice(void *info, bool removeExisting = true, QPointingDevice *master = nullptr);
242 void xi2SetupDevices();
243 // TODO get rid of this: store minimal necessary info in a subclass of QPointingDevicePrivate
244 struct TouchDeviceData {
245 QPointingDevice *qtTouchDevice = nullptr;
246 QHash<int, QWindowSystemInterface::TouchPoint> touchPoints;
247 QHash<int, QPointF> pointPressedPosition; // in screen coordinates where each point was pressed
249 double min = 0;
250 double max = 0;
251 int number = -1;
253 };
254 QList<ValuatorClassInfo> valuatorInfo;
255
256 // Stuff that is relevant only for touchpads
257 QPointF firstPressedPosition; // in screen coordinates where the first point was pressed
258 QPointF firstPressedNormalPosition; // device coordinates (0 to 1, 0 to 1) where the first point was pressed
259 QSizeF size; // device size in mm
260 bool providesTouchOrientation = false;
261 };
262 TouchDeviceData *populateTouchDevices(void *info, QXcbScrollingDevicePrivate *scrollingDeviceP, bool *used = nullptr);
263 TouchDeviceData *touchDeviceForId(int id);
264 void xi2HandleEvent(xcb_ge_event_t *event);
265 void xi2HandleGesturePinchEvent(void *event);
266 void xi2HandleGestureSwipeEvent(void *event);
267 void xi2HandleHierarchyEvent(void *event);
268 void xi2HandleDeviceChangedEvent(void *event);
269 void xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindow);
270#if QT_CONFIG(tabletevent)
271 // TODO get rid of this: store minimal necessary info in a subclass of QXcbScrollingDevice (some tablets can scroll)
272 struct TabletData {
273 int deviceId = 0;
277 Qt::MouseButtons buttons;
278 qint64 serialId = 0;
279 bool inProximity = false;
280 struct ValuatorClassInfo {
281 double minVal = 0;
282 double maxVal = 0;
283 double curVal = 0;
284 int number = -1;
285 };
286 QHash<int, ValuatorClassInfo> valuatorInfo;
287 };
288 friend class QTypeInfo<TabletData>;
289 friend class QTypeInfo<TabletData::ValuatorClassInfo>;
290 bool xi2HandleTabletEvent(const void *event, TabletData *tabletData);
291 void xi2ReportTabletEvent(const void *event, TabletData *tabletData);
292 QList<TabletData> m_tabletData;
293 TabletData *tabletDataForDevice(int id);
294#endif // QT_CONFIG(tabletevent)
295 void xi2HandleScrollEvent(void *event, const QPointingDevice *scrollingDevice);
296 void xi2UpdateScrollingDevice(QInputDevice *scrollingDevice);
297 QXcbScrollingDevice *scrollingDeviceForId(int id);
298
299 static bool xi2GetValuatorValueIfSet(const void *event, int valuatorNum, double *value);
300
301 QHash<int, TouchDeviceData> m_touchDevices;
302
303 struct StartSystemMoveResizeInfo {
304 xcb_window_t window = XCB_NONE;
305 uint16_t deviceid;
306 uint32_t pointid;
307 int edges;
308 } m_startSystemMoveResizeInfo;
309 bool m_duringSystemMoveResize;
310
311 const bool m_canGrabServer;
312 const xcb_visualid_t m_defaultVisualId;
313
314 QList<QXcbVirtualDesktop *> m_virtualDesktops;
315 QList<QXcbScreen *> m_screens;
316
317 xcb_timestamp_t m_time = XCB_CURRENT_TIME;
318 xcb_timestamp_t m_netWmUserTime = XCB_CURRENT_TIME;
319
320 QXcbKeyboard *m_keyboard = nullptr;
321#ifndef QT_NO_CLIPBOARD
322 QXcbClipboard *m_clipboard = nullptr;
323#endif
324#if QT_CONFIG(draganddrop)
325 QXcbDrag *m_drag = nullptr;
326#endif
327 QScopedPointer<QXcbWMSupport> m_wmSupport;
328 QXcbNativeInterface *m_nativeInterface = nullptr;
329
330 QXcbEventQueue *m_eventQueue = nullptr;
331
332 WindowMapper m_mapper;
333
334 Qt::MouseButtons m_buttonState;
335 Qt::MouseButton m_button = Qt::NoButton;
336
337 QXcbWindow *m_focusWindow = nullptr;
338 QXcbWindow *m_mouseGrabber = nullptr;
339 QXcbWindow *m_mousePressWindow = nullptr;
340
341#if QT_CONFIG(gestures)
342 qreal m_lastPinchScale = 0;
343#endif
344
345 xcb_window_t m_clientLeader = 0;
346 QByteArray m_startupId;
347 QXcbSystemTrayTracker *m_systemTrayTracker = nullptr;
348 mutable QXcbGlIntegration *m_glIntegration = nullptr;
349 mutable bool m_glIntegrationInitialized = false;
350 bool m_xiGrab = false;
351 QList<int> m_xiMasterPointerIds;
352 QList<int> m_xiSlavePointerIds;
353
354 xcb_window_t m_qtSelectionOwner = 0;
355
356 friend class QXcbEventQueue;
357
358 QTimer m_focusInTimer;
359
360};
361#if QT_CONFIG(tabletevent)
362Q_DECLARE_TYPEINFO(QXcbConnection::TabletData::ValuatorClassInfo, Q_PRIMITIVE_TYPE);
363Q_DECLARE_TYPEINFO(QXcbConnection::TabletData, Q_RELOCATABLE_TYPE);
364#endif
365
367{
368public:
371 void release();
372private:
373 QXcbConnection *m_connection;
374};
375
376// The xcb_send_event() requires all events to have 32 bytes. It calls memcpy() on the
377// passed in event. If the passed in event is less than 32 bytes, memcpy() reaches into
378// unrelated memory.
379template <typename T>
380struct alignas(32) q_padded_xcb_event : T { };
381
383
384#endif
\inmodule QtCore
Definition qbytearray.h:57
\inmodule QtCore
Definition qcoreevent.h:45
\inmodule QtCore
Definition qhash.h:820
DeviceType
This enum represents the type of device that generated a QPointerEvent.
Definition qlist.h:75
\inmodule QtCore
\inmodule QtCore\reentrant
Definition qpoint.h:217
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
Definition qsize.h:208
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
\inmodule QtCore
Definition qtimer.h:20
\inmodule QtGui
Definition qwindow.h:63
xcb_connection_t * xcb_connection() const
const xcb_setup_t * setup() const
Q_NODISCARD_CTOR QXcbConnectionGrabber(QXcbConnection *connection)
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]
QSet< QString >::iterator it
Combined button and popup list for selecting options.
MouseButton
Definition qnamespace.h:56
@ NoButton
Definition qnamespace.h:57
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 s
[6]
Definition qopenglext.h:235
GLdouble GLdouble t
Definition qopenglext.h:243
QScreen * screen
[1]
Definition main.cpp:29
#define Q_OBJECT
@ Q_PRIMITIVE_TYPE
Definition qtypeinfo.h:157
@ Q_RELOCATABLE_TYPE
Definition qtypeinfo.h:158
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
Definition qtypeinfo.h:180
long long qint64
Definition qtypes.h:60
double qreal
Definition qtypes.h:187
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)
aWidget window() -> setWindowTitle("New Window Title")
[2]
QHostInfo info
[0]
Definition moc.h:23