1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the plugins of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include "qxcbwindow.h"
46 #include "qxcbconnection.h"
47 #include "qxcbscreen.h"
49 #include "qdri2context.h"
52 #include <xcb/xcb_icccm.h>
54 #include <private/qapplication_p.h>
55 #include <private/qwindowsurface_p.h>
57 #include <QtGui/QWindowSystemInterface>
63 #include <X11/Xutil.h>
66 #if defined(XCB_USE_GLX)
67 #include "qglxintegration.h"
68 #include "qglxconvenience.h"
69 #elif defined(XCB_USE_EGL)
70 #include "../eglconvenience/qeglplatformcontext.h"
71 #include "../eglconvenience/qeglconvenience.h"
72 #include "../eglconvenience/qxlibeglintegration.h"
75 // Returns true if we should set WM_TRANSIENT_FOR on \a w
76 static inline bool isTransient(const QWidget *w)
78 return ((w->windowType() == Qt::Dialog
79 || w->windowType() == Qt::Sheet
80 || w->windowType() == Qt::Tool
81 || w->windowType() == Qt::SplashScreen
82 || w->windowType() == Qt::ToolTip
83 || w->windowType() == Qt::Drawer
84 || w->windowType() == Qt::Popup)
85 && !w->testAttribute(Qt::WA_X11BypassTransientForHint));
88 QXcbWindow::QXcbWindow(QWidget *tlw)
89 : QPlatformWindow(tlw)
92 m_screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWidget(tlw));
94 setConnection(m_screen->connection());
96 const quint32 mask = XCB_CW_BACK_PIXMAP | XCB_CW_EVENT_MASK;
97 const quint32 values[] = {
101 XCB_EVENT_MASK_EXPOSURE
102 | XCB_EVENT_MASK_STRUCTURE_NOTIFY
103 | XCB_EVENT_MASK_KEY_PRESS
104 | XCB_EVENT_MASK_KEY_RELEASE
105 | XCB_EVENT_MASK_BUTTON_PRESS
106 | XCB_EVENT_MASK_BUTTON_RELEASE
107 | XCB_EVENT_MASK_BUTTON_MOTION
108 | XCB_EVENT_MASK_ENTER_WINDOW
109 | XCB_EVENT_MASK_LEAVE_WINDOW
110 | XCB_EVENT_MASK_PROPERTY_CHANGE
111 | XCB_EVENT_MASK_FOCUS_CHANGE
114 #if defined(XCB_USE_GLX) || defined(XCB_USE_EGL)
115 if (tlw->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL
116 && QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL))
118 #if defined(XCB_USE_GLX)
119 XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(m_screen),m_screen->screenNumber(), tlw->platformWindowFormat());
120 #elif defined(XCB_USE_EGL)
121 EGLDisplay eglDisplay = connection()->egl_display();
122 EGLConfig eglConfig = q_configFromQPlatformWindowFormat(eglDisplay,tlw->platformWindowFormat(),true);
123 VisualID id = QXlibEglIntegration::getCompatibleVisualId(DISPLAY_FROM_XCB(this), eglDisplay, eglConfig);
125 XVisualInfo visualInfoTemplate;
126 memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
127 visualInfoTemplate.visualid = id;
129 XVisualInfo *visualInfo;
130 int matchingCount = 0;
131 visualInfo = XGetVisualInfo(DISPLAY_FROM_XCB(this), VisualIDMask, &visualInfoTemplate, &matchingCount);
134 m_depth = visualInfo->depth;
135 m_format = (m_depth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
136 Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(this), m_screen->root(), visualInfo->visual, AllocNone);
138 XSetWindowAttributes a;
139 a.background_pixel = WhitePixel(DISPLAY_FROM_XCB(this), m_screen->screenNumber());
140 a.border_pixel = BlackPixel(DISPLAY_FROM_XCB(this), m_screen->screenNumber());
142 m_window = XCreateWindow(DISPLAY_FROM_XCB(this), m_screen->root(), tlw->x(), tlw->y(), tlw->width(), tlw->height(),
143 0, visualInfo->depth, InputOutput, visualInfo->visual,
144 CWBackPixel|CWBorderPixel|CWColormap, &a);
146 printf("created GL window: %d\n", m_window);
148 qFatal("no window!");
151 #endif //defined(XCB_USE_GLX) || defined(XCB_USE_EGL)
153 m_window = xcb_generate_id(xcb_connection());
154 m_depth = m_screen->screen()->root_depth;
155 m_format = (m_depth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
157 Q_XCB_CALL(xcb_create_window(xcb_connection(),
158 XCB_COPY_FROM_PARENT, // depth -- same as root
159 m_window, // window id
160 m_screen->root(), // parent window id
166 XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
167 m_screen->screen()->root_visual, // visual
171 printf("created regular window: %d\n", m_window);
174 Q_XCB_CALL(xcb_change_window_attributes(xcb_connection(), m_window, mask, values));
176 xcb_atom_t properties[4];
177 int propertyCount = 0;
178 properties[propertyCount++] = atom(QXcbAtom::WM_DELETE_WINDOW);
179 properties[propertyCount++] = atom(QXcbAtom::WM_TAKE_FOCUS);
180 properties[propertyCount++] = atom(QXcbAtom::_NET_WM_PING);
182 if (m_screen->syncRequestSupported())
183 properties[propertyCount++] = atom(QXcbAtom::_NET_WM_SYNC_REQUEST);
185 if (tlw->windowFlags() & Qt::WindowContextHelpButtonHint)
186 properties[propertyCount++] = atom(QXcbAtom::_NET_WM_CONTEXT_HELP);
188 Q_XCB_CALL(xcb_change_property(xcb_connection(),
189 XCB_PROP_MODE_REPLACE,
191 atom(QXcbAtom::WM_PROTOCOLS),
199 if (m_screen->syncRequestSupported()) {
200 m_syncCounter = xcb_generate_id(xcb_connection());
201 Q_XCB_CALL(xcb_sync_create_counter(xcb_connection(), m_syncCounter, m_syncValue));
203 Q_XCB_CALL(xcb_change_property(xcb_connection(),
204 XCB_PROP_MODE_REPLACE,
206 atom(QXcbAtom::_NET_WM_SYNC_REQUEST_COUNTER),
213 if (isTransient(tlw) && tlw->parentWidget()) {
215 QWidget *p = tlw->parentWidget()->window();
216 xcb_window_t parentWindow = p->winId();
217 Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
218 XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32,
223 // set the PID to let the WM kill the application if unresponsive
225 Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
226 atom(QXcbAtom::_NET_WM_PID), XCB_ATOM_CARDINAL, 32,
230 QXcbWindow::~QXcbWindow()
233 if (m_screen->syncRequestSupported())
234 Q_XCB_CALL(xcb_sync_destroy_counter(xcb_connection(), m_syncCounter));
235 Q_XCB_CALL(xcb_destroy_window(xcb_connection(), m_window));
238 void QXcbWindow::setGeometry(const QRect &rect)
240 QPlatformWindow::setGeometry(rect);
242 const quint32 mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
243 const quint32 values[] = { rect.x(), rect.y(), rect.width(), rect.height() };
245 Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, values));
248 void QXcbWindow::setVisible(bool visible)
250 xcb_wm_hints_t hints;
252 if (widget()->isMinimized())
253 xcb_wm_hints_set_iconic(&hints);
255 xcb_wm_hints_set_normal(&hints);
256 xcb_set_wm_hints(xcb_connection(), m_window, &hints);
257 Q_XCB_CALL(xcb_map_window(xcb_connection(), m_window));
258 connection()->sync();
260 Q_XCB_CALL(xcb_unmap_window(xcb_connection(), m_window));
262 // send synthetic UnmapNotify event according to icccm 4.1.4
263 xcb_unmap_notify_event_t event;
264 event.response_type = XCB_UNMAP_NOTIFY;
265 event.sequence = 0; // does this matter?
266 event.event = m_screen->root();
267 event.window = m_window;
268 event.from_configure = false;
269 Q_XCB_CALL(xcb_send_event(xcb_connection(), false, m_screen->root(),
270 XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event));
272 xcb_flush(xcb_connection());
277 quint32 flags, functions, decorations;
283 MWM_HINTS_FUNCTIONS = (1L << 0),
285 MWM_FUNC_ALL = (1L << 0),
286 MWM_FUNC_RESIZE = (1L << 1),
287 MWM_FUNC_MOVE = (1L << 2),
288 MWM_FUNC_MINIMIZE = (1L << 3),
289 MWM_FUNC_MAXIMIZE = (1L << 4),
290 MWM_FUNC_CLOSE = (1L << 5),
292 MWM_HINTS_DECORATIONS = (1L << 1),
294 MWM_DECOR_ALL = (1L << 0),
295 MWM_DECOR_BORDER = (1L << 1),
296 MWM_DECOR_RESIZEH = (1L << 2),
297 MWM_DECOR_TITLE = (1L << 3),
298 MWM_DECOR_MENU = (1L << 4),
299 MWM_DECOR_MINIMIZE = (1L << 5),
300 MWM_DECOR_MAXIMIZE = (1L << 6),
302 MWM_HINTS_INPUT_MODE = (1L << 2),
304 MWM_INPUT_MODELESS = 0L,
305 MWM_INPUT_PRIMARY_APPLICATION_MODAL = 1L,
306 MWM_INPUT_FULL_APPLICATION_MODAL = 3L
309 Qt::WindowFlags QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
311 Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
313 setNetWmWindowTypes(flags);
315 if (type == Qt::ToolTip)
316 flags |= Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint;
317 if (type == Qt::Popup)
318 flags |= Qt::X11BypassWindowManagerHint;
320 bool topLevel = (flags & Qt::Window);
321 bool popup = (type == Qt::Popup);
322 bool dialog = (type == Qt::Dialog
323 || type == Qt::Sheet);
324 bool desktop = (type == Qt::Desktop);
325 bool tool = (type == Qt::Tool || type == Qt::SplashScreen
326 || type == Qt::ToolTip || type == Qt::Drawer);
333 bool tooltip = (type == Qt::ToolTip);
337 mwmhints.functions = 0L;
338 mwmhints.decorations = 0;
339 mwmhints.input_mode = 0L;
340 mwmhints.status = 0L;
342 if (type != Qt::SplashScreen) {
343 mwmhints.flags |= MWM_HINTS_DECORATIONS;
345 bool customize = flags & Qt::CustomizeWindowHint;
346 if (!(flags & Qt::FramelessWindowHint) && !(customize && !(flags & Qt::WindowTitleHint))) {
347 mwmhints.decorations |= MWM_DECOR_BORDER;
348 mwmhints.decorations |= MWM_DECOR_RESIZEH;
350 if (flags & Qt::WindowTitleHint)
351 mwmhints.decorations |= MWM_DECOR_TITLE;
353 if (flags & Qt::WindowSystemMenuHint)
354 mwmhints.decorations |= MWM_DECOR_MENU;
356 if (flags & Qt::WindowMinimizeButtonHint) {
357 mwmhints.decorations |= MWM_DECOR_MINIMIZE;
358 mwmhints.functions |= MWM_FUNC_MINIMIZE;
361 if (flags & Qt::WindowMaximizeButtonHint) {
362 mwmhints.decorations |= MWM_DECOR_MAXIMIZE;
363 mwmhints.functions |= MWM_FUNC_MAXIMIZE;
366 if (flags & Qt::WindowCloseButtonHint)
367 mwmhints.functions |= MWM_FUNC_CLOSE;
370 // if type == Qt::SplashScreen
371 mwmhints.decorations = MWM_DECOR_ALL;
374 if (mwmhints.functions != 0) {
375 mwmhints.flags |= MWM_HINTS_FUNCTIONS;
376 mwmhints.functions |= MWM_FUNC_MOVE | MWM_FUNC_RESIZE;
378 mwmhints.functions = MWM_FUNC_ALL;
381 if (!(flags & Qt::FramelessWindowHint)
382 && flags & Qt::CustomizeWindowHint
383 && flags & Qt::WindowTitleHint
385 (Qt::WindowMinimizeButtonHint
386 | Qt::WindowMaximizeButtonHint
387 | Qt::WindowCloseButtonHint)))
389 // a special case - only the titlebar without any button
390 mwmhints.flags = MWM_HINTS_FUNCTIONS;
391 mwmhints.functions = MWM_FUNC_MOVE | MWM_FUNC_RESIZE;
392 mwmhints.decorations = 0;
395 if (mwmhints.flags != 0l) {
396 Q_XCB_CALL(xcb_change_property(xcb_connection(),
397 XCB_PROP_MODE_REPLACE,
399 atom(QXcbAtom::_MOTIF_WM_HINTS),
400 atom(QXcbAtom::_MOTIF_WM_HINTS),
405 Q_XCB_CALL(xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::_MOTIF_WM_HINTS)));
408 if (popup || tooltip) {
409 const quint32 mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER;
410 const quint32 values[] = { true, true };
412 Q_XCB_CALL(xcb_change_window_attributes(xcb_connection(), m_window, mask, values));
415 return QPlatformWindow::setWindowFlags(flags);
418 void QXcbWindow::setNetWmWindowTypes(Qt::WindowFlags flags)
420 // in order of decreasing priority
421 QVector<uint> windowTypes;
423 Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
428 windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_DIALOG));
432 windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_UTILITY));
435 windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_TOOLTIP));
437 case Qt::SplashScreen:
438 windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_SPLASH));
444 if (flags & Qt::FramelessWindowHint)
445 windowTypes.append(atom(QXcbAtom::_KDE_NET_WM_WINDOW_TYPE_OVERRIDE));
447 windowTypes.append(atom(QXcbAtom::_NET_WM_WINDOW_TYPE_NORMAL));
449 Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
450 atom(QXcbAtom::_NET_WM_WINDOW_TYPE), XCB_ATOM_ATOM, 32,
451 windowTypes.count(), windowTypes.constData()));
454 WId QXcbWindow::winId() const
459 void QXcbWindow::setParent(const QPlatformWindow *parent)
461 QPoint topLeft = geometry().topLeft();
462 Q_XCB_CALL(xcb_reparent_window(xcb_connection(), window(), static_cast<const QXcbWindow *>(parent)->window(), topLeft.x(), topLeft.y()));
465 void QXcbWindow::setWindowTitle(const QString &title)
467 QByteArray ba = title.toUtf8();
468 Q_XCB_CALL(xcb_change_property(xcb_connection(),
469 XCB_PROP_MODE_REPLACE,
471 atom(QXcbAtom::_NET_WM_NAME),
472 atom(QXcbAtom::UTF8_STRING),
478 void QXcbWindow::raise()
480 const quint32 mask = XCB_CONFIG_WINDOW_STACK_MODE;
481 const quint32 values[] = { XCB_STACK_MODE_ABOVE };
482 Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, values));
485 void QXcbWindow::lower()
487 const quint32 mask = XCB_CONFIG_WINDOW_STACK_MODE;
488 const quint32 values[] = { XCB_STACK_MODE_BELOW };
489 Q_XCB_CALL(xcb_configure_window(xcb_connection(), m_window, mask, values));
492 void QXcbWindow::requestActivateWindow()
494 Q_XCB_CALL(xcb_set_input_focus(xcb_connection(), XCB_INPUT_FOCUS_PARENT, m_window, XCB_TIME_CURRENT_TIME));
495 connection()->sync();
498 QPlatformGLContext *QXcbWindow::glContext() const
500 if (!QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) {
501 printf("no opengl\n");
505 #if defined(XCB_USE_GLX)
506 QXcbWindow *that = const_cast<QXcbWindow *>(this);
507 that->m_context = new QGLXContext(m_window, m_screen, widget()->platformWindowFormat());
508 #elif defined(XCB_USE_EGL)
509 EGLDisplay display = connection()->egl_display();
510 EGLConfig config = q_configFromQPlatformWindowFormat(display,widget()->platformWindowFormat(),true);
511 QVector<EGLint> eglContextAttrs;
512 eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
513 eglContextAttrs.append(2);
514 eglContextAttrs.append(EGL_NONE);
516 EGLSurface eglSurface = eglCreateWindowSurface(display,config,(EGLNativeWindowType)m_window,0);
517 QXcbWindow *that = const_cast<QXcbWindow *>(this);
518 that->m_context = new QEGLPlatformContext(display, config, eglContextAttrs.data(), eglSurface, EGL_OPENGL_ES_API);
519 #elif defined(XCB_USE_DRI2)
520 QXcbWindow *that = const_cast<QXcbWindow *>(this);
521 that->m_context = new QDri2Context(that);
527 void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event)
529 QWindowSurface *surface = widget()->windowSurface();
531 QRect rect(event->x, event->y, event->width, event->height);
533 surface->flush(widget(), rect, QPoint());
537 void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *event)
539 if (event->format == 32 && event->type == atom(QXcbAtom::WM_PROTOCOLS)) {
540 if (event->data.data32[0] == atom(QXcbAtom::WM_DELETE_WINDOW)) {
541 QWindowSystemInterface::handleCloseEvent(widget());
542 } else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_PING)) {
543 xcb_client_message_event_t reply = *event;
545 reply.response_type = XCB_CLIENT_MESSAGE;
546 reply.window = m_screen->root();
548 xcb_send_event(xcb_connection(), 0, m_screen->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&reply);
549 xcb_flush(xcb_connection());
550 } else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_SYNC_REQUEST)) {
551 if (!m_hasReceivedSyncRequest) {
552 m_hasReceivedSyncRequest = true;
553 printf("Window manager supports _NET_WM_SYNC_REQUEST, syncing resizes\n");
555 m_syncValue.lo = event->data.data32[2];
556 m_syncValue.hi = event->data.data32[3];
561 void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *event)
563 int xpos = geometry().x();
564 int ypos = geometry().y();
566 if ((event->width == geometry().width() && event->height == geometry().height()) || event->x != 0 || event->y != 0) {
571 QRect rect(xpos, ypos, event->width, event->height);
573 if (rect == geometry())
576 QPlatformWindow::setGeometry(rect);
577 QWindowSystemInterface::handleGeometryChange(widget(), rect);
581 static_cast<QDri2Context *>(m_context)->resize(rect.size());
585 static Qt::MouseButtons translateMouseButtons(int s)
587 Qt::MouseButtons ret = 0;
588 if (s & XCB_BUTTON_MASK_1)
589 ret |= Qt::LeftButton;
590 if (s & XCB_BUTTON_MASK_2)
591 ret |= Qt::MidButton;
592 if (s & XCB_BUTTON_MASK_3)
593 ret |= Qt::RightButton;
597 static Qt::MouseButton translateMouseButton(xcb_button_t s)
601 return Qt::LeftButton;
603 return Qt::MidButton;
605 return Qt::RightButton;
611 void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event)
613 QPoint local(event->event_x, event->event_y);
614 QPoint global(event->root_x, event->root_y);
616 Qt::KeyboardModifiers modifiers = Qt::NoModifier;
618 if (event->detail >= 4 && event->detail <= 7) {
619 //logic borrowed from qapplication_x11.cpp
620 int delta = 120 * ((event->detail == 4 || event->detail == 6) ? 1 : -1);
621 bool hor = (((event->detail == 4 || event->detail == 5)
622 && (modifiers & Qt::AltModifier))
623 || (event->detail == 6 || event->detail == 7));
625 QWindowSystemInterface::handleWheelEvent(widget(), event->time,
626 local, global, delta, hor ? Qt::Horizontal : Qt::Vertical);
630 handleMouseEvent(event->detail, event->state, event->time, local, global);
633 void QXcbWindow::handleButtonReleaseEvent(const xcb_button_release_event_t *event)
635 QPoint local(event->event_x, event->event_y);
636 QPoint global(event->root_x, event->root_y);
638 handleMouseEvent(event->detail, event->state, event->time, local, global);
641 void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event)
643 QPoint local(event->event_x, event->event_y);
644 QPoint global(event->root_x, event->root_y);
646 handleMouseEvent(event->detail, event->state, event->time, local, global);
649 void QXcbWindow::handleMouseEvent(xcb_button_t detail, uint16_t state, xcb_timestamp_t time, const QPoint &local, const QPoint &global)
651 Qt::MouseButtons buttons = translateMouseButtons(state);
652 Qt::MouseButton button = translateMouseButton(detail);
654 buttons ^= button; // X event uses state *before*, Qt uses state *after*
656 QWindowSystemInterface::handleMouseEvent(widget(), time, local, global, buttons);
659 void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *)
661 QWindowSystemInterface::handleEnterEvent(widget());
664 void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *)
666 QWindowSystemInterface::handleLeaveEvent(widget());
669 void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *)
671 QWindowSystemInterface::handleWindowActivated(widget());
674 void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *)
676 QWindowSystemInterface::handleWindowActivated(0);
679 void QXcbWindow::updateSyncRequestCounter()
681 if (m_screen->syncRequestSupported() && (m_syncValue.lo != 0 || m_syncValue.hi != 0)) {
682 Q_XCB_CALL(xcb_sync_set_counter(xcb_connection(), m_syncCounter, m_syncValue));
683 xcb_flush(xcb_connection());
684 connection()->sync();