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.cpp
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#include <QtGui/private/qguiapplication_p.h>
5#include <QtCore/QDebug>
6#include <QtCore/QCoreApplication>
7
8#include "qxcbconnection.h"
9#include "qxcbkeyboard.h"
10#include "qxcbwindow.h"
11#include "qxcbclipboard.h"
12#if QT_CONFIG(draganddrop)
13#include "qxcbdrag.h"
14#endif
15#include "qxcbwmsupport.h"
16#include "qxcbnativeinterface.h"
17#include "qxcbintegration.h"
20#include "qxcbglintegration.h"
21#include "qxcbcursor.h"
22#include "qxcbbackingstore.h"
23#include "qxcbeventqueue.h"
24
25#include <QAbstractEventDispatcher>
26#include <QByteArray>
27#include <QScopedPointer>
28
29#include <stdio.h>
30#include <errno.h>
31
32#include <xcb/xfixes.h>
33#define explicit dont_use_cxx_explicit
34#include <xcb/xkb.h>
35#undef explicit
36#include <xcb/xinput.h>
37
38#if QT_CONFIG(xcb_xlib)
39#include "qt_xlib_wrapper.h"
40#endif
41
43
44using namespace Qt::StringLiterals;
45
46Q_LOGGING_CATEGORY(lcQpaXInput, "qt.qpa.input")
47Q_LOGGING_CATEGORY(lcQpaXInputDevices, "qt.qpa.input.devices")
48Q_LOGGING_CATEGORY(lcQpaXInputEvents, "qt.qpa.input.events")
49Q_LOGGING_CATEGORY(lcQpaScreen, "qt.qpa.screen")
50Q_LOGGING_CATEGORY(lcQpaEvents, "qt.qpa.events")
51Q_LOGGING_CATEGORY(lcQpaEventReader, "qt.qpa.events.reader")
52Q_LOGGING_CATEGORY(lcQpaPeeker, "qt.qpa.peeker")
53Q_LOGGING_CATEGORY(lcQpaKeyboard, "qt.qpa.xkeyboard")
54Q_LOGGING_CATEGORY(lcQpaClipboard, "qt.qpa.clipboard")
55Q_LOGGING_CATEGORY(lcQpaXDnd, "qt.qpa.xdnd")
56
57QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName)
59 , m_duringSystemMoveResize(false)
60 , m_canGrabServer(canGrabServer)
61 , m_defaultVisualId(defaultVisualId)
62 , m_nativeInterface(nativeInterface)
63{
64 if (!isConnected())
65 return;
66
67 m_eventQueue = new QXcbEventQueue(this);
68
69 if (hasXRandr())
70 xrandrSelectEvents();
71
72 initializeScreens(false);
73
74 if (hasXInput2()) {
75 xi2SetupDevices();
76 xi2SelectStateEvents();
77 }
78
79 m_wmSupport.reset(new QXcbWMSupport(this));
80 m_keyboard = new QXcbKeyboard(this);
81#ifndef QT_NO_CLIPBOARD
82 m_clipboard = new QXcbClipboard(this);
83#endif
84#if QT_CONFIG(draganddrop)
85 m_drag = new QXcbDrag(this);
86#endif
87
88 setStartupId(qgetenv("DESKTOP_STARTUP_ID"));
89 if (!startupId().isNull())
90 qunsetenv("DESKTOP_STARTUP_ID");
91
92 const int focusInDelay = 100;
93 m_focusInTimer.setSingleShot(true);
94 m_focusInTimer.setInterval(focusInDelay);
95 m_focusInTimer.callOnTimeout(this, []() {
96 // No FocusIn events for us, proceed with FocusOut normally.
98 });
99
100 sync();
101}
102
104{
105#ifndef QT_NO_CLIPBOARD
106 delete m_clipboard;
107#endif
108#if QT_CONFIG(draganddrop)
109 delete m_drag;
110#endif
111 if (m_eventQueue)
112 delete m_eventQueue;
113
114 // Delete screens in reverse order to avoid crash in case of multiple screens
115 while (!m_screens.isEmpty())
117
118 while (!m_virtualDesktops.isEmpty())
119 delete m_virtualDesktops.takeLast();
120
121 delete m_glIntegration;
122
123 delete m_keyboard;
124}
125
127{
128 if (!m_screens.isEmpty()) {
129 Q_ASSERT(m_screens.first()->screenNumber() == primaryScreenNumber());
130 return m_screens.first();
131 }
132
133 return nullptr;
134}
135
137{
138 m_mapper.insert(id, eventListener);
139}
140
142{
143 m_mapper.remove(id);
144}
145
147{
148 return m_mapper.value(id, nullptr);
149}
150
152{
153 QXcbWindowEventListener *listener = m_mapper.value(id, nullptr);
154 if (listener)
155 return listener->toWindow();
156 return nullptr;
157}
158
159#define HANDLE_PLATFORM_WINDOW_EVENT(event_t, windowMember, handler) \
160{ \
161 auto e = reinterpret_cast<event_t *>(event); \
162 if (QXcbWindowEventListener *eventListener = windowEventListenerFromId(e->windowMember)) { \
163 if (eventListener->handleNativeEvent(event)) \
164 return; \
165 eventListener->handler(e); \
166 } \
167} \
168break;
169
170#define HANDLE_KEYBOARD_EVENT(event_t, handler) \
171{ \
172 auto e = reinterpret_cast<event_t *>(event); \
173 if (QXcbWindowEventListener *eventListener = windowEventListenerFromId(e->event)) { \
174 if (eventListener->handleNativeEvent(event)) \
175 return; \
176 m_keyboard->handler(e); \
177 } \
178} \
179break;
180
182 xcb_generic_event_t *event) const
183{
184 quint8 response_type = event->response_type & ~0x80;
185 quint16 sequence = event->sequence;
186
187#define PRINT_AND_RETURN(name) { \
188 qCDebug(log, "%s | %s(%d) | sequence: %d", message, name, response_type, sequence); \
189 return; \
190}
191#define CASE_PRINT_AND_RETURN(name) case name : PRINT_AND_RETURN(#name);
192
193#define XI_PRINT_AND_RETURN(name) { \
194 qCDebug(log, "%s | XInput Event(%s) | sequence: %d", message, name, sequence); \
195 return; \
196}
197#define XI_CASE_PRINT_AND_RETURN(name) case name : XI_PRINT_AND_RETURN(#name);
198
199 switch (response_type) {
200 CASE_PRINT_AND_RETURN( XCB_KEY_PRESS );
201 CASE_PRINT_AND_RETURN( XCB_KEY_RELEASE );
202 CASE_PRINT_AND_RETURN( XCB_BUTTON_PRESS );
203 CASE_PRINT_AND_RETURN( XCB_BUTTON_RELEASE );
204 CASE_PRINT_AND_RETURN( XCB_MOTION_NOTIFY );
205 CASE_PRINT_AND_RETURN( XCB_ENTER_NOTIFY );
206 CASE_PRINT_AND_RETURN( XCB_LEAVE_NOTIFY );
207 CASE_PRINT_AND_RETURN( XCB_FOCUS_IN );
208 CASE_PRINT_AND_RETURN( XCB_FOCUS_OUT );
209 CASE_PRINT_AND_RETURN( XCB_KEYMAP_NOTIFY );
210 CASE_PRINT_AND_RETURN( XCB_EXPOSE );
211 CASE_PRINT_AND_RETURN( XCB_GRAPHICS_EXPOSURE );
212 CASE_PRINT_AND_RETURN( XCB_NO_EXPOSURE );
213 CASE_PRINT_AND_RETURN( XCB_VISIBILITY_NOTIFY );
214 CASE_PRINT_AND_RETURN( XCB_CREATE_NOTIFY );
215 CASE_PRINT_AND_RETURN( XCB_DESTROY_NOTIFY );
216 CASE_PRINT_AND_RETURN( XCB_UNMAP_NOTIFY );
217 CASE_PRINT_AND_RETURN( XCB_MAP_NOTIFY );
218 CASE_PRINT_AND_RETURN( XCB_MAP_REQUEST );
219 CASE_PRINT_AND_RETURN( XCB_REPARENT_NOTIFY );
220 CASE_PRINT_AND_RETURN( XCB_CONFIGURE_NOTIFY );
221 CASE_PRINT_AND_RETURN( XCB_CONFIGURE_REQUEST );
222 CASE_PRINT_AND_RETURN( XCB_GRAVITY_NOTIFY );
223 CASE_PRINT_AND_RETURN( XCB_RESIZE_REQUEST );
224 CASE_PRINT_AND_RETURN( XCB_CIRCULATE_NOTIFY );
225 CASE_PRINT_AND_RETURN( XCB_CIRCULATE_REQUEST );
226 CASE_PRINT_AND_RETURN( XCB_PROPERTY_NOTIFY );
227 CASE_PRINT_AND_RETURN( XCB_SELECTION_CLEAR );
228 CASE_PRINT_AND_RETURN( XCB_SELECTION_REQUEST );
229 CASE_PRINT_AND_RETURN( XCB_SELECTION_NOTIFY );
230 CASE_PRINT_AND_RETURN( XCB_COLORMAP_NOTIFY );
231 CASE_PRINT_AND_RETURN( XCB_CLIENT_MESSAGE );
232 CASE_PRINT_AND_RETURN( XCB_MAPPING_NOTIFY );
233 case XCB_GE_GENERIC: {
234 if (hasXInput2() && isXIEvent(event)) {
235 auto *xiDeviceEvent = reinterpret_cast<const xcb_input_button_press_event_t*>(event); // qt_xcb_input_device_event_t
236 switch (xiDeviceEvent->event_type) {
237 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_KEY_PRESS );
238 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_KEY_RELEASE );
239 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_BUTTON_PRESS );
240 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_BUTTON_RELEASE );
241 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_MOTION );
242 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_ENTER );
243 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_LEAVE );
244 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_FOCUS_IN );
245 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_FOCUS_OUT );
246 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_HIERARCHY );
247 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_PROPERTY );
248 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_RAW_KEY_PRESS );
249 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_RAW_KEY_RELEASE );
250 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_RAW_BUTTON_PRESS );
251 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_RAW_BUTTON_RELEASE );
252 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_RAW_MOTION );
253 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_TOUCH_BEGIN );
254 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_TOUCH_UPDATE );
255 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_TOUCH_END );
256 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_TOUCH_OWNERSHIP );
257 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_RAW_TOUCH_BEGIN );
258 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_RAW_TOUCH_UPDATE );
259 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_RAW_TOUCH_END );
260 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_BARRIER_HIT );
261 XI_CASE_PRINT_AND_RETURN( XCB_INPUT_BARRIER_LEAVE );
262 default:
263 qCDebug(log, "%s | XInput Event(other type) | sequence: %d", message, sequence);
264 return;
265 }
266 } else {
267 qCDebug(log, "%s | %s(%d) | sequence: %d", message, "XCB_GE_GENERIC", response_type, sequence);
268 return;
269 }
270 }
271 }
272 // XFixes
273 if (isXFixesType(response_type, XCB_XFIXES_SELECTION_NOTIFY))
274 PRINT_AND_RETURN("XCB_XFIXES_SELECTION_NOTIFY");
275
276 // XRandR
277 if (isXRandrType(response_type, XCB_RANDR_NOTIFY))
278 PRINT_AND_RETURN("XCB_RANDR_NOTIFY");
279 if (isXRandrType(response_type, XCB_RANDR_SCREEN_CHANGE_NOTIFY))
280 PRINT_AND_RETURN("XCB_RANDR_SCREEN_CHANGE_NOTIFY");
281
282 // XKB
283 if (isXkbType(response_type))
284 PRINT_AND_RETURN("XCB_XKB_* event");
285
286 // UNKNOWN
287 qCDebug(log, "%s | unknown(%d) | sequence: %d", message, response_type, sequence);
288
289#undef PRINT_AND_RETURN
290#undef CASE_PRINT_AND_RETURN
291}
292
293const char *xcb_errors[] =
294{
295 "Success",
296 "BadRequest",
297 "BadValue",
298 "BadWindow",
299 "BadPixmap",
300 "BadAtom",
301 "BadCursor",
302 "BadFont",
303 "BadMatch",
304 "BadDrawable",
305 "BadAccess",
306 "BadAlloc",
307 "BadColor",
308 "BadGC",
309 "BadIDChoice",
310 "BadName",
311 "BadLength",
312 "BadImplementation",
313 "Unknown"
314};
315
317{
318 "Null",
319 "CreateWindow",
320 "ChangeWindowAttributes",
321 "GetWindowAttributes",
322 "DestroyWindow",
323 "DestroySubwindows",
324 "ChangeSaveSet",
325 "ReparentWindow",
326 "MapWindow",
327 "MapSubwindows",
328 "UnmapWindow",
329 "UnmapSubwindows",
330 "ConfigureWindow",
331 "CirculateWindow",
332 "GetGeometry",
333 "QueryTree",
334 "InternAtom",
335 "GetAtomName",
336 "ChangeProperty",
337 "DeleteProperty",
338 "GetProperty",
339 "ListProperties",
340 "SetSelectionOwner",
341 "GetSelectionOwner",
342 "ConvertSelection",
343 "SendEvent",
344 "GrabPointer",
345 "UngrabPointer",
346 "GrabButton",
347 "UngrabButton",
348 "ChangeActivePointerGrab",
349 "GrabKeyboard",
350 "UngrabKeyboard",
351 "GrabKey",
352 "UngrabKey",
353 "AllowEvents",
354 "GrabServer",
355 "UngrabServer",
356 "QueryPointer",
357 "GetMotionEvents",
358 "TranslateCoords",
359 "WarpPointer",
360 "SetInputFocus",
361 "GetInputFocus",
362 "QueryKeymap",
363 "OpenFont",
364 "CloseFont",
365 "QueryFont",
366 "QueryTextExtents",
367 "ListFonts",
368 "ListFontsWithInfo",
369 "SetFontPath",
370 "GetFontPath",
371 "CreatePixmap",
372 "FreePixmap",
373 "CreateGC",
374 "ChangeGC",
375 "CopyGC",
376 "SetDashes",
377 "SetClipRectangles",
378 "FreeGC",
379 "ClearArea",
380 "CopyArea",
381 "CopyPlane",
382 "PolyPoint",
383 "PolyLine",
384 "PolySegment",
385 "PolyRectangle",
386 "PolyArc",
387 "FillPoly",
388 "PolyFillRectangle",
389 "PolyFillArc",
390 "PutImage",
391 "GetImage",
392 "PolyText8",
393 "PolyText16",
394 "ImageText8",
395 "ImageText16",
396 "CreateColormap",
397 "FreeColormap",
398 "CopyColormapAndFree",
399 "InstallColormap",
400 "UninstallColormap",
401 "ListInstalledColormaps",
402 "AllocColor",
403 "AllocNamedColor",
404 "AllocColorCells",
405 "AllocColorPlanes",
406 "FreeColors",
407 "StoreColors",
408 "StoreNamedColor",
409 "QueryColors",
410 "LookupColor",
411 "CreateCursor",
412 "CreateGlyphCursor",
413 "FreeCursor",
414 "RecolorCursor",
415 "QueryBestSize",
416 "QueryExtension",
417 "ListExtensions",
418 "ChangeKeyboardMapping",
419 "GetKeyboardMapping",
420 "ChangeKeyboardControl",
421 "GetKeyboardControl",
422 "Bell",
423 "ChangePointerControl",
424 "GetPointerControl",
425 "SetScreenSaver",
426 "GetScreenSaver",
427 "ChangeHosts",
428 "ListHosts",
429 "SetAccessControl",
430 "SetCloseDownMode",
431 "KillClient",
432 "RotateProperties",
433 "ForceScreenSaver",
434 "SetPointerMapping",
435 "GetPointerMapping",
436 "SetModifierMapping",
437 "GetModifierMapping",
438 "Unknown"
439};
440
441void QXcbConnection::handleXcbError(xcb_generic_error_t *error)
442{
443 qintptr result = 0;
445 if (dispatcher && dispatcher->filterNativeEvent(m_nativeInterface->nativeEventType(), error, &result))
446 return;
447
448 printXcbError("QXcbConnection: XCB error", error);
449}
450
451void QXcbConnection::printXcbError(const char *message, xcb_generic_error_t *error)
452{
453 uint clamped_error_code = qMin<uint>(error->error_code, (sizeof(xcb_errors) / sizeof(xcb_errors[0])) - 1);
454 uint clamped_major_code = qMin<uint>(error->major_code, (sizeof(xcb_protocol_request_codes) / sizeof(xcb_protocol_request_codes[0])) - 1);
455
456 qCDebug(lcQpaXcb, "%s: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d",
457 message,
458 int(error->error_code), xcb_errors[clamped_error_code],
459 int(error->sequence), int(error->resource_id),
460 int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
461 int(error->minor_code));
462}
463
464static Qt::MouseButtons translateMouseButtons(int s)
465{
466 Qt::MouseButtons ret;
467 if (s & XCB_BUTTON_MASK_1)
469 if (s & XCB_BUTTON_MASK_2)
471 if (s & XCB_BUTTON_MASK_3)
473 return ret;
474}
475
477{
478 m_buttonState.setFlag(button, down);
479 m_button = button;
480}
481
483{
484 switch (s) {
485 case 1: return Qt::LeftButton;
486 case 2: return Qt::MiddleButton;
487 case 3: return Qt::RightButton;
488 // Button values 4-7 were already handled as Wheel events, and won't occur here.
489 case 8: return Qt::BackButton; // Also known as Qt::ExtraButton1
490 case 9: return Qt::ForwardButton; // Also known as Qt::ExtraButton2
491 case 10: return Qt::ExtraButton3;
492 case 11: return Qt::ExtraButton4;
493 case 12: return Qt::ExtraButton5;
494 case 13: return Qt::ExtraButton6;
495 case 14: return Qt::ExtraButton7;
496 case 15: return Qt::ExtraButton8;
497 case 16: return Qt::ExtraButton9;
498 case 17: return Qt::ExtraButton10;
499 case 18: return Qt::ExtraButton11;
500 case 19: return Qt::ExtraButton12;
501 case 20: return Qt::ExtraButton13;
502 case 21: return Qt::ExtraButton14;
503 case 22: return Qt::ExtraButton15;
504 case 23: return Qt::ExtraButton16;
505 case 24: return Qt::ExtraButton17;
506 case 25: return Qt::ExtraButton18;
507 case 26: return Qt::ExtraButton19;
508 case 27: return Qt::ExtraButton20;
509 case 28: return Qt::ExtraButton21;
510 case 29: return Qt::ExtraButton22;
511 case 30: return Qt::ExtraButton23;
512 case 31: return Qt::ExtraButton24;
513 default: return Qt::NoButton;
514 }
515}
516
517namespace {
518 typedef union {
519 /* All XKB events share these fields. */
520 struct {
521 uint8_t response_type;
522 uint8_t xkbType;
523 uint16_t sequence;
524 xcb_timestamp_t time;
525 uint8_t deviceID;
526 } any;
527 xcb_xkb_new_keyboard_notify_event_t new_keyboard_notify;
528 xcb_xkb_map_notify_event_t map_notify;
529 xcb_xkb_state_notify_event_t state_notify;
530 } _xkb_event;
531}
532
533void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
534{
535 if (Q_UNLIKELY(lcQpaEvents().isDebugEnabled()))
536 printXcbEvent(lcQpaEvents(), "Event", event);
537
538 qintptr result = 0; // Used only by MS Windows
540 if (dispatcher->filterNativeEvent(m_nativeInterface->nativeEventType(), event, &result))
541 return;
542 }
543
544 uint response_type = event->response_type & ~0x80;
545
546 bool handled = true;
547 switch (response_type) {
548 case XCB_EXPOSE:
549 HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent);
550 case XCB_BUTTON_PRESS: {
551 auto ev = reinterpret_cast<xcb_button_press_event_t *>(event);
552 setTime(ev->time);
553 m_keyboard->updateXKBStateFromCore(ev->state);
554 // the event explicitly contains the state of the three first buttons,
555 // the rest we need to manage ourselves
556 m_buttonState = (m_buttonState & ~0x7) | translateMouseButtons(ev->state);
557 setButtonState(translateMouseButton(ev->detail), true);
558 if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
559 qCDebug(lcQpaXInputEvents, "legacy mouse press, button %d state %X",
560 ev->detail, static_cast<unsigned int>(m_buttonState));
561 HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent);
562 }
563 case XCB_BUTTON_RELEASE: {
564 auto ev = reinterpret_cast<xcb_button_release_event_t *>(event);
565 setTime(ev->time);
566 if (m_duringSystemMoveResize && ev->root != XCB_NONE)
567 abortSystemMoveResize(ev->root);
568 m_keyboard->updateXKBStateFromCore(ev->state);
569 m_buttonState = (m_buttonState & ~0x7) | translateMouseButtons(ev->state);
570 setButtonState(translateMouseButton(ev->detail), false);
571 if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
572 qCDebug(lcQpaXInputEvents, "legacy mouse release, button %d state %X",
573 ev->detail, static_cast<unsigned int>(m_buttonState));
574 HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent);
575 }
576 case XCB_MOTION_NOTIFY: {
577 auto ev = reinterpret_cast<xcb_motion_notify_event_t *>(event);
578 setTime(ev->time);
579 m_keyboard->updateXKBStateFromCore(ev->state);
580 m_buttonState = (m_buttonState & ~0x7) | translateMouseButtons(ev->state);
581 if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
582 qCDebug(lcQpaXInputEvents, "legacy mouse move %d,%d button %d state %X",
583 ev->event_x, ev->event_y, ev->detail, static_cast<unsigned int>(m_buttonState));
584 HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent);
585 }
586 case XCB_CONFIGURE_NOTIFY: {
587 if (isAtLeastXRandR15()) {
588 auto ev = reinterpret_cast<xcb_configure_notify_event_t *>(event);
589 if (ev->event == rootWindow())
590 initializeScreens(true);
591 }
592 HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent);
593 }
594 case XCB_MAP_NOTIFY:
595 HANDLE_PLATFORM_WINDOW_EVENT(xcb_map_notify_event_t, event, handleMapNotifyEvent);
596 case XCB_UNMAP_NOTIFY:
597 HANDLE_PLATFORM_WINDOW_EVENT(xcb_unmap_notify_event_t, event, handleUnmapNotifyEvent);
598 case XCB_DESTROY_NOTIFY:
599 HANDLE_PLATFORM_WINDOW_EVENT(xcb_destroy_notify_event_t, event, handleDestroyNotifyEvent);
600 case XCB_CLIENT_MESSAGE: {
601 auto clientMessage = reinterpret_cast<xcb_client_message_event_t *>(event);
602 if (clientMessage->format != 32)
603 return;
604#if QT_CONFIG(draganddrop)
605 if (clientMessage->type == atom(QXcbAtom::AtomXdndStatus))
606 drag()->handleStatus(clientMessage);
607 else if (clientMessage->type == atom(QXcbAtom::AtomXdndFinished))
608 drag()->handleFinished(clientMessage);
609#endif
610 if (m_systemTrayTracker && clientMessage->type == atom(QXcbAtom::AtomMANAGER))
611 m_systemTrayTracker->notifyManagerClientMessageEvent(clientMessage);
612 HANDLE_PLATFORM_WINDOW_EVENT(xcb_client_message_event_t, window, handleClientMessageEvent);
613 }
614 case XCB_ENTER_NOTIFY:
615 if (hasXInput2()) {
616 // Prefer XI2 enter (XCB_INPUT_ENTER) events over core events.
617 break;
618 }
619 setTime(reinterpret_cast<xcb_enter_notify_event_t *>(event)->time);
620 HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent);
621 case XCB_LEAVE_NOTIFY:
622 {
623 if (hasXInput2()) {
624 // Prefer XI2 leave (XCB_INPUT_LEAVE) events over core events.
625 break;
626 }
627 auto ev = reinterpret_cast<xcb_leave_notify_event_t *>(event);
628 setTime(ev->time);
629 m_keyboard->updateXKBStateFromCore(ev->state);
630 HANDLE_PLATFORM_WINDOW_EVENT(xcb_leave_notify_event_t, event, handleLeaveNotifyEvent);
631 }
632 case XCB_FOCUS_IN:
633 HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_in_event_t, event, handleFocusInEvent);
634 case XCB_FOCUS_OUT:
635 HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_out_event_t, event, handleFocusOutEvent);
636 case XCB_KEY_PRESS:
637 {
638 auto keyPress = reinterpret_cast<xcb_key_press_event_t *>(event);
639 setTime(keyPress->time);
640 m_keyboard->updateXKBStateFromCore(keyPress->state);
641 setTime(keyPress->time);
642 HANDLE_KEYBOARD_EVENT(xcb_key_press_event_t, handleKeyPressEvent);
643 }
644 case XCB_KEY_RELEASE:
645 {
646 auto keyRelease = reinterpret_cast<xcb_key_release_event_t *>(event);
647 setTime(keyRelease->time);
648 m_keyboard->updateXKBStateFromCore(keyRelease->state);
649 HANDLE_KEYBOARD_EVENT(xcb_key_release_event_t, handleKeyReleaseEvent);
650 }
651 case XCB_MAPPING_NOTIFY:
652 m_keyboard->updateKeymap(reinterpret_cast<xcb_mapping_notify_event_t *>(event));
653 break;
654 case XCB_SELECTION_REQUEST:
655 {
656#if QT_CONFIG(draganddrop) || QT_CONFIG(clipboard)
657 auto selectionRequest = reinterpret_cast<xcb_selection_request_event_t *>(event);
658 setTime(selectionRequest->time);
659#endif
660#if QT_CONFIG(draganddrop)
661 if (selectionRequest->selection == atom(QXcbAtom::AtomXdndSelection))
662 m_drag->handleSelectionRequest(selectionRequest);
663 else
664#endif
665 {
666#ifndef QT_NO_CLIPBOARD
667 m_clipboard->handleSelectionRequest(selectionRequest);
668#endif
669 }
670 break;
671 }
672 case XCB_SELECTION_CLEAR:
673 setTime((reinterpret_cast<xcb_selection_clear_event_t *>(event))->time);
674#ifndef QT_NO_CLIPBOARD
675 m_clipboard->handleSelectionClearRequest(reinterpret_cast<xcb_selection_clear_event_t *>(event));
676#endif
677 break;
678 case XCB_SELECTION_NOTIFY:
679 setTime((reinterpret_cast<xcb_selection_notify_event_t *>(event))->time);
680 break;
681 case XCB_PROPERTY_NOTIFY:
682 {
683 auto propertyNotify = reinterpret_cast<xcb_property_notify_event_t *>(event);
684 setTime(propertyNotify->time);
685#ifndef QT_NO_CLIPBOARD
686 if (m_clipboard->handlePropertyNotify(event))
687 break;
688#endif
689 if (propertyNotify->atom == atom(QXcbAtom::Atom_NET_WORKAREA)) {
690 QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(propertyNotify->window);
691 if (virtualDesktop)
692 virtualDesktop->updateWorkArea();
693 } else if (propertyNotify->atom == atom(QXcbAtom::Atom_NET_SUPPORTED)) {
694 m_wmSupport->updateNetWMAtoms();
695 } else {
696 HANDLE_PLATFORM_WINDOW_EVENT(xcb_property_notify_event_t, window, handlePropertyNotifyEvent);
697 }
698 break;
699 }
700 case XCB_GE_GENERIC:
701 // Here the windowEventListener is invoked from xi2HandleEvent()
702 if (hasXInput2() && isXIEvent(event))
703 xi2HandleEvent(reinterpret_cast<xcb_ge_event_t *>(event));
704 break;
705 default:
706 handled = false; // event type not recognized
707 break;
708 }
709
710 if (handled)
711 return;
712
713 handled = true;
714 if (isXFixesType(response_type, XCB_XFIXES_SELECTION_NOTIFY)) {
715 auto notify_event = reinterpret_cast<xcb_xfixes_selection_notify_event_t *>(event);
716 setTime(notify_event->timestamp);
717#ifndef QT_NO_CLIPBOARD
718 m_clipboard->handleXFixesSelectionRequest(notify_event);
719#endif
720 for (QXcbVirtualDesktop *virtualDesktop : std::as_const(m_virtualDesktops))
721 virtualDesktop->handleXFixesSelectionNotify(notify_event);
722 } else if (isXRandrType(response_type, XCB_RANDR_NOTIFY)) {
723 if (!isAtLeastXRandR15())
724 updateScreens(reinterpret_cast<xcb_randr_notify_event_t *>(event));
725 } else if (isXRandrType(response_type, XCB_RANDR_SCREEN_CHANGE_NOTIFY)) {
726 if (!isAtLeastXRandR15()) {
727 auto change_event = reinterpret_cast<xcb_randr_screen_change_notify_event_t *>(event);
728 if (auto virtualDesktop = virtualDesktopForRootWindow(change_event->root))
729 virtualDesktop->handleScreenChange(change_event);
730 }
731 } else if (isXkbType(response_type)) {
732 auto xkb_event = reinterpret_cast<_xkb_event *>(event);
733 if (xkb_event->any.deviceID == m_keyboard->coreDeviceId()) {
734 switch (xkb_event->any.xkbType) {
735 // XkbNewKkdNotify and XkbMapNotify together capture all sorts of keymap
736 // updates (e.g. xmodmap, xkbcomp, setxkbmap), with minimal redundant recompilations.
737 case XCB_XKB_STATE_NOTIFY:
738 m_keyboard->updateXKBState(&xkb_event->state_notify);
739 break;
740 case XCB_XKB_MAP_NOTIFY:
741 m_keyboard->updateKeymap();
742 break;
743 case XCB_XKB_NEW_KEYBOARD_NOTIFY: {
744 xcb_xkb_new_keyboard_notify_event_t *ev = &xkb_event->new_keyboard_notify;
745 if (ev->changed & XCB_XKB_NKN_DETAIL_KEYCODES)
746 m_keyboard->updateKeymap();
747 break;
748 }
749 default:
750 break;
751 }
752 }
753 } else {
754 handled = false; // event type still not recognized
755 }
756
757 if (handled)
758 return;
759
760 if (m_glIntegration)
761 m_glIntegration->handleXcbEvent(event, response_type);
762}
763
765{
766 m_focusWindow = w ? static_cast<QXcbWindow *>(w->handle()) : nullptr;
767}
769{
770 m_mouseGrabber = w;
771 m_mousePressWindow = nullptr;
772}
774{
775 m_mousePressWindow = w;
776}
777
779{
780 return m_startupId;
781}
783{
784 m_startupId = nextId;
785 if (m_clientLeader) {
786 if (!nextId.isEmpty())
787 xcb_change_property(xcb_connection(),
788 XCB_PROP_MODE_REPLACE,
789 clientLeader(),
792 8,
793 nextId.size(),
794 nextId.constData());
795 else
797 }
798}
799
801{
802 if (m_canGrabServer)
803 xcb_grab_server(xcb_connection());
804}
805
807{
808 if (m_canGrabServer)
809 xcb_ungrab_server(xcb_connection());
810}
811
813{
815 if (pvd)
816 return pvd->windowManagerName().toLower();
817
818 return QString();
819}
820
822{
823 // send a dummy event to myself to get the timestamp from X server.
824 xcb_window_t window = rootWindow();
825 xcb_atom_t dummyAtom = atom(QXcbAtom::Atom_QT_GET_TIMESTAMP);
826 xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, window, dummyAtom,
827 XCB_ATOM_INTEGER, 32, 0, nullptr);
828
829 connection()->flush();
830
831 xcb_generic_event_t *event = nullptr;
832
833 // When disconnection is caused by X server, event will never be able to hold
834 // a valid pointer. isConnected(), which calls xcb_connection_has_error(),
835 // can handle this type of disconnection and properly quits the loop.
836 while (isConnected() && !event) {
837 connection()->sync();
838 event = eventQueue()->peek([window, dummyAtom](xcb_generic_event_t *event, int type) {
839 if (type != XCB_PROPERTY_NOTIFY)
840 return false;
841 auto propertyNotify = reinterpret_cast<xcb_property_notify_event_t *>(event);
842 return propertyNotify->window == window && propertyNotify->atom == dummyAtom;
843 });
844 }
845
846 if (!event) {
847 // https://www.x.org/releases/X11R7.7/doc/xproto/x11protocol.html#glossary
848 // > One timestamp value (named CurrentTime) is never generated by the
849 // > server. This value is reserved for use in requests to represent the
850 // > current server time.
851 return XCB_CURRENT_TIME;
852 }
853
854 xcb_property_notify_event_t *pn = reinterpret_cast<xcb_property_notify_event_t *>(event);
855 xcb_timestamp_t timestamp = pn->time;
856 free(event);
857
858 return timestamp;
859}
860
861xcb_window_t QXcbConnection::selectionOwner(xcb_atom_t atom) const
862{
863 auto reply = Q_XCB_REPLY(xcb_get_selection_owner, xcb_connection(), atom);
864 if (!reply) {
865 qCDebug(lcQpaXcb) << "failed to query selection owner";
866 return XCB_NONE;
867 }
868
869 return reply->owner;
870}
871
873{
874 if (!m_qtSelectionOwner) {
875 xcb_screen_t *xcbScreen = primaryVirtualDesktop()->screen();
876 int16_t x = 0, y = 0;
877 uint16_t w = 3, h = 3;
878 m_qtSelectionOwner = xcb_generate_id(xcb_connection());
879 xcb_create_window(xcb_connection(),
880 XCB_COPY_FROM_PARENT, // depth -- same as root
881 m_qtSelectionOwner, // window id
882 xcbScreen->root, // parent window id
883 x, y, w, h,
884 0, // border width
885 XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
886 xcbScreen->root_visual, // visual
887 0, // value mask
888 nullptr); // value list
889
890 QXcbWindow::setWindowTitle(connection(), m_qtSelectionOwner,
891 "Qt Selection Owner for "_L1 + QCoreApplication::applicationName());
892 }
893 return m_qtSelectionOwner;
894}
895
897{
899 return s ? s->root() : 0;
900}
901
903{
904 if (m_clientLeader == 0) {
905 m_clientLeader = xcb_generate_id(xcb_connection());
907 xcb_create_window(xcb_connection(),
908 XCB_COPY_FROM_PARENT,
909 m_clientLeader,
910 screen->root(),
911 0, 0, 1, 1,
912 0,
913 XCB_WINDOW_CLASS_INPUT_OUTPUT,
914 screen->screen()->root_visual,
915 0, nullptr);
916
917
918 QXcbWindow::setWindowTitle(connection(), m_clientLeader,
920
921 xcb_change_property(xcb_connection(),
922 XCB_PROP_MODE_REPLACE,
923 m_clientLeader,
925 XCB_ATOM_WINDOW,
926 32,
927 1,
928 &m_clientLeader);
929
930#if QT_CONFIG(xcb_sm)
931 // If we are session managed, inform the window manager about it
932 QByteArray session = qGuiApp->sessionId().toLatin1();
933 if (!session.isEmpty()) {
934 xcb_change_property(xcb_connection(),
935 XCB_PROP_MODE_REPLACE,
936 m_clientLeader,
938 XCB_ATOM_STRING,
939 8,
940 session.size(),
941 session.constData());
942 }
943#endif
944
946 }
947 return m_clientLeader;
948}
949
962bool QXcbConnection::compressEvent(xcb_generic_event_t *event) const
963{
965 return false;
966
967 uint responseType = event->response_type & ~0x80;
968
969 if (responseType == XCB_MOTION_NOTIFY) {
970 // compress XCB_MOTION_NOTIFY notify events
971 return m_eventQueue->peek(QXcbEventQueue::PeekRetainMatch,
972 [](xcb_generic_event_t *, int type) {
973 return type == XCB_MOTION_NOTIFY;
974 });
975 }
976
977 // compress XI_* events
978 if (responseType == XCB_GE_GENERIC) {
979 if (!hasXInput2())
980 return false;
981
982 // compress XI_Motion
983 if (isXIType(event, XCB_INPUT_MOTION)) {
984#if QT_CONFIG(tabletevent)
985 auto xdev = reinterpret_cast<xcb_input_motion_event_t *>(event);
987 const_cast<QXcbConnection *>(this)->tabletDataForDevice(xdev->sourceid))
988 return false;
989#endif // QT_CONFIG(tabletevent)
990 return m_eventQueue->peek(QXcbEventQueue::PeekRetainMatch,
991 [this](xcb_generic_event_t *next, int) {
992 return isXIType(next, XCB_INPUT_MOTION);
993 });
994 }
995
996 // compress XI_TouchUpdate for the same touch point id
997 if (isXIType(event, XCB_INPUT_TOUCH_UPDATE)) {
998 auto touchUpdateEvent = reinterpret_cast<xcb_input_touch_update_event_t *>(event);
999 uint32_t id = touchUpdateEvent->detail % INT_MAX;
1000
1001 return m_eventQueue->peek(QXcbEventQueue::PeekRetainMatch,
1002 [this, &id](xcb_generic_event_t *next, int) {
1003 if (!isXIType(next, XCB_INPUT_TOUCH_UPDATE))
1004 return false;
1005 auto touchUpdateNextEvent = reinterpret_cast<xcb_input_touch_update_event_t *>(next);
1006 return id == touchUpdateNextEvent->detail % INT_MAX;
1007 });
1008 }
1009
1010 return false;
1011 }
1012
1013 if (responseType == XCB_CONFIGURE_NOTIFY) {
1014 // compress multiple configure notify events for the same window
1015 return m_eventQueue->peek(QXcbEventQueue::PeekRetainMatch,
1016 [event](xcb_generic_event_t *next, int type) {
1017 if (type != XCB_CONFIGURE_NOTIFY)
1018 return false;
1019 auto currentEvent = reinterpret_cast<xcb_configure_notify_event_t *>(event);
1020 auto nextEvent = reinterpret_cast<xcb_configure_notify_event_t *>(next);
1021 return currentEvent->event == nextEvent->event;
1022 });
1023 }
1024
1025 return false;
1026}
1027
1028bool QXcbConnection::isUserInputEvent(xcb_generic_event_t *event) const
1029{
1030 auto eventType = event->response_type & ~0x80;
1031 bool isInputEvent = eventType == XCB_BUTTON_PRESS ||
1032 eventType == XCB_BUTTON_RELEASE ||
1033 eventType == XCB_KEY_PRESS ||
1034 eventType == XCB_KEY_RELEASE ||
1035 eventType == XCB_MOTION_NOTIFY ||
1036 eventType == XCB_ENTER_NOTIFY ||
1037 eventType == XCB_LEAVE_NOTIFY;
1038 if (isInputEvent)
1039 return true;
1040
1041 if (connection()->hasXInput2()) {
1042 isInputEvent = isXIType(event, XCB_INPUT_BUTTON_PRESS) ||
1043 isXIType(event, XCB_INPUT_BUTTON_RELEASE) ||
1044 isXIType(event, XCB_INPUT_MOTION) ||
1045 isXIType(event, XCB_INPUT_TOUCH_BEGIN) ||
1046 isXIType(event, XCB_INPUT_TOUCH_UPDATE) ||
1047 isXIType(event, XCB_INPUT_TOUCH_END) ||
1048 isXIType(event, XCB_INPUT_ENTER) ||
1049 isXIType(event, XCB_INPUT_LEAVE) ||
1050 // wacom driver's way of reporting tool proximity
1051 isXIType(event, XCB_INPUT_PROPERTY);
1052 }
1053 if (isInputEvent)
1054 return true;
1055
1056 if (eventType == XCB_CLIENT_MESSAGE) {
1057 auto clientMessage = reinterpret_cast<const xcb_client_message_event_t *>(event);
1058 if (clientMessage->format == 32 && clientMessage->type == atom(QXcbAtom::AtomWM_PROTOCOLS))
1059 if (clientMessage->data.data32[0] == atom(QXcbAtom::AtomWM_DELETE_WINDOW))
1060 isInputEvent = true;
1061 }
1062
1063 return isInputEvent;
1064}
1065
1066void QXcbConnection::processXcbEvents(QEventLoop::ProcessEventsFlags flags)
1067{
1068 int connection_error = xcb_connection_has_error(xcb_connection());
1069 if (connection_error) {
1070 qWarning("The X11 connection broke (error %d). Did the X11 server die?", connection_error);
1071 exit(1);
1072 }
1073
1074 m_eventQueue->flushBufferedEvents();
1075
1076 while (xcb_generic_event_t *event = m_eventQueue->takeFirst(flags)) {
1077 QScopedPointer<xcb_generic_event_t, QScopedPointerPodDeleter> eventGuard(event);
1078
1079 if (!(event->response_type & ~0x80)) {
1080 handleXcbError(reinterpret_cast<xcb_generic_error_t *>(event));
1081 continue;
1082 }
1083
1084 if (compressEvent(event))
1085 continue;
1086
1088
1089 // The lock-based solution used to free the lock inside this loop,
1090 // hence allowing for more events to arrive. ### Check if we want
1091 // this flush here after QTBUG-70095
1092 m_eventQueue->flushBufferedEvents();
1093 }
1094
1095#if QT_CONFIG(xcb_xlib)
1096 qt_XFlush(static_cast<Display *>(xlib_display()));
1097#endif
1098
1099 xcb_flush(xcb_connection());
1100}
1101
1102const xcb_format_t *QXcbConnection::formatForDepth(uint8_t depth) const
1103{
1104 xcb_format_iterator_t iterator =
1105 xcb_setup_pixmap_formats_iterator(setup());
1106
1107 while (iterator.rem) {
1108 xcb_format_t *format = iterator.data;
1109 if (format->depth == depth)
1110 return format;
1111 xcb_format_next(&iterator);
1112 }
1113
1114 qWarning() << "XCB failed to find an xcb_format_t for depth:" << depth;
1115 return nullptr;
1116}
1117
1119{
1120 // from xcb_aux_sync
1121 xcb_get_input_focus_cookie_t cookie = xcb_get_input_focus(xcb_connection());
1122 free(xcb_get_input_focus_reply(xcb_connection(), cookie, nullptr));
1123}
1124
1126{
1127 if (!m_systemTrayTracker) {
1128 QXcbConnection *self = const_cast<QXcbConnection *>(this);
1129 if ((self->m_systemTrayTracker = QXcbSystemTrayTracker::create(self))) {
1130 connect(m_systemTrayTracker, SIGNAL(systemTrayWindowChanged(QScreen*)),
1131 QGuiApplication::platformNativeInterface(), SIGNAL(systemTrayWindowChanged(QScreen*)));
1132 }
1133 }
1134 return m_systemTrayTracker;
1135}
1136
1138{
1139 int stateMask = 0;
1140 QXcbCursor::queryPointer(connection(), nullptr, nullptr, &stateMask);
1141 return translateMouseButtons(stateMask);
1142}
1143
1145{
1146 if (m_glIntegrationInitialized)
1147 return m_glIntegration;
1148
1149 QStringList glIntegrationNames;
1150 glIntegrationNames << QStringLiteral("xcb_glx") << QStringLiteral("xcb_egl");
1151 QString glIntegrationName = QString::fromLocal8Bit(qgetenv("QT_XCB_GL_INTEGRATION"));
1152 if (!glIntegrationName.isEmpty()) {
1153 qCDebug(lcQpaGl) << "QT_XCB_GL_INTEGRATION is set to" << glIntegrationName;
1154 if (glIntegrationName != "none"_L1) {
1155 glIntegrationNames.removeAll(glIntegrationName);
1156 glIntegrationNames.prepend(glIntegrationName);
1157 } else {
1158 glIntegrationNames.clear();
1159 }
1160 }
1161
1162 if (!glIntegrationNames.isEmpty()) {
1163 qCDebug(lcQpaGl) << "Choosing xcb gl-integration based on following priority\n" << glIntegrationNames;
1164 for (int i = 0; i < glIntegrationNames.size() && !m_glIntegration; i++) {
1165 m_glIntegration = QXcbGlIntegrationFactory::create(glIntegrationNames.at(i));
1166 if (m_glIntegration && !m_glIntegration->initialize(const_cast<QXcbConnection *>(this))) {
1167 qCDebug(lcQpaGl) << "Failed to initialize xcb gl-integration" << glIntegrationNames.at(i);
1168 delete m_glIntegration;
1169 m_glIntegration = nullptr;
1170 }
1171 }
1172 if (!m_glIntegration)
1173 qCDebug(lcQpaGl) << "Failed to create xcb gl-integration";
1174 }
1175
1176 m_glIntegrationInitialized = true;
1177 return m_glIntegration;
1178}
1179
1181{
1182 if (e->type() == QEvent::User + 1) {
1183 QXcbSyncWindowRequest *ev = static_cast<QXcbSyncWindowRequest *>(e);
1184 QXcbWindow *w = ev->window();
1185 if (w) {
1186 w->updateSyncRequestCounter();
1187 ev->invalidate();
1188 }
1189 return true;
1190 }
1191 return QObject::event(e);
1192}
1193
1195{
1196 if (m_window) {
1197 m_window->clearSyncWindowRequest();
1198 m_window = nullptr;
1199 }
1200}
1201
1207
1209{
1210 if (m_connection)
1211 m_connection->ungrabServer();
1212}
1213
1215{
1216 if (m_connection) {
1217 m_connection->ungrabServer();
1218 m_connection = nullptr;
1219 }
1220}
1221
1223
1224#include "moc_qxcbconnection.cpp"
static QAbstractEventDispatcher * instance(QThread *thread=nullptr)
Returns a pointer to the event dispatcher object for the specified thread.
bool filterNativeEvent(const QByteArray &eventType, void *message, qintptr *result)
Sends message through the event filters that were set by installNativeEventFilter().
\inmodule QtCore
Definition qbytearray.h:57
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
Definition qbytearray.h:494
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:124
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Definition qbytearray.h:107
static bool testAttribute(Qt::ApplicationAttribute attribute)
Returns true if attribute attribute is set; otherwise returns false.
QString applicationName
the name of this application
\inmodule QtCore
Definition qcoreevent.h:45
Type type() const
Returns the event type.
Definition qcoreevent.h:304
static QPlatformNativeInterface * platformNativeInterface()
QString applicationDisplayName
the user-visible name of this application
bool remove(const Key &key)
Removes the item that has the key from the hash.
Definition qhash.h:958
T value(const Key &key) const noexcept
Definition qhash.h:1054
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition qhash.h:1303
bool isEmpty() const noexcept
Definition qlist.h:401
T & first()
Definition qlist.h:645
value_type takeLast()
Definition qlist.h:567
\inmodule QtCore
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
virtual bool event(QEvent *event)
This virtual function receives events to an object and should return true if the event e was recogniz...
Definition qobject.cpp:1389
QWindow * window() const
Returns the window which belongs to the QPlatformWindow.
The QScreen class is used to query screen properties. \inmodule QtGui.
Definition qscreen.h:32
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromLocal8Bit(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5949
QString toLower() const &
Definition qstring.h:435
static void handleFocusWindowChanged(QWindow *window, Qt::FocusReason r=Qt::OtherFocusReason)
static void handleScreenRemoved(QPlatformScreen *screen)
Should be called by the implementation whenever a screen is removed.
\inmodule QtGui
Definition qwindow.h:63
@ AtomWM_PROTOCOLS
Definition qxcbatom.h:13
@ AtomXdndStatus
Definition qxcbatom.h:139
@ Atom_QT_GET_TIMESTAMP
Definition qxcbatom.h:58
@ AtomXdndFinished
Definition qxcbatom.h:142
@ AtomXdndSelection
Definition qxcbatom.h:146
@ AtomSM_CLIENT_ID
Definition qxcbatom.h:32
@ AtomWM_CLIENT_LEADER
Definition qxcbatom.h:30
@ Atom_NET_WORKAREA
Definition qxcbatom.h:70
@ AtomMANAGER
Definition qxcbatom.h:20
@ Atom_NET_STARTUP_ID
Definition qxcbatom.h:121
@ AtomUTF8_STRING
Definition qxcbatom.h:133
@ AtomWM_DELETE_WINDOW
Definition qxcbatom.h:14
@ Atom_NET_SUPPORTED
Definition qxcbatom.h:68
bool isXIEvent(xcb_generic_event_t *event) const
xcb_connection_t * xcb_connection() const
const xcb_setup_t * setup() const
bool isXRandrType(uint responseType, int eventType) const
bool isXkbType(uint responseType) const
bool isXIType(xcb_generic_event_t *event, uint16_t type) const
xcb_atom_t atom(QXcbAtom::Atom qatom) const
bool isXFixesType(uint responseType, int eventType) const
void handleSelectionClearRequest(xcb_selection_clear_event_t *event)
bool handlePropertyNotify(const xcb_generic_event_t *event)
void handleSelectionRequest(xcb_selection_request_event_t *event)
void handleXFixesSelectionRequest(xcb_xfixes_selection_notify_event_t *event)
Q_NODISCARD_CTOR QXcbConnectionGrabber(QXcbConnection *connection)
xcb_window_t selectionOwner(xcb_atom_t atom) const
xcb_window_t rootWindow()
bool isUserInputEvent(xcb_generic_event_t *event) const
void setMousePressWindow(QXcbWindow *)
Qt::MouseButton translateMouseButton(xcb_button_t s)
void printXcbEvent(const QLoggingCategory &log, const char *message, xcb_generic_event_t *event) const
QXcbGlIntegration * glIntegration() const
void setMouseGrabber(QXcbWindow *)
void setTime(xcb_timestamp_t t)
void setButtonState(Qt::MouseButton button, bool down)
QString windowManagerName() const
QXcbConnection * connection() const
void processXcbEvents(QEventLoop::ProcessEventsFlags flags)
void printXcbError(const char *message, xcb_generic_error_t *error)
xcb_timestamp_t time() const
QXcbScreen * primaryScreen() const
bool event(QEvent *e) override
This virtual function receives events to an object and should return true if the event e was recogniz...
xcb_window_t qtSelectionOwner()
void handleXcbError(xcb_generic_error_t *error)
QXcbVirtualDesktop * primaryVirtualDesktop() const
void setFocusWindow(QWindow *)
Qt::MouseButtons queryMouseButtons() const
void abortSystemMoveResize(xcb_window_t window)
QXcbEventQueue * eventQueue() const
xcb_window_t clientLeader()
void setStartupId(const QByteArray &nextId)
QXcbWindowEventListener * windowEventListenerFromId(xcb_window_t id)
Qt::MouseButton button() const
QByteArray startupId() const
const xcb_format_t * formatForDepth(uint8_t depth) const
QXcbWindow * platformWindowFromId(xcb_window_t id)
void addWindowEventListener(xcb_window_t id, QXcbWindowEventListener *eventListener)
xcb_timestamp_t getTimestamp()
void handleXcbEvent(xcb_generic_event_t *event)
QXcbSystemTrayTracker * systemTrayTracker() const
void removeWindowEventListener(xcb_window_t id)
static void queryPointer(QXcbConnection *c, QXcbVirtualDesktop **virtualDesktop, QPoint *pos, int *keybMask=nullptr)
xcb_generic_event_t * takeFirst(QEventLoop::ProcessEventsFlags flags)
xcb_generic_event_t * peek(Peeker &&peeker)
static QXcbGlIntegration * create(const QString &name)
virtual bool initialize(QXcbConnection *connection)=0
virtual bool handleXcbEvent(xcb_generic_event_t *event, uint responseType)
void updateKeymap(xcb_mapping_notify_event_t *event)
void updateXKBState(xcb_xkb_state_notify_event_t *state)
int coreDeviceId() const
void updateXKBStateFromCore(quint16 state)
const QByteArray & nativeEventType() const
int screenNumber() const
Definition qxcbscreen.h:149
static QXcbSystemTrayTracker * create(QXcbConnection *connection)
void notifyManagerClientMessageEvent(const xcb_client_message_event_t *)
QString windowManagerName() const
Definition qxcbscreen.h:69
xcb_screen_t * screen() const
Definition qxcbscreen.h:38
virtual QXcbWindow * toWindow()
void clearSyncWindowRequest()
Definition qxcbwindow.h:139
void setWindowTitle(const QString &title) override
Reimplement to set the window title to title.
QPushButton * button
[2]
short next
Definition keywords.cpp:445
Combined button and popup list for selecting options.
MouseButton
Definition qnamespace.h:56
@ ExtraButton9
Definition qnamespace.h:74
@ LeftButton
Definition qnamespace.h:58
@ ExtraButton16
Definition qnamespace.h:81
@ ExtraButton5
Definition qnamespace.h:70
@ BackButton
Definition qnamespace.h:61
@ ExtraButton18
Definition qnamespace.h:83
@ ExtraButton6
Definition qnamespace.h:71
@ ExtraButton20
Definition qnamespace.h:85
@ RightButton
Definition qnamespace.h:59
@ ExtraButton14
Definition qnamespace.h:79
@ ExtraButton12
Definition qnamespace.h:77
@ ExtraButton15
Definition qnamespace.h:80
@ ExtraButton17
Definition qnamespace.h:82
@ ExtraButton10
Definition qnamespace.h:75
@ MiddleButton
Definition qnamespace.h:60
@ ExtraButton19
Definition qnamespace.h:84
@ ExtraButton23
Definition qnamespace.h:88
@ ForwardButton
Definition qnamespace.h:64
@ ExtraButton21
Definition qnamespace.h:86
@ ExtraButton22
Definition qnamespace.h:87
@ ExtraButton24
Definition qnamespace.h:89
@ ExtraButton11
Definition qnamespace.h:76
@ ExtraButton13
Definition qnamespace.h:78
@ NoButton
Definition qnamespace.h:57
@ ExtraButton8
Definition qnamespace.h:73
@ ExtraButton3
Definition qnamespace.h:68
@ ExtraButton7
Definition qnamespace.h:72
@ ExtraButton4
Definition qnamespace.h:69
@ AA_CompressTabletEvents
Definition qnamespace.h:464
@ AA_CompressHighFrequencyEvents
Definition qnamespace.h:460
@ ActiveWindowFocusReason
static QString displayName(CGDirectDisplayID displayID)
#define Q_UNLIKELY(x)
DBusConnection const char DBusError * error
DBusConnection * connection
EGLDeviceEXT * devices
#define qGuiApp
#define qWarning
Definition qlogging.h:166
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
return ret
#define SIGNAL(a)
Definition qobjectdefs.h:53
GLint GLint GLint GLint GLint x
[0]
GLint GLenum GLsizei GLsizei GLsizei depth
GLfloat GLfloat GLfloat w
[0]
GLenum type
GLbitfield flags
GLuint GLsizei const GLchar * message
GLint GLsizei GLsizei GLenum format
GLint y
GLfloat GLfloat GLfloat GLfloat h
struct _cl_event * event
GLdouble s
[6]
Definition qopenglext.h:235
GLuint64EXT * result
[6]
GLenum GLenum GLenum input
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define QStringLiteral(str)
void qt_XFlush(Display *dpy)
QScreen * screen
[1]
Definition main.cpp:29
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
Q_CORE_EXPORT bool qunsetenv(const char *varName)
unsigned short quint16
Definition qtypes.h:48
unsigned int uint
Definition qtypes.h:34
unsigned char quint8
Definition qtypes.h:46
ptrdiff_t qintptr
Definition qtypes.h:166
static uint nextId
#define HANDLE_KEYBOARD_EVENT(event_t, handler)
#define CASE_PRINT_AND_RETURN(name)
const char * xcb_protocol_request_codes[]
static Qt::MouseButtons translateMouseButtons(int s)
#define PRINT_AND_RETURN(name)
#define XI_CASE_PRINT_AND_RETURN(name)
#define HANDLE_PLATFORM_WINDOW_EVENT(event_t, windowMember, handler)
const char * xcb_errors[]
#define Q_XCB_REPLY(call,...)
aWidget window() -> setWindowTitle("New Window Title")
[2]
QNetworkReply * reply