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