summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb/qxcbwindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbwindow.cpp')
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp161
1 files changed, 58 insertions, 103 deletions
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index affc2a0dd6..475a4e37f3 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -51,6 +51,7 @@
#include "qxcbscreen.h"
#include "qxcbdrag.h"
#include "qxcbkeyboard.h"
+#include "qxcbimage.h"
#include "qxcbwmsupport.h"
#include "qxcbimage.h"
#include "qxcbnativeinterface.h"
@@ -176,80 +177,23 @@ static inline bool isTransient(const QWindow *w)
|| w->type() == Qt::Popup;
}
-static inline QImage::Format imageFormatForVisual(int depth, quint32 red_mask, quint32 blue_mask, bool *rgbSwap)
+void QXcbWindow::setImageFormatForVisual(const xcb_visualtype_t *visual)
{
- if (rgbSwap)
- *rgbSwap = false;
- switch (depth) {
- case 32:
- if (blue_mask == 0xff)
- return QImage::Format_ARGB32_Premultiplied;
- if (red_mask == 0x3ff)
- return QImage::Format_A2BGR30_Premultiplied;
- if (blue_mask == 0x3ff)
- return QImage::Format_A2RGB30_Premultiplied;
- if (red_mask == 0xff) {
- if (rgbSwap)
- *rgbSwap = true;
- return QImage::Format_ARGB32_Premultiplied;
- }
- break;
- case 30:
- if (red_mask == 0x3ff)
- return QImage::Format_BGR30;
- if (blue_mask == 0x3ff)
- return QImage::Format_RGB30;
- break;
- case 24:
- if (blue_mask == 0xff)
- return QImage::Format_RGB32;
- if (red_mask == 0xff) {
- if (rgbSwap)
- *rgbSwap = true;
- return QImage::Format_RGB32;
- }
- break;
- case 16:
- if (blue_mask == 0x1f)
- return QImage::Format_RGB16;
- if (red_mask == 0x1f) {
- if (rgbSwap)
- *rgbSwap = true;
- return QImage::Format_RGB16;
- }
- break;
- case 15:
- if (blue_mask == 0x1f)
- return QImage::Format_RGB555;
- if (red_mask == 0x1f) {
- if (rgbSwap)
- *rgbSwap = true;
- return QImage::Format_RGB555;
- }
- break;
-#if QT_CONFIG(xcb_native_painting)
- case 8:
- if (QXcbIntegration::instance() && QXcbIntegration::instance()->nativePaintingEnabled())
- return QImage::Format_Indexed8;
- break;
-#endif
- default:
- break;
- }
- qWarning("Unsupported screen format: depth: %d, red_mask: %x, blue_mask: %x", depth, red_mask, blue_mask);
+ if (qt_xcb_imageFormatForVisual(connection(), m_depth, visual, &m_imageFormat, &m_imageRgbSwap))
+ return;
- switch (depth) {
+ switch (m_depth) {
+ case 32:
case 24:
qWarning("Using RGB32 fallback, if this works your X11 server is reporting a bad screen format.");
- return QImage::Format_RGB32;
+ m_imageFormat = QImage::Format_RGB32;
+ break;
case 16:
qWarning("Using RGB16 fallback, if this works your X11 server is reporting a bad screen format.");
- return QImage::Format_RGB16;
+ m_imageFormat = QImage::Format_RGB16;
default:
break;
}
-
- return QImage::Format_Invalid;
}
static inline bool positionIncludesFrame(QWindow *w)
@@ -287,7 +231,7 @@ static inline XTextProperty* qstringToXTP(Display *dpy, const QString& s)
if (!mapper || errCode < 0) {
mapper = QTextCodec::codecForName("latin1");
if (!mapper || !mapper->canEncode(s))
- return Q_NULLPTR;
+ return nullptr;
#endif
static QByteArray qcs;
qcs = s.toLatin1();
@@ -322,7 +266,7 @@ static QWindow *childWindowAt(QWindow *win, const QPoint &p)
&& win->geometry().contains(win->parent()->mapFromGlobal(p))) {
return win;
}
- return Q_NULLPTR;
+ return nullptr;
}
static const char *wm_window_type_property_id = "_q_xcb_wm_window_type";
@@ -381,7 +325,7 @@ void QXcbWindow::create()
}
if (!visual)
visual = platformScreen->visualForId(m_visualId);
- m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask, &m_imageRgbSwap);
+ setImageFormatForVisual(visual);
connection()->addWindowEventListener(m_window, this);
return;
}
@@ -418,7 +362,7 @@ void QXcbWindow::create()
resolveFormat(platformScreen->surfaceFormatFor(window()->requestedFormat()));
- const xcb_visualtype_t *visual = Q_NULLPTR;
+ const xcb_visualtype_t *visual = nullptr;
if (connection()->hasDefaultVisualId()) {
visual = platformScreen->visualForId(connection()->defaultVisualId());
@@ -451,7 +395,7 @@ void QXcbWindow::create()
m_visualId = visual->visual_id;
m_depth = platformScreen->depthOfVisual(m_visualId);
- m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask, &m_imageRgbSwap);
+ setImageFormatForVisual(visual);
quint32 mask = XCB_CW_BACK_PIXMAP
| XCB_CW_BORDER_PIXEL
@@ -641,7 +585,7 @@ void QXcbWindow::destroy()
if (connection()->focusWindow() == this)
doFocusOut();
if (connection()->mouseGrabber() == this)
- connection()->setMouseGrabber(Q_NULLPTR);
+ connection()->setMouseGrabber(nullptr);
if (m_syncCounter && m_usingSyncProtocol)
xcb_sync_destroy_counter(xcb_connection(), m_syncCounter);
@@ -877,12 +821,12 @@ void QXcbWindow::hide()
xcb_flush(xcb_connection());
if (connection()->mouseGrabber() == this)
- connection()->setMouseGrabber(Q_NULLPTR);
+ connection()->setMouseGrabber(nullptr);
if (QPlatformWindow *w = connection()->mousePressWindow()) {
// Unset mousePressWindow when it (or one of its parents) is unmapped
while (w) {
if (w == this) {
- connection()->setMousePressWindow(Q_NULLPTR);
+ connection()->setMousePressWindow(nullptr);
break;
}
w = w->parent();
@@ -900,7 +844,7 @@ void QXcbWindow::hide()
// Find the top level window at cursor position.
// Don't use QGuiApplication::topLevelAt(): search only the virtual siblings of this window's screen
- QWindow *enterWindow = Q_NULLPTR;
+ QWindow *enterWindow = nullptr;
const auto screens = xcbScreen()->virtualSiblings();
for (QPlatformScreen *screen : screens) {
if (screen->geometry().contains(cursorPos)) {
@@ -1998,13 +1942,14 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
return;
if (event->type == atom(QXcbAtom::WM_PROTOCOLS)) {
- if (event->data.data32[0] == atom(QXcbAtom::WM_DELETE_WINDOW)) {
+ xcb_atom_t protocolAtom = event->data.data32[0];
+ if (protocolAtom == atom(QXcbAtom::WM_DELETE_WINDOW)) {
QWindowSystemInterface::handleCloseEvent(window());
- } else if (event->data.data32[0] == atom(QXcbAtom::WM_TAKE_FOCUS)) {
+ } else if (protocolAtom == atom(QXcbAtom::WM_TAKE_FOCUS)) {
connection()->setTime(event->data.data32[1]);
relayFocusToModalWindow();
return;
- } else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_PING)) {
+ } else if (protocolAtom == atom(QXcbAtom::_NET_WM_PING)) {
if (event->window == xcbScreen()->root())
return;
@@ -2013,20 +1958,23 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
reply.response_type = XCB_CLIENT_MESSAGE;
reply.window = xcbScreen()->root();
- xcb_send_event(xcb_connection(), 0, xcbScreen()->root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (const char *)&reply);
+ xcb_send_event(xcb_connection(), 0, xcbScreen()->root(),
+ XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
+ (const char *)&reply);
xcb_flush(xcb_connection());
- } else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_SYNC_REQUEST)) {
+ } else if (protocolAtom == atom(QXcbAtom::_NET_WM_SYNC_REQUEST)) {
connection()->setTime(event->data.data32[1]);
m_syncValue.lo = event->data.data32[2];
m_syncValue.hi = event->data.data32[3];
if (m_usingSyncProtocol)
m_syncState = SyncReceived;
#ifndef QT_NO_WHATSTHIS
- } else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_CONTEXT_HELP)) {
+ } else if (protocolAtom == atom(QXcbAtom::_NET_WM_CONTEXT_HELP)) {
QWindowSystemInterface::handleEnterWhatsThisEvent();
#endif
} else {
- qWarning() << "QXcbWindow: Unhandled WM_PROTOCOLS message:" << connection()->atomName(event->data.data32[0]);
+ qCWarning(lcQpaXcb, "Unhandled WM_PROTOCOLS (%s)",
+ connection()->atomName(protocolAtom).constData());
}
#ifndef QT_NO_DRAGANDDROP
} else if (event->type == atom(QXcbAtom::XdndEnter)) {
@@ -2054,7 +2002,7 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
|| event->type == atom(QXcbAtom::_GTK_LOAD_ICONTHEMES)) {
//silence the _COMPIZ and _GTK messages for now
} else {
- qWarning() << "QXcbWindow: Unhandled client message:" << connection()->atomName(event->type);
+ qCWarning(lcQpaXcb) << "Unhandled client message: " << connection()->atomName(event->type);
}
}
@@ -2163,7 +2111,8 @@ void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event)
}
void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, int root_y,
- int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source)
+ int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp,
+ QEvent::Type type, Qt::MouseEventSource source)
{
const bool isWheel = detail >= 4 && detail <= 7;
if (!isWheel && window() != QGuiApplication::focusWindow()) {
@@ -2212,11 +2161,12 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in
connection()->setMousePressWindow(this);
- handleMouseEvent(timestamp, local, global, modifiers, source);
+ handleMouseEvent(timestamp, local, global, modifiers, type, source);
}
void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x, int root_y,
- int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source)
+ int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp,
+ QEvent::Type type, Qt::MouseEventSource source)
{
QPoint local(event_x, event_y);
QPoint global(root_x, root_y);
@@ -2227,9 +2177,9 @@ void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x,
}
if (connection()->buttonState() == Qt::NoButton)
- connection()->setMousePressWindow(Q_NULLPTR);
+ connection()->setMousePressWindow(nullptr);
- handleMouseEvent(timestamp, local, global, modifiers, source);
+ handleMouseEvent(timestamp, local, global, modifiers, type, source);
}
static inline bool doCheckUnGrabAncestor(QXcbConnection *conn)
@@ -2252,7 +2202,7 @@ static inline bool doCheckUnGrabAncestor(QXcbConnection *conn)
return true;
}
-static bool ignoreLeaveEvent(quint8 mode, quint8 detail, QXcbConnection *conn = Q_NULLPTR)
+static bool ignoreLeaveEvent(quint8 mode, quint8 detail, QXcbConnection *conn = nullptr)
{
return ((doCheckUnGrabAncestor(conn)
&& mode == XCB_NOTIFY_MODE_GRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR)
@@ -2261,7 +2211,7 @@ static bool ignoreLeaveEvent(quint8 mode, quint8 detail, QXcbConnection *conn =
|| detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL);
}
-static bool ignoreEnterEvent(quint8 mode, quint8 detail, QXcbConnection *conn = Q_NULLPTR)
+static bool ignoreEnterEvent(quint8 mode, quint8 detail, QXcbConnection *conn = nullptr)
{
return ((doCheckUnGrabAncestor(conn)
&& mode == XCB_NOTIFY_MODE_UNGRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR)
@@ -2330,7 +2280,8 @@ void QXcbWindow::handleLeaveNotifyEvent(int root_x, int root_y,
}
void QXcbWindow::handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y,
- Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source)
+ Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp,
+ QEvent::Type type, Qt::MouseEventSource source)
{
QPoint local(event_x, event_y);
QPoint global(root_x, root_y);
@@ -2338,33 +2289,34 @@ void QXcbWindow::handleMotionNotifyEvent(int event_x, int event_y, int root_x, i
// "mousePressWindow" can be NULL i.e. if a window will be grabbed or unmapped, so set it again here.
// Unset "mousePressWindow" when mouse button isn't pressed - in some cases the release event won't arrive.
const bool isMouseButtonPressed = (connection()->buttonState() != Qt::NoButton);
- const bool hasMousePressWindow = (connection()->mousePressWindow() != Q_NULLPTR);
+ const bool hasMousePressWindow = (connection()->mousePressWindow() != nullptr);
if (isMouseButtonPressed && !hasMousePressWindow)
connection()->setMousePressWindow(this);
else if (hasMousePressWindow && !isMouseButtonPressed)
- connection()->setMousePressWindow(Q_NULLPTR);
+ connection()->setMousePressWindow(nullptr);
- handleMouseEvent(timestamp, local, global, modifiers, source);
+ handleMouseEvent(timestamp, local, global, modifiers, type, source);
}
void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event)
{
Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state);
handleButtonPressEvent(event->event_x, event->event_y, event->root_x, event->root_y, event->detail,
- modifiers, event->time);
+ modifiers, event->time, QEvent::MouseButtonPress);
}
void QXcbWindow::handleButtonReleaseEvent(const xcb_button_release_event_t *event)
{
Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state);
handleButtonReleaseEvent(event->event_x, event->event_y, event->root_x, event->root_y, event->detail,
- modifiers, event->time);
+ modifiers, event->time, QEvent::MouseButtonRelease);
}
void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event)
{
Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state);
- handleMotionNotifyEvent(event->event_x, event->event_y, event->root_x, event->root_y, modifiers, event->time);
+ handleMotionNotifyEvent(event->event_x, event->event_y, event->root_x, event->root_y, modifiers,
+ event->time, QEvent::MouseMove);
}
#if QT_CONFIG(xinput2)
@@ -2415,18 +2367,18 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
qCDebug(lcQpaXInputEvents, "XI2 mouse press, button %d, time %d, source %s", button, ev->time, sourceName);
conn->setButtonState(button, true);
- handleButtonPressEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, source);
+ handleButtonPressEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, QEvent::MouseButtonPress, source);
break;
case XI_ButtonRelease:
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
qCDebug(lcQpaXInputEvents, "XI2 mouse release, button %d, time %d, source %s", button, ev->time, sourceName);
conn->setButtonState(button, false);
- handleButtonReleaseEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, source);
+ handleButtonReleaseEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, QEvent::MouseButtonRelease, source);
break;
case XI_Motion:
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
qCDebug(lcQpaXInputEvents, "XI2 mouse motion %d,%d, time %d, source %s", event_x, event_y, ev->time, sourceName);
- handleMotionNotifyEvent(event_x, event_y, root_x, root_y, modifiers, ev->time, source);
+ handleMotionNotifyEvent(event_x, event_y, root_x, root_y, modifiers, ev->time, QEvent::MouseMove, source);
break;
default:
qWarning() << "Unrecognized XI2 mouse event" << ev->evtype;
@@ -2471,10 +2423,13 @@ void QXcbWindow::handleXIEnterLeave(xcb_ge_event_t *event)
QXcbWindow *QXcbWindow::toWindow() { return this; }
void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global,
- Qt::KeyboardModifiers modifiers, Qt::MouseEventSource source)
+ Qt::KeyboardModifiers modifiers, QEvent::Type type, Qt::MouseEventSource source)
{
connection()->setTime(time);
- QWindowSystemInterface::handleMouseEvent(window(), time, local, global, connection()->buttonState(), modifiers, source);
+ Qt::MouseButton button = type == QEvent::MouseMove ? Qt::NoButton : connection()->button();
+ QWindowSystemInterface::handleMouseEvent(window(), time, local, global,
+ connection()->buttonState(), button,
+ type, modifiers, source);
}
void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *event)
@@ -2524,7 +2479,7 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
m_lastWindowStateEvent = newState;
m_windowState = newState;
if ((m_windowState & Qt::WindowMinimized) && connection()->mouseGrabber() == this)
- connection()->setMouseGrabber(Q_NULLPTR);
+ connection()->setMouseGrabber(nullptr);
}
return;
} else if (event->atom == atom(QXcbAtom::_NET_FRAME_EXTENTS)) {
@@ -2592,7 +2547,7 @@ bool QXcbWindow::setKeyboardGrabEnabled(bool grab)
bool QXcbWindow::setMouseGrabEnabled(bool grab)
{
if (!grab && connection()->mouseGrabber() == this)
- connection()->setMouseGrabber(Q_NULLPTR);
+ connection()->setMouseGrabber(nullptr);
#if QT_CONFIG(xinput2)
if (connection()->hasXInput2() && !connection()->xi2MouseEventsDisabled()) {