summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp71
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h10
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.h6
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.cpp46
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.h11
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp52
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp103
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h5
-rw-r--r--src/plugins/platforms/xcb/xcb-plugin.pro5
-rw-r--r--src/plugins/platforms/xcb/xcb-static/xcb-static.pro2
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 &region)
{
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 &region);
#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