diff options
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.cpp | 71 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.h | 10 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbcursor.cpp | 2 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbcursor.h | 6 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbnativeinterface.cpp | 46 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbnativeinterface.h | 11 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbscreen.cpp | 52 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbscreen.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 103 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.h | 5 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/xcb-plugin.pro | 5 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/xcb-static/xcb-static.pro | 2 |
12 files changed, 244 insertions, 71 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 4c4df137a3..1192894693 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -257,6 +257,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, const char , has_shape_extension(false) , has_randr_extension(false) , has_input_shape(false) + , m_buttons(0) { #ifdef XCB_USE_XLIB Display *dpy = XOpenDisplay(m_displayName.constData()); @@ -312,6 +313,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, const char initializeAllAtoms(); m_time = XCB_CURRENT_TIME; + m_netWmUserTime = XCB_CURRENT_TIME; initializeXRandr(); updateScreens(); @@ -662,6 +664,73 @@ void QXcbConnection::handleXcbError(xcb_generic_error_t *error) #endif } +static Qt::MouseButtons translateMouseButtons(int s) +{ + Qt::MouseButtons ret = 0; + if (s & XCB_BUTTON_MASK_1) + ret |= Qt::LeftButton; + if (s & XCB_BUTTON_MASK_2) + ret |= Qt::MidButton; + if (s & XCB_BUTTON_MASK_3) + ret |= Qt::RightButton; + return ret; +} + +static Qt::MouseButton translateMouseButton(xcb_button_t s) +{ + switch (s) { + case 1: return Qt::LeftButton; + case 2: return Qt::MidButton; + case 3: return Qt::RightButton; + // Button values 4-7 were already handled as Wheel events, and won't occur here. + case 8: return Qt::BackButton; // Also known as Qt::ExtraButton1 + case 9: return Qt::ForwardButton; // Also known as Qt::ExtraButton2 + case 10: return Qt::ExtraButton3; + case 11: return Qt::ExtraButton4; + case 12: return Qt::ExtraButton5; + case 13: return Qt::ExtraButton6; + case 14: return Qt::ExtraButton7; + case 15: return Qt::ExtraButton8; + case 16: return Qt::ExtraButton9; + case 17: return Qt::ExtraButton10; + case 18: return Qt::ExtraButton11; + case 19: return Qt::ExtraButton12; + case 20: return Qt::ExtraButton13; + case 21: return Qt::ExtraButton14; + case 22: return Qt::ExtraButton15; + case 23: return Qt::ExtraButton16; + case 24: return Qt::ExtraButton17; + case 25: return Qt::ExtraButton18; + case 26: return Qt::ExtraButton19; + case 27: return Qt::ExtraButton20; + case 28: return Qt::ExtraButton21; + case 29: return Qt::ExtraButton22; + case 30: return Qt::ExtraButton23; + case 31: return Qt::ExtraButton24; + default: return Qt::NoButton; + } +} + +void QXcbConnection::handleButtonPress(xcb_generic_event_t *ev) +{ + xcb_button_press_event_t *event = (xcb_button_press_event_t *)ev; + + // the event explicitly contains the state of the three first buttons, + // the rest we need to manage ourselves + m_buttons = (m_buttons & ~0x7) | translateMouseButtons(event->state); + m_buttons |= translateMouseButton(event->detail); +} + +void QXcbConnection::handleButtonRelease(xcb_generic_event_t *ev) +{ + xcb_button_release_event_t *event = (xcb_button_release_event_t *)ev; + + // the event explicitly contains the state of the three first buttons, + // the rest we need to manage ourselves + m_buttons = (m_buttons & ~0x7) | translateMouseButtons(event->state); + m_buttons &= ~translateMouseButton(event->detail); +} + void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) { #ifdef Q_XCB_DEBUG @@ -686,8 +755,10 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) case XCB_EXPOSE: HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent); case XCB_BUTTON_PRESS: + handleButtonPress(event); HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent); case XCB_BUTTON_RELEASE: + handleButtonRelease(event); HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent); case XCB_MOTION_NOTIFY: HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent); diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index c67acb3218..464d918adf 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -370,6 +370,9 @@ public: inline xcb_timestamp_t time() const { return m_time; } inline void setTime(xcb_timestamp_t t) { if (t > m_time) m_time = t; } + inline xcb_timestamp_t netWmUserTime() const { return m_netWmUserTime; } + inline void setNetWmUserTime(xcb_timestamp_t t) { if (t > m_netWmUserTime) m_netWmUserTime = t; } + bool hasGLX() const { return has_glx_extension; } bool hasXFixes() const { return xfixes_first_event > 0; } bool hasXShape() const { return has_shape_extension; } @@ -380,6 +383,8 @@ public: xcb_timestamp_t getTimestamp(); + Qt::MouseButtons buttons() const { return m_buttons; } + private slots: void processXcbEvents(); @@ -400,6 +405,8 @@ private: QXcbScreen* findOrCreateScreen(QList<QXcbScreen *>& newScreens, int screenNumber, xcb_screen_t* xcbScreen, xcb_randr_get_output_info_reply_t *output = NULL); void updateScreens(); + void handleButtonPress(xcb_generic_event_t *event); + void handleButtonRelease(xcb_generic_event_t *event); bool m_xi2Enabled; int m_xi2Minor; @@ -448,6 +455,7 @@ private: xcb_atom_t m_allAtoms[QXcbAtom::NAtoms]; xcb_timestamp_t m_time; + xcb_timestamp_t m_netWmUserTime; QByteArray m_displayName; @@ -501,6 +509,8 @@ private: bool has_shape_extension; bool has_randr_extension; bool has_input_shape; + + Qt::MouseButtons m_buttons; }; #define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display())) diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp index c1cfbd02d6..e1dfe3d6c0 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.cpp +++ b/src/plugins/platforms/xcb/qxcbcursor.cpp @@ -291,6 +291,7 @@ QXcbCursor::~QXcbCursor() xcb_close_font(xcb_connection(), cursorFont); } +#ifndef QT_NO_CURSOR void QXcbCursor::changeCursor(QCursor *cursor, QWindow *widget) { QXcbWindow *w = 0; @@ -507,6 +508,7 @@ xcb_cursor_t QXcbCursor::createBitmapCursor(QCursor *cursor) } return c; } +#endif void QXcbCursor::queryPointer(QXcbConnection *c, xcb_window_t *rootWin, QPoint *pos, int *keybMask) { diff --git a/src/plugins/platforms/xcb/qxcbcursor.h b/src/plugins/platforms/xcb/qxcbcursor.h index 4c74034988..a4f3bf11ee 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.h +++ b/src/plugins/platforms/xcb/qxcbcursor.h @@ -52,20 +52,26 @@ class QXcbCursor : public QXcbObject, public QPlatformCursor public: QXcbCursor(QXcbConnection *conn, QXcbScreen *screen); ~QXcbCursor(); +#ifndef QT_NO_CURSOR void changeCursor(QCursor *cursor, QWindow *widget); +#endif QPoint pos() const; void setPos(const QPoint &pos); static void queryPointer(QXcbConnection *c, xcb_window_t *rootWin, QPoint *pos, int *keybMask = 0); private: +#ifndef QT_NO_CURSOR xcb_cursor_t createFontCursor(int cshape); xcb_cursor_t createBitmapCursor(QCursor *cursor); xcb_cursor_t createNonStandardCursor(int cshape); +#endif QXcbScreen *m_screen; +#ifndef QT_NO_CURSOR QMap<int, xcb_cursor_t> m_shapeCursorMap; QMap<qint64, xcb_cursor_t> m_bitmapCursorMap; +#endif }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index a44e7fb959..9c360df900 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -71,6 +71,8 @@ public: insert("screen",QXcbNativeInterface::Screen); insert("eglcontext",QXcbNativeInterface::EglContext); insert("glxcontext",QXcbNativeInterface::GLXContext); + insert("apptime",QXcbNativeInterface::AppTime); + insert("appusertime",QXcbNativeInterface::AppUserTime); } }; @@ -109,18 +111,24 @@ void *QXcbNativeInterface::nativeResourceForScreen(const QByteArray &resource, Q const QXcbResourceMap::const_iterator it = qXcbResourceMap()->constFind(resource.toLower()); if (it == qXcbResourceMap()->constEnd() || !screen->handle()) return 0; + void *result = 0; const QXcbScreen *xcbScreen = static_cast<QXcbScreen *>(screen->handle()); switch (it.value()) { case Display: #ifdef XCB_USE_XLIB - return xcbScreen->connection()->xlib_display(); -#else - break; + result = xcbScreen->connection()->xlib_display(); #endif + break; + case AppTime: + result = appTime(xcbScreen); + break; + case AppUserTime: + result = appUserTime(xcbScreen); + break; default: break; } - return 0; + return result; } void *QXcbNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window) @@ -151,6 +159,36 @@ void *QXcbNativeInterface::nativeResourceForWindow(const QByteArray &resourceStr return result; } +QPlatformNativeInterface::NativeResourceForScreenFunction QXcbNativeInterface::nativeResourceFunctionForScreen(const QByteArray &resource) +{ + const QByteArray lowerCaseResource = resource.toLower(); + if (lowerCaseResource == "setapptime") + return NativeResourceForScreenFunction(setAppTime); + else if (lowerCaseResource == "setappusertime") + return NativeResourceForScreenFunction(setAppUserTime); + return 0; +} + +void *QXcbNativeInterface::appTime(const QXcbScreen *screen) +{ + return reinterpret_cast<void *>(quintptr(screen->connection()->time())); +} + +void *QXcbNativeInterface::appUserTime(const QXcbScreen *screen) +{ + return reinterpret_cast<void *>(quintptr(screen->connection()->netWmUserTime())); +} + +void QXcbNativeInterface::setAppTime(QScreen* screen, xcb_timestamp_t time) +{ + static_cast<QXcbScreen *>(screen->handle())->connection()->setTime(time); +} + +void QXcbNativeInterface::setAppUserTime(QScreen* screen, xcb_timestamp_t time) +{ + static_cast<QXcbScreen *>(screen->handle())->connection()->setNetWmUserTime(time); +} + QPlatformNativeInterface::NativeResourceForContextFunction QXcbNativeInterface::nativeResourceFunctionForContext(const QByteArray &resource) { QByteArray lowerCaseResource = resource.toLower(); diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h index a7e0a207cb..e2e03fce8f 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.h +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h @@ -43,11 +43,13 @@ #define QXCBNATIVEINTERFACE_H #include <qpa/qplatformnativeinterface.h> +#include <xcb/xcb.h> QT_BEGIN_NAMESPACE class QWidget; class QXcbScreen; +class QXcbConnection; class QXcbNativeInterface : public QPlatformNativeInterface { @@ -59,7 +61,9 @@ public: Screen, GraphicsDevice, EglContext, - GLXContext + GLXContext, + AppTime, + AppUserTime }; QXcbNativeInterface(); @@ -69,6 +73,7 @@ public: void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window); NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource); + NativeResourceForScreenFunction nativeResourceFunctionForScreen(const QByteArray &resource) Q_DECL_OVERRIDE; inline const QByteArray &genericEventFilterType() const { return m_genericEventFilterType; } @@ -77,6 +82,10 @@ public: void *connectionForWindow(QWindow *window); void *screenForWindow(QWindow *window); void *graphicsDeviceForWindow(QWindow *window); + void *appTime(const QXcbScreen *screen); + void *appUserTime(const QXcbScreen *screen); + static void setAppTime(QScreen *screen, xcb_timestamp_t time); + static void setAppUserTime(QScreen *screen, xcb_timestamp_t time); static void *eglContextForContext(QOpenGLContext *context); static void *glxContextForContext(QOpenGLContext *context); diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index 6452186bbf..fc80662c46 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -50,6 +50,7 @@ #include <QDebug> #include <qpa/qwindowsysteminterface.h> +#include <private/qmath_p.h> QT_BEGIN_NAMESPACE @@ -65,6 +66,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr, , m_orientation(Qt::PrimaryOrientation) , m_number(number) , m_refreshRate(60) + , m_forcedDpi(-1) { if (connection->hasXRandr()) xcb_randr_select_input(xcb_connection(), screen()->root, true); @@ -81,6 +83,9 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr, if (m_availableGeometry.isEmpty()) m_availableGeometry = QRect(QPoint(), m_virtualSize); + readXResources(); + + #ifdef Q_XCB_DEBUG qDebug(); qDebug("Screen output %s of xcb screen %d:", m_outputName.toUtf8().constData(), m_number); @@ -242,8 +247,11 @@ QImage::Format QXcbScreen::format() const QDpi QXcbScreen::logicalDpi() const { - return QDpi(25.4 * m_virtualSize.width() / m_virtualSizeMillimeters.width(), - 25.4 * m_virtualSize.height() / m_virtualSizeMillimeters.height()); + if (m_forcedDpi > 0) + return QDpi(m_forcedDpi, m_forcedDpi); + + return QDpi(Q_MM_PER_INCH * m_virtualSize.width() / m_virtualSizeMillimeters.width(), + Q_MM_PER_INCH * m_virtualSize.height() / m_virtualSizeMillimeters.height()); } QPlatformCursor *QXcbScreen::cursor() const @@ -315,6 +323,9 @@ void QXcbScreen::handleScreenChange(xcb_randr_screen_change_notify_event_t *chan QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry()); QWindowSystemInterface::handleScreenAvailableGeometryChange(QPlatformScreen::screen(), availableGeometry()); QWindowSystemInterface::handleScreenOrientationChange(QPlatformScreen::screen(), m_orientation); + QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(QPlatformScreen::screen(), + Q_MM_PER_INCH * m_virtualSize.width() / m_virtualSizeMillimeters.width(), + Q_MM_PER_INCH * m_virtualSize.height() / m_virtualSizeMillimeters.height()); } void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp) @@ -470,4 +481,41 @@ QPixmap QXcbScreen::grabWindow(WId window, int x, int y, int width, int height) return result; } +void QXcbScreen::readXResources() +{ + int offset = 0; + QByteArray resources; + while(1) { + xcb_get_property_reply_t *reply = + xcb_get_property_reply(xcb_connection(), + xcb_get_property_unchecked(xcb_connection(), false, screen()->root, + XCB_ATOM_RESOURCE_MANAGER, + XCB_ATOM_STRING, offset/4, 8192), NULL); + bool more = false; + if (reply && reply->format == 8 && reply->type == XCB_ATOM_STRING) { + resources += QByteArray((const char *)xcb_get_property_value(reply), xcb_get_property_value_length(reply)); + offset += xcb_get_property_value_length(reply); + more = reply->bytes_after != 0; + } + + if (reply) + free(reply); + + if (!more) + break; + } + + QList<QByteArray> split = resources.split('\n'); + for (int i = 0; i < split.size(); ++i) { + const QByteArray &r = split.at(i); + if (r.startsWith("Xft.dpi:\t")) { + bool ok; + int dpi = r.mid(sizeof("Xft.dpi:")).toInt(&ok); + if (ok) + m_forcedDpi = dpi; + break; + } + } +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index d9eee464dc..96d30cde8b 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -96,6 +96,7 @@ public: void updateGeometry(xcb_timestamp_t timestamp); void updateRefreshRate(); + void readXResources(); private: xcb_screen_t *m_screen; xcb_randr_crtc_t m_crtc; @@ -114,6 +115,7 @@ private: QMap<xcb_visualid_t, xcb_visualtype_t> m_visuals; QXcbCursor *m_cursor; int m_refreshRate; + int m_forcedDpi; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 5e4e749c83..528c4c6580 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -385,6 +385,10 @@ void QXcbWindow::create() #ifndef QT_NO_DRAGANDDROP connection()->drag()->dndEnable(this, true); #endif + + const qreal opacity = qt_window_private(window())->opacity; + if (!qFuzzyCompare(opacity, qreal(1.0))) + setOpacity(opacity); } QXcbWindow::~QXcbWindow() @@ -1024,6 +1028,7 @@ void QXcbWindow::updateNetWmStateBeforeMap() void QXcbWindow::updateNetWmUserTime(xcb_timestamp_t timestamp) { xcb_window_t wid = m_window; + connection()->setNetWmUserTime(timestamp); const bool isSupportedByWM = connection()->wmSupport()->isSupportedByWM(atom(QXcbAtom::_NET_WM_USER_TIME_WINDOW)); if (m_netWmUserTimeWindow || isSupportedByWM) { @@ -1112,7 +1117,18 @@ void QXcbWindow::setParent(const QPlatformWindow *parent) void QXcbWindow::setWindowTitle(const QString &title) { - QByteArray ba = title.toUtf8(); + QString fullTitle = title; + if (QGuiApplicationPrivate::displayName) { + // Append display name, if set. + if (!fullTitle.isEmpty()) + fullTitle += QString::fromUtf8(" \xe2\x80\x94 "); // unicode character U+2014, EM DASH + fullTitle += *QGuiApplicationPrivate::displayName; + } else if (fullTitle.isEmpty()) { + // Don't let the window title be completely empty, use the app name as fallback. + fullTitle = QCoreApplication::applicationName(); + } + const QByteArray ba = fullTitle.toUtf8(); + Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, @@ -1460,53 +1476,6 @@ void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event) } } -static Qt::MouseButtons translateMouseButtons(int s) -{ - Qt::MouseButtons ret = 0; - if (s & XCB_BUTTON_MASK_1) - ret |= Qt::LeftButton; - if (s & XCB_BUTTON_MASK_2) - ret |= Qt::MidButton; - if (s & XCB_BUTTON_MASK_3) - ret |= Qt::RightButton; - return ret; -} - -static Qt::MouseButton translateMouseButton(xcb_button_t s) -{ - switch (s) { - case 1: return Qt::LeftButton; - case 2: return Qt::MidButton; - case 3: return Qt::RightButton; - // Button values 4-7 were already handled as Wheel events, and won't occur here. - case 8: return Qt::BackButton; // Also known as Qt::ExtraButton1 - case 9: return Qt::ForwardButton; // Also known as Qt::ExtraButton2 - case 10: return Qt::ExtraButton3; - case 11: return Qt::ExtraButton4; - case 12: return Qt::ExtraButton5; - case 13: return Qt::ExtraButton6; - case 14: return Qt::ExtraButton7; - case 15: return Qt::ExtraButton8; - case 16: return Qt::ExtraButton9; - case 17: return Qt::ExtraButton10; - case 18: return Qt::ExtraButton11; - case 19: return Qt::ExtraButton12; - case 20: return Qt::ExtraButton13; - case 21: return Qt::ExtraButton14; - case 22: return Qt::ExtraButton15; - case 23: return Qt::ExtraButton16; - case 24: return Qt::ExtraButton17; - case 25: return Qt::ExtraButton18; - case 26: return Qt::ExtraButton19; - case 27: return Qt::ExtraButton20; - case 28: return Qt::ExtraButton21; - case 29: return Qt::ExtraButton22; - case 30: return Qt::ExtraButton23; - case 31: return Qt::ExtraButton24; - default: return Qt::NoButton; - } -} - void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event) { updateNetWmUserTime(event->time); @@ -1528,7 +1497,7 @@ void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event) return; } - handleMouseEvent(event->detail, event->state, event->time, local, global, modifiers); + handleMouseEvent(event->time, local, global, modifiers); } void QXcbWindow::handleButtonReleaseEvent(const xcb_button_release_event_t *event) @@ -1537,7 +1506,12 @@ void QXcbWindow::handleButtonReleaseEvent(const xcb_button_release_event_t *even QPoint global(event->root_x, event->root_y); Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); - handleMouseEvent(event->detail, event->state, event->time, local, global, modifiers); + if (event->detail >= 4 && event->detail <= 7) { + // mouse wheel, handled in handleButtonPressEvent() + return; + } + + handleMouseEvent(event->time, local, global, modifiers); } void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event) @@ -1546,19 +1520,13 @@ void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event) QPoint global(event->root_x, event->root_y); Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); - handleMouseEvent(event->detail, event->state, event->time, local, global, modifiers); + handleMouseEvent(event->time, local, global, modifiers); } -void QXcbWindow::handleMouseEvent(xcb_button_t detail, uint16_t state, xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers) +void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers) { connection()->setTime(time); - - Qt::MouseButtons buttons = translateMouseButtons(state); - Qt::MouseButton button = translateMouseButton(detail); - - buttons ^= button; // X event uses state *before*, Qt uses state *after* - - QWindowSystemInterface::handleMouseEvent(window(), time, local, global, buttons, modifiers); + QWindowSystemInterface::handleMouseEvent(window(), time, local, global, connection()->buttons(), modifiers); } class EnterEventChecker @@ -1786,6 +1754,23 @@ static inline xcb_rectangle_t qRectToXCBRectangle(const QRect &r) return result; } +void QXcbWindow::setOpacity(qreal level) +{ + if (!m_window) + return; + + quint32 value = qRound64(qBound(qreal(0), level, qreal(1)) * 0xffffffff); + + Q_XCB_CALL(xcb_change_property(xcb_connection(), + XCB_PROP_MODE_REPLACE, + m_window, + atom(QXcbAtom::_NET_WM_WINDOW_OPACITY), + XCB_ATOM_CARDINAL, + 32, + 1, + (uchar *)&value)); +} + void QXcbWindow::setMask(const QRegion ®ion) { if (!connection()->hasXShape()) diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index bd4d18a175..b2c637281d 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -109,6 +109,8 @@ public: bool startSystemResize(const QPoint &pos, Qt::Corner corner); + void setOpacity(qreal level); + #if !defined(QT_NO_SHAPE) void setMask(const QRegion ®ion); #endif // !QT_NO_SHAPE @@ -132,11 +134,10 @@ public: void handleFocusOutEvent(const xcb_focus_out_event_t *event); void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event); - void handleMouseEvent(xcb_button_t detail, uint16_t state, xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers); + void handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers); void updateSyncRequestCounter(); void updateNetWmUserTime(xcb_timestamp_t timestamp); - void netWmUserTime() const; #if defined(XCB_USE_EGL) QXcbEGLSurface *eglSurface() const; diff --git a/src/plugins/platforms/xcb/xcb-plugin.pro b/src/plugins/platforms/xcb/xcb-plugin.pro index b7b5650eea..5823e97f36 100644 --- a/src/plugins/platforms/xcb/xcb-plugin.pro +++ b/src/plugins/platforms/xcb/xcb-plugin.pro @@ -1,6 +1,7 @@ -TARGET = xcb +TARGET = qxcb PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QXcbIntegrationPlugin load(qt_plugin) QT += core-private gui-private platformsupport-private @@ -109,7 +110,7 @@ contains(QT_CONFIG, xcb-qt) { DEFINES += XCB_USE_RENDER XCB_DIR = ../../../3rdparty/xcb INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/sysinclude - LIBS += -lxcb -L ./xcb-static -l xcb-static + LIBS += -lxcb -L$$OUT_PWD/xcb-static -lxcb-static } else { LIBS += -lxcb -lxcb-image -lxcb-keysyms -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr !contains(DEFINES, QT_NO_SHAPE):LIBS += -lxcb-shape diff --git a/src/plugins/platforms/xcb/xcb-static/xcb-static.pro b/src/plugins/platforms/xcb/xcb-static/xcb-static.pro index d7530fe42e..01667d41db 100644 --- a/src/plugins/platforms/xcb/xcb-static/xcb-static.pro +++ b/src/plugins/platforms/xcb/xcb-static/xcb-static.pro @@ -8,7 +8,7 @@ CONFIG += staticlib XCB_DIR = ../../../../3rdparty/xcb -INCLUDEPATH += $$XCB_DIR/include/xcb $$XCB_DIR/sysinclude +INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/include/xcb $$XCB_DIR/sysinclude # ignore compiler warnings in 3rdparty code QMAKE_CFLAGS_STATIC_LIB+=-w |