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
qxcbwindow.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 "qxcbwindow.h"
5
6#include <QtDebug>
7#include <QMetaEnum>
8#include <QScreen>
9#include <QtCore/QFileInfo>
10#include <QtGui/QIcon>
11#include <QtGui/QRegion>
12#include <QtGui/private/qhighdpiscaling_p.h>
13
14#include "qxcbintegration.h"
15#include "qxcbconnection.h"
16#include "qxcbscreen.h"
17#if QT_CONFIG(draganddrop)
18#include "qxcbdrag.h"
19#endif
20#include "qxcbkeyboard.h"
21#include "qxcbimage.h"
22#include "qxcbwmsupport.h"
23#include "qxcbimage.h"
24#include "qxcbnativeinterface.h"
26
27#include <qpa/qplatformintegration.h>
28#include <qpa/qplatformcursor.h>
29
30#include <algorithm>
31
32#include <xcb/xcb_icccm.h>
33#include <xcb/xfixes.h>
34#include <xcb/shape.h>
35#include <xcb/xinput.h>
36
37#include <private/qguiapplication_p.h>
38#include <private/qwindow_p.h>
39
40#include <qpa/qplatformbackingstore.h>
41#include <qpa/qwindowsysteminterface.h>
42
43#include <stdio.h>
44
45#if QT_CONFIG(xcb_xlib)
46#define register /* C++17 deprecated register */
47#include <X11/Xlib.h>
48#include <X11/Xutil.h>
49#undef register
50#endif
51
52#define XCOORD_MAX 32767
53enum {
56};
57
59
60using namespace Qt::StringLiterals;
61
62Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window");
63Q_LOGGING_CATEGORY(lcQpaXcbWindow, "qt.qpa.xcb.window");
64
66
67#undef FocusIn
68
74
76 XEMBED_MAPPED = (1 << 0),
77};
78
94
96
101
103{
104 // Resolve initial screen via QWindowPrivate::screenForGeometry(),
105 // which works in platform independent coordinates, as opposed to
106 // QPlatformWindow::screenForGeometry() that uses native coordinates.
107 QWindowPrivate *windowPrivate = qt_window_private(window());
108 QScreen *screen = windowPrivate->screenForGeometry(window()->geometry());
109 return static_cast<QXcbScreen*>(screen->handle());
110}
111
112// Returns \c true if we should set WM_TRANSIENT_FOR on \a w
113static inline bool isTransient(const QWindow *w)
114{
115 return w->type() == Qt::Dialog
116 || w->type() == Qt::Sheet
117 || w->type() == Qt::Tool
118 || w->type() == Qt::SplashScreen
119 || w->type() == Qt::ToolTip
120 || w->type() == Qt::Drawer
121 || w->type() == Qt::Popup;
122}
123
124void QXcbWindow::setImageFormatForVisual(const xcb_visualtype_t *visual)
125{
127 return;
128
129 switch (m_depth) {
130 case 32:
131 case 24:
132 qWarning("Using RGB32 fallback, if this works your X11 server is reporting a bad screen format.");
134 break;
135 case 16:
136 qWarning("Using RGB16 fallback, if this works your X11 server is reporting a bad screen format.");
138 break;
139 default:
140 break;
141 }
142}
143
144#if QT_CONFIG(xcb_xlib)
145static inline XTextProperty* qstringToXTP(Display *dpy, const QString& s)
146{
147 #include <X11/Xatom.h>
148
149 static XTextProperty tp = { nullptr, 0, 0, 0 };
150 static bool free_prop = true; // we can't free tp.value in case it references
151 // the data of the static QByteArray below.
152 if (tp.value) {
153 if (free_prop)
154 XFree(tp.value);
155 tp.value = nullptr;
156 free_prop = true;
157 }
158
159 int errCode = 0;
160 QByteArray mapped = s.toLocal8Bit(); // should always be utf-8
161 char* tl[2];
162 tl[0] = mapped.data();
163 tl[1] = nullptr;
164 errCode = XmbTextListToTextProperty(dpy, tl, 1, XStdICCTextStyle, &tp);
165 if (errCode < 0)
166 qCDebug(lcQpaXcb, "XmbTextListToTextProperty result code %d", errCode);
167
168 if (errCode < 0) {
169 static QByteArray qcs;
170 qcs = s.toLatin1();
171 tp.value = (uchar*)qcs.data();
172 tp.encoding = XA_STRING;
173 tp.format = 8;
174 tp.nitems = qcs.size();
175 free_prop = false;
176 }
177 return &tp;
178}
179#endif // QT_CONFIG(xcb_xlib)
180
181// TODO move this into a utility function in QWindow or QGuiApplication
183{
184 for (QObject *obj : win->children()) {
185 if (obj->isWindowType()) {
186 QWindow *childWin = static_cast<QWindow *>(obj);
187 if (childWin->isVisible()) {
188 if (QWindow *recurse = childWindowAt(childWin, p))
189 return recurse;
190 }
191 }
192 }
193 if (!win->isTopLevel()
194 && !(win->flags() & Qt::WindowTransparentForInput)
195 && win->geometry().contains(win->parent()->mapFromGlobal(p))) {
196 return win;
197 }
198 return nullptr;
199}
200
201static const char *wm_window_type_property_id = "_q_xcb_wm_window_type";
202static const char *wm_window_role_property_id = "_q_xcb_wm_window_role";
203
209
210enum : quint32 {
212 = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY
213 | XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_FOCUS_CHANGE,
214
216 | XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE
217 | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE
218 | XCB_EVENT_MASK_BUTTON_MOTION | XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW
219 | XCB_EVENT_MASK_POINTER_MOTION,
220
222 | XCB_EVENT_MASK_VISIBILITY_CHANGE
223 | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT
224 | XCB_EVENT_MASK_COLOR_MAP_CHANGE | XCB_EVENT_MASK_OWNER_GRAB_BUTTON
226
228{
229 xcb_window_t old_m_window = m_window;
230 destroy();
231
234
235 Qt::WindowType type = window()->type();
236
237 QXcbScreen *currentScreen = xcbScreen();
240 ? QHighDpi::toNativeLocalPosition(window()->geometry(), platformScreen)
241 : QHighDpi::toNativePixels(window()->geometry(), platformScreen);
242
243 if (type == Qt::Desktop) {
244 m_window = platformScreen->root();
245 m_depth = platformScreen->screen()->root_depth;
246 m_visualId = platformScreen->screen()->root_visual;
247 const xcb_visualtype_t *visual = nullptr;
248 if (connection()->hasDefaultVisualId()) {
249 visual = platformScreen->visualForId(connection()->defaultVisualId());
250 if (visual)
252 if (!visual)
253 qWarning("Could not use default visual id. Falling back to root_visual for screen.");
254 }
255 if (!visual)
256 visual = platformScreen->visualForId(m_visualId);
259 return;
260 }
261
262 const QSize minimumSize = windowMinimumSize();
263 if (rect.width() > 0 || rect.height() > 0) {
264 rect.setWidth(qBound(1, rect.width(), XCOORD_MAX));
265 rect.setHeight(qBound(1, rect.height(), XCOORD_MAX));
266 } else if (minimumSize.width() > 0 || minimumSize.height() > 0) {
267 rect.setSize(minimumSize);
268 } else {
269 rect.setWidth(QHighDpi::toNativePixels(int(defaultWindowWidth), platformScreen->QPlatformScreen::screen()));
270 rect.setHeight(QHighDpi::toNativePixels(int(defaultWindowHeight), platformScreen->QPlatformScreen::screen()));
271 }
272
274
275 if (platformScreen != currentScreen)
276 QWindowSystemInterface::handleWindowScreenChanged(window(), platformScreen->QPlatformScreen::screen());
277
278 xcb_window_t xcb_parent_id = platformScreen->root();
280 xcb_parent_id = static_cast<QXcbWindow *>(QPlatformWindow::parent())->xcb_window();
282
283 QSurfaceFormat parentFormat = QPlatformWindow::parent()->window()->requestedFormat();
284 if (window()->surfaceType() != QSurface::OpenGLSurface && parentFormat.hasAlpha()) {
285 window()->setFormat(parentFormat);
286 }
287 }
288
289 resolveFormat(platformScreen->surfaceFormatFor(window()->requestedFormat()));
290
291 const xcb_visualtype_t *visual = nullptr;
292
294 visual = platformScreen->visualForId(connection()->systemTrayTracker()->visualId());
295 } else if (connection()->hasDefaultVisualId()) {
296 visual = platformScreen->visualForId(connection()->defaultVisualId());
297 if (!visual)
298 qWarning() << "Failed to use requested visual id.";
299 }
300
302 // When using a Vulkan QWindow via QWidget::createWindowContainer() we
303 // must make sure the visuals are compatible. Now, the parent will be
304 // of RasterGLSurface which typically chooses a GLX/EGL compatible
305 // visual which may not be what the Vulkan window would choose.
306 // Therefore, take the parent's visual.
307 if (window()->surfaceType() == QSurface::VulkanSurface
309 {
310 visual = platformScreen->visualForId(static_cast<QXcbWindow *>(QPlatformWindow::parent())->visualId());
311 }
312 }
313
314 if (!visual)
315 visual = createVisual();
316
317 if (!visual) {
318 qWarning() << "Falling back to using screens root_visual.";
319 visual = platformScreen->visualForId(platformScreen->screen()->root_visual);
320 }
321
322 Q_ASSERT(visual);
323
324 m_visualId = visual->visual_id;
325 m_depth = platformScreen->depthOfVisual(m_visualId);
327
328 quint32 mask = XCB_CW_BACK_PIXMAP
329 | XCB_CW_BORDER_PIXEL
330 | XCB_CW_BIT_GRAVITY
331 | XCB_CW_OVERRIDE_REDIRECT
332 | XCB_CW_SAVE_UNDER
333 | XCB_CW_EVENT_MASK
334 | XCB_CW_COLORMAP;
335
336 quint32 values[] = {
337 XCB_BACK_PIXMAP_NONE,
338 platformScreen->screen()->black_pixel,
339 XCB_GRAVITY_NORTH_WEST,
343 platformScreen->colormapForVisual(m_visualId)
344 };
345
346 m_window = xcb_generate_id(xcb_connection());
347 xcb_create_window(xcb_connection(),
348 m_depth,
349 m_window, // window id
350 xcb_parent_id, // parent window id
351 rect.x(),
352 rect.y(),
353 rect.width(),
354 rect.height(),
355 0, // border width
356 XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
357 m_visualId, // visual
358 mask,
359 values);
360
362
364
365 xcb_atom_t properties[5];
366 int propertyCount = 0;
368 properties[propertyCount++] = atom(QXcbAtom::AtomWM_TAKE_FOCUS);
369 properties[propertyCount++] = atom(QXcbAtom::Atom_NET_WM_PING);
370
371 if (connection()->hasXSync())
373
376
377 xcb_change_property(xcb_connection(),
378 XCB_PROP_MODE_REPLACE,
379 m_window,
381 XCB_ATOM_ATOM,
382 32,
383 propertyCount,
384 properties);
385 m_syncValue.hi = 0;
386 m_syncValue.lo = 0;
387
388 const QByteArray wmClass = QXcbIntegration::instance()->wmClass();
389 if (!wmClass.isEmpty()) {
390 xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE,
392 XCB_ATOM_STRING, 8, wmClass.size(), wmClass.constData());
393 }
394
395 QString desktopFileName = QGuiApplication::desktopFileName();
396 if (QGuiApplication::desktopFileName().isEmpty()) {
397 QFileInfo fi = QFileInfo(QCoreApplication::instance()->applicationFilePath());
398 QStringList domainName =
399 QCoreApplication::instance()->organizationDomain().split(QLatin1Char('.'),
401
402 if (domainName.isEmpty()) {
403 desktopFileName = fi.baseName();
404 } else {
405 for (int i = 0; i < domainName.size(); ++i)
406 desktopFileName.prepend(QLatin1Char('.')).prepend(domainName.at(i));
407 desktopFileName.append(fi.baseName());
408 }
409 }
410 if (!desktopFileName.isEmpty()) {
411 const QByteArray dfName = desktopFileName.toUtf8();
412 xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE,
414 atom(QXcbAtom::AtomUTF8_STRING), 8, dfName.size(), dfName.constData());
415 xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE,
417 atom(QXcbAtom::AtomUTF8_STRING), 8, dfName.size(), dfName.constData());
418 }
419
420 if (connection()->hasXSync()) {
421 m_syncCounter = xcb_generate_id(xcb_connection());
422 xcb_sync_create_counter(xcb_connection(), m_syncCounter, m_syncValue);
423
424 xcb_change_property(xcb_connection(),
425 XCB_PROP_MODE_REPLACE,
426 m_window,
428 XCB_ATOM_CARDINAL,
429 32,
430 1,
432 }
433
434 // set the PID to let the WM kill the application if unresponsive
435 quint32 pid = getpid();
436 xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
437 atom(QXcbAtom::Atom_NET_WM_PID), XCB_ATOM_CARDINAL, 32,
438 1, &pid);
439
440 const QByteArray clientMachine = QSysInfo::machineHostName().toLocal8Bit();
441 if (!clientMachine.isEmpty()) {
442 xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
443 atom(QXcbAtom::AtomWM_CLIENT_MACHINE), XCB_ATOM_STRING, 8,
444 clientMachine.size(), clientMachine.constData());
445 }
446
447 // Create WM_HINTS property on the window, so we can xcb_icccm_get_wm_hints*()
448 // from various setter functions for adjusting the hints.
449 xcb_icccm_wm_hints_t hints;
450 memset(&hints, 0, sizeof(hints));
451 hints.flags = XCB_ICCCM_WM_HINT_WINDOW_GROUP;
452 hints.window_group = connection()->clientLeader();
453 xcb_icccm_set_wm_hints(xcb_connection(), m_window, &hints);
454
455 xcb_window_t leader = connection()->clientLeader();
456 xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
457 atom(QXcbAtom::AtomWM_CLIENT_LEADER), XCB_ATOM_WINDOW, 32,
458 1, &leader);
459
460 /* Add XEMBED info; this operation doesn't initiate the embedding. */
462 xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
465 32, 2, (void *)data);
466
467 if (connection()->hasXInput2())
469
470 setWindowState(window()->windowStates());
473
474 // force sync to read outstanding requests - see QTBUG-29106
475 connection()->sync();
476
477#if QT_CONFIG(draganddrop)
478 connection()->drag()->dndEnable(this, true);
479#endif
480
481 const qreal opacity = qt_window_private(window())->opacity;
482 if (!qFuzzyCompare(opacity, qreal(1.0)))
483 setOpacity(opacity);
484
486
487 if (window()->isTopLevel())
489
492 setWindowRole(QString::fromLatin1(wmWindowRole));
493 }
494
497
498 if (m_window != old_m_window) {
500 QList<QPointer<QXcbWindow>> transientChildren = m_wmTransientForChildren;
502 for (auto transientChild : transientChildren) {
503 if (transientChild)
504 transientChild->updateWmTransientFor();
505 }
506 }
507 }
508}
509
514
517{
518 m_window = nativeHandle;
519
520 // Reflect the foreign window's geometry as our own
521 if (auto geometry = Q_XCB_REPLY(xcb_get_geometry, xcb_connection(), m_window)) {
522 QRect nativeGeometry(geometry->x, geometry->y, geometry->width, geometry->height);
523 QPlatformWindow::setGeometry(nativeGeometry);
524 }
525
526 // And reparent, if we have a parent already
529}
530
532{
533 // Clear window so that destroy() does not affect it
534 m_window = 0;
535
536 if (connection()->mouseGrabber() == this)
537 connection()->setMouseGrabber(nullptr);
538 if (connection()->mousePressWindow() == this)
540}
541
543{
544 if (connection()->focusWindow() == this)
545 doFocusOut();
546 if (connection()->mouseGrabber() == this)
547 connection()->setMouseGrabber(nullptr);
548 if (connection()->mousePressWindow() == this)
550
551 if (m_syncCounter && connection()->hasXSync())
552 xcb_sync_destroy_counter(xcb_connection(), m_syncCounter);
553 if (m_window) {
556 // Some window managers, like metacity, do XSelectInput on the _NET_WM_USER_TIME_WINDOW window,
557 // without trapping BadWindow (which crashes when the user time window is destroyed).
558 connection()->sync();
559 xcb_destroy_window(xcb_connection(), m_netWmUserTimeWindow);
560 m_netWmUserTimeWindow = XCB_NONE;
561 }
563 xcb_destroy_window(xcb_connection(), m_window);
564 m_window = 0;
565 }
566
567 m_mapped = false;
569
572}
573
575{
577
579
581
582 QXcbScreen *currentScreen = xcbScreen();
584
585 if (!newScreen)
586 newScreen = xcbScreen();
587
588 if (newScreen != currentScreen)
589 QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen());
590
591 if (qt_window_private(window())->positionAutomatic) {
592 const quint32 mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
593 const qint32 values[] = {
594 qBound<qint32>(1, rect.width(), XCOORD_MAX),
595 qBound<qint32>(1, rect.height(), XCOORD_MAX),
596 };
597 xcb_configure_window(xcb_connection(), m_window, mask, reinterpret_cast<const quint32*>(values));
598 } else {
599 const quint32 mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
600 const qint32 values[] = {
601 qBound<qint32>(-XCOORD_MAX, rect.x(), XCOORD_MAX),
602 qBound<qint32>(-XCOORD_MAX, rect.y(), XCOORD_MAX),
603 qBound<qint32>(1, rect.width(), XCOORD_MAX),
604 qBound<qint32>(1, rect.height(), XCOORD_MAX),
605 };
606 xcb_configure_window(xcb_connection(), m_window, mask, reinterpret_cast<const quint32*>(values));
607 if (window()->parent() && !window()->transientParent()) {
608 // Wait for server reply for parented windows to ensure that a few window
609 // moves will come as a one event. This is important when native widget is
610 // moved a few times in X and Y directions causing native scroll. Widget
611 // must get single event to not trigger unwanted widget position changes
612 // and then expose events causing backingstore flushes with incorrect
613 // offset causing image crruption.
614 connection()->sync();
615 }
616 }
617
618 xcb_flush(xcb_connection());
619}
620
622{
624 if (connection()->wmSupport()->isSupportedByWM(atom(QXcbAtom::Atom_NET_FRAME_EXTENTS))) {
625 auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), false, m_window,
626 atom(QXcbAtom::Atom_NET_FRAME_EXTENTS), XCB_ATOM_CARDINAL, 0, 4);
627 if (reply && reply->type == XCB_ATOM_CARDINAL && reply->format == 32 && reply->value_len == 4) {
628 quint32 *data = (quint32 *)xcb_get_property_value(reply.get());
629 // _NET_FRAME_EXTENTS format is left, right, top, bottom
630 m_frameMargins = QMargins(data[0], data[2], data[1], data[3]);
631 m_dirtyFrameMargins = false;
632 return m_frameMargins;
633 }
634 }
635
636 // _NET_FRAME_EXTENTS property is not available, so
637 // walk up the window tree to get the frame parent
638 xcb_window_t window = m_window;
639 xcb_window_t parent = m_window;
640
641 bool foundRoot = false;
642
643 const QList<xcb_window_t> &virtualRoots =
645
646 while (!foundRoot) {
647 auto reply = Q_XCB_REPLY_UNCHECKED(xcb_query_tree, xcb_connection(), parent);
648 if (reply) {
649 if (reply->root == reply->parent || virtualRoots.indexOf(reply->parent) != -1 || reply->parent == XCB_WINDOW_NONE) {
650 foundRoot = true;
651 } else {
652 window = parent;
654 }
655 } else {
656 m_dirtyFrameMargins = false;
658 return m_frameMargins;
659 }
660 }
661
663
664 auto reply = Q_XCB_REPLY(xcb_translate_coordinates, xcb_connection(), window, parent, 0, 0);
665 if (reply) {
666 offset = QPoint(reply->dst_x, reply->dst_y);
667 }
668
669 auto geom = Q_XCB_REPLY(xcb_get_geometry, xcb_connection(), parent);
670 if (geom) {
671 // --
672 // add the border_width for the window managers frame... some window managers
673 // do not use a border_width of zero for their frames, and if we the left and
674 // top strut, we ensure that pos() is absolutely correct. frameGeometry()
675 // will still be incorrect though... perhaps i should have foffset as well, to
676 // indicate the frame offset (equal to the border_width on X).
677 // - Brad
678 // -- copied from qwidget_x11.cpp
679
680 int left = offset.x() + geom->border_width;
681 int top = offset.y() + geom->border_width;
682 int right = geom->width + geom->border_width - geometry().width() - offset.x();
683 int bottom = geom->height + geom->border_width - geometry().height() - offset.y();
684
686 }
687
688 m_dirtyFrameMargins = false;
689 }
690
691 return m_frameMargins;
692}
693
694void QXcbWindow::setVisible(bool visible)
695{
696 if (visible)
697 show();
698 else
699 hide();
700}
701
703{
704 xcb_window_t transientXcbParent = XCB_NONE;
705 if (isTransient(window())) {
706 QWindow *tp = window()->transientParent();
707 if (tp && tp->handle()) {
708 QXcbWindow *handle = static_cast<QXcbWindow *>(tp->handle());
709 transientXcbParent = tp->handle()->winId();
710 if (transientXcbParent) {
711 handle->registerWmTransientForChild(this);
712 qCDebug(lcQpaXcbWindow) << Q_FUNC_INFO << static_cast<QPlatformWindow *>(handle)
713 << " registerWmTransientForChild " << static_cast<QPlatformWindow *>(this);
714 }
715 }
716 // Default to client leader if there is no transient parent, else modal dialogs can
717 // be hidden by their parents.
718 if (!transientXcbParent)
719 transientXcbParent = connection()->clientLeader();
720 if (transientXcbParent) { // ICCCM 4.1.2.6
721 xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
722 XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32,
723 1, &transientXcbParent);
724 qCDebug(lcQpaXcbWindow, "0x%x added XCB_ATOM_WM_TRANSIENT_FOR 0x%x", m_window, transientXcbParent);
725 }
726 }
727 if (!transientXcbParent)
728 xcb_delete_property(xcb_connection(), m_window, XCB_ATOM_WM_TRANSIENT_FOR);
729}
730
739
741{
742 if (window()->isTopLevel()) {
744 qCDebug(lcQpaWindow) << "QXcbWindow: need to recreate window" << window() << m_recreationReasons;
745 create();
747 }
748
749 // update WM_NORMAL_HINTS
751
752 // update WM_TRANSIENT_FOR
754
755 // update _NET_WM_STATE
757 }
758
759 // QWidget-attribute Qt::WA_ShowWithoutActivating.
760 const auto showWithoutActivating = window()->property("_q_showWithoutActivating");
761 if (showWithoutActivating.isValid() && showWithoutActivating.toBool())
763 else if (connection()->time() != XCB_TIME_CURRENT_TIME)
765
767 return; // defer showing until XEMBED_EMBEDDED_NOTIFY
768
769 xcb_map_window(xcb_connection(), m_window);
770
773
774 xcbScreen()->windowShown(this);
775
776 connection()->sync();
777}
778
780{
781 xcb_unmap_window(xcb_connection(), m_window);
782
783 // send synthetic UnmapNotify event according to icccm 4.1.4
784 q_padded_xcb_event<xcb_unmap_notify_event_t> event = {};
785 event.response_type = XCB_UNMAP_NOTIFY;
786 event.event = xcbScreen()->root();
787 event.window = m_window;
788 event.from_configure = false;
789 xcb_send_event(xcb_connection(), false, xcbScreen()->root(),
790 XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&event);
791
792 xcb_flush(xcb_connection());
793
794 if (connection()->mouseGrabber() == this)
795 connection()->setMouseGrabber(nullptr);
796 if (QPlatformWindow *w = connection()->mousePressWindow()) {
797 // Unset mousePressWindow when it (or one of its parents) is unmapped
798 while (w) {
799 if (w == this) {
801 break;
802 }
803 w = w->parent();
804 }
805 }
806
807 m_mapped = false;
808
809 // Hiding a modal window doesn't send an enter event to its transient parent when the
810 // mouse is already over the parent window, so the enter event must be emulated.
811 if (window()->isModal()) {
812 // Get the cursor position at modal window screen
813 const QPoint nativePos = xcbScreen()->cursor()->pos();
814 const QPoint cursorPos = QHighDpi::fromNativePixels(nativePos, xcbScreen()->screenForPosition(nativePos)->screen());
815
816 // Find the top level window at cursor position.
817 // Don't use QGuiApplication::topLevelAt(): search only the virtual siblings of this window's screen
818 QWindow *enterWindow = nullptr;
819 const auto screens = xcbScreen()->virtualSiblings();
820 for (QPlatformScreen *screen : screens) {
821 if (screen->geometry().contains(cursorPos)) {
822 const QPoint devicePosition = QHighDpi::toNativePixels(cursorPos, screen->screen());
823 enterWindow = screen->topLevelAt(devicePosition);
824 break;
825 }
826 }
827
828 if (enterWindow && enterWindow != window()) {
829 // Find the child window at cursor position, otherwise use the top level window
830 if (QWindow *childWindow = childWindowAt(enterWindow, cursorPos))
831 enterWindow = childWindow;
832 const QPoint localPos = enterWindow->mapFromGlobal(cursorPos);
834 localPos * QHighDpiScaling::factor(enterWindow),
835 nativePos);
836 }
837 }
838}
839
841{
842 QWindow *w = static_cast<QWindowPrivate *>(QObjectPrivate::get(window()))->eventReceiver();
843 // get top-level window
844 while (w && w->parent())
845 w = w->parent();
846
847 QWindow *modalWindow = nullptr;
848 const bool blocked = QGuiApplicationPrivate::instance()->isWindowBlocked(w, &modalWindow);
849 if (blocked && modalWindow != w) {
850 modalWindow->requestActivate();
851 connection()->flush();
852 return true;
853 }
854
855 return false;
856}
857
866
868{
869 connection()->setFocusWindow(nullptr);
871 // Do not set the active window to nullptr if there is a FocusIn coming.
873}
874
880
881enum {
883
884 MWM_FUNC_ALL = (1L << 0),
885 MWM_FUNC_RESIZE = (1L << 1),
886 MWM_FUNC_MOVE = (1L << 2),
887 MWM_FUNC_MINIMIZE = (1L << 3),
888 MWM_FUNC_MAXIMIZE = (1L << 4),
889 MWM_FUNC_CLOSE = (1L << 5),
890
892
893 MWM_DECOR_ALL = (1L << 0),
894 MWM_DECOR_BORDER = (1L << 1),
895 MWM_DECOR_RESIZEH = (1L << 2),
896 MWM_DECOR_TITLE = (1L << 3),
897 MWM_DECOR_MENU = (1L << 4),
900};
901
902QXcbWindow::NetWmStates QXcbWindow::netWmStates()
903{
904 NetWmStates result;
905
906 auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(),
908 XCB_ATOM_ATOM, 0, 1024);
909
910 if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM) {
911 const xcb_atom_t *states = static_cast<const xcb_atom_t *>(xcb_get_property_value(reply.get()));
912 const xcb_atom_t *statesEnd = states + reply->length;
913 if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::Atom_NET_WM_STATE_ABOVE)))
915 if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::Atom_NET_WM_STATE_BELOW)))
917 if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::Atom_NET_WM_STATE_FULLSCREEN)))
919 if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::Atom_NET_WM_STATE_MAXIMIZED_HORZ)))
921 if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::Atom_NET_WM_STATE_MAXIMIZED_VERT)))
923 if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::Atom_NET_WM_STATE_MODAL)))
925 if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::Atom_NET_WM_STATE_STAYS_ON_TOP)))
927 if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::Atom_NET_WM_STATE_DEMANDS_ATTENTION)))
929 if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::Atom_NET_WM_STATE_HIDDEN)))
931 } else {
932 qCDebug(lcQpaXcb, "getting net wm state (%x), empty\n", m_window);
933 }
934
935 return result;
936}
937
939{
941
942 if (type == Qt::ToolTip)
944 if (type == Qt::Popup)
946
947 Qt::WindowFlags oldflags = window()->flags();
952
953 const quint32 mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK;
954 const quint32 values[] = {
955 // XCB_CW_OVERRIDE_REDIRECT
957 // XCB_CW_EVENT_MASK
959 };
960
961 xcb_change_window_attributes(xcb_connection(), xcb_window(), mask, values);
962
963 WindowTypes wmWindowTypes;
965 wmWindowTypes = static_cast<WindowTypes>(
966 qvariant_cast<int>(window()->property(wm_window_type_property_id)));
967 }
968
972
975}
976
978{
980
981 QtMotifWmHints mwmhints;
982 memset(&mwmhints, 0, sizeof(mwmhints));
983
984 if (type != Qt::SplashScreen) {
985 mwmhints.flags |= MWM_HINTS_DECORATIONS;
986
987 bool customize = flags & Qt::CustomizeWindowHint;
988 if (type == Qt::Window && !customize) {
990 if (!(flags & defaultFlags))
991 flags |= defaultFlags;
992 }
993 if (!(flags & Qt::FramelessWindowHint) && !(customize && !(flags & Qt::WindowTitleHint))) {
994 mwmhints.decorations |= MWM_DECOR_BORDER;
995 mwmhints.decorations |= MWM_DECOR_RESIZEH;
996 mwmhints.decorations |= MWM_DECOR_TITLE;
997
999 mwmhints.decorations |= MWM_DECOR_MENU;
1000
1002 mwmhints.decorations |= MWM_DECOR_MINIMIZE;
1003 mwmhints.functions |= MWM_FUNC_MINIMIZE;
1004 }
1005
1007 mwmhints.decorations |= MWM_DECOR_MAXIMIZE;
1008 mwmhints.functions |= MWM_FUNC_MAXIMIZE;
1009 }
1010
1012 mwmhints.functions |= MWM_FUNC_CLOSE;
1013 }
1014 } else {
1015 // if type == Qt::SplashScreen
1016 mwmhints.decorations = MWM_DECOR_ALL;
1017 }
1018
1019 if (mwmhints.functions != 0) {
1020 mwmhints.flags |= MWM_HINTS_FUNCTIONS;
1021 mwmhints.functions |= MWM_FUNC_MOVE | MWM_FUNC_RESIZE;
1022 } else {
1023 mwmhints.functions = MWM_FUNC_ALL;
1024 }
1025
1029 && !(flags &
1033 {
1034 // a special case - only the titlebar without any button
1035 mwmhints.flags = MWM_HINTS_FUNCTIONS;
1036 mwmhints.functions = MWM_FUNC_MOVE | MWM_FUNC_RESIZE;
1037 mwmhints.decorations = 0;
1038 }
1039
1040 if (mwmhints.flags) {
1041 xcb_change_property(xcb_connection(),
1042 XCB_PROP_MODE_REPLACE,
1043 m_window,
1046 32,
1047 5,
1048 &mwmhints);
1049 } else {
1051 }
1052}
1053
1054void QXcbWindow::setNetWmState(bool set, xcb_atom_t one, xcb_atom_t two)
1055{
1056 xcb_client_message_event_t event;
1057
1058 event.response_type = XCB_CLIENT_MESSAGE;
1059 event.format = 32;
1060 event.sequence = 0;
1061 event.window = m_window;
1062 event.type = atom(QXcbAtom::Atom_NET_WM_STATE);
1063 event.data.data32[0] = set ? 1 : 0;
1064 event.data.data32[1] = one;
1065 event.data.data32[2] = two;
1066 event.data.data32[3] = 0;
1067 event.data.data32[4] = 0;
1068
1069 xcb_send_event(xcb_connection(), 0, xcbScreen()->root(),
1070 XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
1071 (const char *)&event);
1072}
1073
1085
1093
1095{
1096 if (Q_UNLIKELY(m_mapped))
1097 qCDebug(lcQpaXcb()) << "internal info: " << Q_FUNC_INFO << "called on mapped window";
1098
1099 NetWmStates states;
1100 const Qt::WindowFlags flags = window()->flags();
1104 } else if (flags & Qt::WindowStaysOnBottomHint) {
1106 }
1107
1108 if (window()->windowStates() & Qt::WindowMinimized)
1110
1111 if (window()->windowStates() & Qt::WindowFullScreen)
1113
1114 if (window()->windowStates() & Qt::WindowMaximized) {
1117 }
1118
1119 if (window()->modality() != Qt::NonModal)
1121
1122 // According to EWMH:
1123 // "The Window Manager should remove _NET_WM_STATE whenever a window is withdrawn".
1124 // Which means that we don't have to read this property before changing it on a withdrawn
1125 // window. But there are situations where users want to adjust this property as well
1126 // (e4cea305ed2ba3c9f580bf9d16c59a1048af0e8a), so instead of overwriting the property
1127 // we first read it and then merge our hints with the existing values, allowing a user
1128 // to set custom hints.
1129
1130 QList<xcb_atom_t> atoms;
1131 auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(),
1133 XCB_ATOM_ATOM, 0, 1024);
1134 if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM && reply->value_len > 0) {
1135 const xcb_atom_t *data = static_cast<const xcb_atom_t *>(xcb_get_property_value(reply.get()));
1136 atoms.resize(reply->value_len);
1137 memcpy((void *)&atoms.first(), (void *)data, reply->value_len * sizeof(xcb_atom_t));
1138 }
1139
1141 atoms.push_back(atom(QXcbAtom::Atom_NET_WM_STATE_ABOVE));
1143 atoms.push_back(atom(QXcbAtom::Atom_NET_WM_STATE_BELOW));
1145 atoms.push_back(atom(QXcbAtom::Atom_NET_WM_STATE_HIDDEN));
1153 atoms.push_back(atom(QXcbAtom::Atom_NET_WM_STATE_MODAL));
1158
1159 if (atoms.isEmpty()) {
1160 xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::Atom_NET_WM_STATE));
1161 } else {
1162 xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
1163 atom(QXcbAtom::Atom_NET_WM_STATE), XCB_ATOM_ATOM, 32,
1164 atoms.size(), atoms.constData());
1165 }
1166 xcb_flush(xcb_connection());
1167}
1168
1169void QXcbWindow::setWindowState(Qt::WindowStates state)
1170{
1171 if (state == m_windowState)
1172 return;
1173
1174 Qt::WindowStates unsetState = m_windowState & ~state;
1175 Qt::WindowStates newState = state & ~m_windowState;
1176
1177 // unset old state
1178 if (unsetState & Qt::WindowMinimized)
1179 xcb_map_window(xcb_connection(), m_window);
1180 if (unsetState & Qt::WindowMaximized)
1181 setNetWmState(false,
1184 if (unsetState & Qt::WindowFullScreen)
1186
1187 // set new state
1189 {
1190 xcb_client_message_event_t event;
1191
1192 event.response_type = XCB_CLIENT_MESSAGE;
1193 event.format = 32;
1194 event.sequence = 0;
1195 event.window = m_window;
1196 event.type = atom(QXcbAtom::AtomWM_CHANGE_STATE);
1197 event.data.data32[0] = XCB_ICCCM_WM_STATE_ICONIC;
1198 event.data.data32[1] = 0;
1199 event.data.data32[2] = 0;
1200 event.data.data32[3] = 0;
1201 event.data.data32[4] = 0;
1202
1203 xcb_send_event(xcb_connection(), 0, xcbScreen()->root(),
1204 XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
1205 (const char *)&event);
1206 }
1207 m_minimized = true;
1208 }
1209
1210 // set Maximized && FullScreen state if need
1212
1213 xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_hints_unchecked(xcb_connection(), m_window);
1214 xcb_icccm_wm_hints_t hints;
1215 if (xcb_icccm_get_wm_hints_reply(xcb_connection(), cookie, &hints, nullptr)) {
1217 xcb_icccm_wm_hints_set_iconic(&hints);
1218 else
1219 xcb_icccm_wm_hints_set_normal(&hints);
1220 xcb_icccm_set_wm_hints(xcb_connection(), m_window, &hints);
1221 }
1222
1223 connection()->sync();
1225}
1226
1227void QXcbWindow::updateNetWmUserTime(xcb_timestamp_t timestamp)
1228{
1229 xcb_window_t wid = m_window;
1230 // If timestamp == 0, then it means that the window should not be
1231 // initially activated. Don't update global user time for this
1232 // special case.
1233 if (timestamp != 0)
1234 connection()->setNetWmUserTime(timestamp);
1235
1237 if (m_netWmUserTimeWindow || isSupportedByWM) {
1238 if (!m_netWmUserTimeWindow) {
1239 m_netWmUserTimeWindow = xcb_generate_id(xcb_connection());
1240 xcb_create_window(xcb_connection(),
1241 XCB_COPY_FROM_PARENT, // depth -- same as root
1242 m_netWmUserTimeWindow, // window id
1243 m_window, // parent window id
1244 -1, -1, 1, 1,
1245 0, // border width
1246 XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
1247 m_visualId, // visual
1248 0, // value mask
1249 nullptr); // value list
1251 xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, atom(QXcbAtom::Atom_NET_WM_USER_TIME_WINDOW),
1252 XCB_ATOM_WINDOW, 32, 1, &m_netWmUserTimeWindow);
1254
1256 QStringLiteral("Qt NET_WM User Time Window"));
1257
1258 } else if (!isSupportedByWM) {
1259 // WM no longer supports it, then we should remove the
1260 // _NET_WM_USER_TIME_WINDOW atom.
1262 xcb_destroy_window(xcb_connection(), m_netWmUserTimeWindow);
1263 m_netWmUserTimeWindow = XCB_NONE;
1264 } else {
1266 }
1267 }
1268 xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, wid, atom(QXcbAtom::Atom_NET_WM_USER_TIME),
1269 XCB_ATOM_CARDINAL, 32, 1, &timestamp);
1270}
1271
1273{
1274 if (!connection()->hasXFixes() || transparent == m_transparent)
1275 return;
1276
1277 xcb_rectangle_t rectangle;
1278
1279 xcb_rectangle_t *rect = nullptr;
1280 int nrect = 0;
1281
1282 if (!transparent) {
1283 rectangle.x = 0;
1284 rectangle.y = 0;
1285 rectangle.width = geometry().width();
1286 rectangle.height = geometry().height();
1287 rect = &rectangle;
1288 nrect = 1;
1289 }
1290
1291 xcb_xfixes_region_t region = xcb_generate_id(xcb_connection());
1292 xcb_xfixes_create_region(xcb_connection(), region, nrect, rect);
1293 xcb_xfixes_set_window_shape_region_checked(xcb_connection(), m_window, XCB_SHAPE_SK_INPUT, 0, 0, region);
1294 xcb_xfixes_destroy_region(xcb_connection(), region);
1295
1296 m_transparent = transparent;
1297}
1298
1299void QXcbWindow::updateDoesNotAcceptFocus(bool doesNotAcceptFocus)
1300{
1301 xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_hints_unchecked(xcb_connection(), m_window);
1302
1303 xcb_icccm_wm_hints_t hints;
1304 if (!xcb_icccm_get_wm_hints_reply(xcb_connection(), cookie, &hints, nullptr))
1305 return;
1306
1307 xcb_icccm_wm_hints_set_input(&hints, !doesNotAcceptFocus);
1308 xcb_icccm_set_wm_hints(xcb_connection(), m_window, &hints);
1309}
1310
1312{
1313 return m_window;
1314}
1315
1317{
1318 QPoint topLeft = geometry().topLeft();
1319
1320 xcb_window_t xcb_parent_id;
1321 if (parent) {
1322 const QXcbWindow *qXcbParent = static_cast<const QXcbWindow *>(parent);
1323 xcb_parent_id = qXcbParent->xcb_window();
1324 m_embedded = qXcbParent->isForeignWindow();
1325 } else {
1326 xcb_parent_id = xcbScreen()->root();
1327 m_embedded = false;
1328 }
1329 xcb_reparent_window(xcb_connection(), xcb_window(), xcb_parent_id, topLeft.x(), topLeft.y());
1330}
1331
1336
1338{
1339 const QByteArray ba = title.toUtf8();
1340 xcb_change_property(xcb_connection(),
1341 XCB_PROP_MODE_REPLACE,
1342 m_window,
1345 8,
1346 ba.size(),
1347 ba.constData());
1348}
1349
1351{
1352 QList<quint32> icon_data;
1353 if (!icon.isNull()) {
1354 QList<QSize> availableSizes = icon.availableSizes();
1355 if (availableSizes.isEmpty()) {
1356 // try to use default sizes since the icon can be a scalable image like svg.
1357 availableSizes.push_back(QSize(16,16));
1358 availableSizes.push_back(QSize(32,32));
1359 availableSizes.push_back(QSize(64,64));
1360 availableSizes.push_back(QSize(128,128));
1361 }
1362 for (int i = 0; i < availableSizes.size(); ++i) {
1363 QSize size = availableSizes.at(i);
1365 if (!pixmap.isNull()) {
1366 QImage image = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
1367 int pos = icon_data.size();
1368 icon_data.resize(pos + 2 + image.width()*image.height());
1369 icon_data[pos++] = image.width();
1370 icon_data[pos++] = image.height();
1371 memcpy(icon_data.data() + pos, image.bits(), image.width()*image.height()*4);
1372 }
1373 }
1374 }
1375
1376 if (!icon_data.isEmpty()) {
1377 // Ignore icon exceeding maximum xcb request length
1378 if (quint64(icon_data.size()) > quint64(xcb_get_maximum_request_length(xcb_connection()))) {
1379 qWarning() << "Ignoring window icon" << icon_data.size()
1380 << "exceeds maximum xcb request length"
1381 << xcb_get_maximum_request_length(xcb_connection());
1382 return;
1383 }
1384 xcb_change_property(xcb_connection(),
1385 XCB_PROP_MODE_REPLACE,
1386 m_window,
1389 32,
1390 icon_data.size(),
1391 (unsigned char *) icon_data.data());
1392 } else {
1393 xcb_delete_property(xcb_connection(),
1394 m_window,
1396 }
1397}
1398
1400{
1401 const quint32 mask = XCB_CONFIG_WINDOW_STACK_MODE;
1402 const quint32 values[] = { XCB_STACK_MODE_ABOVE };
1403 xcb_configure_window(xcb_connection(), m_window, mask, values);
1404}
1405
1407{
1408 const quint32 mask = XCB_CONFIG_WINDOW_STACK_MODE;
1409 const quint32 values[] = { XCB_STACK_MODE_BELOW };
1410 xcb_configure_window(xcb_connection(), m_window, mask, values);
1411}
1412
1414{
1415 // update WM_NORMAL_HINTS
1416 xcb_size_hints_t hints;
1417 memset(&hints, 0, sizeof(hints));
1418
1419 const QRect rect = geometry();
1421
1422 if (!win->positionAutomatic)
1423 xcb_icccm_size_hints_set_position(&hints, true, rect.x(), rect.y());
1424 if (rect.width() < QWINDOWSIZE_MAX || rect.height() < QWINDOWSIZE_MAX)
1425 xcb_icccm_size_hints_set_size(&hints, true, rect.width(), rect.height());
1426
1427 /* Gravity describes how to interpret x and y values the next time
1428 window needs to be positioned on a screen.
1429 XCB_GRAVITY_STATIC : the left top corner of the client window
1430 XCB_GRAVITY_NORTH_WEST : the left top corner of the frame window */
1431 auto gravity = win->positionPolicy == QWindowPrivate::WindowFrameInclusive
1432 ? XCB_GRAVITY_NORTH_WEST : XCB_GRAVITY_STATIC;
1433
1434 xcb_icccm_size_hints_set_win_gravity(&hints, gravity);
1435
1436 QSize minimumSize = windowMinimumSize();
1437 QSize maximumSize = windowMaximumSize();
1438 QSize baseSize = windowBaseSize();
1439 QSize sizeIncrement = windowSizeIncrement();
1440
1441 if (minimumSize.width() > 0 || minimumSize.height() > 0)
1442 xcb_icccm_size_hints_set_min_size(&hints,
1443 qMin(XCOORD_MAX,minimumSize.width()),
1444 qMin(XCOORD_MAX,minimumSize.height()));
1445
1446 if (maximumSize.width() < QWINDOWSIZE_MAX || maximumSize.height() < QWINDOWSIZE_MAX)
1447 xcb_icccm_size_hints_set_max_size(&hints,
1448 qMin(XCOORD_MAX, maximumSize.width()),
1449 qMin(XCOORD_MAX, maximumSize.height()));
1450
1451 if (sizeIncrement.width() > 0 || sizeIncrement.height() > 0) {
1452 if (!baseSize.isNull() && baseSize.isValid())
1453 xcb_icccm_size_hints_set_base_size(&hints, baseSize.width(), baseSize.height());
1454 xcb_icccm_size_hints_set_resize_inc(&hints, sizeIncrement.width(), sizeIncrement.height());
1455 }
1456
1457 xcb_icccm_set_wm_normal_hints(xcb_connection(), m_window, &hints);
1458
1460}
1461
1463{
1464 /* Never activate embedded windows; doing that would prevent the container
1465 * to re-gain the keyboard focus later. */
1466 if (m_embedded) {
1468 return;
1469 }
1470
1471 {
1472 QMutexLocker locker(&m_mappedMutex);
1473 if (!m_mapped) {
1474 m_deferredActivation = true;
1475 return;
1476 }
1477 m_deferredActivation = false;
1478 }
1479
1481 QWindow *focusWindow = QGuiApplication::focusWindow();
1482 xcb_window_t current = XCB_NONE;
1483 if (focusWindow) {
1484 if (QPlatformWindow *pw = focusWindow->handle())
1485 current = pw->winId();
1486 }
1487
1488 if (window()->isTopLevel()
1490 && (!focusWindow || !window()->isAncestorOf(focusWindow))
1491 && connection()->wmSupport()->isSupportedByWM(atom(QXcbAtom::Atom_NET_ACTIVE_WINDOW))) {
1492 xcb_client_message_event_t event;
1493
1494 event.response_type = XCB_CLIENT_MESSAGE;
1495 event.format = 32;
1496 event.sequence = 0;
1497 event.window = m_window;
1499 event.data.data32[0] = 1;
1500 event.data.data32[1] = connection()->time();
1501 event.data.data32[2] = current;
1502 event.data.data32[3] = 0;
1503 event.data.data32[4] = 0;
1504
1505 xcb_send_event(xcb_connection(), 0, xcbScreen()->root(),
1506 XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
1507 (const char *)&event);
1508 } else {
1509 xcb_set_input_focus(xcb_connection(), XCB_INPUT_FOCUS_PARENT, m_window, connection()->time());
1510 }
1511
1512 connection()->sync();
1513}
1514
1516{
1517 return m_format;
1518}
1519
1520QXcbWindow::WindowTypes QXcbWindow::wmWindowTypes() const
1521{
1522 WindowTypes result;
1523
1524 auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(),
1526 XCB_ATOM_ATOM, 0, 1024);
1527 if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM) {
1528 const xcb_atom_t *types = static_cast<const xcb_atom_t *>(xcb_get_property_value(reply.get()));
1529 const xcb_atom_t *types_end = types + reply->length;
1530 for (; types != types_end; types++) {
1532 switch (type) {
1534 result |= WindowType::Normal;
1535 break;
1537 result |= WindowType::Desktop;
1538 break;
1540 result |= WindowType::Dock;
1541 break;
1543 result |= WindowType::Toolbar;
1544 break;
1546 result |= WindowType::Menu;
1547 break;
1549 result |= WindowType::Utility;
1550 break;
1552 result |= WindowType::Splash;
1553 break;
1555 result |= WindowType::Dialog;
1556 break;
1558 result |= WindowType::DropDownMenu;
1559 break;
1561 result |= WindowType::PopupMenu;
1562 break;
1564 result |= WindowType::Tooltip;
1565 break;
1567 result |= WindowType::Notification;
1568 break;
1570 result |= WindowType::Combo;
1571 break;
1573 result |= WindowType::Dnd;
1574 break;
1576 result |= WindowType::KdeOverride;
1577 break;
1578 default:
1579 break;
1580 }
1581 }
1582 }
1583 return result;
1584}
1585
1586void QXcbWindow::setWmWindowType(WindowTypes types, Qt::WindowFlags flags)
1587{
1588 QList<xcb_atom_t> atoms;
1589
1590 // manual selection 1 (these are never set by Qt and take precedence)
1591 if (types & WindowType::Normal)
1593 if (types & WindowType::Desktop)
1595 if (types & WindowType::Dock)
1597 if (types & WindowType::Notification)
1599
1600 // manual selection 2 (Qt uses these during auto selection);
1601 if (types & WindowType::Utility)
1603 if (types & WindowType::Splash)
1605 if (types & WindowType::Dialog)
1607 if (types & WindowType::Tooltip)
1609 if (types & WindowType::KdeOverride)
1611
1612 // manual selection 3 (these can be set by Qt, but don't have a
1613 // corresponding Qt::WindowType). note that order of the *MENU
1614 // atoms is important
1615 if (types & WindowType::Menu)
1617 if (types & WindowType::DropDownMenu)
1619 if (types & WindowType::PopupMenu)
1621 if (types & WindowType::Toolbar)
1623 if (types & WindowType::Combo)
1625 if (types & WindowType::Dnd)
1627
1628 // automatic selection
1630 switch (type) {
1631 case Qt::Dialog:
1632 case Qt::Sheet:
1633 if (!(types & WindowType::Dialog))
1635 break;
1636 case Qt::Tool:
1637 case Qt::Drawer:
1638 if (!(types & WindowType::Utility))
1640 break;
1641 case Qt::ToolTip:
1642 if (!(types & WindowType::Tooltip))
1644 break;
1645 case Qt::SplashScreen:
1646 if (!(types & WindowType::Splash))
1648 break;
1649 default:
1650 break;
1651 }
1652
1653 if ((flags & Qt::FramelessWindowHint) && !(types & WindowType::KdeOverride)) {
1654 // override netwm type - quick and easy for KDE noborder
1656 }
1657
1658 if (atoms.size() == 1 && atoms.first() == atom(QXcbAtom::Atom_NET_WM_WINDOW_TYPE_NORMAL))
1659 atoms.clear();
1660 else
1662
1663 if (atoms.isEmpty()) {
1665 } else {
1666 xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
1667 atom(QXcbAtom::Atom_NET_WM_WINDOW_TYPE), XCB_ATOM_ATOM, 32,
1668 atoms.size(), atoms.constData());
1669 }
1670 xcb_flush(xcb_connection());
1671}
1672
1674{
1675 QByteArray roleData = role.toLatin1();
1676 xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window,
1677 atom(QXcbAtom::AtomWM_WINDOW_ROLE), XCB_ATOM_STRING, 8,
1678 roleData.size(), roleData.constData());
1679}
1680
1682{
1683 const quint32 mask = XCB_CW_BACK_PIXMAP;
1684 const quint32 values[] = { XCB_BACK_PIXMAP_PARENT_RELATIVE };
1685 xcb_change_window_attributes(xcb_connection(), m_window, mask, values);
1686}
1687
1689{
1690 if (!connection()->systemTrayTracker())
1691 return false;
1693 return true;
1694}
1695
1696bool QXcbWindow::handleNativeEvent(xcb_generic_event_t *event)
1697{
1698 auto eventType = connection()->nativeInterface()->nativeEventType();
1699 qintptr result = 0; // Used only by MS Windows
1701}
1702
1703void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event)
1704{
1705 QRect rect(event->x, event->y, event->width, event->height);
1707
1708 bool pending = true;
1709
1711 [this, &pending](xcb_generic_event_t *event, int type) {
1712 if (type != XCB_EXPOSE)
1713 return false;
1714 auto expose = reinterpret_cast<xcb_expose_event_t *>(event);
1715 if (expose->window != m_window)
1716 return false;
1717 if (expose->count == 0)
1718 pending = false;
1719 m_exposeRegion |= QRect(expose->x, expose->y, expose->width, expose->height);
1720 free(expose);
1721 return true;
1722 });
1723
1724 // if count is non-zero there are more expose events pending
1725 if (event->count == 0 || !pending) {
1728 }
1729}
1730
1731void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *event)
1732{
1733 if (event->format != 32)
1734 return;
1735
1736 if (event->type == atom(QXcbAtom::AtomWM_PROTOCOLS)) {
1737 xcb_atom_t protocolAtom = event->data.data32[0];
1738 if (protocolAtom == atom(QXcbAtom::AtomWM_DELETE_WINDOW)) {
1740 } else if (protocolAtom == atom(QXcbAtom::AtomWM_TAKE_FOCUS)) {
1741 connection()->setTime(event->data.data32[1]);
1743 return;
1744 } else if (protocolAtom == atom(QXcbAtom::Atom_NET_WM_PING)) {
1745 if (event->window == xcbScreen()->root())
1746 return;
1747
1748 xcb_client_message_event_t reply = *event;
1749
1750 reply.response_type = XCB_CLIENT_MESSAGE;
1751 reply.window = xcbScreen()->root();
1752
1753 xcb_send_event(xcb_connection(), 0, xcbScreen()->root(),
1754 XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
1755 (const char *)&reply);
1756 xcb_flush(xcb_connection());
1757 } else if (protocolAtom == atom(QXcbAtom::Atom_NET_WM_SYNC_REQUEST)) {
1758 connection()->setTime(event->data.data32[1]);
1759 m_syncValue.lo = event->data.data32[2];
1760 m_syncValue.hi = event->data.data32[3];
1761 if (connection()->hasXSync())
1763#ifndef QT_NO_WHATSTHIS
1764 } else if (protocolAtom == atom(QXcbAtom::Atom_NET_WM_CONTEXT_HELP)) {
1765 QWindowSystemInterface::handleEnterWhatsThisEvent();
1766#endif
1767 } else {
1768 qCWarning(lcQpaXcb, "Unhandled WM_PROTOCOLS (%s)",
1769 connection()->atomName(protocolAtom).constData());
1770 }
1771#if QT_CONFIG(draganddrop)
1772 } else if (event->type == atom(QXcbAtom::AtomXdndEnter)) {
1773 connection()->drag()->handleEnter(this, event);
1774 } else if (event->type == atom(QXcbAtom::AtomXdndPosition)) {
1775 connection()->drag()->handlePosition(this, event);
1776 } else if (event->type == atom(QXcbAtom::AtomXdndLeave)) {
1777 connection()->drag()->handleLeave(this, event);
1778 } else if (event->type == atom(QXcbAtom::AtomXdndDrop)) {
1779 connection()->drag()->handleDrop(this, event);
1780#endif
1781 } else if (event->type == atom(QXcbAtom::Atom_XEMBED)) {
1783 } else if (event->type == atom(QXcbAtom::Atom_NET_ACTIVE_WINDOW)) {
1784 doFocusIn();
1785 } else if (event->type == atom(QXcbAtom::AtomMANAGER)
1788 // Ignore _NET_WM_STATE, MANAGER which are relate to tray icons
1789 // and other messages.
1795 //silence the _COMPIZ and _GTK messages for now
1796 } else {
1797 qCWarning(lcQpaXcb) << "Unhandled client message: " << connection()->atomName(event->type);
1798 }
1799}
1800
1801void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *event)
1802{
1803 bool fromSendEvent = (event->response_type & 0x80);
1804 QPoint pos(event->x, event->y);
1806 // Do not trust the position, query it instead.
1807 auto reply = Q_XCB_REPLY(xcb_translate_coordinates, xcb_connection(),
1808 xcb_window(), xcbScreen()->root(), 0, 0);
1809 if (reply) {
1810 pos.setX(reply->dst_x);
1811 pos.setY(reply->dst_y);
1812 }
1813 }
1814
1815 const QRect actualGeometry = QRect(pos, QSize(event->width, event->height));
1817 if (!newScreen)
1818 return;
1819
1821
1822 // QPlatformScreen::screen() is updated asynchronously, so we can't compare it
1823 // with the newScreen. Just send the WindowScreenChanged event and QGuiApplication
1824 // will make the comparison later.
1826
1829
1830 // Send the synthetic expose event on resize only when the window is shrunk,
1831 // because the "XCB_GRAVITY_NORTH_WEST" flag doesn't send it automatically.
1833 && (actualGeometry.width() < m_oldWindowSize.width()
1834 || actualGeometry.height() < m_oldWindowSize.height())) {
1835 QWindowSystemInterface::handleExposeEvent(window(), QRegion(0, 0, actualGeometry.width(), actualGeometry.height()));
1836 }
1837 m_oldWindowSize = actualGeometry.size();
1838
1839 if (connection()->hasXSync() && m_syncState == SyncReceived)
1841
1842 m_dirtyFrameMargins = true;
1843}
1844
1846{
1847 return m_mapped;
1848}
1849
1851{
1852 return m_embedded;
1853}
1854
1856{
1857 if (!m_embedded)
1859
1860 QPoint ret;
1861 auto reply = Q_XCB_REPLY(xcb_translate_coordinates, xcb_connection(),
1862 xcb_window(), xcbScreen()->root(),
1863 pos.x(), pos.y());
1864 if (reply) {
1865 ret.setX(reply->dst_x);
1866 ret.setY(reply->dst_y);
1867 }
1868
1869 return ret;
1870}
1871
1873{
1874 if (!m_embedded)
1876
1877 QPoint ret;
1878 auto reply = Q_XCB_REPLY(xcb_translate_coordinates, xcb_connection(),
1879 xcbScreen()->root(), xcb_window(),
1880 pos.x(), pos.y());
1881 if (reply) {
1882 ret.setX(reply->dst_x);
1883 ret.setY(reply->dst_y);
1884 }
1885
1886 return ret;
1887}
1888
1889void QXcbWindow::handleMapNotifyEvent(const xcb_map_notify_event_t *event)
1890{
1891 if (event->window == m_window) {
1893 m_mapped = true;
1894 const bool deferredActivation = m_deferredActivation;
1896 if (deferredActivation)
1898
1900 }
1901}
1902
1903void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event)
1904{
1905 if (event->window == m_window) {
1907 m_mapped = false;
1910 }
1911}
1912
1913void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, int root_y,
1914 int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp,
1916{
1917 const bool isWheel = detail >= 4 && detail <= 7;
1918 if (!isWheel && window() != QGuiApplication::focusWindow()) {
1919 QWindow *w = static_cast<QWindowPrivate *>(QObjectPrivate::get(window()))->eventReceiver();
1921 && w->type() != Qt::ToolTip
1922 && w->type() != Qt::Popup) {
1923 w->requestActivate();
1924 }
1925 }
1926
1927 updateNetWmUserTime(timestamp);
1928
1929 if (m_embedded && !m_trayIconWindow) {
1931 const QXcbWindow *container = static_cast<const QXcbWindow *>(QPlatformWindow::parent());
1932 Q_ASSERT(container != nullptr);
1933
1935 }
1936 }
1937 QPoint local(event_x, event_y);
1938 QPoint global(root_x, root_y);
1939
1940 if (isWheel) {
1941 if (!connection()->isAtLeastXI21()) {
1942 QPoint angleDelta;
1943 if (detail == 4)
1944 angleDelta.setY(120);
1945 else if (detail == 5)
1946 angleDelta.setY(-120);
1947 else if (detail == 6)
1948 angleDelta.setX(120);
1949 else if (detail == 7)
1950 angleDelta.setX(-120);
1952 angleDelta = angleDelta.transposed();
1953 QWindowSystemInterface::handleWheelEvent(window(), timestamp, local, global, QPoint(), angleDelta, modifiers);
1954 }
1955 return;
1956 }
1957
1959
1960 handleMouseEvent(timestamp, local, global, modifiers, type, source);
1961}
1962
1963void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x, int root_y,
1964 int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp,
1966{
1967 QPoint local(event_x, event_y);
1968 QPoint global(root_x, root_y);
1969
1970 if (detail >= 4 && detail <= 7) {
1971 // mouse wheel, handled in handleButtonPressEvent()
1972 return;
1973 }
1974
1975 if (connection()->buttonState() == Qt::NoButton) {
1976 connection()->setMousePressWindow(nullptr);
1978 }
1979
1980 handleMouseEvent(timestamp, local, global, modifiers, type, source);
1981}
1982
1983static inline bool doCheckUnGrabAncestor(QXcbConnection *conn)
1984{
1985 /* Checking for XCB_NOTIFY_MODE_GRAB and XCB_NOTIFY_DETAIL_ANCESTOR prevents unwanted
1986 * enter/leave events on AwesomeWM on mouse button press. It also ignores duplicated
1987 * enter/leave events on Alt+Tab switching on some WMs with XInput2 events.
1988 * Without XInput2 events the (Un)grabAncestor cannot be checked when mouse button is
1989 * not pressed, otherwise (e.g. on Alt+Tab) it can igonre important enter/leave events.
1990 */
1991 if (conn) {
1992 const bool mouseButtonsPressed = (conn->buttonState() != Qt::NoButton);
1993 return mouseButtonsPressed || conn->hasXInput2();
1994 }
1995 return true;
1996}
1997
1999{
2000 return ((doCheckUnGrabAncestor(conn)
2001 && mode == XCB_NOTIFY_MODE_GRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR)
2002 || (mode == XCB_NOTIFY_MODE_UNGRAB && detail == XCB_NOTIFY_DETAIL_INFERIOR)
2003 || detail == XCB_NOTIFY_DETAIL_VIRTUAL
2004 || detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL);
2005}
2006
2008{
2009 return ((doCheckUnGrabAncestor(conn)
2010 && mode == XCB_NOTIFY_MODE_UNGRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR)
2011 || (mode != XCB_NOTIFY_MODE_NORMAL && mode != XCB_NOTIFY_MODE_UNGRAB)
2012 || detail == XCB_NOTIFY_DETAIL_VIRTUAL
2013 || detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL);
2014}
2015
2016void QXcbWindow::handleEnterNotifyEvent(int event_x, int event_y, int root_x, int root_y,
2017 quint8 mode, quint8 detail, xcb_timestamp_t timestamp)
2018{
2019 connection()->setTime(timestamp);
2020
2022 || (connection()->mousePressWindow() && !m_ignorePressedWindowOnMouseLeave)) {
2023 return;
2024 }
2025
2026 // Updates scroll valuators, as user might have done some scrolling outside our X client.
2028
2029 if (mode == XCB_NOTIFY_MODE_UNGRAB && connection()->queryMouseButtons() != Qt::NoButton)
2031
2032 const QPoint global = QPoint(root_x, root_y);
2033 const QPoint local(event_x, event_y);
2035}
2036
2037void QXcbWindow::handleLeaveNotifyEvent(int root_x, int root_y,
2038 quint8 mode, quint8 detail, xcb_timestamp_t timestamp)
2039{
2040 connection()->setTime(timestamp);
2041
2042 QXcbWindow *mousePressWindow = connection()->mousePressWindow();
2044 || (mousePressWindow && !m_ignorePressedWindowOnMouseLeave)) {
2045 return;
2046 }
2047
2048 // check if enter event is buffered
2049 auto event = connection()->eventQueue()->peek([](xcb_generic_event_t *event, int type) {
2050 if (type != XCB_ENTER_NOTIFY)
2051 return false;
2052 auto enter = reinterpret_cast<xcb_enter_notify_event_t *>(event);
2053 return !ignoreEnterEvent(enter->mode, enter->detail);
2054 });
2055 auto enter = reinterpret_cast<xcb_enter_notify_event_t *>(event);
2056 QXcbWindow *enterWindow = enter ? connection()->platformWindowFromId(enter->event) : nullptr;
2057
2058 if (enterWindow) {
2059 QPoint local(enter->event_x, enter->event_y);
2060 QPoint global = QPoint(root_x, root_y);
2061 QWindowSystemInterface::handleEnterLeaveEvent(enterWindow->window(), window(), local, global);
2062 } else {
2065 connection()->setMousePressWindow(nullptr);
2066 }
2067
2068 free(enter);
2069}
2070
2071void QXcbWindow::handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y,
2072 Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp,
2074{
2075 QPoint local(event_x, event_y);
2076 QPoint global(root_x, root_y);
2077
2078 // "mousePressWindow" can be NULL i.e. if a window will be grabbed or unmapped, so set it again here.
2079 // Unset "mousePressWindow" when mouse button isn't pressed - in some cases the release event won't arrive.
2080 const bool isMouseButtonPressed = (connection()->buttonState() != Qt::NoButton);
2081 const bool hasMousePressWindow = (connection()->mousePressWindow() != nullptr);
2082 if (isMouseButtonPressed && !hasMousePressWindow)
2084 else if (hasMousePressWindow && !isMouseButtonPressed)
2085 connection()->setMousePressWindow(nullptr);
2086
2087 handleMouseEvent(timestamp, local, global, modifiers, type, source);
2088}
2089
2090void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event)
2091{
2092 Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state);
2093 handleButtonPressEvent(event->event_x, event->event_y, event->root_x, event->root_y, event->detail,
2095}
2096
2097void QXcbWindow::handleButtonReleaseEvent(const xcb_button_release_event_t *event)
2098{
2099 Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state);
2100 handleButtonReleaseEvent(event->event_x, event->event_y, event->root_x, event->root_y, event->detail,
2102}
2103
2104void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event)
2105{
2106 Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state);
2107 handleMotionNotifyEvent(event->event_x, event->event_y, event->root_x, event->root_y, modifiers,
2108 event->time, QEvent::MouseMove);
2109}
2110
2111static inline int fixed1616ToInt(xcb_input_fp1616_t val)
2112{
2113 return int(qreal(val) / 0x10000);
2114}
2115
2116#define qt_xcb_mask_is_set(ptr, event) (((unsigned char*)(ptr))[(event)>>3] & (1 << ((event) & 7)))
2117
2119{
2120 QXcbConnection *conn = connection();
2121 auto *ev = reinterpret_cast<xcb_input_button_press_event_t *>(event);
2122
2123 if (ev->buttons_len > 0) {
2124 unsigned char *buttonMask = (unsigned char *) &ev[1];
2125 // There is a bug in the evdev driver which leads to receiving mouse events without
2126 // XIPointerEmulated being set: https://bugs.freedesktop.org/show_bug.cgi?id=98188
2127 // Filter them out by other attributes: when their source device is a touch screen
2128 // and the LMB is pressed.
2129 if (qt_xcb_mask_is_set(buttonMask, 1) && conn->isTouchScreen(ev->sourceid)) {
2130 if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
2131 qCDebug(lcQpaXInput, "XI2 mouse event from touch device %d was ignored", ev->sourceid);
2132 return;
2133 }
2134 for (int i = 1; i <= 15; ++i)
2135 conn->setButtonState(conn->translateMouseButton(i), qt_xcb_mask_is_set(buttonMask, i));
2136 }
2137
2138 const Qt::KeyboardModifiers modifiers = conn->keyboard()->translateModifiers(ev->mods.effective);
2139 const int event_x = fixed1616ToInt(ev->event_x);
2140 const int event_y = fixed1616ToInt(ev->event_y);
2141 const int root_x = fixed1616ToInt(ev->root_x);
2142 const int root_y = fixed1616ToInt(ev->root_y);
2143
2144 conn->keyboard()->updateXKBStateFromXI(&ev->mods, &ev->group);
2145
2146 const Qt::MouseButton button = conn->xiToQtMouseButton(ev->detail);
2147
2148 const char *sourceName = nullptr;
2149 if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) {
2150 const QMetaObject *metaObject = qt_getEnumMetaObject(source);
2151 const QMetaEnum me = metaObject->enumerator(metaObject->indexOfEnumerator(qt_getEnumName(source)));
2152 sourceName = me.valueToKey(source);
2153 }
2154
2155 switch (ev->event_type) {
2156 case XCB_INPUT_BUTTON_PRESS:
2157 if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
2158 qCDebug(lcQpaXInputEvents, "XI2 mouse press, button %d, time %d, source %s", button, ev->time, sourceName);
2159 conn->setButtonState(button, true);
2160 handleButtonPressEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, QEvent::MouseButtonPress, source);
2161 break;
2162 case XCB_INPUT_BUTTON_RELEASE:
2163 if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
2164 qCDebug(lcQpaXInputEvents, "XI2 mouse release, button %d, time %d, source %s", button, ev->time, sourceName);
2165 conn->setButtonState(button, false);
2166 handleButtonReleaseEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, QEvent::MouseButtonRelease, source);
2167 break;
2168 case XCB_INPUT_MOTION:
2169 if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
2170 qCDebug(lcQpaXInputEvents, "XI2 mouse motion %d,%d, time %d, source %s", event_x, event_y, ev->time, sourceName);
2171 handleMotionNotifyEvent(event_x, event_y, root_x, root_y, modifiers, ev->time, QEvent::MouseMove, source);
2172 break;
2173 default:
2174 qWarning() << "Unrecognized XI2 mouse event" << ev->event_type;
2175 break;
2176 }
2177}
2178
2180{
2181 auto *ev = reinterpret_cast<xcb_input_enter_event_t *>(event);
2182
2183 // Compare the window with current mouse grabber to prevent deliver events to any other windows.
2184 // If leave event occurs and the window is under mouse - allow to deliver the leave event.
2185 QXcbWindow *mouseGrabber = connection()->mouseGrabber();
2186 if (mouseGrabber && mouseGrabber != this
2187 && (ev->event_type != XCB_INPUT_LEAVE || QGuiApplicationPrivate::currentMouseWindow != window())) {
2188 return;
2189 }
2190
2191 const int root_x = fixed1616ToInt(ev->root_x);
2192 const int root_y = fixed1616ToInt(ev->root_y);
2193
2194 switch (ev->event_type) {
2195 case XCB_INPUT_ENTER: {
2196 const int event_x = fixed1616ToInt(ev->event_x);
2197 const int event_y = fixed1616ToInt(ev->event_y);
2198 qCDebug(lcQpaXInputEvents, "XI2 mouse enter %d,%d, mode %d, detail %d, time %d",
2199 event_x, event_y, ev->mode, ev->detail, ev->time);
2200 handleEnterNotifyEvent(event_x, event_y, root_x, root_y, ev->mode, ev->detail, ev->time);
2201 break;
2202 }
2203 case XCB_INPUT_LEAVE:
2204 qCDebug(lcQpaXInputEvents, "XI2 mouse leave, mode %d, detail %d, time %d",
2205 ev->mode, ev->detail, ev->time);
2206 connection()->keyboard()->updateXKBStateFromXI(&ev->mods, &ev->group);
2207 handleLeaveNotifyEvent(root_x, root_y, ev->mode, ev->detail, ev->time);
2208 break;
2209 }
2210}
2211
2213
2225
2226void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *event)
2227{
2228 handleEnterNotifyEvent(event->event_x, event->event_y, event->root_x, event->root_y, event->mode, event->detail, event->time);
2229}
2230
2231void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event)
2232{
2233 handleLeaveNotifyEvent(event->root_x, event->root_y, event->mode, event->detail, event->time);
2234}
2235
2236void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *event)
2237{
2238 connection()->setTime(event->time);
2239
2240 const bool propertyDeleted = event->state == XCB_PROPERTY_DELETE;
2241
2243 if (propertyDeleted)
2244 return;
2245
2246 Qt::WindowStates newState = Qt::WindowNoState;
2247
2248 if (event->atom == atom(QXcbAtom::AtomWM_STATE)) { // WM_STATE: Quick check for 'Minimize'.
2249 auto reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(),
2251 XCB_ATOM_ANY, 0, 1024);
2252 if (reply && reply->format == 32 && reply->type == atom(QXcbAtom::AtomWM_STATE)) {
2253 const quint32 *data = (const quint32 *)xcb_get_property_value(reply.get());
2254 if (reply->length != 0)
2255 m_minimized = (data[0] == XCB_ICCCM_WM_STATE_ICONIC
2256 || (data[0] == XCB_ICCCM_WM_STATE_WITHDRAWN && m_minimized));
2257 }
2258 }
2259
2260 const NetWmStates states = netWmStates();
2261 // _NET_WM_STATE_HIDDEN should be set by the Window Manager to indicate that a window would
2262 // not be visible on the screen if its desktop/viewport were active and its coordinates were
2263 // within the screen bounds. The canonical example is that minimized windows should be in
2264 // the _NET_WM_STATE_HIDDEN state.
2265 if (m_minimized && (!connection()->wmSupport()->isSupportedByWM(NetWmStateHidden)
2266 || states.testFlag(NetWmStateHidden)))
2268
2273 // Send Window state, compress events in case other flags (modality, etc) are changed.
2278 if ((m_windowState & Qt::WindowMinimized) && connection()->mouseGrabber() == this)
2279 connection()->setMouseGrabber(nullptr);
2280 }
2281 return;
2282 } else if (event->atom == atom(QXcbAtom::Atom_NET_FRAME_EXTENTS)) {
2283 m_dirtyFrameMargins = true;
2284 }
2285}
2286
2287void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *event)
2288{
2289 // Ignore focus events that are being sent only because the pointer is over
2290 // our window, even if the input focus is in a different window.
2291 if (event->detail == XCB_NOTIFY_DETAIL_POINTER)
2292 return;
2293
2295 doFocusIn();
2296}
2297
2298
2299void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *event)
2300{
2301 // Ignore focus events that are being sent only because the pointer is over
2302 // our window, even if the input focus is in a different window.
2303 if (event->detail == XCB_NOTIFY_DETAIL_POINTER)
2304 return;
2305 doFocusOut();
2306}
2307
2309{
2311 // window manager does not expect a sync event yet.
2312 return;
2313 }
2314 if (connection()->hasXSync() && (m_syncValue.lo != 0 || m_syncValue.hi != 0)) {
2315 xcb_sync_set_counter(xcb_connection(), m_syncCounter, m_syncValue);
2316 xcb_flush(xcb_connection());
2317
2318 m_syncValue.lo = 0;
2319 m_syncValue.hi = 0;
2321 }
2322}
2323
2324const xcb_visualtype_t *QXcbWindow::createVisual()
2325{
2327 : nullptr;
2328}
2329
2331{
2332 if (grab && !connection()->canGrab())
2333 return false;
2334
2335 if (!grab) {
2336 xcb_ungrab_keyboard(xcb_connection(), XCB_TIME_CURRENT_TIME);
2337 return true;
2338 }
2339
2340 auto reply = Q_XCB_REPLY(xcb_grab_keyboard, xcb_connection(), false,
2341 m_window, XCB_TIME_CURRENT_TIME,
2342 XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
2343 return reply && reply->status == XCB_GRAB_STATUS_SUCCESS;
2344}
2345
2347{
2348 if (!grab && connection()->mouseGrabber() == this)
2349 connection()->setMouseGrabber(nullptr);
2350
2351 if (grab && !connection()->canGrab())
2352 return false;
2353
2354 if (connection()->hasXInput2()) {
2356 if (grab && result)
2357 connection()->setMouseGrabber(this);
2358 return result;
2359 }
2360
2361 if (!grab) {
2362 xcb_ungrab_pointer(xcb_connection(), XCB_TIME_CURRENT_TIME);
2363 return true;
2364 }
2365
2366 auto reply = Q_XCB_REPLY(xcb_grab_pointer, xcb_connection(),
2367 false, m_window,
2368 (XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE
2369 | XCB_EVENT_MASK_BUTTON_MOTION | XCB_EVENT_MASK_ENTER_WINDOW
2370 | XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_POINTER_MOTION),
2371 XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC,
2372 XCB_WINDOW_NONE, XCB_CURSOR_NONE,
2373 XCB_TIME_CURRENT_TIME);
2374 bool result = reply && reply->status == XCB_GRAB_STATUS_SUCCESS;
2375 if (result)
2376 connection()->setMouseGrabber(this);
2377 return result;
2378}
2379
2381{
2382 switch (event->type()) {
2383 case QEvent::FocusIn:
2384 if (m_embedded && !m_trayIconWindow && !event->spontaneous()) {
2385 QFocusEvent *focusEvent = static_cast<QFocusEvent *>(event);
2386 switch (focusEvent->reason()) {
2387 case Qt::TabFocusReason:
2389 {
2390 const QXcbWindow *container =
2391 static_cast<const QXcbWindow *>(QPlatformWindow::parent());
2392 sendXEmbedMessage(container->xcb_window(),
2393 focusEvent->reason() == Qt::TabFocusReason ?
2395 event->accept();
2396 }
2397 break;
2398 default:
2399 break;
2400 }
2401 }
2402 break;
2403 default:
2404 break;
2405 }
2407}
2408
2410{
2412}
2413
2418
2420{
2421 const xcb_atom_t moveResize = connection()->atom(QXcbAtom::Atom_NET_WM_MOVERESIZE);
2422 if (!connection()->wmSupport()->isSupportedByWM(moveResize))
2423 return false;
2424
2425 // ### FIXME QTBUG-53389
2426 bool startedByTouch = connection()->startSystemMoveResizeForTouch(m_window, edges);
2427 if (startedByTouch) {
2428 const QString wmname = connection()->windowManagerName();
2429 if (wmname != "kwin"_L1 && wmname != "openbox"_L1) {
2430 qCDebug(lcQpaXInputDevices) << "only KDE and OpenBox support startSystemMove/Resize which is triggered from touch events: XDG_CURRENT_DESKTOP="
2431 << qgetenv("XDG_CURRENT_DESKTOP");
2433 return false;
2434 }
2435 // KWin, Openbox, AwesomeWM and Gnome have been tested to work with _NET_WM_MOVERESIZE.
2436 } else { // Started by mouse press.
2438 }
2439
2440 return true;
2441}
2442
2444{
2445 if (edges == (Qt::TopEdge | Qt::LeftEdge))
2446 return 0;
2447 if (edges == Qt::TopEdge)
2448 return 1;
2449 if (edges == (Qt::TopEdge | Qt::RightEdge))
2450 return 2;
2451 if (edges == Qt::RightEdge)
2452 return 3;
2453 if (edges == (Qt::RightEdge | Qt::BottomEdge))
2454 return 4;
2455 if (edges == Qt::BottomEdge)
2456 return 5;
2457 if (edges == (Qt::BottomEdge | Qt::LeftEdge))
2458 return 6;
2459 if (edges == Qt::LeftEdge)
2460 return 7;
2461
2462 qWarning() << "Cannot convert " << edges << "to _NET_WM_MOVERESIZE direction.";
2463 return 0;
2464}
2465
2466void QXcbWindow::doStartSystemMoveResize(const QPoint &globalPos, int edges)
2467{
2468 qCDebug(lcQpaXInputDevices) << "triggered system move or resize via sending _NET_WM_MOVERESIZE client message";
2469 const xcb_atom_t moveResize = connection()->atom(QXcbAtom::Atom_NET_WM_MOVERESIZE);
2470 xcb_client_message_event_t xev;
2471 xev.response_type = XCB_CLIENT_MESSAGE;
2472 xev.type = moveResize;
2473 xev.sequence = 0;
2474 xev.window = xcb_window();
2475 xev.format = 32;
2476 xev.data.data32[0] = globalPos.x();
2477 xev.data.data32[1] = globalPos.y();
2478 if (edges == 16)
2479 xev.data.data32[2] = 8; // move
2480 else
2481 xev.data.data32[2] = qtEdgesToXcbMoveResizeDirection(Qt::Edges(edges));
2482 xev.data.data32[3] = XCB_BUTTON_INDEX_1;
2483 xev.data.data32[4] = 0;
2484 xcb_ungrab_pointer(connection()->xcb_connection(), XCB_CURRENT_TIME);
2485 xcb_send_event(connection()->xcb_connection(), false, xcbScreen()->root(),
2486 XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY,
2487 (const char *)&xev);
2488
2490}
2491
2492// Sends an XEmbed message.
2494 quint32 detail, quint32 data1, quint32 data2)
2495{
2496 xcb_client_message_event_t event;
2497
2498 event.response_type = XCB_CLIENT_MESSAGE;
2499 event.format = 32;
2500 event.sequence = 0;
2501 event.window = window;
2502 event.type = atom(QXcbAtom::Atom_XEMBED);
2503 event.data.data32[0] = connection()->time();
2504 event.data.data32[1] = message;
2505 event.data.data32[2] = detail;
2506 event.data.data32[3] = data1;
2507 event.data.data32[4] = data2;
2508 xcb_send_event(xcb_connection(), false, window, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);
2509}
2510
2512{
2513 /* Check from window system event queue if the next queued activation
2514 * targets a window other than @window.
2515 */
2519 return systemEvent && systemEvent->focused != window;
2520}
2521
2522void QXcbWindow::handleXEmbedMessage(const xcb_client_message_event_t *event)
2523{
2524 connection()->setTime(event->data.data32[0]);
2525 switch (event->data.data32[1]) {
2528 break;
2530 xcb_map_window(xcb_connection(), m_window);
2531 xcbScreen()->windowShown(this);
2532 break;
2533 case XEMBED_FOCUS_IN:
2535 Qt::FocusReason reason;
2536 switch (event->data.data32[2]) {
2537 case XEMBED_FOCUS_FIRST:
2538 reason = Qt::TabFocusReason;
2539 break;
2540 case XEMBED_FOCUS_LAST:
2541 reason = Qt::BacktabFocusReason;
2542 break;
2544 default:
2545 reason = Qt::OtherFocusReason;
2546 break;
2547 }
2550 break;
2551 case XEMBED_FOCUS_OUT:
2554 connection()->setFocusWindow(nullptr);
2556 }
2557 break;
2558 }
2559}
2560
2561static inline xcb_rectangle_t qRectToXCBRectangle(const QRect &r)
2562{
2563 xcb_rectangle_t result;
2564 result.x = qMax(SHRT_MIN, r.x());
2565 result.y = qMax(SHRT_MIN, r.y());
2566 result.width = qMin((int)USHRT_MAX, r.width());
2567 result.height = qMin((int)USHRT_MAX, r.height());
2568 return result;
2569}
2570
2572{
2573 if (!m_window)
2574 return;
2575
2576 quint32 value = qRound64(qBound(qreal(0), level, qreal(1)) * 0xffffffff);
2577
2578 xcb_change_property(xcb_connection(),
2579 XCB_PROP_MODE_REPLACE,
2580 m_window,
2582 XCB_ATOM_CARDINAL,
2583 32,
2584 1,
2585 (uchar *)&value);
2586}
2587
2588QList<xcb_rectangle_t> qRegionToXcbRectangleList(const QRegion &region)
2589{
2590 QList<xcb_rectangle_t> rects;
2591 rects.reserve(region.rectCount());
2592 for (const QRect &r : region)
2593 rects.push_back(qRectToXCBRectangle(r));
2594 return rects;
2595}
2596
2597void QXcbWindow::setMask(const QRegion &region)
2598{
2599 if (!connection()->hasXShape())
2600 return;
2601 if (region.isEmpty()) {
2602 xcb_shape_mask(connection()->xcb_connection(), XCB_SHAPE_SO_SET,
2603 XCB_SHAPE_SK_BOUNDING, xcb_window(), 0, 0, XCB_NONE);
2604 } else {
2605 const auto rects = qRegionToXcbRectangleList(region);
2606 xcb_shape_rectangles(connection()->xcb_connection(), XCB_SHAPE_SO_SET,
2607 XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED,
2608 xcb_window(), 0, 0, rects.size(), &rects[0]);
2609 }
2610}
2611
2621
2623{
2624 return m_visualId;
2625}
2626
2628{
2630}
2631
2640
2642{
2643 return static_cast<QXcbScreen *>(screen());
2644}
2645
2646void QXcbWindow::setWindowTitle(const QXcbConnection *conn, xcb_window_t window, const QString &title)
2647{
2648 QString fullTitle = formatWindowTitle(title, QString::fromUtf8(" \xe2\x80\x94 ")); // unicode character U+2014, EM DASH
2649 const QByteArray ba = std::move(fullTitle).toUtf8();
2650 xcb_change_property(conn->xcb_connection(),
2651 XCB_PROP_MODE_REPLACE,
2652 window,
2655 8,
2656 ba.size(),
2657 ba.constData());
2658
2659#if QT_CONFIG(xcb_xlib)
2660 Display *dpy = static_cast<Display *>(conn->xlib_display());
2661 XTextProperty *text = qstringToXTP(dpy, title);
2662 if (text)
2663 XSetWMName(dpy, window, text);
2664#endif
2665 xcb_flush(conn->xcb_connection());
2666}
2667
2669{
2670 const xcb_atom_t utf8Atom = conn->atom(QXcbAtom::AtomUTF8_STRING);
2671 auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, conn->xcb_connection(),
2672 false, window, conn->atom(QXcbAtom::Atom_NET_WM_NAME),
2673 utf8Atom, 0, 1024);
2674 if (reply && reply->format == 8 && reply->type == utf8Atom) {
2675 const char *name = reinterpret_cast<const char *>(xcb_get_property_value(reply.get()));
2676 return QString::fromUtf8(name, xcb_get_property_value_length(reply.get()));
2677 }
2678
2679 reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, conn->xcb_connection(),
2680 false, window, conn->atom(QXcbAtom::AtomWM_NAME),
2681 XCB_ATOM_STRING, 0, 1024);
2682 if (reply && reply->format == 8 && reply->type == XCB_ATOM_STRING) {
2683 const char *name = reinterpret_cast<const char *>(xcb_get_property_value(reply.get()));
2684 return QString::fromLatin1(name, xcb_get_property_value_length(reply.get()));
2685 }
2686
2687 return QString();
2688}
2689
2691
\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 QCoreApplication * instance() noexcept
Returns a pointer to the application's QCoreApplication (or QGuiApplication/QApplication) instance.
static void postEvent(QObject *receiver, QEvent *event, int priority=Qt::NormalEventPriority)
\inmodule QtCore
Definition qcoreevent.h:45
Type
This enum type defines the valid event types in Qt.
Definition qcoreevent.h:51
@ MouseMove
Definition qcoreevent.h:63
@ FocusIn
Definition qcoreevent.h:66
@ MouseButtonPress
Definition qcoreevent.h:60
@ MouseButtonRelease
Definition qcoreevent.h:61
The QFocusEvent class contains event parameters for widget focus events.
Definition qevent.h:470
Qt::FocusReason reason() const
Returns the reason for this focus event.
Definition qevent.cpp:1569
static QGuiApplicationPrivate * instance()
static QWindow * currentMouseWindow
static QWindow * modalWindow()
Returns the most recently shown modal window.
static QWindow * focusWindow()
Returns the QWindow that receives events tied to focus, such as key events.
QString desktopFileName
the base name of the desktop entry for this application
static qreal factor(C *context)
The QIcon class provides scalable icons in different modes and states.
Definition qicon.h:20
bool isNull() const
Returns true if the icon is empty; otherwise returns false.
Definition qicon.cpp:1019
QList< QSize > availableSizes(Mode mode=Normal, State state=Off) const
Definition qicon.cpp:1144
QPixmap pixmap(const QSize &size, Mode mode=Normal, State state=Off) const
Returns a pixmap with the requested size, mode, and state, generating one if necessary.
Definition qicon.cpp:834
\inmodule QtGui
Definition qimage.h:37
@ Format_RGB32
Definition qimage.h:46
@ Format_RGB16
Definition qimage.h:49
@ Format_ARGB32
Definition qimage.h:47
bool isEmpty() const noexcept
Definition qlist.h:401
void append(parameter_type t)
Definition qlist.h:458
void clear()
Definition qlist.h:434
\inmodule QtCore
Definition qmargins.h:24
\inmodule QtCore
const char * valueToKey(int value) const
Returns the string that is used as the name of the given enumeration value, or \nullptr if value is n...
\inmodule QtCore
Definition qmutex.h:313
void unlock() noexcept
Unlocks the mutex.
Definition qmutex.h:289
void lock() noexcept
Locks the mutex.
Definition qmutex.h:286
QObject * parent
Definition qobject.h:73
static QObjectPrivate * get(QObject *o)
Definition qobject_p.h:150
\inmodule QtCore
Definition qobject.h:103
const QObjectList & children() const
Returns a list of child objects.
Definition qobject.h:201
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:346
QList< QByteArray > dynamicPropertyNames() const
Definition qobject.cpp:4352
QVariant property(const char *name) const
Returns the value of the object's name property.
Definition qobject.cpp:4323
Returns a copy of the pixmap that is transformed using the given transformation transform and transfo...
Definition qpixmap.h:27
virtual QPoint pos() const
The QPlatformScreen class provides an abstraction for visual displays.
virtual QRect geometry() const =0
Reimplement in subclass to return the pixel geometry of the screen.
QScreen * screen() const
virtual QWindow * topLevelAt(const QPoint &point) const
Return the given top level window for a given position.
The QPlatformWindow class provides an abstraction for top-level windows.
static QString formatWindowTitle(const QString &title, const QString &separator)
Call this method to put together a window title composed of title separator the application display n...
virtual QPoint mapFromGlobal(const QPoint &pos) const
Translates the global screen coordinate pos to window coordinates using native methods.
QWindow * window() const
Returns the window which belongs to the QPlatformWindow.
QPlatformScreen * screenForGeometry(const QRect &newGeometry) const
Helper function for finding the new screen for newGeometry in response to a geometry changed event.
QPlatformScreen * screen() const override
Returns the platform screen handle corresponding to this platform window, or null if the window is no...
QSize windowMinimumSize() const
Returns the QWindow minimum size.
virtual bool windowEvent(QEvent *event)
Reimplement this method to be able to do any platform specific event handling.
QPlatformWindow * parent() const
Returns the parent platform window (or \nullptr if orphan).
virtual void setGeometry(const QRect &rect)
This function is called by Qt whenever a window is moved or resized using the QWindow API.
virtual void requestActivateWindow()
Reimplement to let Qt be able to request activation/focus for a window.
virtual QRect geometry() const
Returns the current geometry of a window.
virtual WId winId() const
Reimplement in subclasses to return a handle to the native window.
virtual bool isAncestorOf(const QPlatformWindow *child) const
Returns true if the window is an ancestor of the given child.
virtual QPoint mapToGlobal(const QPoint &pos) const
Translates the window coordinate pos to global screen coordinates using native methods.
virtual bool isForeignWindow() const
QSize windowBaseSize() const
Returns the QWindow base size.
QSize windowMaximumSize() const
Returns the QWindow maximum size.
QSize windowSizeIncrement() const
Returns the QWindow size increment.
\inmodule QtCore\reentrant
Definition qpoint.h:25
constexpr QPoint transposed() const noexcept
Definition qpoint.h:39
constexpr int x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:130
constexpr void setY(int y) noexcept
Sets the y coordinate of this point to the given y coordinate.
Definition qpoint.h:145
constexpr int y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:135
constexpr void setX(int x) noexcept
Sets the x coordinate of this point to the given x coordinate.
Definition qpoint.h:140
\inmodule QtCore\reentrant
Definition qrect.h:30
bool contains(const QRect &r, bool proper=false) const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qrect.cpp:855
The QRegion class specifies a clip region for a painter.
Definition qregion.h:27
int rectCount() const noexcept
bool isEmpty() const
Returns true if the region is empty; otherwise returns false.
The QScreen class is used to query screen properties. \inmodule QtGui.
Definition qscreen.h:32
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:133
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:130
constexpr bool isNull() const noexcept
Returns true if both the width and height is 0; otherwise returns false.
Definition qsize.h:121
constexpr bool isEmpty() const noexcept
Returns true if either of the width and height is less than or equal to 0; otherwise returns false.
Definition qsize.h:124
constexpr bool isValid() const noexcept
Returns true if both the width and height is equal to or greater than 0; otherwise returns false.
Definition qsize.h:127
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QByteArray toLatin1() const &
Definition qstring.h:630
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5871
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6018
QString & append(QChar c)
Definition qstring.cpp:3252
QByteArray toUtf8() const &
Definition qstring.h:634
QString & prepend(QChar c)
Definition qstring.h:478
The QSurfaceFormat class represents the format of a QSurface. \inmodule QtGui.
@ OpenGLSurface
Definition qsurface.h:32
@ VulkanSurface
Definition qsurface.h:35
static QString machineHostName()
Definition qsysinfo.cpp:929
void start(int msec)
Starts or restarts the timer with a timeout interval of msec milliseconds.
Definition qtimer.cpp:241
void stop()
Stops the timer.
Definition qtimer.cpp:267
QByteArray toByteArray() const
Returns the variant as a QByteArray if the variant has userType() \l QMetaType::QByteArray or \l QMet...
QRect geometry
the geometry of the widget relative to its parent and excluding the window frame
Definition qwidget.h:106
static WindowSystemEvent * peekWindowSystemEvent(EventType t)
static bool handleNativeEvent(QWindow *window, const QByteArray &eventType, void *message, qintptr *result)
Passes a native event identified by eventType to the window.
static void handleWindowScreenChanged(QWindow *window, QScreen *newScreen)
static void handleLeaveEvent(QWindow *window)
static void handleFocusWindowChanged(QWindow *window, Qt::FocusReason r=Qt::OtherFocusReason)
static bool handleMouseEvent(QWindow *window, const QPointF &local, const QPointF &global, Qt::MouseButtons state, Qt::MouseButton button, QEvent::Type type, Qt::KeyboardModifiers mods=Qt::NoModifier, Qt::MouseEventSource source=Qt::MouseEventNotSynthesized)
static bool handleCloseEvent(QWindow *window)
static void handleGeometryChange(QWindow *window, const QRect &newRect)
static void handleEnterLeaveEvent(QWindow *enter, QWindow *leave, const QPointF &local=QPointF(), const QPointF &global=QPointF())
This method can be used to ensure leave and enter events are both in queue when moving from one QWind...
static bool handleExposeEvent(QWindow *window, const QRegion &region)
static void handleEnterEvent(QWindow *window, const QPointF &local=QPointF(), const QPointF &global=QPointF())
static bool handleWheelEvent(QWindow *window, const QPointF &local, const QPointF &global, QPoint pixelDelta, QPoint angleDelta, Qt::KeyboardModifiers mods=Qt::NoModifier, Qt::ScrollPhase phase=Qt::NoScrollPhase, Qt::MouseEventSource source=Qt::MouseEventNotSynthesized)
static void handleWindowStateChanged(QWindow *window, Qt::WindowStates newState, int oldState=-1)
\inmodule QtGui
Definition qwindow.h:63
Qt::WindowFlags flags
the window flags of the window
Definition qwindow.h:79
@ AtomXdndDrop
Definition qxcbatom.h:141
@ Atom_NET_WM_STATE_MAXIMIZED_HORZ
Definition qxcbatom.h:87
@ Atom_NET_WM_WINDOW_TYPE_DROPDOWN_MENU
Definition qxcbatom.h:106
@ Atom_NET_WM_WINDOW_TYPE_COMBO
Definition qxcbatom.h:110
@ Atom_NET_WM_PID
Definition qxcbatom.h:79
@ Atom_COMPIZ_DECOR_DELETE_PIXMAP
Definition qxcbatom.h:201
@ AtomWM_PROTOCOLS
Definition qxcbatom.h:13
@ Atom_NET_WM_WINDOW_TYPE_MENU
Definition qxcbatom.h:102
@ Atom_MOTIF_WM_HINTS
Definition qxcbatom.h:60
@ Atom_XEMBED_INFO
Definition qxcbatom.h:162
@ Atom_KDE_NET_WM_DESKTOP_FILE
Definition qxcbatom.h:115
@ Atom_NET_WM_MOVERESIZE
Definition qxcbatom.h:73
@ AtomWM_NAME
Definition qxcbatom.h:27
@ Atom_NET_WM_WINDOW_TYPE
Definition qxcbatom.h:98
@ Atom_COMPIZ_DECOR_PENDING
Definition qxcbatom.h:199
@ Atom_NET_WM_WINDOW_TYPE_DOCK
Definition qxcbatom.h:100
@ Atom_NET_WM_PING
Definition qxcbatom.h:16
@ AtomXdndLeave
Definition qxcbatom.h:140
@ Atom_GTK_LOAD_ICONTHEMES
Definition qxcbatom.h:204
@ Atom_NET_WM_WINDOW_TYPE_POPUP_MENU
Definition qxcbatom.h:107
@ Atom_XEMBED
Definition qxcbatom.h:161
@ AtomWM_CLIENT_MACHINE
Definition qxcbatom.h:33
@ Atom_NET_WM_STATE_HIDDEN
Definition qxcbatom.h:92
@ Atom_GTK_APPLICATION_ID
Definition qxcbatom.h:203
@ AtomWM_CHANGE_STATE
Definition qxcbatom.h:25
@ AtomXdndEnter
Definition qxcbatom.h:137
@ Atom_NET_WM_WINDOW_TYPE_UTILITY
Definition qxcbatom.h:103
@ Atom_NET_WM_WINDOW_TYPE_DND
Definition qxcbatom.h:111
@ Atom_NET_WM_STATE_BELOW
Definition qxcbatom.h:85
@ Atom_NET_WM_WINDOW_TYPE_DIALOG
Definition qxcbatom.h:105
@ AtomWM_CLIENT_LEADER
Definition qxcbatom.h:30
@ Atom_NET_WM_STATE_MAXIMIZED_VERT
Definition qxcbatom.h:88
@ Atom_KDE_NET_WM_WINDOW_TYPE_OVERRIDE
Definition qxcbatom.h:113
@ Atom_NET_WM_STATE
Definition qxcbatom.h:83
@ Atom_NET_FRAME_EXTENTS
Definition qxcbatom.h:117
@ Atom_NET_WM_SYNC_REQUEST
Definition qxcbatom.h:18
@ Atom_NET_WM_STATE_MODAL
Definition qxcbatom.h:89
@ AtomMANAGER
Definition qxcbatom.h:20
@ Atom_NET_WM_ICON
Definition qxcbatom.h:77
@ Atom_NET_WM_SYNC_REQUEST_COUNTER
Definition qxcbatom.h:19
@ Atom_NET_WM_WINDOW_OPACITY
Definition qxcbatom.h:81
@ Atom_NET_WM_STATE_STAYS_ON_TOP
Definition qxcbatom.h:90
@ AtomWM_WINDOW_ROLE
Definition qxcbatom.h:31
@ Atom_NET_WM_WINDOW_TYPE_TOOLBAR
Definition qxcbatom.h:101
@ Atom_NET_WM_STATE_ABOVE
Definition qxcbatom.h:84
@ AtomUTF8_STRING
Definition qxcbatom.h:133
@ Atom_NET_WM_ICON_NAME
Definition qxcbatom.h:76
@ Atom_COMPIZ_DECOR_REQUEST
Definition qxcbatom.h:200
@ AtomWM_DELETE_WINDOW
Definition qxcbatom.h:14
@ Atom_NET_WM_WINDOW_TYPE_TOOLTIP
Definition qxcbatom.h:108
@ Atom_NET_WM_WINDOW_TYPE_SPLASH
Definition qxcbatom.h:104
@ Atom_NET_WM_STATE_FULLSCREEN
Definition qxcbatom.h:86
@ Atom_NET_WM_STATE_DEMANDS_ATTENTION
Definition qxcbatom.h:91
@ AtomWM_CLASS
Definition qxcbatom.h:26
@ Atom_NET_WM_WINDOW_TYPE_NORMAL
Definition qxcbatom.h:112
@ Atom_NET_WM_NAME
Definition qxcbatom.h:75
@ Atom_NET_WM_CONTEXT_HELP
Definition qxcbatom.h:17
@ AtomCARDINAL
Definition qxcbatom.h:134
@ AtomXdndPosition
Definition qxcbatom.h:138
@ AtomWM_STATE
Definition qxcbatom.h:24
@ Atom_NET_WM_USER_TIME
Definition qxcbatom.h:94
@ AtomWM_TAKE_FOCUS
Definition qxcbatom.h:15
@ Atom_NET_WM_USER_TIME_WINDOW
Definition qxcbatom.h:95
@ Atom_NET_ACTIVE_WINDOW
Definition qxcbatom.h:129
@ Atom_COMPIZ_TOOLKIT_ACTION
Definition qxcbatom.h:202
@ Atom_NET_WM_WINDOW_TYPE_DESKTOP
Definition qxcbatom.h:99
@ Atom_NET_WM_WINDOW_TYPE_NOTIFICATION
Definition qxcbatom.h:109
QXcbAtom::Atom qatom(xcb_atom_t atom) const
QByteArray atomName(xcb_atom_t atom)
xcb_connection_t * xcb_connection() const
xcb_atom_t atom(QXcbAtom::Atom qatom) const
void setMousePressWindow(QXcbWindow *)
Qt::MouseButton translateMouseButton(xcb_button_t s)
QXcbKeyboard * keyboard() const
QTimer & focusInTimer()
QXcbWindow * mouseGrabber() const
QXcbWindow * mousePressWindow() const
Qt::MouseButtons buttonState() const
void setMouseGrabber(QXcbWindow *)
void setTime(xcb_timestamp_t t)
void setButtonState(Qt::MouseButton button, bool down)
QString windowManagerName() const
xcb_visualid_t defaultVisualId() const
bool isTouchScreen(int id)
void setNetWmUserTime(xcb_timestamp_t t)
xcb_timestamp_t time() const
bool startSystemMoveResizeForTouch(xcb_window_t window, int edges)
QXcbWMSupport * wmSupport() const
void setFocusWindow(QWindow *)
void abortSystemMoveResize(xcb_window_t window)
QXcbEventQueue * eventQueue() const
xcb_window_t clientLeader()
void setDuringSystemMoveResize(bool during)
void xi2SelectDeviceEvents(xcb_window_t window)
Qt::MouseButton xiToQtMouseButton(uint32_t b)
Qt::MouseButton button() const
QXcbNativeInterface * nativeInterface() const
QXcbWindow * platformWindowFromId(xcb_window_t id)
bool xi2SetMouseGrabEnabled(xcb_window_t w, bool grab)
void addWindowEventListener(xcb_window_t id, QXcbWindowEventListener *eventListener)
QXcbSystemTrayTracker * systemTrayTracker() const
void removeWindowEventListener(xcb_window_t id)
xcb_generic_event_t * peek(Peeker &&peeker)
QXcbForeignWindow(QWindow *window, WId nativeHandle)
static QXcbIntegration * instance()
Qt::KeyboardModifiers translateModifiers(int s) const
void updateXKBStateFromXI(void *modInfo, void *groupInfo)
const QByteArray & nativeEventType() const
QXcbConnection * connection() const
Definition qxcbobject.h:17
xcb_connection_t * xcb_connection() const
Definition qxcbobject.h:20
xcb_atom_t atom(QXcbAtom::Atom atom) const
Definition qxcbobject.h:19
void setConnection(QXcbConnection *connection)
Definition qxcbobject.h:16
const xcb_visualtype_t * visualForFormat(const QSurfaceFormat &format) const
Definition qxcbscreen.h:173
QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &format) const
xcb_screen_t * screen() const
Definition qxcbscreen.h:152
xcb_window_t root() const
Definition qxcbscreen.h:153
quint8 depthOfVisual(xcb_visualid_t visualid) const
Definition qxcbscreen.h:176
const xcb_visualtype_t * visualForId(xcb_visualid_t visualid) const
QList< QPlatformScreen * > virtualSiblings() const override
Returns a list of all the platform screens that are part of the same virtual desktop.
Definition qxcbscreen.h:143
QPlatformCursor * cursor() const override
Reimplement this function in subclass to return the cursor of the screen.
void windowShown(QXcbWindow *window)
xcb_colormap_t colormapForVisual(xcb_visualid_t visualid) const
Definition qxcbscreen.h:175
void requestSystemTrayWindowDock(xcb_window_t window) const
const QList< xcb_window_t > & virtualRoots() const
bool isSupportedByWM(xcb_atom_t atom) const
xcb_window_t xcb_window() const
Definition qxcbwindow.h:94
@ NetWmStateMaximizedHorz
Definition qxcbwindow.h:34
@ NetWmStateModal
Definition qxcbwindow.h:36
@ NetWmStateHidden
Definition qxcbwindow.h:39
@ NetWmStateStaysOnTop
Definition qxcbwindow.h:37
@ NetWmStateBelow
Definition qxcbwindow.h:32
@ NetWmStateFullScreen
Definition qxcbwindow.h:33
@ NetWmStateAbove
Definition qxcbwindow.h:31
@ NetWmStateMaximizedVert
Definition qxcbwindow.h:35
@ NetWmStateDemandsAttention
Definition qxcbwindow.h:38
QXcbWindow * toWindow() override
xcb_window_t m_window
Definition qxcbwindow.h:214
Qt::WindowStates m_windowState
Definition qxcbwindow.h:223
bool m_minimized
Definition qxcbwindow.h:231
void handleEnterNotifyEvent(const xcb_enter_notify_event_t *event) override
void handleClientMessageEvent(const xcb_client_message_event_t *event) override
void setMask(const QRegion &region) override
Reimplement to be able to let Qt set the mask of a window.
void updateSyncRequestCounter()
void updateWmTransientFor()
QSurfaceFormat format() const override
Returns the actual surface format of the window.
bool m_imageRgbSwap
Definition qxcbwindow.h:218
QXcbScreen * initialScreen() const
void setOpacity(qreal level) override
Reimplement to be able to let Qt set the opacity level of a window.
WindowTypes wmWindowTypes() const
bool requestSystemTrayWindowDock()
virtual const xcb_visualtype_t * createVisual()
void setTransparentForMouseEvents(bool transparent)
virtual void destroy()
void lower() override
Reimplement to be able to let Qt lower windows to the bottom of the desktop.
void setGeometry(const QRect &rect) override
This function is called by Qt whenever a window is moved or resized using the QWindow API.
bool m_dirtyFrameMargins
Definition qxcbwindow.h:238
QMargins m_frameMargins
Definition qxcbwindow.h:239
QRegion m_exposeRegion
Definition qxcbwindow.h:241
bool startSystemResize(Qt::Edges edges) override
Reimplement this method to start a system resize operation if the system supports it and return true ...
void setWmWindowType(WindowTypes types, Qt::WindowFlags flags)
@ SyncAndConfigureReceived
Definition qxcbwindow.h:253
bool setKeyboardGrabEnabled(bool grab) override
void handleButtonReleaseEvent(const xcb_button_release_event_t *event) override
bool handleNativeEvent(xcb_generic_event_t *event) override
void handleExposeEvent(const xcb_expose_event_t *event) override
void handleXIEnterLeave(xcb_ge_event_t *) override
QSurfaceFormat m_format
Definition qxcbwindow.h:236
xcb_sync_int64_t m_syncValue
Definition qxcbwindow.h:220
void setAlertState(bool enabled) override
Reimplement this method to set whether the window demands attention (for example, by flashing the tas...
void setParent(const QPlatformWindow *window) override
This function is called to enable native child window in QPA.
QXcbScreen * xcbScreen() const
bool m_deferredActivation
Definition qxcbwindow.h:228
void handleXEmbedMessage(const xcb_client_message_event_t *event)
QList< QPointer< QXcbWindow > > m_wmTransientForChildren
Definition qxcbwindow.h:264
uint visualId() const override
void propagateSizeHints() override
Reimplement to propagate the size hints of the QWindow.
void setWindowState(Qt::WindowStates state) override
Requests setting the window state of this surface to type.
void updateNetWmUserTime(xcb_timestamp_t timestamp)
QXcbWindow(QWindow *window)
void setNetWmState(bool set, xcb_atom_t one, xcb_atom_t two=0)
QPoint m_lastPointerPosition
Definition qxcbwindow.h:243
void doFocusIn()
void handleMapNotifyEvent(const xcb_map_notify_event_t *event) override
QPoint m_lastPointerGlobalPosition
Definition qxcbwindow.h:244
void setMotifWmHints(Qt::WindowFlags flags)
void setWindowIconText(const QString &title) override
bool m_trayIconWindow
Definition qxcbwindow.h:232
void setImageFormatForVisual(const xcb_visualtype_t *visual)
void sendXEmbedMessage(xcb_window_t window, quint32 message, quint32 detail=0, quint32 data1=0, quint32 data2=0)
static bool isTrayIconWindow(QWindow *window)
Definition qxcbwindow.h:149
void setWindowIcon(const QIcon &icon) override
Reimplement to set the window icon to icon.
void handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event) override
bool relayFocusToModalWindow() const
void setWindowRole(const QString &role) override
void registerWmTransientForChild(QXcbWindow *)
void postSyncWindowRequest()
QMargins frameMargins() const override
void doFocusOut()
xcb_visualid_t m_visualId
Definition qxcbwindow.h:246
SyncState m_syncState
Definition qxcbwindow.h:255
void handleMotionNotifyEvent(const xcb_motion_notify_event_t *event) override
bool m_alertState
Definition qxcbwindow.h:230
qreal m_sizeHintsScaleFactor
Definition qxcbwindow.h:260
void setVisible(bool visible) override
Reimplemented in subclasses to show the surface if visible is true, and hide it if visible is false.
void requestActivateWindow() override
Reimplement to let Qt be able to request activation/focus for a window.
void updateDoesNotAcceptFocus(bool doesNotAcceptFocus)
xcb_sync_counter_t m_syncCounter
Definition qxcbwindow.h:221
bool m_transparent
Definition qxcbwindow.h:227
bool isExposed() const override
Returns if this window is exposed in the windowing system.
bool m_embedded
Definition qxcbwindow.h:229
bool m_ignorePressedWindowOnMouseLeave
Definition qxcbwindow.h:233
void setWindowTitle(const QString &title) override
Reimplement to set the window title to title.
NetWmStates netWmStates()
QSize m_oldWindowSize
Definition qxcbwindow.h:242
bool needsSync() const
void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event) override
bool windowEvent(QEvent *event) override
Reimplement this method to be able to do any platform specific event handling.
void handleXIMouseEvent(xcb_ge_event_t *, Qt::MouseEventSource source=Qt::MouseEventNotSynthesized) override
bool isEmbedded() const override
Returns true if the window is a child of a non-Qt window.
QPoint mapFromGlobal(const QPoint &pos) const override
Translates the global screen coordinate pos to window coordinates using native methods.
void setWindowFlags(Qt::WindowFlags flags) override
Requests setting the window flags of this surface to flags.
static QString windowTitle(const QXcbConnection *conn, xcb_window_t window)
QXcbSyncWindowRequest * m_pendingSyncRequest
Definition qxcbwindow.h:257
void raise() override
Reimplement to be able to let Qt raise windows to the top of the desktop.
QImage::Format m_imageFormat
Definition qxcbwindow.h:217
void handleConfigureNotifyEvent(const xcb_configure_notify_event_t *event) override
void handleButtonPressEvent(const xcb_button_press_event_t *event) override
Qt::WindowStates m_lastWindowStateEvent
Definition qxcbwindow.h:248
void handleFocusOutEvent(const xcb_focus_out_event_t *event) override
RecreationReasons m_recreationReasons
Definition qxcbwindow.h:262
QPoint mapToGlobal(const QPoint &pos) const override
Translates the window coordinate pos to global screen coordinates using native methods.
WId winId() const override
Reimplement in subclasses to return a handle to the native window.
virtual void resolveFormat(const QSurfaceFormat &format)
Definition qxcbwindow.h:167
bool startSystemMoveResize(const QPoint &pos, int edges)
virtual void create()
void handleFocusInEvent(const xcb_focus_in_event_t *event) override
@ WindowStaysOnBottomHintChanged
Definition qxcbwindow.h:47
@ RecreationNotNeeded
Definition qxcbwindow.h:45
@ WindowStaysOnTopHintChanged
Definition qxcbwindow.h:46
void handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers, QEvent::Type type, Qt::MouseEventSource source)
bool setMouseGrabEnabled(bool grab) override
void handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event) override
bool startSystemMove() override
Reimplement this method to start a system move operation if the system supports it and return true to...
void doStartSystemMoveResize(const QPoint &globalPos, int edges)
void setParentRelativeBackPixmap()
bool m_mapped
Definition qxcbwindow.h:226
xcb_window_t m_netWmUserTimeWindow
Definition qxcbwindow.h:234
QMutex m_mappedMutex
Definition qxcbwindow.h:225
QXcbScreen * parentScreen()
void setNetWmStateOnUnmappedWindow()
EGLImageKHR int int EGLuint64KHR * modifiers
QString text
QPushButton * button
[2]
rect
[4]
else opt state
[0]
void newState(QList< State > &states, const char *token, const char *lexem, bool pre)
T toNativePixels(const T &value, const C *context)
T toNativeLocalPosition(const T &value, const C *context)
T fromNativePixels(const T &value, const C *context)
QRegion toNativeLocalRegion(const QRegion &pointRegion, const QWindow *window)
Combined button and popup list for selecting options.
QFuture< QtPrivate::MapResultType< Sequence, MapFunctor > > mapped(QThreadPool *pool, Sequence &&sequence, MapFunctor &&map)
@ WindowFullScreen
Definition qnamespace.h:255
@ WindowNoState
Definition qnamespace.h:252
@ WindowMinimized
Definition qnamespace.h:253
@ WindowMaximized
Definition qnamespace.h:254
MouseButton
Definition qnamespace.h:56
@ NoButton
Definition qnamespace.h:57
@ NonModal
MouseEventSource
@ AltModifier
@ RightEdge
@ TopEdge
@ BottomEdge
@ LeftEdge
@ SkipEmptyParts
Definition qnamespace.h:128
WindowType
Definition qnamespace.h:205
@ CustomizeWindowHint
Definition qnamespace.h:239
@ BypassWindowManagerHint
Definition qnamespace.h:223
@ Desktop
Definition qnamespace.h:215
@ FramelessWindowHint
Definition qnamespace.h:225
@ WindowDoesNotAcceptFocus
Definition qnamespace.h:236
@ WindowContextHelpButtonHint
Definition qnamespace.h:231
@ WindowStaysOnBottomHint
Definition qnamespace.h:240
@ ToolTip
Definition qnamespace.h:213
@ Drawer
Definition qnamespace.h:210
@ Popup
Definition qnamespace.h:211
@ WindowType_Mask
Definition qnamespace.h:220
@ Window
Definition qnamespace.h:207
@ SplashScreen
Definition qnamespace.h:214
@ WindowStaysOnTopHint
Definition qnamespace.h:233
@ WindowMaximizeButtonHint
Definition qnamespace.h:229
@ WindowMinimizeButtonHint
Definition qnamespace.h:228
@ Dialog
Definition qnamespace.h:208
@ WindowMinMaxButtonsHint
Definition qnamespace.h:230
@ Sheet
Definition qnamespace.h:209
@ WindowTransparentForInput
Definition qnamespace.h:234
@ Tool
Definition qnamespace.h:212
@ WindowTitleHint
Definition qnamespace.h:226
@ X11BypassWindowManagerHint
Definition qnamespace.h:224
@ WindowSystemMenuHint
Definition qnamespace.h:227
@ WindowCloseButtonHint
Definition qnamespace.h:241
FocusReason
@ BacktabFocusReason
@ OtherFocusReason
@ ActiveWindowFocusReason
@ TabFocusReason
Definition image.cpp:4
@ defaultWindowHeight
@ defaultWindowWidth
#define Q_UNLIKELY(x)
#define Q_FUNC_INFO
static const QCssKnownValue properties[NumProperties - 1]
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage return DBusPendingCall * pending
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
Definition qfloat16.h:333
qint64 qRound64(qfloat16 d) noexcept
Definition qfloat16.h:330
#define qWarning
Definition qlogging.h:166
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
return ret
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qBound(const T &min, const T &val, const T &max)
Definition qminmax.h:44
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
static bool contains(const QJsonArray &haystack, unsigned needle)
Definition qopengl.cpp:116
GLenum GLsizei GLsizei GLint * values
[15]
GLuint64 GLenum void * handle
GLenum mode
GLenum GLuint GLint level
GLfloat GLfloat GLfloat w
[0]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLboolean r
[2]
GLsizei GLenum GLenum * types
GLdouble GLdouble GLdouble GLdouble top
GLdouble GLdouble right
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLint left
GLenum type
GLint GLint bottom
GLbitfield flags
GLuint GLsizei const GLchar * message
GLenum GLuint GLintptr offset
GLuint name
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLsizei GLsizei GLchar * source
struct _cl_event * event
GLhandleARB obj
[2]
GLdouble s
[6]
Definition qopenglext.h:235
GLuint GLfloat * val
GLuint64EXT * result
[6]
GLfloat GLfloat p
[1]
GLuint * states
#define QWINDOWSIZE_MAX
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define QStringLiteral(str)
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
struct _XDisplay Display
@ Q_PRIMITIVE_TYPE
Definition qtypeinfo.h:157
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
Definition qtypeinfo.h:180
unsigned int quint32
Definition qtypes.h:50
unsigned char uchar
Definition qtypes.h:32
int qint32
Definition qtypes.h:49
unsigned long long quint64
Definition qtypes.h:61
unsigned int uint
Definition qtypes.h:34
double qreal
Definition qtypes.h:187
unsigned char quint8
Definition qtypes.h:46
ptrdiff_t qintptr
Definition qtypes.h:166
Q_GUI_EXPORT QWindowPrivate * qt_window_private(QWindow *window)
Definition qwindow.cpp:2950
#define enabled
static Qt::MouseButtons queryMouseButtons()
const char property[13]
Definition qwizard.cpp:101
#define Q_XCB_REPLY(call,...)
#define Q_XCB_REPLY_UNCHECKED(call,...)
QT_BEGIN_NAMESPACE bool qt_xcb_imageFormatForVisual(QXcbConnection *connection, uint8_t depth, const xcb_visualtype_t *visual, QImage::Format *imageFormat, bool *needsRgbSwap)
Definition qxcbimage.cpp:68
static bool fromSendEvent(const void *event)
static QXcbSystemTrayTracker * systemTrayTracker(const QScreen *s)
static uint qtEdgesToXcbMoveResizeDirection(Qt::Edges edges)
#define XCOORD_MAX
static bool doCheckUnGrabAncestor(QXcbConnection *conn)
static const char * wm_window_type_property_id
static bool isTransient(const QWindow *w)
#define qt_xcb_mask_is_set(ptr, event)
static bool ignoreEnterEvent(quint8 mode, quint8 detail, QXcbConnection *conn=nullptr)
static const char * wm_window_role_property_id
@ baseEventMask
@ transparentForInputEventMask
@ defaultEventMask
QList< xcb_rectangle_t > qRegionToXcbRectangleList(const QRegion &region)
static bool focusWindowChangeQueued(const QWindow *window)
static xcb_rectangle_t qRectToXCBRectangle(const QRect &r)
const quint32 XEMBED_VERSION
@ MWM_HINTS_DECORATIONS
@ MWM_FUNC_MINIMIZE
@ MWM_FUNC_ALL
@ MWM_FUNC_MAXIMIZE
@ MWM_DECOR_MINIMIZE
@ MWM_DECOR_MAXIMIZE
@ MWM_HINTS_FUNCTIONS
@ MWM_DECOR_MENU
@ MWM_DECOR_BORDER
@ MWM_DECOR_ALL
@ MWM_FUNC_RESIZE
@ MWM_FUNC_MOVE
@ MWM_FUNC_CLOSE
@ MWM_DECOR_TITLE
@ MWM_DECOR_RESIZEH
QX11EmbedInfoFlags
@ XEMBED_MAPPED
static int fixed1616ToInt(xcb_input_fp1616_t val)
static bool ignoreLeaveEvent(quint8 mode, quint8 detail, QXcbConnection *conn)
QX11EmbedMessageType
@ XEMBED_REQUEST_FOCUS
@ XEMBED_UNREGISTER_ACCELERATOR
@ XEMBED_WINDOW_DEACTIVATE
@ XEMBED_FOCUS_OUT
@ XEMBED_REGISTER_ACCELERATOR
@ XEMBED_MODALITY_OFF
@ XEMBED_FOCUS_IN
@ XEMBED_MODALITY_ON
@ XEMBED_WINDOW_ACTIVATE
@ XEMBED_FOCUS_NEXT
@ XEMBED_FOCUS_PREV
@ XEMBED_EMBEDDED_NOTIFY
@ XEMBED_ACTIVATE_ACCELERATOR
@ defaultWindowHeight
@ defaultWindowWidth
QX11EmbedFocusInDetail
@ XEMBED_FOCUS_CURRENT
@ XEMBED_FOCUS_FIRST
@ XEMBED_FOCUS_LAST
static QWindow * childWindowAt(QWindow *win, const QPoint &p)
QList< xcb_rectangle_t > qRegionToXcbRectangleList(const QRegion &region)
QWidget * win
Definition settings.cpp:6
QFuture< QSet< QChar > > set
[10]
QByteArray ba
[0]
std::array< QModelRoleData, 3 > roleData
[13]
obj metaObject() -> className()
QString title
[35]
QLayoutItem * child
[0]
widget render & pixmap
aWidget window() -> setWindowTitle("New Window Title")
[2]
QNetworkReply * reply
QJSValue global
\inmodule QtCore \reentrant
Definition qchar.h:18
bool contains(const AT &t) const noexcept
Definition qlist.h:45
\inmodule QtCore
quint32 decorations