diff options
Diffstat (limited to 'src/plugins/platforms/wayland_common')
37 files changed, 509 insertions, 275 deletions
diff --git a/src/plugins/platforms/wayland_common/qwaylandclipboard.cpp b/src/plugins/platforms/wayland_common/qwaylandclipboard.cpp index 31fe60455..4cf055d30 100644 --- a/src/plugins/platforms/wayland_common/qwaylandclipboard.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandclipboard.cpp @@ -46,7 +46,7 @@ #include "qwaylanddatasource.h" #include "qwaylanddatadevicemanager.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandClipboard::QWaylandClipboard(QWaylandDisplay *display) : mDisplay(display) @@ -82,3 +82,4 @@ bool QWaylandClipboard::supportsMode(QClipboard::Mode mode) const return mode == QClipboard::Clipboard; } +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandcursor.cpp b/src/plugins/platforms/wayland_common/qwaylandcursor.cpp index 9ea1836b7..e0abba304 100644 --- a/src/plugins/platforms/wayland_common/qwaylandcursor.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandcursor.cpp @@ -51,7 +51,7 @@ #include <wayland-cursor.h> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandCursor::QWaylandCursor(QWaylandScreen *screen) : mDisplay(screen->display()) @@ -74,12 +74,17 @@ QWaylandCursor::~QWaylandCursor() wl_cursor_theme_destroy(mCursorTheme); } -void QWaylandCursor::changeCursor(QCursor *cursor, QWindow *window) +struct wl_cursor_image *QWaylandCursor::cursorImage(Qt::CursorShape newShape) { - Q_UNUSED(window) - struct wl_cursor *waylandCursor = 0; - const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor; + + /* Hide cursor */ + if (newShape == Qt::BlankCursor) + { + mDisplay->setCursor(NULL, NULL); + return NULL; + } + if (newShape < Qt::BitmapCursor) { waylandCursor = requestCursor((WaylandCursor)newShape); } else if (newShape == Qt::BitmapCursor) { @@ -90,17 +95,31 @@ void QWaylandCursor::changeCursor(QCursor *cursor, QWindow *window) if (!waylandCursor) { qDebug("Could not find cursor for shape %d", newShape); - return; + return NULL; } struct wl_cursor_image *image = waylandCursor->images[0]; - struct wl_buffer *buffer = wl_cursor_image_get_buffer(image); if (!buffer) { qDebug("Could not find buffer for cursor"); + return NULL; + } + + return image; +} + +void QWaylandCursor::changeCursor(QCursor *cursor, QWindow *window) +{ + Q_UNUSED(window) + + const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor; + + struct wl_cursor_image *image = cursorImage(newShape); + if (!image) { return; } + struct wl_buffer *buffer = wl_cursor_image_get_buffer(image); mDisplay->setCursor(buffer, image); } @@ -132,9 +151,6 @@ void QWaylandCursor::setPos(const QPoint &pos) wl_cursor *QWaylandCursor::requestCursor(WaylandCursor shape) { - if (shape == BlankCursor) - return 0; - struct wl_cursor *cursor = mCursors.value(shape, 0); //If the cursor has not been loaded already, load it @@ -277,3 +293,5 @@ void QWaylandCursor::initCursorMap() mCursorNamesMap.insert(ResizeSouthWestCursor, "sw-resize"); mCursorNamesMap.insert(ResizeSouthWestCursor, "bottom_left_corner"); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandcursor.h b/src/plugins/platforms/wayland_common/qwaylandcursor.h index df5dcbe39..ceb6d7488 100644 --- a/src/plugins/platforms/wayland_common/qwaylandcursor.h +++ b/src/plugins/platforms/wayland_common/qwaylandcursor.h @@ -45,11 +45,14 @@ #include <qpa/qplatformcursor.h> #include <QMap> +struct wl_cursor; +struct wl_cursor_image; +struct wl_cursor_theme; + QT_BEGIN_NAMESPACE class QWaylandDisplay; class QWaylandScreen; -struct wl_cursor_theme; class QWaylandCursor : public QPlatformCursor { @@ -62,6 +65,8 @@ public: QPoint pos() const; void setPos(const QPoint &pos); + struct wl_cursor_image *cursorImage(Qt::CursorShape shape); + private: enum WaylandCursor { ArrowCursor = Qt::ArrowCursor, diff --git a/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.cpp b/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.cpp index 901069c5c..8674aae9e 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.cpp +++ b/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.cpp @@ -58,12 +58,13 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE void QWaylandDataDeviceManager::data_offer(void *data, struct wl_data_device *data_device, struct wl_data_offer *id) { + Q_UNUSED(data_device); QWaylandDataDeviceManager *handler = static_cast<QWaylandDataDeviceManager *>(data); new QWaylandDataOffer(handler->display(),id); @@ -322,4 +323,4 @@ struct wl_data_device_manager *QWaylandDataDeviceManager::handle() const return m_data_device_manager; } - +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylanddataoffer.cpp b/src/plugins/platforms/wayland_common/qwaylanddataoffer.cpp index d2080ea55..d98cfc2ab 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddataoffer.cpp +++ b/src/plugins/platforms/wayland_common/qwaylanddataoffer.cpp @@ -47,7 +47,7 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE void QWaylandDataOffer::offer_sync_callback(void *data, struct wl_callback *callback, @@ -143,3 +143,5 @@ struct wl_data_offer *QWaylandDataOffer::handle() const { return m_data_offer; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylanddataoffer.h b/src/plugins/platforms/wayland_common/qwaylanddataoffer.h index fada683a2..abc7c690a 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddataoffer.h +++ b/src/plugins/platforms/wayland_common/qwaylanddataoffer.h @@ -52,6 +52,9 @@ #include <stdint.h> struct wl_callback; +struct wl_callback_listener; +struct wl_data_offer; +struct wl_data_offer_listener; QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylanddatasource.cpp b/src/plugins/platforms/wayland_common/qwaylanddatasource.cpp index ad280b03c..7bf8b0c96 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddatasource.cpp +++ b/src/plugins/platforms/wayland_common/qwaylanddatasource.cpp @@ -50,7 +50,7 @@ #include <unistd.h> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE void QWaylandDataSource::data_source_target(void *data, struct wl_data_source *wl_data_source, @@ -117,3 +117,5 @@ struct wl_data_source *QWaylandDataSource::handle() const { return m_data_source; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylanddecoration.cpp b/src/plugins/platforms/wayland_common/qwaylanddecoration.cpp index f5f79ae67..a4b978330 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddecoration.cpp +++ b/src/plugins/platforms/wayland_common/qwaylanddecoration.cpp @@ -44,6 +44,7 @@ #include "qwaylandwindow.h" #include "qwaylandshellsurface.h" #include "qwaylandinputdevice.h" +#include "qwaylandscreen.h" #include <QtGui/QGuiApplication> #include <QtGui/QImage> @@ -52,7 +53,7 @@ #include <QtGui/QPalette> #include <QtGui/QLinearGradient> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE #define BUTTON_SPACING 5 @@ -128,7 +129,6 @@ QWaylandDecoration::QWaylandDecoration(QWaylandWindow *window) , m_isDirty(true) , m_decorationContentImage(0) , m_margins(3,30,3,3) - , m_hasSetCursor(false) , m_mouseButtons(Qt::NoButton) { m_wayland_window->setDecoration(this); @@ -312,7 +312,7 @@ bool QWaylandDecoration::handleMouse(QWaylandInputDevice *inputDevice, const QPo // Figure out what area mouse is in if (closeButtonRect().contains(local) && isLeftClicked(b)) { - QCoreApplication::postEvent(m_window, new QCloseEvent()); + QWindowSystemInterface::handleCloseEvent(m_window); } else if (maximizeButtonRect().contains(local) && isLeftClicked(b)) { m_window->setWindowState(m_wayland_window->isMaximized() ? Qt::WindowNoState : Qt::WindowMaximized); } else if (minimizeButtonRect().contains(local) && isLeftClicked(b)) { @@ -326,7 +326,7 @@ bool QWaylandDecoration::handleMouse(QWaylandInputDevice *inputDevice, const QPo } else if (local.x() > m_window->width() - m_margins.right() + m_margins.left()) { processMouseRight(inputDevice,local,b,mods); } else { - restoreMouseCursor(); + m_wayland_window->restoreMouseCursor(inputDevice); return false; } @@ -334,15 +334,6 @@ bool QWaylandDecoration::handleMouse(QWaylandInputDevice *inputDevice, const QPo return true; } -void QWaylandDecoration::restoreMouseCursor() -{ - if (m_hasSetCursor) { - overrideCursor(Qt::ArrowCursor); - QGuiApplication::restoreOverrideCursor(); - m_hasSetCursor = false; - } -} - bool QWaylandDecoration::inMouseButtonPressedState() const { return m_mouseButtons & Qt::NoButton; @@ -370,19 +361,19 @@ void QWaylandDecoration::processMouseTop(QWaylandInputDevice *inputDevice, const if (local.y() <= m_margins.bottom()) { if (local.x() <= margins().left()) { //top left bit - overrideCursor(Qt::SizeFDiagCursor); + m_wayland_window->setMouseCursor(inputDevice, Qt::SizeFDiagCursor); startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP_LEFT,b); } else if (local.x() > m_window->width() - margins().right()) { //top right bit - overrideCursor(Qt::SizeBDiagCursor); + m_wayland_window->setMouseCursor(inputDevice, Qt::SizeBDiagCursor); startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP_RIGHT,b); } else { //top reszie bit - overrideCursor(Qt::SplitVCursor); + m_wayland_window->setMouseCursor(inputDevice, Qt::SplitVCursor); startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP,b); } } else { - restoreMouseCursor(); + m_wayland_window->restoreMouseCursor(inputDevice); startMove(inputDevice,b); } @@ -393,15 +384,15 @@ void QWaylandDecoration::processMouseBottom(QWaylandInputDevice *inputDevice, co Q_UNUSED(mods); if (local.x() <= margins().left()) { //bottom left bit - overrideCursor(Qt::SizeBDiagCursor); + m_wayland_window->setMouseCursor(inputDevice, Qt::SizeBDiagCursor); startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT,b); } else if (local.x() > m_window->width() - margins().right()) { //bottom right bit - overrideCursor(Qt::SizeFDiagCursor); + m_wayland_window->setMouseCursor(inputDevice, Qt::SizeFDiagCursor); startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT,b); } else { //bottom bit - overrideCursor(Qt::SplitVCursor); + m_wayland_window->setMouseCursor(inputDevice, Qt::SplitVCursor); startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_BOTTOM,b); } } @@ -410,7 +401,7 @@ void QWaylandDecoration::processMouseLeft(QWaylandInputDevice *inputDevice, cons { Q_UNUSED(local); Q_UNUSED(mods); - overrideCursor(Qt::SplitHCursor); + m_wayland_window->setMouseCursor(inputDevice, Qt::SplitHCursor); startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_LEFT,b); } @@ -418,7 +409,7 @@ void QWaylandDecoration::processMouseRight(QWaylandInputDevice *inputDevice, con { Q_UNUSED(local); Q_UNUSED(mods); - overrideCursor(Qt::SplitHCursor); + m_wayland_window->setMouseCursor(inputDevice, Qt::SplitHCursor); startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_RIGHT,b); } @@ -463,3 +454,5 @@ void QWaylandDecoration::setBackgroundColor(const QColor &c) { m_backgroundColor = c; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylanddecoration.h b/src/plugins/platforms/wayland_common/qwaylanddecoration.h index 14755699d..5efeab226 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddecoration.h +++ b/src/plugins/platforms/wayland_common/qwaylanddecoration.h @@ -60,6 +60,7 @@ class QWindow; class QPaintDevice; class QPainter; class QEvent; +class QWaylandScreen; class QWaylandWindow; class QWaylandInputDevice; @@ -73,7 +74,6 @@ public: bool isDirty() const; bool handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,Qt::MouseButtons b,Qt::KeyboardModifiers mods); - void restoreMouseCursor(); bool inMouseButtonPressedState() const; void startResize(QWaylandInputDevice *inputDevice,enum wl_shell_surface_resize resize, Qt::MouseButtons buttons); @@ -93,8 +93,6 @@ protected: void paint(QPaintDevice *device); private: - void overrideCursor(Qt::CursorShape shape); - void processMouseTop(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods); void processMouseBottom(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods); void processMouseLeft(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods); @@ -114,8 +112,6 @@ private: QImage m_decorationContentImage; QMargins m_margins; - bool m_hasSetCursor; - Qt::CursorShape m_cursorShape; Qt::MouseButtons m_mouseButtons; QColor m_foregroundColor; @@ -153,20 +149,6 @@ inline QColor QWaylandDecoration::backgroundColor() const return m_backgroundColor; } -inline void QWaylandDecoration::overrideCursor(Qt::CursorShape shape) -{ - if (m_hasSetCursor) { - if (m_cursorShape != shape) { - QGuiApplication::changeOverrideCursor(QCursor(shape)); - m_cursorShape = shape; - } - } else { - QGuiApplication::setOverrideCursor(QCursor(shape)); - m_hasSetCursor = true; - m_cursorShape = shape; - } -} - QT_END_NAMESPACE #endif // QWAYLANDDECORATION_H diff --git a/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp b/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp index bb056c969..6cc01d0ed 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp @@ -53,9 +53,7 @@ #include "qwaylandglintegration.h" #endif -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT -#include "windowmanager_integration/qwaylandwindowmanagerintegration.h" -#endif +#include "qwaylandwindowmanagerintegration.h" #include "qwaylandextendedoutput.h" #include "qwaylandextendedsurface.h" @@ -68,7 +66,7 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE struct wl_surface *QWaylandDisplay::createSurface(void *handle) { @@ -84,12 +82,10 @@ QWaylandGLIntegration * QWaylandDisplay::eglIntegration() } #endif -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT QWaylandWindowManagerIntegration *QWaylandDisplay::windowManagerIntegration() { return mWindowManagerIntegration; } -#endif QWaylandInputDevice *QWaylandDisplay::lastKeyboardFocusInputDevice() const { @@ -139,9 +135,7 @@ QWaylandDisplay::QWaylandDisplay() mEglIntegration = QWaylandGLIntegration::createGLIntegration(this); #endif -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT mWindowManagerIntegration = new QWaylandWindowManagerIntegration(this); -#endif blockingReadEvents(); @@ -168,13 +162,15 @@ QWaylandDisplay::~QWaylandDisplay(void) void QWaylandDisplay::flushRequests() { - wl_display_dispatch_queue_pending(mDisplay, mEventQueue); + if (wl_display_dispatch_queue_pending(mDisplay, mEventQueue) == -1 && errno == EPIPE) + QCoreApplication::quit(); wl_display_flush(mDisplay); } void QWaylandDisplay::blockingReadEvents() { - wl_display_dispatch_queue(mDisplay, mEventQueue); + if (wl_display_dispatch_queue(mDisplay, mEventQueue) == -1 && errno == EPIPE) + QCoreApplication::quit(); } QWaylandScreen *QWaylandDisplay::screenForOutput(struct wl_output *output) const @@ -196,8 +192,20 @@ void QWaylandDisplay::addRegistryListener(RegistryListener listener, void *data) void QWaylandDisplay::waitForScreens() { flushRequests(); - while (mScreens.isEmpty()) - blockingReadEvents(); + + while (true) { + bool screensReady = !mScreens.isEmpty(); + + for (int ii = 0; screensReady && ii < mScreens.count(); ++ii) { + if (mScreens.at(ii)->geometry() == QRect(0, 0, 0, 0)) + screensReady = false; + } + + if (!screensReady) + blockingReadEvents(); + else + return; + } } void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uint32_t version) @@ -219,17 +227,17 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin mInputDevices.append(inputDevice); } else if (interface == "wl_data_device_manager") { mDndSelectionHandler = new QWaylandDataDeviceManager(this, id); - } else if (interface == "wl_output_extension") { + } else if (interface == "qt_output_extension") { mOutputExtension = new QtWayland::qt_output_extension(registry, id); foreach (QPlatformScreen *screen, screens()) static_cast<QWaylandScreen *>(screen)->createExtendedOutput(); - } else if (interface == "wl_surface_extension") { + } else if (interface == "qt_surface_extension") { mWindowExtension = new QtWayland::qt_surface_extension(registry, id); - } else if (interface == "wl_sub_surface_extension") { + } else if (interface == "qt_sub_surface_extension") { mSubSurfaceExtension = new QtWayland::qt_sub_surface_extension(registry, id); - } else if (interface == "wl_touch_extension") { + } else if (interface == "qt_touch_extension") { mTouchExtension = new QWaylandTouchExtension(this, id); - } else if (interface == "wl_qtkey_extension") { + } else if (interface == "qt_key_extension") { mQtKeyExtension = new QWaylandQtKeyExtension(this, id); } @@ -252,3 +260,4 @@ void QWaylandDisplay::forceRoundTrip() wl_display_roundtrip(mDisplay); } +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylanddisplay.h b/src/plugins/platforms/wayland_common/qwaylanddisplay.h index bb26be69f..6b2cc89d6 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddisplay.h +++ b/src/plugins/platforms/wayland_common/qwaylanddisplay.h @@ -50,6 +50,8 @@ #include <wayland-client.h> #include <qwayland-wayland.h> +struct wl_cursor_image; + QT_BEGIN_NAMESPACE class QAbstractEventDispatcher; @@ -96,9 +98,7 @@ public: QWaylandGLIntegration *eglIntegration(); #endif -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT QWaylandWindowManagerIntegration *windowManagerIntegration(); -#endif void setCursor(struct wl_buffer *buffer, struct wl_cursor_image *image); @@ -162,6 +162,7 @@ private: QtWayland::qt_output_extension *mOutputExtension; QWaylandTouchExtension *mTouchExtension; QWaylandQtKeyExtension *mQtKeyExtension; + QWaylandWindowManagerIntegration *mWindowManagerIntegration; QSocketNotifier *mReadNotifier; int mFd; @@ -174,10 +175,6 @@ private: QWaylandGLIntegration *mEglIntegration; #endif -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT - QWaylandWindowManagerIntegration *mWindowManagerIntegration; -#endif - static void shellHandleConfigure(void *data, struct wl_shell *shell, uint32_t time, uint32_t edges, struct wl_surface *surface, diff --git a/src/plugins/platforms/wayland_common/qwaylanddnd.cpp b/src/plugins/platforms/wayland_common/qwaylanddnd.cpp index 790fbbd09..0dc80e636 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddnd.cpp +++ b/src/plugins/platforms/wayland_common/qwaylanddnd.cpp @@ -43,7 +43,7 @@ #include "qwaylanddatadevicemanager.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandDrag::QWaylandDrag(QWaylandDisplay *display) : m_display(display) @@ -93,3 +93,5 @@ Qt::DropAction QWaylandDrag::executedDropAction() const { return Qt::CopyAction; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandeventthread.cpp b/src/plugins/platforms/wayland_common/qwaylandeventthread.cpp index 5c0a1d5b2..ca968a2d0 100644 --- a/src/plugins/platforms/wayland_common/qwaylandeventthread.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandeventthread.cpp @@ -1,11 +1,14 @@ #include "qwaylandeventthread.h" #include <QtCore/QSocketNotifier> +#include <QCoreApplication> #include <unistd.h> #include <fcntl.h> #include <stdio.h> #include <errno.h> +QT_BEGIN_NAMESPACE + QWaylandEventThread::QWaylandEventThread(QObject *parent) : QObject(parent) , m_display(0) @@ -29,7 +32,8 @@ void QWaylandEventThread::displayConnect() void QWaylandEventThread::readWaylandEvents() { - wl_display_dispatch(m_display); + if (wl_display_dispatch(m_display) == -1 && errno == EPIPE) + QCoreApplication::quit(); emit newEventsRead(); } @@ -53,3 +57,5 @@ wl_display *QWaylandEventThread::display() const QMutexLocker displayLock(m_displayLock); return m_display; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandeventthread.h b/src/plugins/platforms/wayland_common/qwaylandeventthread.h index bedf4ea51..f4aec744c 100644 --- a/src/plugins/platforms/wayland_common/qwaylandeventthread.h +++ b/src/plugins/platforms/wayland_common/qwaylandeventthread.h @@ -5,6 +5,8 @@ #include <QMutex> #include <wayland-client.h> +QT_BEGIN_NAMESPACE + class QSocketNotifier; class QWaylandEventThread : public QObject @@ -37,4 +39,6 @@ private: }; +QT_END_NAMESPACE + #endif // QWAYLANDEVENTTHREAD_H diff --git a/src/plugins/platforms/wayland_common/qwaylandextendedoutput.cpp b/src/plugins/platforms/wayland_common/qwaylandextendedoutput.cpp index 24b264e28..d7c684be9 100644 --- a/src/plugins/platforms/wayland_common/qwaylandextendedoutput.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandextendedoutput.cpp @@ -47,7 +47,7 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandExtendedOutput::QWaylandExtendedOutput(QWaylandScreen *screen, ::qt_extended_output *extended_output) : QtWayland::qt_extended_output(extended_output) @@ -96,3 +96,5 @@ void QWaylandExtendedOutput::extended_output_set_screen_rotation(int32_t rotatio } QWindowSystemInterface::handleScreenOrientationChange(m_screen->screen(), m_orientation); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandextendedsurface.cpp b/src/plugins/platforms/wayland_common/qwaylandextendedsurface.cpp index 46280bcf3..58eb0a833 100644 --- a/src/plugins/platforms/wayland_common/qwaylandextendedsurface.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandextendedsurface.cpp @@ -53,15 +53,19 @@ #include <qpa/qplatformnativeinterface.h> #include <qpa/qwindowsysteminterface.h> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandExtendedSurface::QWaylandExtendedSurface(QWaylandWindow *window, struct ::qt_extended_surface *extended_surface) : QtWayland::qt_extended_surface(extended_surface) , m_window(window) - , m_exposed(true) { } +QWaylandExtendedSurface::~QWaylandExtendedSurface() +{ + qt_extended_surface_destroy(object()); +} + void QWaylandExtendedSurface::updateGenericProperty(const QString &name, const QVariant &value) { QByteArray byteValue; @@ -107,18 +111,9 @@ QVariant QWaylandExtendedSurface::property(const QString &name, const QVariant & return m_properties.value(name,defaultValue); } -void QWaylandExtendedSurface::extended_surface_onscreen_visibility(int32_t visible) +void QWaylandExtendedSurface::extended_surface_onscreen_visibility(int32_t visibility) { - // Do not send events when the state is not changing... - if (visible == m_exposed) - return; - - m_exposed = visible; - QWaylandWindow *w = m_window; - QWindowSystemInterface::handleExposeEvent(w->window(), - visible - ? QRegion(w->geometry()) - : QRegion()); + m_window->window()->setVisibility(static_cast<QWindow::Visibility>(visibility)); } void QWaylandExtendedSurface::extended_surface_set_generic_property(const QString &name, wl_array *value) @@ -136,6 +131,11 @@ void QWaylandExtendedSurface::extended_surface_set_generic_property(const QStrin nativeInterface->emitWindowPropertyChanged(m_window, name); } +void QWaylandExtendedSurface::extended_surface_close() +{ + QWindowSystemInterface::handleCloseEvent(m_window->window()); +} + Qt::WindowFlags QWaylandExtendedSurface::setWindowFlags(Qt::WindowFlags flags) { uint wlFlags = 0; @@ -147,3 +147,5 @@ Qt::WindowFlags QWaylandExtendedSurface::setWindowFlags(Qt::WindowFlags flags) return flags & (Qt::WindowStaysOnTopHint | Qt::WindowOverridesSystemGestures); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandextendedsurface.h b/src/plugins/platforms/wayland_common/qwaylandextendedsurface.h index 9dbebaf47..4bef5e073 100644 --- a/src/plugins/platforms/wayland_common/qwaylandextendedsurface.h +++ b/src/plugins/platforms/wayland_common/qwaylandextendedsurface.h @@ -57,6 +57,7 @@ class QWaylandExtendedSurface : public QtWayland::qt_extended_surface { public: QWaylandExtendedSurface(QWaylandWindow *window, struct ::qt_extended_surface *extended_surface); + ~QWaylandExtendedSurface(); void setContentOrientation(Qt::ScreenOrientation orientation); @@ -68,16 +69,13 @@ public: Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags); - bool isExposed() const { return m_exposed; } - private: - void extended_surface_onscreen_visibility(int32_t visible) Q_DECL_OVERRIDE; + void extended_surface_onscreen_visibility(int32_t visibility) Q_DECL_OVERRIDE; void extended_surface_set_generic_property(const QString &name, wl_array *value) Q_DECL_OVERRIDE; + void extended_surface_close() Q_DECL_OVERRIDE; QWaylandWindow *m_window; QVariantMap m_properties; - - bool m_exposed; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandglintegration.cpp b/src/plugins/platforms/wayland_common/qwaylandglintegration.cpp index a4b3331c6..bafb99443 100644 --- a/src/plugins/platforms/wayland_common/qwaylandglintegration.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandglintegration.cpp @@ -41,7 +41,7 @@ #include "qwaylandglintegration.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandGLIntegration::QWaylandGLIntegration() { @@ -52,3 +52,5 @@ QWaylandGLIntegration::~QWaylandGLIntegration() { } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp index 62cbdf36b..aab939f6d 100644 --- a/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp @@ -46,6 +46,8 @@ #include "qwaylandbuffer.h" #include "qwaylanddatadevicemanager.h" #include "qwaylandtouch.h" +#include "qwaylandscreen.h" +#include "qwaylandcursor.h" #include <QtGui/private/qpixmap_raster_p.h> #include <qpa/qplatformwindow.h> @@ -53,6 +55,7 @@ #include <unistd.h> #include <fcntl.h> +#include <sys/mman.h> #include <wayland-cursor.h> @@ -63,18 +66,20 @@ #include <X11/keysym.h> #endif -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, uint32_t id) : QtWayland::wl_seat(display->wl_registry(), id) , mQDisplay(display) , mDisplay(display->wl_display()) + , mFocusCallback(0) , mCaps(0) , mTransferDevice(0) , mPointerFocus(0) , mKeyboardFocus(0) , mTouchFocus(0) , mButtons(0) + , mCursorSerial(0) , mTouchDevice(0) #ifndef QT_NO_WAYLAND_XKB , mXkbContext(0) @@ -90,7 +95,7 @@ QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, uint32_t id) names.variant = strdup(""); names.options = strdup(""); - xkb_context *mXkbContext = xkb_context_new(xkb_context_flags(0)); + mXkbContext = xkb_context_new(xkb_context_flags(0)); if (mXkbContext) { mXkbMap = xkb_map_new_from_names(mXkbContext, &names, xkb_map_compile_flags(0)); if (mXkbMap) { @@ -167,9 +172,28 @@ void QWaylandInputDevice::removeMouseButtonFromState(Qt::MouseButton button) mButtons = mButtons & !button; } +void QWaylandInputDevice::setCursor(Qt::CursorShape newShape, QWaylandScreen *screen) +{ + struct wl_cursor_image *image = screen->waylandCursor()->cursorImage(newShape); + if (!image) { + return; + } + + struct wl_buffer *buffer = wl_cursor_image_get_buffer(image); + setCursor(buffer, image); +} + void QWaylandInputDevice::setCursor(struct wl_buffer *buffer, struct wl_cursor_image *image) { if (mCaps & WL_SEAT_CAPABILITY_POINTER) { + mCursorSerial = mEnterSerial; + /* Hide cursor */ + if (!buffer) + { + set_cursor(mEnterSerial, NULL, 0, 0); + return; + } + set_cursor(mEnterSerial, pointerSurface, image->hotspot_x, image->hotspot_y); wl_surface_attach(pointerSurface, buffer, 0, 0); @@ -187,16 +211,17 @@ void QWaylandInputDevice::pointer_enter(uint32_t serial, struct wl_surface *surf if (!surface) return; - QGuiApplication::setOverrideCursor(QCursor(Qt::ArrowCursor)); - QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); - window->handleMouseEnter(); - window->handleMouse(this, mTime, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); + window->window()->setCursor(window->window()->cursor()); + mPointerFocus = window; mTime = QWaylandDisplay::currentTimeMillisec(); mSerial = serial; mEnterSerial = serial; + + window->handleMouseEnter(this); + window->handleMouse(this, mTime, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); } void QWaylandInputDevice::pointer_leave(uint32_t time, struct wl_surface *surface) @@ -206,10 +231,8 @@ void QWaylandInputDevice::pointer_leave(uint32_t time, struct wl_surface *surfac if (!surface) return; - QGuiApplication::restoreOverrideCursor(); - QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); - window->handleMouseLeave(); + window->handleMouseLeave(this); mPointerFocus = 0; mButtons = Qt::NoButton; @@ -401,30 +424,73 @@ static const uint32_t KeyTbl[] = { 0, 0 }; -static uint32_t translateKey(uint32_t sym, char *string, size_t size) +static int keysymToQtKey(xkb_keysym_t key) { - Q_UNUSED(size); - string[0] = '\0'; + int code = 0; + int i = 0; + while (KeyTbl[i]) { + if (key == KeyTbl[i]) { + code = (int)KeyTbl[i+1]; + break; + } + i += 2; + } - if (sym >= XK_F1 && sym <= XK_F35) - return Qt::Key_F1 + (int(sym) - XK_F1); + return code; +} - for (int i = 0; KeyTbl[i]; i += 2) - if (sym == KeyTbl[i]) - return KeyTbl[i + 1]; +static int keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers &modifiers, const QString &text) +{ + int code = 0; + + if (keysym >= XKB_KEY_F1 && keysym <= XKB_KEY_F35) { + code = Qt::Key_F1 + (int(keysym) - XKB_KEY_F1); + } else if (keysym >= XKB_KEY_KP_Space && keysym <= XKB_KEY_KP_9) { + if (keysym >= XKB_KEY_KP_0) { + // numeric keypad keys + code = Qt::Key_0 + ((int)keysym - XKB_KEY_KP_0); + } else { + code = keysymToQtKey(keysym); + } + modifiers |= Qt::KeypadModifier; + } else if (text.length() == 1 && text.unicode()->unicode() > 0x1f + && text.unicode()->unicode() != 0x7f + && !(keysym >= XKB_KEY_dead_grave && keysym <= XKB_KEY_dead_currency)) { + code = text.unicode()->toUpper().unicode(); + } else { + // any other keys + code = keysymToQtKey(keysym); + } - string[0] = sym; - string[1] = '\0'; - return toupper(sym); + return code; } #endif // QT_NO_WAYLAND_XKB void QWaylandInputDevice::keyboard_keymap(uint32_t format, int32_t fd, uint32_t size) { +#ifndef QT_NO_WAYLAND_XKB + if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { + close(fd); + return; + } + + char *map_str = (char *)mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + if (map_str == MAP_FAILED) { + close(fd); + return; + } + + mXkbMap = xkb_map_new_from_string(mXkbContext, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, (xkb_keymap_compile_flags)0); + munmap(map_str, size); + close(fd); + + mXkbState = xkb_state_new(mXkbMap); +#else Q_UNUSED(format); Q_UNUSED(fd); Q_UNUSED(size); +#endif } void QWaylandInputDevice::keyboard_enter(uint32_t time, struct wl_surface *surface, struct wl_array *keys) @@ -435,10 +501,14 @@ void QWaylandInputDevice::keyboard_enter(uint32_t time, struct wl_surface *surfa if (!surface) return; + QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); mKeyboardFocus = window; - mQDisplay->setLastKeyboardFocusInputDevice(this); - QWindowSystemInterface::handleWindowActivated(window->window()); + + if (!mFocusCallback) { + mFocusCallback = wl_display_sync(mDisplay); + wl_callback_add_listener(mFocusCallback, &QWaylandInputDevice::callback, this); + } } void QWaylandInputDevice::keyboard_leave(uint32_t time, struct wl_surface *surface) @@ -447,7 +517,32 @@ void QWaylandInputDevice::keyboard_leave(uint32_t time, struct wl_surface *surfa Q_UNUSED(surface); mKeyboardFocus = NULL; - mQDisplay->setLastKeyboardFocusInputDevice(0); + + // Use a callback to set the focus because we may get a leave/enter pair, and + // the latter one would be lost in the QWindowSystemInterface queue, if + // we issue the handleWindowActivated() calls immediately. + if (!mFocusCallback) { + mFocusCallback = wl_display_sync(mDisplay); + wl_callback_add_listener(mFocusCallback, &QWaylandInputDevice::callback, this); + } +} + +const wl_callback_listener QWaylandInputDevice::callback = { + QWaylandInputDevice::focusCallback +}; + +void QWaylandInputDevice::focusCallback(void *data, struct wl_callback *callback, uint32_t time) +{ + Q_UNUSED(time); + Q_UNUSED(callback); + QWaylandInputDevice *self = static_cast<QWaylandInputDevice *>(data); + if (self->mFocusCallback) { + wl_callback_destroy(self->mFocusCallback); + self->mFocusCallback = 0; + } + + self->mQDisplay->setLastKeyboardFocusInputDevice(self->mKeyboardFocus ? self : 0); + QWindowSystemInterface::handleWindowActivated(self->mKeyboardFocus ? self->mKeyboardFocus->window() : 0); } void QWaylandInputDevice::keyboard_key(uint32_t serial, uint32_t time, uint32_t key, uint32_t state) @@ -476,15 +571,15 @@ void QWaylandInputDevice::keyboard_key(uint32_t serial, uint32_t time, uint32_t Qt::KeyboardModifiers modifiers = translateModifiers(mXkbState); QEvent::Type type = isDown ? QEvent::KeyPress : QEvent::KeyRelease; - char s[2]; - sym = translateKey(sym, s, sizeof s); + uint utf32 = xkb_keysym_to_utf32(sym); + QString text = QString::fromUcs4(&utf32, 1); + + int qtkey = keysymToQtKey(sym, modifiers, text); - if (window) - QWindowSystemInterface::handleExtendedKeyEvent(window->window(), - time, type, sym, - modifiers, - code, 0, 0, - QString::fromLatin1(s)); + QWindowSystemInterface::handleExtendedKeyEvent(window->window(), + time, type, qtkey, + modifiers, + code, 0, 0, text); } #else // Generic fallback for single hard keys: Assume 'key' is a Qt key code. @@ -621,7 +716,9 @@ void QWaylandInputDevice::touch_frame() return; } - QWindowSystemInterface::handleTouchEvent(0, mTouchDevice, mTouchPoints); + QWindow *window = mTouchFocus ? mTouchFocus->window() : 0; + + QWindowSystemInterface::handleTouchEvent(window, mTouchDevice, mTouchPoints); bool allReleased = true; for (int i = 0; i < mTouchPoints.count(); ++i) @@ -634,7 +731,9 @@ void QWaylandInputDevice::touch_frame() mTouchPoints.clear(); if (allReleased) { - QWindowSystemInterface::handleTouchEvent(0, mTouchDevice, mTouchPoints); + QWindowSystemInterface::handleTouchEvent(window, mTouchDevice, mTouchPoints); mPrevTouchPoints.clear(); } } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandinputdevice.h b/src/plugins/platforms/wayland_common/qwaylandinputdevice.h index c0e57a909..c92026841 100644 --- a/src/plugins/platforms/wayland_common/qwaylandinputdevice.h +++ b/src/plugins/platforms/wayland_common/qwaylandinputdevice.h @@ -75,6 +75,7 @@ public: struct ::wl_seat *wl_seat() { return QtWayland::wl_seat::object(); } + void setCursor(Qt::CursorShape cursor, QWaylandScreen *screen); void setCursor(struct wl_buffer *buffer, struct wl_cursor_image *image); void handleWindowDestroyed(QWaylandWindow *window); @@ -84,10 +85,12 @@ public: void removeMouseButtonFromState(Qt::MouseButton button); uint32_t serial() const; + uint32_t cursorSerial() const { return mCursorSerial; } private: QWaylandDisplay *mQDisplay; struct wl_display *mDisplay; + struct wl_callback *mFocusCallback; uint32_t mCaps; @@ -104,6 +107,7 @@ private: uint32_t mTime; uint32_t mSerial; uint32_t mEnterSerial; + uint32_t mCursorSerial; void seat_capabilities(uint32_t caps) Q_DECL_OVERRIDE; @@ -152,6 +156,9 @@ private: void handleTouchPoint(int id, double x, double y, Qt::TouchPointState state); + static const wl_callback_listener callback; + static void focusCallback(void *data, struct wl_callback *callback, uint32_t time); + QList<QWindowSystemInterface::TouchPoint> mTouchPoints; QList<QWindowSystemInterface::TouchPoint> mPrevTouchPoints; QTouchDevice *mTouchDevice; diff --git a/src/plugins/platforms/wayland_common/qwaylandintegration.cpp b/src/plugins/platforms/wayland_common/qwaylandintegration.cpp index c3a479a21..b0d5b271f 100644 --- a/src/plugins/platforms/wayland_common/qwaylandintegration.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandintegration.cpp @@ -47,6 +47,7 @@ #include "qwaylandnativeinterface.h" #include "qwaylandclipboard.h" #include "qwaylanddnd.h" +#include "qwaylandwindowmanagerintegration.h" #include "QtPlatformSupport/private/qgenericunixfontdatabase_p.h" #include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h> @@ -67,11 +68,37 @@ #include "qwaylandglintegration.h" #endif -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT -#include "windowmanager_integration/qwaylandwindowmanagerintegration.h" -#endif -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE + +class GenericWaylandTheme: public QGenericUnixTheme +{ +public: + static QStringList themeNames() + { + QStringList result; + + if (QGuiApplication::desktopSettingsAware()) { + const QByteArray desktopEnvironment = QGuiApplicationPrivate::platformIntegration()->services()->desktopEnvironment(); + + // Ignore X11 desktop environments + if (!desktopEnvironment.isEmpty() && + desktopEnvironment != QByteArrayLiteral("UNKNOWN") && + desktopEnvironment != QByteArrayLiteral("KDE") && + desktopEnvironment != QByteArrayLiteral("GNOME") && + desktopEnvironment != QByteArrayLiteral("UNITY") && + desktopEnvironment != QByteArrayLiteral("MATE") && + desktopEnvironment != QByteArrayLiteral("XFCE") && + desktopEnvironment != QByteArrayLiteral("LXDE")) + result.push_back(desktopEnvironment.toLower()); + } + + if (result.isEmpty()) + result.push_back(QLatin1String(QGenericUnixTheme::name)); + + return result; + } +}; QWaylandIntegration::QWaylandIntegration() : mFontDb(new QGenericUnixFontDatabase()) @@ -84,7 +111,6 @@ QWaylandIntegration::QWaylandIntegration() #endif { QGuiApplicationPrivate::instance()->setEventDispatcher(mEventDispatcher); - QGuiApplication::setDesktopSettingsAware(false); mDisplay = new QWaylandDisplay(); mClipboard = new QWaylandClipboard(mDisplay); mDrag = new QWaylandDrag(mDisplay); @@ -184,10 +210,9 @@ QPlatformInputContext *QWaylandIntegration::inputContext() const QVariant QWaylandIntegration::styleHint(StyleHint hint) const { -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT if (hint == ShowIsFullScreen && mDisplay->windowManagerIntegration()) return mDisplay->windowManagerIntegration()->showIsFullScreen(); -#endif + return QPlatformIntegration::styleHint(hint); } @@ -198,11 +223,7 @@ QPlatformAccessibility *QWaylandIntegration::accessibility() const QPlatformServices *QWaylandIntegration::services() const { -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT return mDisplay->windowManagerIntegration(); -#else - return QWaylandIntegration::services(); -#endif } QWaylandDisplay *QWaylandIntegration::display() const @@ -212,10 +233,12 @@ QWaylandDisplay *QWaylandIntegration::display() const QStringList QWaylandIntegration::themeNames() const { - return QGenericUnixTheme::themeNames(); + return GenericWaylandTheme::themeNames(); } QPlatformTheme *QWaylandIntegration::createPlatformTheme(const QString &name) const { - return QGenericUnixTheme::createUnixTheme(name); + return GenericWaylandTheme::createUnixTheme(name); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandnativeinterface.cpp b/src/plugins/platforms/wayland_common/qwaylandnativeinterface.cpp index 31d25c0f9..354e8dbaa 100644 --- a/src/plugins/platforms/wayland_common/qwaylandnativeinterface.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandnativeinterface.cpp @@ -45,12 +45,11 @@ #include "qwaylandextendedsurface.h" #include "qwaylandintegration.h" #include "qwaylanddisplay.h" +#include "qwaylandwindowmanagerintegration.h" #include <QtGui/private/qguiapplication_p.h> #include <QtGui/QScreen> -#include "windowmanager_integration/qwaylandwindowmanagerintegration.h" - -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandNativeInterface::QWaylandNativeInterface(QWaylandIntegration *integration) : m_integration(integration) @@ -78,7 +77,7 @@ void *QWaylandNativeInterface::nativeResourceForWindow(const QByteArray &resourc if (lowerCaseResource == "compositor") return const_cast<wl_compositor *>(m_integration->display()->wl_compositor()); if (lowerCaseResource == "surface") { - return ((QWaylandWindow *) window->handle())->wl_surface(); + return ((QWaylandWindow *) window->handle())->object(); } return NULL; @@ -131,3 +130,5 @@ void QWaylandNativeInterface::emitWindowPropertyChanged(QPlatformWindow *window, { emit windowPropertyChanged(window,name); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandqtkey.cpp b/src/plugins/platforms/wayland_common/qwaylandqtkey.cpp index d9f2071ec..e723078cd 100644 --- a/src/plugins/platforms/wayland_common/qwaylandqtkey.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandqtkey.cpp @@ -42,7 +42,7 @@ #include "qwaylandqtkey.h" #include "qwaylandinputdevice.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandQtKeyExtension::QWaylandQtKeyExtension(QWaylandDisplay *display, uint32_t id) : QtWayland::qt_key_extension(display->wl_registry(), id) @@ -63,7 +63,7 @@ void QWaylandQtKeyExtension::key_extension_qtkey(uint32_t time, { QList<QWaylandInputDevice *> inputDevices = m_display->inputDevices(); if (inputDevices.isEmpty()) { - qWarning("wl_qtkey_extension: handle_qtkey: No input device"); + qWarning("qt_key_extension: handle_qtkey: No input device"); return; } @@ -71,7 +71,7 @@ void QWaylandQtKeyExtension::key_extension_qtkey(uint32_t time, QWaylandWindow *win = dev->mKeyboardFocus; if (!win || !win->window()) { - qWarning("wl_qtkey_extension: handle_qtkey: No keyboard focus"); + qWarning("qt_key_extension: handle_qtkey: No keyboard focus"); return; } @@ -80,3 +80,5 @@ void QWaylandQtKeyExtension::key_extension_qtkey(uint32_t time, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandscreen.cpp b/src/plugins/platforms/wayland_common/qwaylandscreen.cpp index 1cb1b9cfb..5956c2fd3 100644 --- a/src/plugins/platforms/wayland_common/qwaylandscreen.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandscreen.cpp @@ -47,7 +47,7 @@ #include <qpa/qwindowsysteminterface.h> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, uint32_t id) : QtWayland::wl_output(waylandDisplay->wl_registry(), id) @@ -56,6 +56,7 @@ QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, uint32_t id) , mDepth(32) , mRefreshRate(60000) , mFormat(QImage::Format_ARGB32_Premultiplied) + , mOutputName(QStringLiteral("Screen%1").arg(id)) , mWaylandCursor(new QWaylandCursor(this)) { // handle case of output extension global being sent after outputs @@ -138,11 +139,12 @@ void QWaylandScreen::output_mode(uint32_t flags, int width, int height, int refr if (size != mGeometry.size()) { mGeometry.setSize(size); QWindowSystemInterface::handleScreenGeometryChange(screen(), mGeometry); + QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), mGeometry); } if (refresh != mRefreshRate) { mRefreshRate = refresh; - QWindowSystemInterface::handleScreenRefreshRateChange(screen(), mRefreshRate); + QWindowSystemInterface::handleScreenRefreshRateChange(screen(), refreshRate()); } } @@ -155,9 +157,11 @@ void QWaylandScreen::output_geometry(int32_t x, int32_t y, { Q_UNUSED(subpixel); Q_UNUSED(make); - Q_UNUSED(model); Q_UNUSED(transform); + if (!model.isEmpty()) + mOutputName = model; + QRect geom(x, y, width, height); if (mGeometry == geom) @@ -165,4 +169,7 @@ void QWaylandScreen::output_geometry(int32_t x, int32_t y, mGeometry = geom; QWindowSystemInterface::handleScreenGeometryChange(screen(), mGeometry); + QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), mGeometry); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandscreen.h b/src/plugins/platforms/wayland_common/qwaylandscreen.h index 005f25eea..91848ad05 100644 --- a/src/plugins/platforms/wayland_common/qwaylandscreen.h +++ b/src/plugins/platforms/wayland_common/qwaylandscreen.h @@ -69,7 +69,10 @@ public: Qt::ScreenOrientation orientation() const; qreal refreshRate() const; + QString name() const { return mOutputName; } + QPlatformCursor *cursor() const; + QWaylandCursor *waylandCursor() const { return mWaylandCursor; }; ::wl_output *output() { return object(); } @@ -94,6 +97,7 @@ private: int mRefreshRate; QImage::Format mFormat; QSize mPhysicalSize; + QString mOutputName; QWaylandCursor *mWaylandCursor; }; diff --git a/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp b/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp index 986890732..6e638e6b1 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp @@ -49,7 +49,7 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandShellSurface::QWaylandShellSurface(struct ::wl_shell_surface *shell_surface, QWaylandWindow *window) : QtWayland::wl_shell_surface(shell_surface) @@ -114,7 +114,7 @@ void QWaylandShellSurface::setTopLevel() void QWaylandShellSurface::updateTransientParent(QWindow *parent) { QWaylandWindow *parent_wayland_window = static_cast<QWaylandWindow *>(parent->handle()); - if (!parent_wayland_window || !parent_wayland_window->shellSurface()) + if (!parent_wayland_window) return; // set_transient expects a position relative to the parent @@ -132,7 +132,7 @@ void QWaylandShellSurface::updateTransientParent(QWindow *parent) || wf.testFlag(Qt::WindowTransparentForInput)) flags |= WL_SHELL_SURFACE_TRANSIENT_INACTIVE; - set_transient(parent_wayland_window->wl_surface(), + set_transient(parent_wayland_window->object(), transientPos.x(), transientPos.y(), flags); @@ -140,8 +140,8 @@ void QWaylandShellSurface::updateTransientParent(QWindow *parent) void QWaylandShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial) { - QWaylandWindow *parent_wayland_window = parent->topLevelWindow(); - if (!parent_wayland_window || !parent_wayland_window->shellSurface()) + QWaylandWindow *parent_wayland_window = parent; + if (!parent_wayland_window) return; // set_popup expects a position relative to the parent @@ -152,19 +152,8 @@ void QWaylandShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevice transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top()); } - wl_shell_surface_set_popup(object(), device->wl_seat(), serial, - parent_wayland_window->wl_surface(), - transientPos.x(), transientPos.y(), 0); -} - -void QWaylandShellSurface::setClassName(const char *className) -{ - set_class(className); -} - -void QWaylandShellSurface::setTitle(const char *title) -{ - set_title(title); + set_popup(device->wl_seat(), serial, parent_wayland_window->object(), + transientPos.x(), transientPos.y(), 0); } void QWaylandShellSurface::shell_surface_ping(uint32_t serial) @@ -183,3 +172,5 @@ void QWaylandShellSurface::shell_surface_popup_done() { QCoreApplication::postEvent(m_window->window(), new QCloseEvent()); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandshellsurface.h b/src/plugins/platforms/wayland_common/qwaylandshellsurface.h index 9e886cf0a..172a0f965 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshellsurface.h +++ b/src/plugins/platforms/wayland_common/qwaylandshellsurface.h @@ -76,10 +76,6 @@ private: void updateTransientParent(QWindow *parent); void setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial); - void setClassName(const char *_class); - - void setTitle(const char *title); - QWaylandWindow *m_window; bool m_maximized; bool m_fullscreen; diff --git a/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.cpp b/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.cpp index 93161a3f7..00a4b13a2 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.cpp @@ -172,11 +172,13 @@ void QWaylandShmBackingStore::beginPaint(const QRegion &) waylandWindow->waitForFrameSync(); } + waylandWindow()->setCanResize(false); } void QWaylandShmBackingStore::endPaint() { mPainting = false; + waylandWindow()->setCanResize(true); } void QWaylandShmBackingStore::ensureSize() @@ -224,8 +226,8 @@ void QWaylandShmBackingStore::flush(QWindow *window, const QRegion ®ion, cons waylandWindow()->damage(rect); } } + waylandWindow()->commit(); mFrontBufferIsDirty = false; - waylandWindow()->doResize(); } void QWaylandShmBackingStore::resize(const QSize &size, const QRegion &) @@ -299,18 +301,17 @@ void QWaylandShmBackingStore::done(void *data, wl_callback *callback, uint32_t t wl_callback_destroy(self->mFrameCallback); self->mFrameCallback = 0; - if (self->mFrontBuffer != window->attached()) { - delete window->attached(); - } - - if (window->attached() != self->mFrontBuffer) - window->attachOffset(self->mFrontBuffer); if (self->mFrontBufferIsDirty && !self->mPainting) { self->mFrontBufferIsDirty = false; - self->mFrameCallback = wl_surface_frame(window->wl_surface()); + self->mFrameCallback = wl_surface_frame(window->object()); wl_callback_add_listener(self->mFrameCallback,&self->frameCallbackListener,self); + if (self->mFrontBuffer != window->attached()) { + delete window->attached(); + } + window->attachOffset(self->mFrontBuffer); window->damage(QRect(QPoint(0,0),self->mFrontBuffer->size())); + window->commit(); } } @@ -319,4 +320,3 @@ const struct wl_callback_listener QWaylandShmBackingStore::frameCallbackListener }; QT_END_NAMESPACE - diff --git a/src/plugins/platforms/wayland_common/qwaylandshmwindow.cpp b/src/plugins/platforms/wayland_common/qwaylandshmwindow.cpp index f4a0ede0c..48a1bfd53 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshmwindow.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandshmwindow.cpp @@ -47,7 +47,7 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandShmWindow::QWaylandShmWindow(QWindow *window) : QWaylandWindow(window) @@ -69,3 +69,5 @@ void QWaylandShmWindow::setBackingStore(QWaylandShmBackingStore *backingStore) { mBackingStore = backingStore; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandsubsurface.cpp b/src/plugins/platforms/wayland_common/qwaylandsubsurface.cpp index 99713bb6b..0e9d575a9 100644 --- a/src/plugins/platforms/wayland_common/qwaylandsubsurface.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandsubsurface.cpp @@ -45,7 +45,7 @@ #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandSubSurface::QWaylandSubSurface(QWaylandWindow *window, struct ::qt_sub_surface *sub_surface) : QtWayland::qt_sub_surface(sub_surface) @@ -87,3 +87,5 @@ void QWaylandSubSurface::adjustPositionOfChildren() } setPositionToParent(m_window); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandtouch.cpp b/src/plugins/platforms/wayland_common/qwaylandtouch.cpp index b19165d6d..5835d9d3c 100644 --- a/src/plugins/platforms/wayland_common/qwaylandtouch.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandtouch.cpp @@ -42,7 +42,7 @@ #include "qwaylandtouch.h" #include "qwaylandinputdevice.h" -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandTouchExtension::QWaylandTouchExtension(QWaylandDisplay *display, uint32_t id) : QtWayland::qt_touch_extension(display->wl_registry(), id), @@ -78,7 +78,7 @@ void QWaylandTouchExtension::touch_extension_touch(uint32_t time, if (!mInputDevice) { QList<QWaylandInputDevice *> inputDevices = mDisplay->inputDevices(); if (inputDevices.isEmpty()) { - qWarning("wl_touch_extension: handle_touch: No input devices"); + qWarning("qt_touch_extension: handle_touch: No input devices"); return; } mInputDevice = inputDevices.first(); @@ -89,7 +89,7 @@ void QWaylandTouchExtension::touch_extension_touch(uint32_t time, if (!win) win = mInputDevice->mKeyboardFocus; if (!win || !win->window()) { - qWarning("wl_touch_extension: handle_touch: No pointer focus"); + qWarning("qt_touch_extension: handle_touch: No pointer focus"); return; } mTargetWindow = win->window(); @@ -205,3 +205,5 @@ void QWaylandTouchExtension::touch_extension_configure(uint32_t flags) { mFlags = flags; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandwindow.cpp b/src/plugins/platforms/wayland_common/qwaylandwindow.cpp index 666222107..27b624fb2 100644 --- a/src/plugins/platforms/wayland_common/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandwindow.cpp @@ -49,25 +49,23 @@ #include "qwaylandextendedsurface.h" #include "qwaylandsubsurface.h" #include "qwaylanddecoration.h" +#include "qwaylandwindowmanagerintegration.h" #include <QtCore/QFileInfo> #include <QtGui/QWindow> -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT -#include "windowmanager_integration/qwaylandwindowmanagerintegration.h" -#endif - -#include <QCoreApplication> +#include <QGuiApplication> #include <qpa/qwindowsysteminterface.h> #include <QtCore/QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE QWaylandWindow::QWaylandWindow(QWindow *window) : QObject() , QPlatformWindow(window) - , mDisplay(QWaylandScreen::waylandScreenFromWindow(window)->display()) + , mScreen(QWaylandScreen::waylandScreenFromWindow(window)) + , mDisplay(mScreen->display()) , mShellSurface(0) , mExtendedWindow(0) , mSubSurfaceWindow(0) @@ -77,7 +75,8 @@ QWaylandWindow::QWaylandWindow(QWindow *window) , mBuffer(0) , mWaitingForFrameSync(false) , mFrameCallback(0) - , mResizeExposedSent(false) + , mRequestResizeSent(false) + , mCanResize(true) , mSentInitialResize(false) , mMouseDevice(0) , mMouseSerial(0) @@ -88,25 +87,26 @@ QWaylandWindow::QWaylandWindow(QWindow *window) static WId id = 1; mWindowId = id++; - if (mDisplay->shell() && !(window->flags() & Qt::BypassWindowManagerHint)) - mShellSurface = new QWaylandShellSurface(mDisplay->shell()->get_shell_surface(wl_surface()), this); + if (mDisplay->shell() && window->type() & Qt::Window && !(window->flags() & Qt::BypassWindowManagerHint)) + mShellSurface = new QWaylandShellSurface(mDisplay->shell()->get_shell_surface(object()), this); if (mDisplay->windowExtension()) - mExtendedWindow = new QWaylandExtendedSurface(this, mDisplay->windowExtension()->get_extended_surface(wl_surface())); + mExtendedWindow = new QWaylandExtendedSurface(this, mDisplay->windowExtension()->get_extended_surface(object())); if (mDisplay->subSurfaceExtension()) - mSubSurfaceWindow = new QWaylandSubSurface(this, mDisplay->subSurfaceExtension()->get_sub_surface_aware_surface(wl_surface())); + mSubSurfaceWindow = new QWaylandSubSurface(this, mDisplay->subSurfaceExtension()->get_sub_surface_aware_surface(object())); if (mShellSurface) { // Set surface class to the .desktop file name (obtained from executable name) QFileInfo exeFileInfo(qApp->applicationFilePath()); QString className = exeFileInfo.baseName() + QLatin1String(".desktop"); - mShellSurface->setClassName(className.toUtf8().constData()); + mShellSurface->set_class(className); } if (QPlatformWindow::parent() && mSubSurfaceWindow) { mSubSurfaceWindow->setParent(static_cast<const QWaylandWindow *>(QPlatformWindow::parent())); - } else if (window->transientParent()) { - if (window->transientParent() && mShellSurface) + } else if (window->transientParent() && mShellSurface) { + if (window->type() != Qt::Popup) { mShellSurface->updateTransientParent(window->transientParent()); + } } else if (mShellSurface) { mShellSurface->setTopLevel(); } @@ -123,10 +123,18 @@ QWaylandWindow::~QWaylandWindow() delete mExtendedWindow; destroy(); } + if (mFrameCallback) + wl_callback_destroy(mFrameCallback); QList<QWaylandInputDevice *> inputDevices = mDisplay->inputDevices(); for (int i = 0; i < inputDevices.size(); ++i) inputDevices.at(i)->handleWindowDestroyed(this); + + const QWindow *parent = window(); + foreach (QWindow *w, QGuiApplication::topLevelWindows()) { + if (w->transientParent() == parent) + QWindowSystemInterface::handleCloseEvent(w); + } } QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface) @@ -150,8 +158,7 @@ void QWaylandWindow::setParent(const QPlatformWindow *parent) void QWaylandWindow::setWindowTitle(const QString &title) { if (mShellSurface) { - QByteArray titleUtf8 = title.toUtf8(); - mShellSurface->setTitle(titleUtf8.constData()); + mShellSurface->set_title(title); } if (mWindowDecoration && window()->isVisible()) @@ -175,6 +182,11 @@ void QWaylandWindow::setGeometry(const QRect &rect) if (mWindowDecoration && window()->isVisible()) mWindowDecoration->update(); + + if (mConfigure.isEmpty()) { + QWindowSystemInterface::handleGeometryChange(window(), rect); + QWindowSystemInterface::handleExposeEvent(window(), QRegion(rect)); + } } void QWaylandWindow::setVisible(bool visible) @@ -201,38 +213,42 @@ void QWaylandWindow::setVisible(bool visible) // there was no frame before it will be stuck at the waitForFrameSync() in // QWaylandShmBackingStore::beginPaint(). } else { - QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); + QWindowSystemInterface::handleExposeEvent(window(), QRegion()); attach(static_cast<QWaylandBuffer *>(0), 0, 0); } damage(QRect(QPoint(0,0),geometry().size())); + commit(); } -bool QWaylandWindow::isExposed() const +void QWaylandWindow::raise() { - if (!window()->isVisible()) - return false; if (mExtendedWindow) - return mExtendedWindow->isExposed(); - return true; + mExtendedWindow->raise(); } +void QWaylandWindow::lower() +{ + if (mExtendedWindow) + mExtendedWindow->lower(); +} + void QWaylandWindow::configure(uint32_t edges, int32_t width, int32_t height) { + QMutexLocker resizeLocker(&mResizeLock); mConfigure.edges |= edges; mConfigure.width = width; mConfigure.height = height; - if (!mResizeExposedSent) { - mResizeExposedSent = true; - QMetaObject::invokeMethod(this, "doResize", Qt::QueuedConnection); + if (!mRequestResizeSent && !mConfigure.isEmpty()) { + mRequestResizeSent= true; + QMetaObject::invokeMethod(this, "requestResize", Qt::QueuedConnection); } } void QWaylandWindow::doResize() { - mResizeExposedSent = false; if (mConfigure.isEmpty()) { return; } @@ -255,13 +271,34 @@ void QWaylandWindow::doResize() } mOffset += QPoint(x, y); - mResizeLock.lock(); setGeometry(geometry); - mResizeLock.unlock(); mConfigure.clear(); QWindowSystemInterface::handleGeometryChange(window(), geometry); - QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry)); +} + +void QWaylandWindow::setCanResize(bool canResize) +{ + QMutexLocker lock(&mResizeLock); + mCanResize = canResize; + + if (canResize && !mConfigure.isEmpty()) { + doResize(); + QWindowSystemInterface::handleExposeEvent(window(), geometry()); + } +} + +void QWaylandWindow::requestResize() +{ + QMutexLocker lock(&mResizeLock); + + if (mCanResize) { + doResize(); + } + + mRequestResizeSent = false; + lock.unlock(); + QWindowSystemInterface::handleExposeEvent(window(), geometry()); QWindowSystemInterface::flushWindowSystemEvents(); } @@ -269,8 +306,10 @@ void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y) { mBuffer = buffer; - if (window()->isVisible()) + if (mBuffer) attach(mBuffer->buffer(), x, y); + else + QtWayland::wl_surface::attach(0, 0, 0); } void QWaylandWindow::attachOffset(QWaylandBuffer *buffer) @@ -293,9 +332,9 @@ void QWaylandWindow::damage(const QRect &rect) wl_callback_add_listener(mFrameCallback,&QWaylandWindow::callbackListener,this); mWaitingForFrameSync = true; } - - damage(rect.x(), rect.y(), rect.width(), rect.height()); - commit(); + if (mBuffer) { + damage(rect.x(), rect.y(), rect.width(), rect.height()); + } } const wl_callback_listener QWaylandWindow::callbackListener = { @@ -379,6 +418,9 @@ void QWaylandWindow::setWindowState(Qt::WindowState state) default: mShellSurface->setNormal(); } + + QWindowSystemInterface::handleWindowStateChanged(window(), mState); + QWindowSystemInterface::flushWindowSystemEvents(); // Required for oldState to work on WindowStateChanged } void QWaylandWindow::setWindowFlags(Qt::WindowFlags flags) @@ -434,21 +476,20 @@ void QWaylandWindow::setDecoration(QWaylandDecoration *decoration) } } -QWaylandWindow *QWaylandWindow::topLevelWindow() +static QWindow *topLevelWindow(QWindow *window) { - QWaylandWindow *w = this; - while (w->QPlatformWindow::parent()) { - w = static_cast<QWaylandWindow *>(w->QPlatformWindow::parent()); - } - return w; + while (QWindow *parent = window->parent()) + window = parent; + return window; } QWaylandWindow *QWaylandWindow::transientParent() const { if (window()->transientParent()) { - // Take the top level window here, since the transient parent may be some non-native - // QWindow, which cannot have the mMouseDevice and mMouseSerial - return static_cast<QWaylandWindow *>(window()->transientParent()->handle())->topLevelWindow(); + // Take the top level window here, since the transient parent may be a QWidgetWindow + // or some other window without a shell surface, which is then not able to get mouse + // events, nor set mMouseSerial and mMouseDevice. + return static_cast<QWaylandWindow *>(topLevelWindow(window()->transientParent())->handle()); } return 0; } @@ -468,23 +509,24 @@ void QWaylandWindow::handleMouse(QWaylandInputDevice *inputDevice, ulong timesta QWindowSystemInterface::handleMouseEvent(window(),timestamp,local,global,b,mods); } -void QWaylandWindow::handleMouseEnter() +void QWaylandWindow::handleMouseEnter(QWaylandInputDevice *inputDevice) { if (!mWindowDecoration) { QWindowSystemInterface::handleEnterEvent(window()); } + restoreMouseCursor(inputDevice); } -void QWaylandWindow::handleMouseLeave() +void QWaylandWindow::handleMouseLeave(QWaylandInputDevice *inputDevice) { if (mWindowDecoration) { if (mMouseEventsInContentArea) { QWindowSystemInterface::handleLeaveEvent(window()); } - mWindowDecoration->restoreMouseCursor(); } else { QWindowSystemInterface::handleLeaveEvent(window()); } + restoreMouseCursor(inputDevice); } void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, ulong timestamp, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods) @@ -505,7 +547,7 @@ void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDe globalTranslated.setX(globalTranslated.x() - marg.left()); globalTranslated.setY(globalTranslated.y() - marg.top()); if (!mMouseEventsInContentArea) { - mWindowDecoration->restoreMouseCursor(); + restoreMouseCursor(inputDevice); QWindowSystemInterface::handleEnterEvent(window()); } QWindowSystemInterface::handleMouseEvent(window(), timestamp, localTranslated, globalTranslated, b, mods); @@ -519,3 +561,18 @@ void QWaylandWindow::handleMouseEventWithDecoration(QWaylandInputDevice *inputDe mWindowDecoration->handleMouse(inputDevice,local,global,b,mods); } } + +void QWaylandWindow::setMouseCursor(QWaylandInputDevice *device, Qt::CursorShape shape) +{ + if (m_cursorShape != shape || device->serial() > device->cursorSerial()) { + device->setCursor(shape, mScreen); + m_cursorShape = shape; + } +} + +void QWaylandWindow::restoreMouseCursor(QWaylandInputDevice *device) +{ + setMouseCursor(device, window()->cursor().shape()); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandwindow.h b/src/plugins/platforms/wayland_common/qwaylandwindow.h index 3cd891f65..8fd104d0a 100644 --- a/src/plugins/platforms/wayland_common/qwaylandwindow.h +++ b/src/plugins/platforms/wayland_common/qwaylandwindow.h @@ -122,10 +122,6 @@ public: QMargins frameMargins() const; - // TODO: remove? - struct ::wl_surface *wl_surface() { return object(); } - const struct ::wl_surface *wl_surface() const { return object(); } - static QWaylandWindow *fromWlSurface(::wl_surface *surface); QWaylandShellSurface *shellSurface() const; @@ -137,7 +133,8 @@ public: void setWindowState(Qt::WindowState state); void setWindowFlags(Qt::WindowFlags flags); - bool isExposed() const; + void raise() Q_DECL_OVERRIDE; + void lower() Q_DECL_OVERRIDE; QWaylandDecoration *decoration() const; void setDecoration(QWaylandDecoration *decoration); @@ -149,25 +146,27 @@ public: const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods); - void handleMouseEnter(); - void handleMouseLeave(); + void handleMouseEnter(QWaylandInputDevice *inputDevice); + void handleMouseLeave(QWaylandInputDevice *inputDevice); bool createDecoration(); inline bool isMaximized() const { return mState == Qt::WindowMaximized; } inline bool isFullscreen() const { return mState == Qt::WindowFullScreen; } - QWaylandWindow *topLevelWindow(); + void setMouseCursor(QWaylandInputDevice *device, Qt::CursorShape shape); + void restoreMouseCursor(QWaylandInputDevice *device); + QWaylandWindow *transientParent() const; QMutex *resizeMutex() { return &mResizeLock; } - -public slots: void doResize(); + void setCanResize(bool canResize); +public slots: + void requestResize(); protected: - virtual void createDecorationInstance() {} - + QWaylandScreen *mScreen; QWaylandDisplay *mDisplay; QWaylandShellSurface *mShellSurface; QWaylandExtendedSurface *mExtendedWindow; @@ -176,6 +175,7 @@ protected: QWaylandDecoration *mWindowDecoration; bool mMouseEventsInContentArea; Qt::MouseButtons mMousePressedInContentArea; + Qt::CursorShape m_cursorShape; QWaylandBuffer *mBuffer; WId mWindowId; @@ -185,7 +185,8 @@ protected: QMutex mResizeLock; QWaylandWindowConfigure mConfigure; - bool mResizeExposedSent; + bool mRequestResizeSent; + bool mCanResize; bool mSentInitialResize; QPoint mOffset; diff --git a/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.cpp b/src/plugins/platforms/wayland_common/qwaylandwindowmanagerintegration.cpp index 673400bda..7543ba13c 100644 --- a/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandwindowmanagerintegration.cpp @@ -54,7 +54,7 @@ #include <QDebug> -QT_USE_NAMESPACE +QT_BEGIN_NAMESPACE class QWaylandWindowManagerIntegrationPrivate { public: @@ -93,7 +93,7 @@ bool QWaylandWindowManagerIntegration::showIsFullScreen() const void QWaylandWindowManagerIntegration::wlHandleListenerGlobal(void *data, wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) { Q_UNUSED(version); - if (interface == "wl_windowmanager") + if (interface == "qt_windowmanager") static_cast<QWaylandWindowManagerIntegration *>(data)->init(registry, id); } @@ -108,6 +108,27 @@ void QWaylandWindowManagerIntegration::windowmanager_quit() QGuiApplication::quit(); } +QByteArray QWaylandWindowManagerIntegration::desktopEnvironment() const +{ + const QByteArray xdgCurrentDesktop = qgetenv("XDG_CURRENT_DESKTOP"); + if (!xdgCurrentDesktop.isEmpty()) + return xdgCurrentDesktop.toUpper(); // KDE, GNOME, UNITY, LXDE, MATE, XFCE... + + // Classic fallbacks + if (!qEnvironmentVariableIsEmpty("KDE_FULL_SESSION")) + return QByteArrayLiteral("KDE"); + if (!qEnvironmentVariableIsEmpty("GNOME_DESKTOP_SESSION_ID")) + return QByteArrayLiteral("GNOME"); + + // Fallback to checking $DESKTOP_SESSION (unreliable) + const QByteArray desktopSession = qgetenv("DESKTOP_SESSION"); + if (desktopSession == "gnome") + return QByteArrayLiteral("GNOME"); + if (desktopSession == "xfce") + return QByteArrayLiteral("XFCE"); + + return QByteArrayLiteral("UNKNOWN"); +} void QWaylandWindowManagerIntegration::openUrl_helper(const QUrl &url) { @@ -134,3 +155,5 @@ bool QWaylandWindowManagerIntegration::openDocument(const QUrl &url) openUrl_helper(url); return true; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.h b/src/plugins/platforms/wayland_common/qwaylandwindowmanagerintegration.h index 0982632d2..4524ce121 100644 --- a/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.h +++ b/src/plugins/platforms/wayland_common/qwaylandwindowmanagerintegration.h @@ -65,6 +65,8 @@ public: explicit QWaylandWindowManagerIntegration(QWaylandDisplay *waylandDisplay); virtual ~QWaylandWindowManagerIntegration(); + QByteArray desktopEnvironment() const; + bool openUrl(const QUrl &url); bool openDocument(const QUrl &url); diff --git a/src/plugins/platforms/wayland_common/wayland_common.pro b/src/plugins/platforms/wayland_common/wayland_common.pro index 4a1b0e885..d8aedb65f 100644 --- a/src/plugins/platforms/wayland_common/wayland_common.pro +++ b/src/plugins/platforms/wayland_common/wayland_common.pro @@ -2,7 +2,6 @@ TEMPLATE = lib CONFIG += staticlib include ($$PWD/wayland_common_share.pri) -include (windowmanager_integration/windowmanager_integration.pri) SOURCES += qwaylandintegration.cpp \ qwaylandnativeinterface.cpp \ @@ -26,7 +25,8 @@ SOURCES += qwaylandintegration.cpp \ qwaylandqtkey.cpp \ ../../../shared/qwaylandmimehelper.cpp \ qwaylanddecoration.cpp \ - qwaylandeventthread.cpp + qwaylandeventthread.cpp\ + qwaylandwindowmanagerintegration.cpp HEADERS += qwaylandintegration.h \ qwaylandnativeinterface.h \ @@ -51,7 +51,8 @@ HEADERS += qwaylandintegration.h \ qwaylandqtkey.h \ ../../../shared/qwaylandmimehelper.h \ qwaylanddecoration.h \ - qwaylandeventthread.h + qwaylandeventthread.h \ + qwaylandwindowmanagerintegration.h contains(DEFINES, QT_WAYLAND_GL_SUPPORT) { SOURCES += qwaylandglintegration.cpp @@ -64,6 +65,7 @@ WAYLANDCLIENTSOURCES += \ ../../../extensions/output-extension.xml \ ../../../extensions/touch-extension.xml \ ../../../extensions/qtkey-extension.xml \ + ../../../extensions/windowmanager.xml \ PLUGIN_TYPE = platforms diff --git a/src/plugins/platforms/wayland_common/windowmanager_integration/windowmanager_integration.pri b/src/plugins/platforms/wayland_common/windowmanager_integration/windowmanager_integration.pri deleted file mode 100644 index 9228358ec..000000000 --- a/src/plugins/platforms/wayland_common/windowmanager_integration/windowmanager_integration.pri +++ /dev/null @@ -1,16 +0,0 @@ -DEFINES += QT_WAYLAND_WINDOWMANAGER_SUPPORT - -contains(DEFINES, QT_WAYLAND_WINDOWMANAGER_SUPPORT) { - - WAYLANDCLIENTSOURCES += $$PWD/../../../../extensions/windowmanager.xml - - HEADERS += \ - $$PWD/qwaylandwindowmanagerintegration.h - - SOURCES += \ - $$PWD/qwaylandwindowmanagerintegration.cpp - -} - - - |