diff options
Diffstat (limited to 'src/plugins/platforms/wayland_common')
40 files changed, 673 insertions, 1313 deletions
diff --git a/src/plugins/platforms/wayland_common/qwaylandcursor.cpp b/src/plugins/platforms/wayland_common/qwaylandcursor.cpp index d4823950..9ea1836b 100644 --- a/src/plugins/platforms/wayland_common/qwaylandcursor.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandcursor.cpp @@ -57,7 +57,15 @@ QWaylandCursor::QWaylandCursor(QWaylandScreen *screen) : mDisplay(screen->display()) { //TODO: Make wl_cursor_theme_load arguments configurable here - mCursorTheme = wl_cursor_theme_load("default", 32, mDisplay->shm()); + QByteArray cursorTheme = qgetenv("XCURSOR_THEME"); + if (cursorTheme.isEmpty()) + cursorTheme = QByteArray("default"); + QByteArray cursorSizeFromEnv = qgetenv("XCURSOR_SIZE"); + bool hasCursorSize = false; + int cursorSize = cursorSizeFromEnv.toInt(&hasCursorSize); + if (!hasCursorSize || cursorSize <= 0) + cursorSize = 32; + mCursorTheme = wl_cursor_theme_load(cursorTheme, cursorSize, mDisplay->shm()); initCursorMap(); } diff --git a/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.cpp b/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.cpp index d4ba6179..901069c5 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.cpp +++ b/src/plugins/platforms/wayland_common/qwaylanddatadevicemanager.cpp @@ -86,7 +86,7 @@ void QWaylandDataDeviceManager::enter(void *data, return; data_device_manager->m_drag_last_event_time = time; - data_device_manager->m_drag_current_event_window = static_cast<QWaylandWindow *>(wl_surface_get_user_data(surface)); + data_device_manager->m_drag_current_event_window = QWaylandWindow::fromWlSurface(surface); if (!surface) return; QWaylandDataOffer *offer = static_cast<QWaylandDataOffer *>(wl_data_offer_get_user_data(id)); @@ -261,7 +261,7 @@ void QWaylandDataDeviceManager::createAndSetDrag(QDrag *drag) p.drawPixmap(0,0,pixmap); } - m_drag_icon_surface = wl_compositor_create_surface(m_display->wl_compositor()); + m_drag_icon_surface = m_display->compositor()->create_surface(); wl_surface_attach(m_drag_icon_surface, m_drag_icon_buffer->buffer(), -drag->hotSpot().x(), -drag->hotSpot().y()); wl_data_device_start_drag(transfer_device, m_drag_data_source->handle(), m_drag_surface, m_drag_icon_surface, QWaylandDisplay::currentTimeMillisec()); diff --git a/src/plugins/platforms/wayland_common/qwaylanddecoration.cpp b/src/plugins/platforms/wayland_common/qwaylanddecoration.cpp index 11baeeb6..f5f79ae6 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddecoration.cpp +++ b/src/plugins/platforms/wayland_common/qwaylanddecoration.cpp @@ -46,6 +46,7 @@ #include "qwaylandinputdevice.h" #include <QtGui/QGuiApplication> +#include <QtGui/QImage> #include <QtGui/QCursor> #include <QtGui/QPainter> #include <QtGui/QPalette> @@ -124,6 +125,8 @@ static const char * const qt_normalizeup_xpm[] = { QWaylandDecoration::QWaylandDecoration(QWaylandWindow *window) : m_window(window->window()) , m_wayland_window(window) + , m_isDirty(true) + , m_decorationContentImage(0) , m_margins(3,30,3,3) , m_hasSetCursor(false) , m_mouseButtons(Qt::NoButton) @@ -144,6 +147,26 @@ QWaylandDecoration::~QWaylandDecoration() m_wayland_window->setDecoration(0); } +const QImage &QWaylandDecoration::contentImage() +{ + if (m_isDirty) { + //Update the decoration backingstore + + m_decorationContentImage = QImage(window()->frameGeometry().size(), QImage::Format_ARGB32_Premultiplied); + m_decorationContentImage.fill(Qt::transparent); + this->paint(&m_decorationContentImage); + + m_isDirty = false; + } + + return m_decorationContentImage; +} + +void QWaylandDecoration::update() +{ + m_isDirty = true; +} + void QWaylandDecoration::paint(QPaintDevice *device) { QRect surfaceRect(QPoint(), window()->frameGeometry().size()); diff --git a/src/plugins/platforms/wayland_common/qwaylanddecoration.h b/src/plugins/platforms/wayland_common/qwaylanddecoration.h index 0ad9b030..14755699 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddecoration.h +++ b/src/plugins/platforms/wayland_common/qwaylanddecoration.h @@ -48,6 +48,7 @@ #include <QtGui/QCursor> #include <QtGui/QColor> #include <QtGui/QStaticText> +#include <QtGui/QImage> #include <wayland-client.h> @@ -68,7 +69,8 @@ public: QWaylandDecoration(QWaylandWindow *window); virtual ~QWaylandDecoration(); - virtual void paintDecoration() = 0; + void update(); + bool isDirty() const; bool handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,Qt::MouseButtons b,Qt::KeyboardModifiers mods); void restoreMouseCursor(); @@ -79,6 +81,7 @@ public: QMargins margins() const; QWindow *window() const; QWaylandWindow *waylandWindow() const; + const QImage &contentImage(); void setForegroundColor(const QColor &c); inline QColor foregroundColor() const; @@ -107,6 +110,9 @@ private: QWindow *m_window; QWaylandWindow *m_wayland_window; + bool m_isDirty; + QImage m_decorationContentImage; + QMargins m_margins; bool m_hasSetCursor; Qt::CursorShape m_cursorShape; @@ -117,6 +123,11 @@ private: QStaticText m_windowTitle; }; +inline bool QWaylandDecoration::isDirty() const +{ + return m_isDirty; +} + inline QMargins QWaylandDecoration::margins() const { return m_margins; diff --git a/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp b/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp index 0e4fb588..bb056c96 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland_common/qwaylanddisplay.cpp @@ -48,7 +48,6 @@ #include "qwaylandinputdevice.h" #include "qwaylandclipboard.h" #include "qwaylanddatadevicemanager.h" -#include "qwaylandshell.h" #ifdef QT_WAYLAND_GL_SUPPORT #include "qwaylandglintegration.h" @@ -73,7 +72,7 @@ QT_USE_NAMESPACE struct wl_surface *QWaylandDisplay::createSurface(void *handle) { - struct wl_surface * surface = wl_compositor_create_surface(mCompositor); + struct wl_surface *surface = mCompositor.create_surface(); wl_surface_set_user_data(surface, handle); return surface; } @@ -104,11 +103,7 @@ void QWaylandDisplay::setLastKeyboardFocusInputDevice(QWaylandInputDevice *devic static QWaylandDisplay *display = 0; -const struct wl_registry_listener QWaylandDisplay::registryListener = { - QWaylandDisplay::displayHandleGlobal -}; - -QWaylandDisplay::QWaylandDisplay(void) +QWaylandDisplay::QWaylandDisplay() : mLastKeyboardFocusInputDevice(0) , mDndSelectionHandler(0) , mWindowExtension(0) @@ -131,9 +126,10 @@ QWaylandDisplay::QWaylandDisplay(void) //Create a new even queue for the QtGui thread mEventQueue = wl_display_create_queue(mDisplay); - mRegistry = wl_display_get_registry(mDisplay); - wl_proxy_set_queue((struct wl_proxy *)mRegistry, mEventQueue); - wl_registry_add_listener(mRegistry, ®istryListener, this); + struct ::wl_registry *registry = wl_display_get_registry(mDisplay); + wl_proxy_set_queue((struct wl_proxy *)registry, mEventQueue); + + init(registry); QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher; connect(dispatcher, SIGNAL(aboutToBlock()), this, SLOT(flushRequests())); @@ -144,7 +140,7 @@ QWaylandDisplay::QWaylandDisplay(void) #endif #ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT - mWindowManagerIntegration = QWaylandWindowManagerIntegration::createIntegration(this); + mWindowManagerIntegration = new QWaylandWindowManagerIntegration(this); #endif blockingReadEvents(); @@ -170,27 +166,10 @@ QWaylandDisplay::~QWaylandDisplay(void) delete mEventThreadObject; } -void QWaylandDisplay::createNewScreen(struct wl_output *output) -{ - QWaylandScreen *waylandScreen = new QWaylandScreen(this,output); - mScreens.append(waylandScreen); -} - -void QWaylandDisplay::scheduleRedraw(QWaylandWindow *window) -{ - if (!mWindows.contains(window)) - mWindows << window; -} - void QWaylandDisplay::flushRequests() { wl_display_dispatch_queue_pending(mDisplay, mEventQueue); wl_display_flush(mDisplay); - - foreach (QWaylandWindow *w, mWindows) { - w->redraw(); - } - mWindows.clear(); } void QWaylandDisplay::blockingReadEvents() @@ -208,51 +187,12 @@ QWaylandScreen *QWaylandDisplay::screenForOutput(struct wl_output *output) const return 0; } -void QWaylandDisplay::outputHandleGeometry(void *data, - struct wl_output *output, - int32_t x, int32_t y, - int32_t physicalWidth, - int32_t physicalHeight, - int subpixel, - const char *make, const char *model, - int32_t transform) -{ - Q_UNUSED(subpixel); - Q_UNUSED(make); - Q_UNUSED(model); - Q_UNUSED(transform); - QWaylandDisplay *waylandDisplay = static_cast<QWaylandDisplay *>(data); - QRect outputRect = QRect(x, y, physicalWidth, physicalHeight); - waylandDisplay->screenForOutput(output)->setGeometry(outputRect); -} - -void QWaylandDisplay::mode(void *data, - struct wl_output *output, - uint32_t flags, - int width, - int height, - int refresh) -{ - QWaylandDisplay *waylandDisplay = static_cast<QWaylandDisplay *>(data); - - if (flags & WL_OUTPUT_MODE_CURRENT) { - QWaylandScreen *screen = waylandDisplay->screenForOutput(output); - if (screen) - screen->handleMode(QSize(width, height), refresh); - } -} - void QWaylandDisplay::addRegistryListener(RegistryListener listener, void *data) { Listener l = { listener, data }; mRegistryListeners.append(l); } -const struct wl_output_listener QWaylandDisplay::outputListener = { - QWaylandDisplay::outputHandleGeometry, - QWaylandDisplay::mode -}; - void QWaylandDisplay::waitForScreens() { flushRequests(); @@ -260,53 +200,41 @@ void QWaylandDisplay::waitForScreens() blockingReadEvents(); } -void QWaylandDisplay::displayHandleGlobal(void *data, - struct wl_registry *registry, - uint32_t id, - const char *interface, - uint32_t version) -{ - Q_UNUSED(registry); - QWaylandDisplay *that = static_cast<QWaylandDisplay *>(data); - that->displayHandleGlobal(id, QByteArray(interface), version); -} - -void QWaylandDisplay::displayHandleGlobal(uint32_t id, - const QByteArray &interface, - uint32_t version) +void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uint32_t version) { Q_UNUSED(version); + struct ::wl_registry *registry = object(); + if (interface == "wl_output") { - struct wl_output *output = static_cast<struct wl_output *>(wl_registry_bind(mRegistry,id,&wl_output_interface,1)); - createNewScreen(output); - wl_output_add_listener(output, &outputListener, this); + mScreens.append(new QWaylandScreen(this, id)); } else if (interface == "wl_compositor") { - mCompositor = static_cast<struct wl_compositor *>(wl_registry_bind(mRegistry, id,&wl_compositor_interface,1)); + mCompositor.init(registry, id); } else if (interface == "wl_shm") { - mShm = static_cast<struct wl_shm *>(wl_registry_bind(mRegistry, id, &wl_shm_interface,1)); + mShm = static_cast<struct wl_shm *>(wl_registry_bind(registry, id, &wl_shm_interface,1)); } else if (interface == "wl_shell"){ - mShell = new QWaylandShell(this,id,version); + mShell = new QtWayland::wl_shell(registry, id); } else if (interface == "wl_seat") { QWaylandInputDevice *inputDevice = new QWaylandInputDevice(this, id); mInputDevices.append(inputDevice); } else if (interface == "wl_data_device_manager") { mDndSelectionHandler = new QWaylandDataDeviceManager(this, id); } else if (interface == "wl_output_extension") { - mOutputExtension = new QWaylandOutputExtension(this,id); + mOutputExtension = new QtWayland::qt_output_extension(registry, id); + foreach (QPlatformScreen *screen, screens()) + static_cast<QWaylandScreen *>(screen)->createExtendedOutput(); } else if (interface == "wl_surface_extension") { - mWindowExtension = new QWaylandSurfaceExtension(this,id); + mWindowExtension = new QtWayland::qt_surface_extension(registry, id); } else if (interface == "wl_sub_surface_extension") { - mSubSurfaceExtension = new QWaylandSubSurfaceExtension(this,id); + mSubSurfaceExtension = new QtWayland::qt_sub_surface_extension(registry, id); } else if (interface == "wl_touch_extension") { mTouchExtension = new QWaylandTouchExtension(this, id); } else if (interface == "wl_qtkey_extension") { mQtKeyExtension = new QWaylandQtKeyExtension(this, id); } - foreach (Listener l, mRegistryListeners) { - (*l.listener)(l.data, mRegistry, id, interface, version); - } + foreach (Listener l, mRegistryListeners) + (*l.listener)(l.data, registry, id, interface, version); } uint32_t QWaylandDisplay::currentTimeMillisec() diff --git a/src/plugins/platforms/wayland_common/qwaylanddisplay.h b/src/plugins/platforms/wayland_common/qwaylanddisplay.h index 637e05b9..bb26be69 100644 --- a/src/plugins/platforms/wayland_common/qwaylanddisplay.h +++ b/src/plugins/platforms/wayland_common/qwaylanddisplay.h @@ -48,6 +48,7 @@ #include <QtCore/QWaitCondition> #include <wayland-client.h> +#include <qwayland-wayland.h> QT_BEGIN_NAMESPACE @@ -60,22 +61,25 @@ class QWaylandScreen; class QWaylandGLIntegration; class QWaylandWindowManagerIntegration; class QWaylandDataDeviceManager; -class QWaylandShell; -class QWaylandSurfaceExtension; -class QWaylandSubSurfaceExtension; -class QWaylandOutputExtension; class QWaylandTouchExtension; class QWaylandQtKeyExtension; class QWaylandWindow; class QWaylandEventThread; +namespace QtWayland { + class qt_output_extension; + class qt_shell; + class qt_sub_surface_extension; + class qt_surface_extension; +} + typedef void (*RegistryListener)(void *data, struct wl_registry *registry, uint32_t id, - const char *interface, + const QString &interface, uint32_t version); -class QWaylandDisplay : public QObject { +class QWaylandDisplay : public QObject, public QtWayland::wl_registry { Q_OBJECT public: @@ -100,10 +104,12 @@ public: struct wl_display *wl_display() const { return mDisplay; } struct wl_event_queue *wl_event_queue() const { return mEventQueue; } - struct wl_registry *wl_registry() const { return mRegistry; } - struct wl_compositor *wl_compositor() const { return mCompositor; } + struct ::wl_registry *wl_registry() { return object(); } + + const struct wl_compositor *wl_compositor() const { return mCompositor.object(); } + QtWayland::wl_compositor *compositor() { return &mCompositor; } - QWaylandShell *shell() const { return mShell; } + QtWayland::wl_shell *shell() { return mShell; } QList<QWaylandInputDevice *> inputDevices() const { return mInputDevices; } @@ -112,9 +118,9 @@ public: QWaylandDataDeviceManager *dndSelectionHandler() const { return mDndSelectionHandler; } - QWaylandSurfaceExtension *windowExtension() const { return mWindowExtension; } - QWaylandSubSurfaceExtension *subSurfaceExtension() const { return mSubSurfaceExtension; } - QWaylandOutputExtension *outputExtension() const { return mOutputExtension; } + QtWayland::qt_surface_extension *windowExtension() const { return mWindowExtension; } + QtWayland::qt_sub_surface_extension *subSurfaceExtension() const { return mSubSurfaceExtension; } + QtWayland::qt_output_extension *outputExtension() const { return mOutputExtension; } QWaylandTouchExtension *touchExtension() const { return mTouchExtension; } /* wl_registry_add_listener does not add but rather sets a listener, so this function is used @@ -127,18 +133,12 @@ public: void forceRoundTrip(); - void scheduleRedraw(QWaylandWindow *window); - public slots: - void createNewScreen(struct wl_output *output); void blockingReadEvents(); void flushRequests(); private: void waitForScreens(); - void displayHandleGlobal(uint32_t id, - const QByteArray &interface, - uint32_t version); struct Listener { RegistryListener listener; @@ -147,21 +147,19 @@ private: struct wl_display *mDisplay; struct wl_event_queue *mEventQueue; - struct wl_registry *mRegistry; - struct wl_compositor *mCompositor; + QtWayland::wl_compositor mCompositor; struct wl_shm *mShm; QThread *mEventThread; QWaylandEventThread *mEventThreadObject; - QWaylandShell *mShell; + QtWayland::wl_shell *mShell; QList<QPlatformScreen *> mScreens; QList<QWaylandInputDevice *> mInputDevices; QList<Listener> mRegistryListeners; - QList<QWaylandWindow *> mWindows; QWaylandInputDevice *mLastKeyboardFocusInputDevice; QWaylandDataDeviceManager *mDndSelectionHandler; - QWaylandSurfaceExtension *mWindowExtension; - QWaylandSubSurfaceExtension *mSubSurfaceExtension; - QWaylandOutputExtension *mOutputExtension; + QtWayland::qt_surface_extension *mWindowExtension; + QtWayland::qt_sub_surface_extension *mSubSurfaceExtension; + QtWayland::qt_output_extension *mOutputExtension; QWaylandTouchExtension *mTouchExtension; QWaylandQtKeyExtension *mQtKeyExtension; @@ -170,28 +168,7 @@ private: int mWritableNotificationFd; bool mScreensInitialized; - static const struct wl_registry_listener registryListener; - static const struct wl_output_listener outputListener; - - static void displayHandleGlobal(void *data, - struct wl_registry *registry, - uint32_t id, - const char *interface, - uint32_t version); - static void outputHandleGeometry(void *data, - struct wl_output *output, - int32_t x, int32_t y, - int32_t width, int32_t height, - int subpixel, - const char *make, - const char *model, - int32_t transform); - static void mode(void *data, - struct wl_output *wl_output, - uint32_t flags, - int width, - int height, - int refresh); + void registry_global(uint32_t id, const QString &interface, uint32_t version) Q_DECL_OVERRIDE; #ifdef QT_WAYLAND_GL_SUPPORT QWaylandGLIntegration *mEglIntegration; diff --git a/src/plugins/platforms/wayland_common/qwaylandextendedoutput.cpp b/src/plugins/platforms/wayland_common/qwaylandextendedoutput.cpp index 7b6f9f3c..24b264e2 100644 --- a/src/plugins/platforms/wayland_common/qwaylandextendedoutput.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandextendedoutput.cpp @@ -43,44 +43,17 @@ #include "qwaylandscreen.h" -#include "wayland-output-extension-client-protocol.h" - #include <qpa/qwindowsysteminterface.h> #include <QtCore/QDebug> QT_USE_NAMESPACE -QWaylandOutputExtension::QWaylandOutputExtension(QWaylandDisplay *display, uint32_t id) -{ - m_output_extension = static_cast<struct wl_output_extension *>( - wl_registry_bind(display->wl_registry(), id, &wl_output_extension_interface, 1)); - - QList<QPlatformScreen *> platformScreens = display->screens(); - for (int i = 0; i < platformScreens.size(); i++) { - QWaylandScreen *waylandScreen = static_cast<QWaylandScreen *>(platformScreens.at(i)); - if (!waylandScreen->extendedOutput()) { - QWaylandExtendedOutput *extendedOutput = getExtendedOutput(waylandScreen); - waylandScreen->setExtendedOutput(extendedOutput); - qDebug() << "extended output enabled"; - } - } -} - -QWaylandExtendedOutput *QWaylandOutputExtension::getExtendedOutput(QWaylandScreen *screen) -{ - qDebug() << "getExtendedOutput"; - struct wl_extended_output *extended_output = - wl_output_extension_get_extended_output(m_output_extension,screen->output()); - return new QWaylandExtendedOutput(screen,extended_output); -} - -QWaylandExtendedOutput::QWaylandExtendedOutput(QWaylandScreen *screen, wl_extended_output *extended_output) - : m_extended_output(extended_output) +QWaylandExtendedOutput::QWaylandExtendedOutput(QWaylandScreen *screen, ::qt_extended_output *extended_output) + : QtWayland::qt_extended_output(extended_output) , m_screen(screen) , m_orientation(m_screen->orientation()) { - wl_extended_output_add_listener(m_extended_output,&extended_output_listener,this); } Qt::ScreenOrientation QWaylandExtendedOutput::currentOrientation() const @@ -92,40 +65,34 @@ void QWaylandExtendedOutput::setOrientationUpdateMask(Qt::ScreenOrientations ori { int mask = 0; if (orientations & Qt::PortraitOrientation) - mask |= WL_EXTENDED_OUTPUT_ROTATION_PORTRAITORIENTATION; + mask |= QT_EXTENDED_OUTPUT_ROTATION_PORTRAITORIENTATION; if (orientations & Qt::LandscapeOrientation) - mask |= WL_EXTENDED_OUTPUT_ROTATION_LANDSCAPEORIENTATION; + mask |= QT_EXTENDED_OUTPUT_ROTATION_LANDSCAPEORIENTATION; if (orientations & Qt::InvertedPortraitOrientation) - mask |= WL_EXTENDED_OUTPUT_ROTATION_INVERTEDPORTRAITORIENTATION; + mask |= QT_EXTENDED_OUTPUT_ROTATION_INVERTEDPORTRAITORIENTATION; if (orientations & Qt::InvertedLandscapeOrientation) - mask |= WL_EXTENDED_OUTPUT_ROTATION_INVERTEDLANDSCAPEORIENTATION; - wl_extended_output_set_orientation_update_mask(m_extended_output, mask); + mask |= QT_EXTENDED_OUTPUT_ROTATION_INVERTEDLANDSCAPEORIENTATION; + set_orientation_update_mask(mask); } -void QWaylandExtendedOutput::set_screen_rotation(void *data, wl_extended_output *wl_extended_output, int32_t rotation) +void QWaylandExtendedOutput::extended_output_set_screen_rotation(int32_t rotation) { - Q_UNUSED(wl_extended_output); - QWaylandExtendedOutput *extended_output = static_cast<QWaylandExtendedOutput *>(data); switch (rotation) { - case WL_EXTENDED_OUTPUT_ROTATION_PORTRAITORIENTATION: - extended_output->m_orientation = Qt::PortraitOrientation; + case QT_EXTENDED_OUTPUT_ROTATION_PORTRAITORIENTATION: + m_orientation = Qt::PortraitOrientation; break; - case WL_EXTENDED_OUTPUT_ROTATION_LANDSCAPEORIENTATION: - extended_output->m_orientation = Qt::LandscapeOrientation; + case QT_EXTENDED_OUTPUT_ROTATION_LANDSCAPEORIENTATION: + m_orientation = Qt::LandscapeOrientation; break; - case WL_EXTENDED_OUTPUT_ROTATION_INVERTEDPORTRAITORIENTATION: - extended_output->m_orientation = Qt::InvertedPortraitOrientation; + case QT_EXTENDED_OUTPUT_ROTATION_INVERTEDPORTRAITORIENTATION: + m_orientation = Qt::InvertedPortraitOrientation; break; - case WL_EXTENDED_OUTPUT_ROTATION_INVERTEDLANDSCAPEORIENTATION: - extended_output->m_orientation = Qt::InvertedLandscapeOrientation; + case QT_EXTENDED_OUTPUT_ROTATION_INVERTEDLANDSCAPEORIENTATION: + m_orientation = Qt::InvertedLandscapeOrientation; break; default: - extended_output->m_orientation = Qt::PortraitOrientation; + m_orientation = Qt::PortraitOrientation; break; } - QWindowSystemInterface::handleScreenOrientationChange(extended_output->m_screen->screen(), extended_output->m_orientation); + QWindowSystemInterface::handleScreenOrientationChange(m_screen->screen(), m_orientation); } - -const struct wl_extended_output_listener QWaylandExtendedOutput::extended_output_listener = { - QWaylandExtendedOutput::set_screen_rotation -}; diff --git a/src/plugins/platforms/wayland_common/qwaylandextendedoutput.h b/src/plugins/platforms/wayland_common/qwaylandextendedoutput.h index 780f5702..dd9ce6a8 100644 --- a/src/plugins/platforms/wayland_common/qwaylandextendedoutput.h +++ b/src/plugins/platforms/wayland_common/qwaylandextendedoutput.h @@ -43,38 +43,25 @@ #define QWAYLANDEXTENDEDOUTPUT_H #include "qwaylanddisplay.h" +#include "qwayland-output-extension.h" QT_BEGIN_NAMESPACE class QWaylandExtendedOutput; -class QWaylandOutputExtension +class QWaylandExtendedOutput : public QtWayland::qt_extended_output { public: - QWaylandOutputExtension(QWaylandDisplay *display, uint32_t id); - - QWaylandExtendedOutput* getExtendedOutput(QWaylandScreen *screen); -private: - struct wl_output_extension *m_output_extension; -}; - -class QWaylandExtendedOutput -{ -public: - QWaylandExtendedOutput(QWaylandScreen *screen, struct wl_extended_output *extended_output); + QWaylandExtendedOutput(QWaylandScreen *screen, struct ::qt_extended_output *extended_output); Qt::ScreenOrientation currentOrientation() const; void setOrientationUpdateMask(Qt::ScreenOrientations mask); private: - struct wl_extended_output *m_extended_output; + void extended_output_set_screen_rotation(int32_t rotation) Q_DECL_OVERRIDE; + QWaylandScreen *m_screen; Qt::ScreenOrientation m_orientation; - - static void set_screen_rotation(void *data, - struct wl_extended_output *wl_extended_output, - int32_t rotation); - static const struct wl_extended_output_listener extended_output_listener; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandextendedsurface.cpp b/src/plugins/platforms/wayland_common/qwaylandextendedsurface.cpp index 82b294b0..46280bcf 100644 --- a/src/plugins/platforms/wayland_common/qwaylandextendedsurface.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandextendedsurface.cpp @@ -44,7 +44,6 @@ #include "qwaylandwindow.h" #include "wayland-client.h" -#include "wayland-surface-extension-client-protocol.h" #include "qwaylanddisplay.h" @@ -56,65 +55,41 @@ QT_USE_NAMESPACE -QWaylandSurfaceExtension::QWaylandSurfaceExtension(QWaylandDisplay *display, uint32_t id) -{ - m_surface_extension = static_cast<struct wl_surface_extension *>( - wl_registry_bind(display->wl_registry(), id, &wl_surface_extension_interface, 1)); -} - -QWaylandExtendedSurface *QWaylandSurfaceExtension::getExtendedWindow(QWaylandWindow *window) -{ - struct wl_surface *surface = window->wl_surface(); - Q_ASSERT(surface); - struct wl_extended_surface *extended_surface = - wl_surface_extension_get_extended_surface(m_surface_extension,surface); - - return new QWaylandExtendedSurface(window,extended_surface); -} - - -QWaylandExtendedSurface::QWaylandExtendedSurface(QWaylandWindow *window, struct wl_extended_surface *extended_surface) - : m_window(window) - , m_extended_surface(extended_surface) +QWaylandExtendedSurface::QWaylandExtendedSurface(QWaylandWindow *window, struct ::qt_extended_surface *extended_surface) + : QtWayland::qt_extended_surface(extended_surface) + , m_window(window) , m_exposed(true) { - wl_extended_surface_add_listener(m_extended_surface,&QWaylandExtendedSurface::extended_surface_listener,this); } void QWaylandExtendedSurface::updateGenericProperty(const QString &name, const QVariant &value) { - QByteArray byteValue; QDataStream ds(&byteValue, QIODevice::WriteOnly); ds << value; - struct wl_array data; - data.size = byteValue.size(); - data.data = (void*)byteValue.constData(); - data.alloc = 0; - - wl_extended_surface_update_generic_property(m_extended_surface,qPrintable(name),&data); + update_generic_property(name, byteValue); - m_properties.insert(name,value); + m_properties.insert(name, value); QWaylandNativeInterface *nativeInterface = static_cast<QWaylandNativeInterface *>( QGuiApplication::platformNativeInterface()); - nativeInterface->emitWindowPropertyChanged(m_window,name); + nativeInterface->emitWindowPropertyChanged(m_window, name); } static int32_t waylandRotationFromScreenOrientation(Qt::ScreenOrientation orientation) { switch (orientation) { - case Qt::PortraitOrientation: return WL_EXTENDED_SURFACE_ORIENTATION_PORTRAITORIENTATION; - case Qt::InvertedPortraitOrientation: return WL_EXTENDED_SURFACE_ORIENTATION_INVERTEDPORTRAITORIENTATION; - case Qt::LandscapeOrientation: return WL_EXTENDED_SURFACE_ORIENTATION_LANDSCAPEORIENTATION; - case Qt::InvertedLandscapeOrientation: return WL_EXTENDED_SURFACE_ORIENTATION_INVERTEDLANDSCAPEORIENTATION; - default: return WL_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION; + case Qt::PortraitOrientation: return QT_EXTENDED_SURFACE_ORIENTATION_PORTRAITORIENTATION; + case Qt::InvertedPortraitOrientation: return QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDPORTRAITORIENTATION; + case Qt::LandscapeOrientation: return QT_EXTENDED_SURFACE_ORIENTATION_LANDSCAPEORIENTATION; + case Qt::InvertedLandscapeOrientation: return QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDLANDSCAPEORIENTATION; + default: return QT_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION; } } void QWaylandExtendedSurface::setContentOrientation(Qt::ScreenOrientation orientation) { - wl_extended_surface_set_content_orientation(m_extended_surface, waylandRotationFromScreenOrientation(orientation)); + set_content_orientation(waylandRotationFromScreenOrientation(orientation)); } QVariantMap QWaylandExtendedSurface::properties() const @@ -132,59 +107,43 @@ QVariant QWaylandExtendedSurface::property(const QString &name, const QVariant & return m_properties.value(name,defaultValue); } -void QWaylandExtendedSurface::onscreen_visibility(void *data, wl_extended_surface *wl_extended_surface, int32_t visible) +void QWaylandExtendedSurface::extended_surface_onscreen_visibility(int32_t visible) { - QWaylandExtendedSurface *extendedWindow = static_cast<QWaylandExtendedSurface *>(data); - Q_UNUSED(extendedWindow); - Q_UNUSED(wl_extended_surface); - // Do not send events when the state is not changing... - if (visible == extendedWindow->m_window->isExposed()) + if (visible == m_exposed) return; - extendedWindow->m_exposed = visible; - QWaylandWindow *w = extendedWindow->m_window; + m_exposed = visible; + QWaylandWindow *w = m_window; QWindowSystemInterface::handleExposeEvent(w->window(), visible ? QRegion(w->geometry()) : QRegion()); - QWindowSystemInterface::flushWindowSystemEvents(); } -void QWaylandExtendedSurface::set_generic_property(void *data, wl_extended_surface *wl_extended_surface, const char *name, wl_array *value) +void QWaylandExtendedSurface::extended_surface_set_generic_property(const QString &name, wl_array *value) { - Q_UNUSED(wl_extended_surface); - - QWaylandExtendedSurface *extended_window = static_cast<QWaylandExtendedSurface *>(data); + QByteArray data = QByteArray::fromRawData(static_cast<char *>(value->data), value->size); QVariant variantValue; - QByteArray baValue = QByteArray((const char*)value->data, value->size); - QDataStream ds(&baValue, QIODevice::ReadOnly); + QDataStream ds(data); ds >> variantValue; - QString qstring_name = QString::fromLatin1(name); - extended_window->m_properties.insert(qstring_name,variantValue); + m_properties.insert(name, variantValue); QWaylandNativeInterface *nativeInterface = static_cast<QWaylandNativeInterface *>( - QGuiApplication::platformNativeInterface()); - nativeInterface->emitWindowPropertyChanged(extended_window->m_window,QString::fromLatin1(name)); + QGuiApplication::platformNativeInterface()); + nativeInterface->emitWindowPropertyChanged(m_window, name); } Qt::WindowFlags QWaylandExtendedSurface::setWindowFlags(Qt::WindowFlags flags) { uint wlFlags = 0; - if (flags & Qt::WindowStaysOnTopHint) wlFlags |= WL_EXTENDED_SURFACE_WINDOWFLAG_STAYSONTOP; - if (flags & Qt::WindowOverridesSystemGestures) wlFlags |= WL_EXTENDED_SURFACE_WINDOWFLAG_OVERRIDESSYSTEMGESTURES; - wl_extended_surface_set_window_flags(m_extended_surface, wlFlags); + if (flags & Qt::WindowStaysOnTopHint) wlFlags |= QT_EXTENDED_SURFACE_WINDOWFLAG_STAYSONTOP; + if (flags & Qt::WindowOverridesSystemGestures) wlFlags |= QT_EXTENDED_SURFACE_WINDOWFLAG_OVERRIDESSYSTEMGESTURES; - return flags & ( - Qt::WindowStaysOnTopHint - | Qt::WindowOverridesSystemGestures - ); -} + set_window_flags(wlFlags); -const struct wl_extended_surface_listener QWaylandExtendedSurface::extended_surface_listener = { - QWaylandExtendedSurface::onscreen_visibility, - QWaylandExtendedSurface::set_generic_property -}; + return flags & (Qt::WindowStaysOnTopHint | Qt::WindowOverridesSystemGestures); +} diff --git a/src/plugins/platforms/wayland_common/qwaylandextendedsurface.h b/src/plugins/platforms/wayland_common/qwaylandextendedsurface.h index 940d9ab7..9dbebaf4 100644 --- a/src/plugins/platforms/wayland_common/qwaylandextendedsurface.h +++ b/src/plugins/platforms/wayland_common/qwaylandextendedsurface.h @@ -46,31 +46,22 @@ #include <QtCore/QVariant> #include <wayland-client.h> +#include <qwayland-surface-extension.h> QT_BEGIN_NAMESPACE class QWaylandDisplay; class QWaylandWindow; -class QWaylandExtendedSurface; -class QWaylandSurfaceExtension +class QWaylandExtendedSurface : public QtWayland::qt_extended_surface { public: - QWaylandSurfaceExtension(QWaylandDisplay *display, uint32_t id); - - QWaylandExtendedSurface *getExtendedWindow(QWaylandWindow *window); -private: - struct wl_surface_extension *m_surface_extension; -}; - -class QWaylandExtendedSurface -{ -public: - QWaylandExtendedSurface(QWaylandWindow *window, struct wl_extended_surface *extended_surface); + QWaylandExtendedSurface(QWaylandWindow *window, struct ::qt_extended_surface *extended_surface); void setContentOrientation(Qt::ScreenOrientation orientation); void updateGenericProperty(const QString &name, const QVariant &value); + QVariantMap properties() const; QVariant property(const QString &name); QVariant property(const QString &name, const QVariant &defaultValue); @@ -80,22 +71,12 @@ public: bool isExposed() const { return m_exposed; } private: - QWaylandWindow *m_window; - struct wl_extended_surface *m_extended_surface; + void extended_surface_onscreen_visibility(int32_t visible) Q_DECL_OVERRIDE; + void extended_surface_set_generic_property(const QString &name, wl_array *value) Q_DECL_OVERRIDE; + QWaylandWindow *m_window; QVariantMap m_properties; - static void onscreen_visibility(void *data, - struct wl_extended_surface *wl_extended_surface, - int32_t visible); - - static void set_generic_property(void *data, - struct wl_extended_surface *wl_extended_surface, - const char *name, - struct wl_array *value); - - static const struct wl_extended_surface_listener extended_surface_listener; - bool m_exposed; }; diff --git a/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp index 9820854d..62cbdf36 100644 --- a/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandinputdevice.cpp @@ -66,7 +66,8 @@ QT_USE_NAMESPACE QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, uint32_t id) - : mQDisplay(display) + : QtWayland::wl_seat(display->wl_registry(), id) + , mQDisplay(display) , mDisplay(display->wl_display()) , mCaps(0) , mTransferDevice(0) @@ -81,10 +82,6 @@ QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, uint32_t id) , mXkbState(0) #endif { - mSeat = static_cast<struct wl_seat *>(wl_registry_bind(display->wl_registry(), id, &wl_seat_interface, 1)); - wl_seat_add_listener(mSeat, &seatListener, this); - wl_seat_set_user_data(mSeat, this); - #ifndef QT_NO_WAYLAND_XKB xkb_rule_names names; names.rules = strdup("evdev"); @@ -122,59 +119,26 @@ QWaylandInputDevice::~QWaylandInputDevice() #endif } -const struct wl_seat_listener QWaylandInputDevice::seatListener = { - QWaylandInputDevice::seat_capabilities -}; - -const struct wl_pointer_listener QWaylandInputDevice::pointerListener = { - QWaylandInputDevice::pointer_enter, - QWaylandInputDevice::pointer_leave, - QWaylandInputDevice::pointer_motion, - QWaylandInputDevice::pointer_button, - QWaylandInputDevice::pointer_axis -}; - -const struct wl_keyboard_listener QWaylandInputDevice::keyboardListener = { - QWaylandInputDevice::keyboard_keymap, - QWaylandInputDevice::keyboard_enter, - QWaylandInputDevice::keyboard_leave, - QWaylandInputDevice::keyboard_key, - QWaylandInputDevice::keyboard_modifiers -}; - -const struct wl_touch_listener QWaylandInputDevice::touchListener = { - QWaylandInputDevice::touch_down, - QWaylandInputDevice::touch_up, - QWaylandInputDevice::touch_motion, - QWaylandInputDevice::touch_frame, - QWaylandInputDevice::touch_cancel -}; - -void QWaylandInputDevice::seat_capabilities(void *data, struct wl_seat *seat, uint32_t caps) +void QWaylandInputDevice::seat_capabilities(uint32_t caps) { - QWaylandInputDevice *self = static_cast<QWaylandInputDevice *>(data); - self->mCaps = caps; + mCaps = caps; - if (caps & WL_SEAT_CAPABILITY_KEYBOARD) { - self->mDeviceInterfaces.keyboard = wl_seat_get_keyboard(seat); - wl_keyboard_add_listener(self->mDeviceInterfaces.keyboard, &keyboardListener, self); - } + if (caps & WL_SEAT_CAPABILITY_KEYBOARD) + QtWayland::wl_keyboard::init(get_keyboard()); if (caps & WL_SEAT_CAPABILITY_POINTER) { - self->mDeviceInterfaces.pointer = wl_seat_get_pointer(seat); - self->mDeviceInterfaces.pointerSurface = self->mQDisplay->createSurface(self); - wl_pointer_add_listener(self->mDeviceInterfaces.pointer, &pointerListener, self); + QtWayland::wl_pointer::init(get_pointer()); + pointerSurface = mQDisplay->createSurface(this); } if (caps & WL_SEAT_CAPABILITY_TOUCH) { - self->mDeviceInterfaces.touch = wl_seat_get_touch(seat); - wl_touch_add_listener(self->mDeviceInterfaces.touch, &touchListener, self); - - if (!self->mTouchDevice) { - self->mTouchDevice = new QTouchDevice; - self->mTouchDevice->setType(QTouchDevice::TouchScreen); - self->mTouchDevice->setCapabilities(QTouchDevice::Position); - QWindowSystemInterface::registerTouchDevice(self->mTouchDevice); + QtWayland::wl_touch::init(get_touch()); + + if (!mTouchDevice) { + mTouchDevice = new QTouchDevice; + mTouchDevice->setType(QTouchDevice::TouchScreen); + mTouchDevice->setCapabilities(QTouchDevice::Position); + QWindowSystemInterface::registerTouchDevice(mTouchDevice); } } } @@ -189,7 +153,7 @@ void QWaylandInputDevice::handleWindowDestroyed(QWaylandWindow *window) void QWaylandInputDevice::setTransferDevice(struct wl_data_device *device) { - mTransferDevice = device; + mTransferDevice = device; } struct wl_data_device *QWaylandInputDevice::transferDevice() const @@ -206,51 +170,37 @@ void QWaylandInputDevice::removeMouseButtonFromState(Qt::MouseButton button) void QWaylandInputDevice::setCursor(struct wl_buffer *buffer, struct wl_cursor_image *image) { if (mCaps & WL_SEAT_CAPABILITY_POINTER) { - wl_pointer_set_cursor(mDeviceInterfaces.pointer, mEnterSerial, mDeviceInterfaces.pointerSurface, - image->hotspot_x, image->hotspot_y); - wl_surface_attach(mDeviceInterfaces.pointerSurface, buffer, 0, 0); - wl_surface_damage(mDeviceInterfaces.pointerSurface, 0, 0, image->width, image->height); - wl_surface_commit(mDeviceInterfaces.pointerSurface); + set_cursor(mEnterSerial, pointerSurface, + image->hotspot_x, image->hotspot_y); + wl_surface_attach(pointerSurface, buffer, 0, 0); + wl_surface_damage(pointerSurface, 0, 0, image->width, image->height); + wl_surface_commit(pointerSurface); } } -void QWaylandInputDevice::pointer_enter(void *data, - struct wl_pointer *pointer, - uint32_t serial, struct wl_surface *surface, +void QWaylandInputDevice::pointer_enter(uint32_t serial, struct wl_surface *surface, wl_fixed_t sx, wl_fixed_t sy) { - Q_UNUSED(pointer); Q_UNUSED(sx); Q_UNUSED(sy); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; if (!surface) return; QGuiApplication::setOverrideCursor(QCursor(Qt::ArrowCursor)); - QWaylandWindow *window = (QWaylandWindow *) wl_surface_get_user_data(surface); + QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); window->handleMouseEnter(); - window->handleMouse(inputDevice, - inputDevice->mTime, - inputDevice->mSurfacePos, - inputDevice->mGlobalPos, - inputDevice->mButtons, - Qt::NoModifier); - inputDevice->mPointerFocus = window; - - inputDevice->mTime = QWaylandDisplay::currentTimeMillisec(); - inputDevice->mSerial = serial; - inputDevice->mEnterSerial = serial; + window->handleMouse(this, mTime, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); + mPointerFocus = window; + + mTime = QWaylandDisplay::currentTimeMillisec(); + mSerial = serial; + mEnterSerial = serial; } -void QWaylandInputDevice::pointer_leave(void *data, - struct wl_pointer *pointer, - uint32_t time, struct wl_surface *surface) +void QWaylandInputDevice::pointer_leave(uint32_t time, struct wl_surface *surface) { - Q_UNUSED(pointer); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - // The event may arrive after destroying the window, indicated by // a null surface. if (!surface) @@ -258,24 +208,20 @@ void QWaylandInputDevice::pointer_leave(void *data, QGuiApplication::restoreOverrideCursor(); - QWaylandWindow *window = (QWaylandWindow *) wl_surface_get_user_data(surface); + QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); window->handleMouseLeave(); - inputDevice->mPointerFocus = 0; - inputDevice->mButtons = Qt::NoButton; + mPointerFocus = 0; + mButtons = Qt::NoButton; - inputDevice->mTime = time; + mTime = time; } -void QWaylandInputDevice::pointer_motion(void *data, - struct wl_pointer *pointer, - uint32_t time, - wl_fixed_t surface_x, wl_fixed_t surface_y) +void QWaylandInputDevice::pointer_motion(uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { - Q_UNUSED(pointer); Q_UNUSED(surface_x); Q_UNUSED(surface_y); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - QWaylandWindow *window = inputDevice->mPointerFocus; + + QWaylandWindow *window = mPointerFocus; if (window == NULL) { // We destroyed the pointer focus surface, but the server @@ -288,27 +234,18 @@ void QWaylandInputDevice::pointer_motion(void *data, QPointF global = window->window()->mapToGlobal(pos.toPoint()); global += delta; - inputDevice->mSurfacePos = pos; - inputDevice->mGlobalPos = global; - inputDevice->mTime = time; + mSurfacePos = pos; + mGlobalPos = global; + mTime = time; - window->handleMouse(inputDevice, - time, - inputDevice->mSurfacePos, - inputDevice->mGlobalPos, - inputDevice->mButtons, - Qt::NoModifier); + window->handleMouse(this, time, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); } -void QWaylandInputDevice::pointer_button(void *data, - struct wl_pointer *pointer, - uint32_t serial, uint32_t time, +void QWaylandInputDevice::pointer_button(uint32_t serial, uint32_t time, uint32_t button, uint32_t state) { - Q_UNUSED(pointer); Q_UNUSED(serial); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - QWaylandWindow *window = inputDevice->mPointerFocus; + QWaylandWindow *window = mPointerFocus; Qt::MouseButton qt_button; // translate from kernel (input.h) 'button' to corresponding Qt:MouseButton. @@ -334,32 +271,20 @@ void QWaylandInputDevice::pointer_button(void *data, } if (state) - inputDevice->mButtons |= qt_button; + mButtons |= qt_button; else - inputDevice->mButtons &= ~qt_button; + mButtons &= ~qt_button; - inputDevice->mTime = time; - inputDevice->mSerial = serial; + mTime = time; + mSerial = serial; - if (window) { - window->handleMouse(inputDevice, - time, - inputDevice->mSurfacePos, - inputDevice->mGlobalPos, - inputDevice->mButtons, - Qt::NoModifier); - } + if (window) + window->handleMouse(this, time, mSurfacePos, mGlobalPos, mButtons, Qt::NoModifier); } -void QWaylandInputDevice::pointer_axis(void *data, - struct wl_pointer *pointer, - uint32_t time, - uint32_t axis, - int32_t value) +void QWaylandInputDevice::pointer_axis(uint32_t time, uint32_t axis, int32_t value) { - Q_UNUSED(pointer); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - QWaylandWindow *window = inputDevice->mPointerFocus; + QWaylandWindow *window = mPointerFocus; QPoint pixelDelta; QPoint angleDelta; @@ -375,10 +300,8 @@ void QWaylandInputDevice::pointer_axis(void *data, } QWindowSystemInterface::handleWheelEvent(window->window(), - time, - inputDevice->mSurfacePos, - inputDevice->mGlobalPos, - pixelDelta, + time, mSurfacePos, + mGlobalPos, pixelDelta, angleDelta); } @@ -497,71 +420,49 @@ static uint32_t translateKey(uint32_t sym, char *string, size_t size) #endif // QT_NO_WAYLAND_XKB -void QWaylandInputDevice::keyboard_keymap(void *data, - struct wl_keyboard *keyboard, - uint32_t format, - int32_t fd, - uint32_t size) +void QWaylandInputDevice::keyboard_keymap(uint32_t format, int32_t fd, uint32_t size) { - Q_UNUSED(data); - Q_UNUSED(keyboard); Q_UNUSED(format); Q_UNUSED(fd); Q_UNUSED(size); } -void QWaylandInputDevice::keyboard_enter(void *data, - struct wl_keyboard *keyboard, - uint32_t time, - struct wl_surface *surface, - struct wl_array *keys) +void QWaylandInputDevice::keyboard_enter(uint32_t time, struct wl_surface *surface, struct wl_array *keys) { - Q_UNUSED(keyboard); Q_UNUSED(time); Q_UNUSED(keys); if (!surface) return; - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - QWaylandWindow *window = (QWaylandWindow *) wl_surface_get_user_data(surface); - inputDevice->mKeyboardFocus = window; - inputDevice->mQDisplay->setLastKeyboardFocusInputDevice(inputDevice); + QWaylandWindow *window = QWaylandWindow::fromWlSurface(surface); + mKeyboardFocus = window; + mQDisplay->setLastKeyboardFocusInputDevice(this); QWindowSystemInterface::handleWindowActivated(window->window()); } -void QWaylandInputDevice::keyboard_leave(void *data, - struct wl_keyboard *keyboard, - uint32_t time, - struct wl_surface *surface) +void QWaylandInputDevice::keyboard_leave(uint32_t time, struct wl_surface *surface) { - Q_UNUSED(keyboard); Q_UNUSED(time); Q_UNUSED(surface); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - inputDevice->mKeyboardFocus = NULL; - inputDevice->mQDisplay->setLastKeyboardFocusInputDevice(0); + mKeyboardFocus = NULL; + mQDisplay->setLastKeyboardFocusInputDevice(0); } -void QWaylandInputDevice::keyboard_key(void *data, - struct wl_keyboard *keyboard, - uint32_t serial, uint32_t time, - uint32_t key, uint32_t state) +void QWaylandInputDevice::keyboard_key(uint32_t serial, uint32_t time, uint32_t key, uint32_t state) { - Q_UNUSED(keyboard); Q_UNUSED(serial); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - QWaylandWindow *window = inputDevice->mKeyboardFocus; + QWaylandWindow *window = mKeyboardFocus; #ifndef QT_NO_WAYLAND_XKB - if (!inputDevice->mXkbMap) + if (!mXkbMap) return; uint32_t code = key + 8; bool isDown = state != 0; const xkb_keysym_t *syms; - uint32_t numSyms = xkb_key_get_syms(inputDevice->mXkbState, code, &syms); - xkb_state_update_key(inputDevice->mXkbState, code, + uint32_t numSyms = xkb_key_get_syms(mXkbState, code, &syms); + xkb_state_update_key(mXkbState, code, isDown ? XKB_KEY_DOWN : XKB_KEY_UP); if (!window) { @@ -572,7 +473,7 @@ void QWaylandInputDevice::keyboard_key(void *data, if (numSyms == 1) { xkb_keysym_t sym = syms[0]; - Qt::KeyboardModifiers modifiers = translateModifiers(inputDevice->mXkbState); + Qt::KeyboardModifiers modifiers = translateModifiers(mXkbState); QEvent::Type type = isDown ? QEvent::KeyPress : QEvent::KeyRelease; char s[2]; @@ -597,24 +498,20 @@ void QWaylandInputDevice::keyboard_key(void *data, #endif } -void QWaylandInputDevice::keyboard_modifiers(void *data, - struct wl_keyboard *keyboard, - uint32_t serial, +void QWaylandInputDevice::keyboard_modifiers(uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) { - Q_UNUSED(keyboard); Q_UNUSED(serial); #ifndef QT_NO_WAYLAND_XKB - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - if (inputDevice->mXkbState) - xkb_state_update_mask(inputDevice->mXkbState, + if (mXkbState) + xkb_state_update_mask(mXkbState, mods_depressed, mods_latched, mods_locked, 0, 0, group); #else - Q_UNUSED(data); + Q_UNUSED(serial); Q_UNUSED(mods_depressed); Q_UNUSED(mods_latched); Q_UNUSED(mods_locked); @@ -622,70 +519,43 @@ void QWaylandInputDevice::keyboard_modifiers(void *data, #endif } -void QWaylandInputDevice::touch_down(void *data, - struct wl_touch *touch, - uint32_t serial, +void QWaylandInputDevice::touch_down(uint32_t serial, uint32_t time, struct wl_surface *surface, int32_t id, wl_fixed_t x, wl_fixed_t y) { - Q_UNUSED(touch); Q_UNUSED(serial); Q_UNUSED(time); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - inputDevice->mTouchFocus = static_cast<QWaylandWindow *>(wl_surface_get_user_data(surface)); - inputDevice->handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointPressed); + mTouchFocus = QWaylandWindow::fromWlSurface(surface); + handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointPressed); } -void QWaylandInputDevice::touch_up(void *data, - struct wl_touch *touch, - uint32_t serial, - uint32_t time, - int32_t id) +void QWaylandInputDevice::touch_up(uint32_t serial, uint32_t time, int32_t id) { - Q_UNUSED(touch); Q_UNUSED(serial); Q_UNUSED(time); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - inputDevice->mTouchFocus = 0; - inputDevice->handleTouchPoint(id, 0, 0, Qt::TouchPointReleased); + mTouchFocus = 0; + handleTouchPoint(id, 0, 0, Qt::TouchPointReleased); } -void QWaylandInputDevice::touch_motion(void *data, - struct wl_touch *touch, - uint32_t time, - int32_t id, - wl_fixed_t x, - wl_fixed_t y) +void QWaylandInputDevice::touch_motion(uint32_t time, int32_t id, wl_fixed_t x, wl_fixed_t y) { - Q_UNUSED(touch); Q_UNUSED(time); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - inputDevice->handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointMoved); + handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointMoved); } -void QWaylandInputDevice::touch_frame(void *data, struct wl_touch *touch) +void QWaylandInputDevice::touch_cancel() { - Q_UNUSED(touch); - QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; - inputDevice->handleTouchFrame(); -} - -void QWaylandInputDevice::touch_cancel(void *data, struct wl_touch *touch) -{ - Q_UNUSED(touch); - QWaylandInputDevice *self = static_cast<QWaylandInputDevice *>(data); - - self->mPrevTouchPoints.clear(); - self->mTouchPoints.clear(); + mPrevTouchPoints.clear(); + mTouchPoints.clear(); - QWaylandTouchExtension *touchExt = self->mQDisplay->touchExtension(); + QWaylandTouchExtension *touchExt = mQDisplay->touchExtension(); if (touchExt) touchExt->touchCanceled(); - QWindowSystemInterface::handleTouchCancelEvent(0, self->mTouchDevice); + QWindowSystemInterface::handleTouchCancelEvent(0, mTouchDevice); } void QWaylandInputDevice::handleTouchPoint(int id, double x, double y, Qt::TouchPointState state) @@ -726,7 +596,7 @@ void QWaylandInputDevice::handleTouchPoint(int id, double x, double y, Qt::Touch mTouchPoints.append(tp); } -void QWaylandInputDevice::handleTouchFrame() +void QWaylandInputDevice::touch_frame() { // Copy all points, that are in the previous but not in the current list, as stationary. for (int i = 0; i < mPrevTouchPoints.count(); ++i) { diff --git a/src/plugins/platforms/wayland_common/qwaylandinputdevice.h b/src/plugins/platforms/wayland_common/qwaylandinputdevice.h index 71634382..c0e57a90 100644 --- a/src/plugins/platforms/wayland_common/qwaylandinputdevice.h +++ b/src/plugins/platforms/wayland_common/qwaylandinputdevice.h @@ -52,6 +52,8 @@ #include <wayland-client.h> +#include "qwayland-wayland.h" + #ifndef QT_NO_WAYLAND_XKB struct xkb_context; struct xkb_keymap; @@ -63,14 +65,15 @@ QT_BEGIN_NAMESPACE class QWaylandWindow; class QWaylandDisplay; -class QWaylandInputDevice { +class QWaylandInputDevice : public QtWayland::wl_pointer, public QtWayland::wl_keyboard, public QtWayland::wl_touch, public QtWayland::wl_seat +{ public: QWaylandInputDevice(QWaylandDisplay *display, uint32_t id); ~QWaylandInputDevice(); uint32_t capabilities() const { return mCaps; } - struct wl_seat *wl_seat() const { return mSeat; } + struct ::wl_seat *wl_seat() { return QtWayland::wl_seat::object(); } void setCursor(struct wl_buffer *buffer, struct wl_cursor_image *image); void handleWindowDestroyed(QWaylandWindow *window); @@ -86,15 +89,9 @@ private: QWaylandDisplay *mQDisplay; struct wl_display *mDisplay; - struct wl_seat *mSeat; uint32_t mCaps; - struct { - struct wl_pointer *pointer; - struct wl_surface *pointerSurface; - struct wl_keyboard *keyboard; - struct wl_touch *touch; - } mDeviceInterfaces; + struct wl_surface *pointerSurface; struct wl_data_device *mTransferDevice; QWaylandWindow *mPointerFocus; @@ -108,91 +105,53 @@ private: uint32_t mSerial; uint32_t mEnterSerial; - static const struct wl_seat_listener seatListener; - - static void seat_capabilities(void *data, - struct wl_seat *seat, - uint32_t caps); - - static const struct wl_pointer_listener pointerListener; - - static void pointer_enter(void *data, - struct wl_pointer *pointer, - uint32_t serial, struct wl_surface *surface, - wl_fixed_t sx, wl_fixed_t sy); - static void pointer_leave(void *data, - struct wl_pointer *pointer, - uint32_t time, struct wl_surface *surface); - static void pointer_motion(void *data, - struct wl_pointer *pointer, - uint32_t time, - wl_fixed_t sx, wl_fixed_t sy); - static void pointer_button(void *data, - struct wl_pointer *pointer, - uint32_t serial, uint32_t time, - uint32_t button, uint32_t state); - static void pointer_axis(void *data, - struct wl_pointer *pointer, - uint32_t time, - uint32_t axis, - wl_fixed_t value); - - static const struct wl_keyboard_listener keyboardListener; - - static void keyboard_keymap(void *data, - struct wl_keyboard *keyboard, - uint32_t format, - int32_t fd, - uint32_t size); - static void keyboard_enter(void *data, - struct wl_keyboard *keyboard, - uint32_t time, - struct wl_surface *surface, - struct wl_array *keys); - static void keyboard_leave(void *data, - struct wl_keyboard *keyboard, - uint32_t time, - struct wl_surface *surface); - static void keyboard_key(void *data, - struct wl_keyboard *keyboard, - uint32_t serial, uint32_t time, - uint32_t key, uint32_t state); - static void keyboard_modifiers(void *data, - struct wl_keyboard *keyboard, - uint32_t serial, - uint32_t mods_depressed, - uint32_t mods_latched, - uint32_t mods_locked, - uint32_t group); - - static const struct wl_touch_listener touchListener; - - static void touch_down(void *data, - struct wl_touch *touch, - uint32_t serial, - uint32_t time, - struct wl_surface *surface, - int32_t id, - wl_fixed_t x, - wl_fixed_t y); - static void touch_up(void *data, - struct wl_touch *touch, - uint32_t serial, - uint32_t time, - int32_t id); - static void touch_motion(void *data, - struct wl_touch *touch, - uint32_t time, - int32_t id, - wl_fixed_t x, - wl_fixed_t y); - static void touch_frame(void *data, - struct wl_touch *touch); - static void touch_cancel(void *data, - struct wl_touch *touch); + void seat_capabilities(uint32_t caps) Q_DECL_OVERRIDE; + + void pointer_enter(uint32_t serial, struct wl_surface *surface, + wl_fixed_t sx, wl_fixed_t sy) Q_DECL_OVERRIDE; + void pointer_leave(uint32_t time, struct wl_surface *surface); + void pointer_motion(uint32_t time, + wl_fixed_t sx, wl_fixed_t sy) Q_DECL_OVERRIDE; + void pointer_button(uint32_t serial, uint32_t time, + uint32_t button, uint32_t state) Q_DECL_OVERRIDE; + void pointer_axis(uint32_t time, + uint32_t axis, + wl_fixed_t value) Q_DECL_OVERRIDE; + + void keyboard_keymap(uint32_t format, + int32_t fd, + uint32_t size) Q_DECL_OVERRIDE; + void keyboard_enter(uint32_t time, + struct wl_surface *surface, + struct wl_array *keys) Q_DECL_OVERRIDE; + void keyboard_leave(uint32_t time, + struct wl_surface *surface) Q_DECL_OVERRIDE; + void keyboard_key(uint32_t serial, uint32_t time, + uint32_t key, uint32_t state) Q_DECL_OVERRIDE; + void keyboard_modifiers(uint32_t serial, + uint32_t mods_depressed, + uint32_t mods_latched, + uint32_t mods_locked, + uint32_t group) Q_DECL_OVERRIDE; + + void touch_down(uint32_t serial, + uint32_t time, + struct wl_surface *surface, + int32_t id, + wl_fixed_t x, + wl_fixed_t y) Q_DECL_OVERRIDE; + void touch_up(uint32_t serial, + uint32_t time, + int32_t id) Q_DECL_OVERRIDE; + void touch_motion(uint32_t time, + int32_t id, + wl_fixed_t x, + wl_fixed_t y) Q_DECL_OVERRIDE; + void touch_frame() Q_DECL_OVERRIDE; + void touch_cancel() Q_DECL_OVERRIDE; void handleTouchPoint(int id, double x, double y, Qt::TouchPointState state); - void handleTouchFrame(); + 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 7aaef546..c3a479a2 100644 --- a/src/plugins/platforms/wayland_common/qwaylandintegration.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandintegration.cpp @@ -84,8 +84,7 @@ QWaylandIntegration::QWaylandIntegration() #endif { QGuiApplicationPrivate::instance()->setEventDispatcher(mEventDispatcher); - //Disable desktop settings for wayland clients for now - QGuiApplicationPrivate::obey_desktop_settings = false; + QGuiApplication::setDesktopSettingsAware(false); mDisplay = new QWaylandDisplay(); mClipboard = new QWaylandClipboard(mDisplay); mDrag = new QWaylandDrag(mDisplay); diff --git a/src/plugins/platforms/wayland_common/qwaylandnativeinterface.cpp b/src/plugins/platforms/wayland_common/qwaylandnativeinterface.cpp index f5829b27..31d25c0f 100644 --- a/src/plugins/platforms/wayland_common/qwaylandnativeinterface.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandnativeinterface.cpp @@ -64,7 +64,7 @@ void *QWaylandNativeInterface::nativeResourceForIntegration(const QByteArray &re if (lowerCaseResource == "display") return m_integration->display()->wl_display(); if (lowerCaseResource == "compositor") - return m_integration->display()->wl_compositor(); + return const_cast<wl_compositor *>(m_integration->display()->wl_compositor()); return 0; } @@ -76,7 +76,7 @@ void *QWaylandNativeInterface::nativeResourceForWindow(const QByteArray &resourc if (lowerCaseResource == "display") return m_integration->display()->wl_display(); if (lowerCaseResource == "compositor") - return m_integration->display()->wl_compositor(); + return const_cast<wl_compositor *>(m_integration->display()->wl_compositor()); if (lowerCaseResource == "surface") { return ((QWaylandWindow *) window->handle())->wl_surface(); } diff --git a/src/plugins/platforms/wayland_common/qwaylandqtkey.cpp b/src/plugins/platforms/wayland_common/qwaylandqtkey.cpp index 76d91c79..d9f2071e 100644 --- a/src/plugins/platforms/wayland_common/qwaylandqtkey.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandqtkey.cpp @@ -42,34 +42,26 @@ #include "qwaylandqtkey.h" #include "qwaylandinputdevice.h" -#include "wayland-qtkey-extension-client-protocol.h" - QT_USE_NAMESPACE QWaylandQtKeyExtension::QWaylandQtKeyExtension(QWaylandDisplay *display, uint32_t id) - : m_display(display) + : QtWayland::qt_key_extension(display->wl_registry(), id) + , m_display(display) { - m_qtkey = static_cast<struct wl_qtkey_extension *>(wl_registry_bind(display->wl_registry(), id, &wl_qtkey_extension_interface, 1)); - wl_qtkey_extension_add_listener(m_qtkey, &qtkey_listener, this); } -void QWaylandQtKeyExtension::handle_qtkey(void *data, - struct wl_qtkey_extension *ext, - uint32_t time, - uint32_t type, - uint32_t key, - uint32_t modifiers, - uint32_t nativeScanCode, - uint32_t nativeVirtualKey, - uint32_t nativeModifiers, - const char *text, - uint32_t autorep, - uint32_t count) +void QWaylandQtKeyExtension::key_extension_qtkey(uint32_t time, + uint32_t type, + uint32_t key, + uint32_t modifiers, + uint32_t nativeScanCode, + uint32_t nativeVirtualKey, + uint32_t nativeModifiers, + const QString &text, + uint32_t autorep, + uint32_t count) { - Q_UNUSED(ext); - QWaylandQtKeyExtension *self = static_cast<QWaylandQtKeyExtension *>(data); - - QList<QWaylandInputDevice *> inputDevices = self->m_display->inputDevices(); + QList<QWaylandInputDevice *> inputDevices = m_display->inputDevices(); if (inputDevices.isEmpty()) { qWarning("wl_qtkey_extension: handle_qtkey: No input device"); return; @@ -85,11 +77,6 @@ void QWaylandQtKeyExtension::handle_qtkey(void *data, QWindow *window = win->window(); QWindowSystemInterface::handleExtendedKeyEvent(window, time, QEvent::Type(type), key, Qt::KeyboardModifiers(modifiers), - nativeScanCode, nativeVirtualKey, nativeModifiers, QString::fromUtf8(text), + nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count); } - -const struct wl_qtkey_extension_listener QWaylandQtKeyExtension::qtkey_listener = { - QWaylandQtKeyExtension::handle_qtkey -}; - diff --git a/src/plugins/platforms/wayland_common/qwaylandqtkey.h b/src/plugins/platforms/wayland_common/qwaylandqtkey.h index adcce613..17b758cf 100644 --- a/src/plugins/platforms/wayland_common/qwaylandqtkey.h +++ b/src/plugins/platforms/wayland_common/qwaylandqtkey.h @@ -45,33 +45,28 @@ #include "qwaylanddisplay.h" #include <qpa/qwindowsysteminterface.h> -class wl_qtkey_extension; +#include "qwayland-qtkey-extension.h" QT_BEGIN_NAMESPACE -class QWaylandQtKeyExtension +class QWaylandQtKeyExtension : public QtWayland::qt_key_extension { public: QWaylandQtKeyExtension(QWaylandDisplay *display, uint32_t id); private: QWaylandDisplay *m_display; - wl_qtkey_extension *m_qtkey; - static const struct wl_qtkey_extension_listener qtkey_listener; - - static void handle_qtkey(void *data, - struct wl_qtkey_extension *ext, - uint32_t time, - uint32_t type, - uint32_t key, - uint32_t modifiers, - uint32_t nativeScanCode, - uint32_t nativeVirtualKey, - uint32_t nativeModifiers, - const char *text, - uint32_t autorep, - uint32_t count); + void key_extension_qtkey(uint32_t time, + uint32_t type, + uint32_t key, + uint32_t modifiers, + uint32_t nativeScanCode, + uint32_t nativeVirtualKey, + uint32_t nativeModifiers, + const QString &text, + uint32_t autorep, + uint32_t count) Q_DECL_OVERRIDE; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandscreen.cpp b/src/plugins/platforms/wayland_common/qwaylandscreen.cpp index 8393058f..1cb1b9cf 100644 --- a/src/plugins/platforms/wayland_common/qwaylandscreen.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandscreen.cpp @@ -49,20 +49,17 @@ QT_USE_NAMESPACE -QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, struct wl_output *output) - : QPlatformScreen() +QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, uint32_t id) + : QtWayland::wl_output(waylandDisplay->wl_registry(), id) , mWaylandDisplay(waylandDisplay) - , mOutput(output) , mExtendedOutput(0) , mDepth(32) , mRefreshRate(60000) , mFormat(QImage::Format_ARGB32_Premultiplied) , mWaylandCursor(new QWaylandCursor(this)) { - //maybe the global is sent after the first screen? - if (waylandDisplay->outputExtension()) { - mExtendedOutput = waylandDisplay->outputExtension()->getExtendedOutput(this); - } + // handle case of output extension global being sent after outputs + createExtendedOutput(); } QWaylandScreen::~QWaylandScreen() @@ -75,15 +72,6 @@ QWaylandDisplay * QWaylandScreen::display() const return mWaylandDisplay; } -void QWaylandScreen::setGeometry(const QRect &geom) -{ - if (mGeometry == geom) - return; - - mGeometry = geom; - QWindowSystemInterface::handleScreenGeometryChange(screen(), mGeometry); -} - QRect QWaylandScreen::geometry() const { return mGeometry; @@ -127,10 +115,11 @@ QWaylandExtendedOutput *QWaylandScreen::extendedOutput() const return mExtendedOutput; } -void QWaylandScreen::setExtendedOutput(QWaylandExtendedOutput *extendedOutput) +void QWaylandScreen::createExtendedOutput() { - Q_ASSERT(!mExtendedOutput); - mExtendedOutput = extendedOutput; + QtWayland::qt_output_extension *extension = mWaylandDisplay->outputExtension(); + if (!mExtendedOutput && extension) + mExtendedOutput = new QWaylandExtendedOutput(this, extension->get_extended_output(output())); } QWaylandScreen * QWaylandScreen::waylandScreenFromWindow(QWindow *window) @@ -139,15 +128,41 @@ QWaylandScreen * QWaylandScreen::waylandScreenFromWindow(QWindow *window) return static_cast<QWaylandScreen *>(platformScreen); } -void QWaylandScreen::handleMode(const QSize &size, int refreshRate) +void QWaylandScreen::output_mode(uint32_t flags, int width, int height, int refresh) { + if (!(flags & WL_OUTPUT_MODE_CURRENT)) + return; + + QSize size(width, height); + if (size != mGeometry.size()) { mGeometry.setSize(size); QWindowSystemInterface::handleScreenGeometryChange(screen(), mGeometry); } - if (refreshRate != mRefreshRate) { - mRefreshRate = refreshRate; + if (refresh != mRefreshRate) { + mRefreshRate = refresh; QWindowSystemInterface::handleScreenRefreshRateChange(screen(), mRefreshRate); } } + +void QWaylandScreen::output_geometry(int32_t x, int32_t y, + int32_t width, int32_t height, + int subpixel, + const QString &make, + const QString &model, + int32_t transform) +{ + Q_UNUSED(subpixel); + Q_UNUSED(make); + Q_UNUSED(model); + Q_UNUSED(transform); + + QRect geom(x, y, width, height); + + if (mGeometry == geom) + return; + + mGeometry = geom; + QWindowSystemInterface::handleScreenGeometryChange(screen(), mGeometry); +} diff --git a/src/plugins/platforms/wayland_common/qwaylandscreen.h b/src/plugins/platforms/wayland_common/qwaylandscreen.h index 3d4b2948..005f25ee 100644 --- a/src/plugins/platforms/wayland_common/qwaylandscreen.h +++ b/src/plugins/platforms/wayland_common/qwaylandscreen.h @@ -44,16 +44,18 @@ #include <qpa/qplatformscreen.h> +#include <qwayland-wayland.h> + QT_BEGIN_NAMESPACE class QWaylandDisplay; class QWaylandCursor; class QWaylandExtendedOutput; -class QWaylandScreen : public QPlatformScreen +class QWaylandScreen : public QPlatformScreen, QtWayland::wl_output { public: - QWaylandScreen(QWaylandDisplay *waylandDisplay, struct wl_output *output); + QWaylandScreen(QWaylandDisplay *waylandDisplay, uint32_t id); ~QWaylandScreen(); QWaylandDisplay *display() const; @@ -69,20 +71,23 @@ public: QPlatformCursor *cursor() const; - wl_output *output() const { return mOutput; } + ::wl_output *output() { return object(); } QWaylandExtendedOutput *extendedOutput() const; - void setExtendedOutput(QWaylandExtendedOutput *extendedOutput); + void createExtendedOutput(); static QWaylandScreen *waylandScreenFromWindow(QWindow *window); - void handleMode(const QSize &size, int refreshRate); - - void setGeometry(const QRect &geom); - private: + void output_mode(uint32_t flags, int width, int height, int refresh) Q_DECL_OVERRIDE; + void output_geometry(int32_t x, int32_t y, + int32_t width, int32_t height, + int subpixel, + const QString &make, + const QString &model, + int32_t transform) Q_DECL_OVERRIDE; + QWaylandDisplay *mWaylandDisplay; - struct wl_output *mOutput; QWaylandExtendedOutput *mExtendedOutput; QRect mGeometry; int mDepth; diff --git a/src/plugins/platforms/wayland_common/qwaylandshell.cpp b/src/plugins/platforms/wayland_common/qwaylandshell.cpp deleted file mode 100644 index 9c37235c..00000000 --- a/src/plugins/platforms/wayland_common/qwaylandshell.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the config.tests of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwaylandshell.h" - -#include "qwaylandshellsurface.h" -#include "qwaylandwindow.h" - -QT_USE_NAMESPACE - -QWaylandShell::QWaylandShell(QWaylandDisplay *display, uint32_t id, uint32_t version) - : m_display(display) -{ - Q_UNUSED(version) - m_shell = static_cast<struct wl_shell *>(wl_registry_bind(m_display->wl_registry(), id, &wl_shell_interface, 1)); -} - -QWaylandShellSurface *QWaylandShell::getShellSurface(QWaylandWindow *window) -{ - Q_ASSERT(window->wl_surface()); - struct wl_shell_surface *shell_surface = wl_shell_get_shell_surface(m_shell,window->wl_surface()); - return new QWaylandShellSurface(shell_surface,window); -} diff --git a/src/plugins/platforms/wayland_common/qwaylandshell.h b/src/plugins/platforms/wayland_common/qwaylandshell.h deleted file mode 100644 index 3c2014f6..00000000 --- a/src/plugins/platforms/wayland_common/qwaylandshell.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the config.tests of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWAYLANDSHELL_H -#define QWAYLANDSHELL_H - -#include "qwaylanddisplay.h" - -QT_BEGIN_NAMESPACE - -class QWaylandWindow; -class QWaylandShellSurface; - -class QWaylandShell -{ -public: - QWaylandShell(QWaylandDisplay *display, uint32_t id, uint32_t version); - - QWaylandShellSurface *getShellSurface(QWaylandWindow *window); - -private: - struct wl_shell *m_shell; - - QWaylandDisplay *m_display; -}; - -QT_END_NAMESPACE - -#endif // QWAYLANDSHELL_H diff --git a/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp b/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp index 890552c2..98689073 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandshellsurface.cpp @@ -51,46 +51,44 @@ QT_USE_NAMESPACE -QWaylandShellSurface::QWaylandShellSurface(struct wl_shell_surface *shell_surface, QWaylandWindow *window) - : m_shell_surface(shell_surface) +QWaylandShellSurface::QWaylandShellSurface(struct ::wl_shell_surface *shell_surface, QWaylandWindow *window) + : QtWayland::wl_shell_surface(shell_surface) , m_window(window) , m_maximized(false) , m_fullscreen(false) { - wl_shell_surface_add_listener(m_shell_surface,&m_shell_surface_listener,this); } QWaylandShellSurface::~QWaylandShellSurface() { - wl_shell_surface_destroy(m_shell_surface); + wl_shell_surface_destroy(object()); } void QWaylandShellSurface::resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges) { - wl_shell_surface_resize(m_shell_surface,inputDevice->wl_seat(), - inputDevice->serial(), - edges); + resize(inputDevice->wl_seat(), + inputDevice->serial(), + edges); } void QWaylandShellSurface::move(QWaylandInputDevice *inputDevice) { - wl_shell_surface_move(m_shell_surface, - inputDevice->wl_seat(), - inputDevice->serial()); + move(inputDevice->wl_seat(), + inputDevice->serial()); } void QWaylandShellSurface::setMaximized() { m_maximized = true; m_size = m_window->window()->geometry().size(); - wl_shell_surface_set_maximized(m_shell_surface, 0); + set_maximized(0); } void QWaylandShellSurface::setFullscreen() { m_fullscreen = true; m_size = m_window->window()->geometry().size(); - wl_shell_surface_set_fullscreen(m_shell_surface, 0, 0, 0); + set_fullscreen(0, 0, 0); } void QWaylandShellSurface::setNormal() @@ -110,7 +108,7 @@ void QWaylandShellSurface::setMinimized() void QWaylandShellSurface::setTopLevel() { - wl_shell_surface_set_toplevel(m_shell_surface); + set_toplevel(); } void QWaylandShellSurface::updateTransientParent(QWindow *parent) @@ -134,11 +132,10 @@ void QWaylandShellSurface::updateTransientParent(QWindow *parent) || wf.testFlag(Qt::WindowTransparentForInput)) flags |= WL_SHELL_SURFACE_TRANSIENT_INACTIVE; - wl_shell_surface_set_transient(m_shell_surface, - parent_wayland_window->wl_surface(), - transientPos.x(), - transientPos.y(), - flags); + set_transient(parent_wayland_window->wl_surface(), + transientPos.x(), + transientPos.y(), + flags); } void QWaylandShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial) @@ -155,52 +152,34 @@ void QWaylandShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevice transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top()); } - wl_shell_surface_set_popup(m_shell_surface, device->wl_seat(), serial, + 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 *_class) +void QWaylandShellSurface::setClassName(const char *className) { - wl_shell_surface_set_class(m_shell_surface, _class); + set_class(className); } void QWaylandShellSurface::setTitle(const char *title) { - wl_shell_surface_set_title(m_shell_surface, title); + set_title(title); } -void QWaylandShellSurface::ping(void *data, - struct wl_shell_surface *wl_shell_surface, - uint32_t serial) +void QWaylandShellSurface::shell_surface_ping(uint32_t serial) { - Q_UNUSED(data); - wl_shell_surface_pong(wl_shell_surface, serial); + pong(serial); } -void QWaylandShellSurface::configure(void *data, - wl_shell_surface *wl_shell_surface, - uint32_t edges, - int32_t width, - int32_t height) +void QWaylandShellSurface::shell_surface_configure(uint32_t edges, + int32_t width, + int32_t height) { - Q_UNUSED(wl_shell_surface); - QWaylandShellSurface *shell_surface = static_cast<QWaylandShellSurface *>(data); - shell_surface->m_window->configure(edges, width, height); + m_window->configure(edges, width, height); } -void QWaylandShellSurface::popup_done(void *data, - struct wl_shell_surface *wl_shell_surface) +void QWaylandShellSurface::shell_surface_popup_done() { - Q_UNUSED(data); - Q_UNUSED(wl_shell_surface); - - QWaylandShellSurface *shell_surface = static_cast<QWaylandShellSurface *>(data); - QCoreApplication::postEvent(shell_surface->m_window->window(), new QCloseEvent()); + QCoreApplication::postEvent(m_window->window(), new QCloseEvent()); } - -const wl_shell_surface_listener QWaylandShellSurface::m_shell_surface_listener = { - QWaylandShellSurface::ping, - QWaylandShellSurface::configure, - QWaylandShellSurface::popup_done -}; diff --git a/src/plugins/platforms/wayland_common/qwaylandshellsurface.h b/src/plugins/platforms/wayland_common/qwaylandshellsurface.h index e9061f0b..9e886cf0 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshellsurface.h +++ b/src/plugins/platforms/wayland_common/qwaylandshellsurface.h @@ -46,19 +46,24 @@ #include <wayland-client.h> +#include "qwayland-wayland.h" + QT_BEGIN_NAMESPACE class QWaylandWindow; class QWaylandInputDevice; class QWindow; -class QWaylandShellSurface +class QWaylandShellSurface : public QtWayland::wl_shell_surface { public: - QWaylandShellSurface(struct wl_shell_surface *shell_surface, QWaylandWindow *window); + QWaylandShellSurface(struct ::wl_shell_surface *shell_surface, QWaylandWindow *window); ~QWaylandShellSurface(); + using QtWayland::wl_shell_surface::resize; void resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges); + + using QtWayland::wl_shell_surface::move; void move(QWaylandInputDevice *inputDevice); private: @@ -71,29 +76,20 @@ private: void updateTransientParent(QWindow *parent); void setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial); - struct wl_shell_surface *handle() const { return m_shell_surface; } - void setClassName(const char *_class); void setTitle(const char *title); - struct wl_shell_surface *m_shell_surface; QWaylandWindow *m_window; bool m_maximized; bool m_fullscreen; QSize m_size; - static void ping(void *data, - struct wl_shell_surface *wl_shell_surface, - uint32_t serial); - static void configure(void *data, - struct wl_shell_surface *wl_shell_surface, - uint32_t edges, - int32_t width, - int32_t height); - static void popup_done(void *data, - struct wl_shell_surface *wl_shell_surface); - static const struct wl_shell_surface_listener m_shell_surface_listener; + void shell_surface_ping(uint32_t serial) Q_DECL_OVERRIDE; + void shell_surface_configure(uint32_t edges, + int32_t width, + int32_t height) Q_DECL_OVERRIDE; + void shell_surface_popup_done() Q_DECL_OVERRIDE; friend class QWaylandWindow; }; diff --git a/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.cpp b/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.cpp index b444d2b2..93161a3f 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.cpp @@ -192,6 +192,9 @@ void QWaylandShmBackingStore::flush(QWindow *window, const QRegion ®ion, cons Q_UNUSED(offset); Q_ASSERT(waylandWindow()->windowType() == QWaylandWindow::Shm); + if (windowDecoration() && windowDecoration()->isDirty()) + updateDecorations(); + mFrontBuffer = mBackBuffer; if (mFrameCallback) { @@ -199,7 +202,7 @@ void QWaylandShmBackingStore::flush(QWindow *window, const QRegion ®ion, cons return; } - mFrameCallback = wl_surface_frame(waylandWindow()->wl_surface()); + mFrameCallback = waylandWindow()->frame(); wl_callback_add_listener(mFrameCallback,&frameCallbackListener,this); QMargins margins = windowDecorationMargins(); @@ -222,6 +225,7 @@ void QWaylandShmBackingStore::flush(QWindow *window, const QRegion ®ion, cons } } mFrontBufferIsDirty = false; + waylandWindow()->doResize(); } void QWaylandShmBackingStore::resize(const QSize &size, const QRegion &) @@ -245,8 +249,8 @@ void QWaylandShmBackingStore::resize(const QSize &size) mBackBuffer = new QWaylandShmBuffer(mDisplay, sizeWithMargins, format); - if (windowDecoration()) - windowDecoration()->paintDecoration(); + if (windowDecoration() && window()->isVisible()) + windowDecoration()->update(); } QImage *QWaylandShmBackingStore::entireSurface() const @@ -254,6 +258,36 @@ QImage *QWaylandShmBackingStore::entireSurface() const return mBackBuffer->image(); } +void QWaylandShmBackingStore::updateDecorations() +{ + QPainter decorationPainter(entireSurface()); + decorationPainter.setCompositionMode(QPainter::CompositionMode_Source); + QImage sourceImage = windowDecoration()->contentImage(); + QRect target; + //Top + target.setX(0); + target.setY(0); + target.setWidth(sourceImage.width()); + target.setHeight(windowDecorationMargins().top()); + decorationPainter.drawImage(target, sourceImage, target); + + //Left + target.setWidth(windowDecorationMargins().left()); + target.setHeight(sourceImage.height()); + decorationPainter.drawImage(target, sourceImage, target); + + //Right + target.setX(sourceImage.width() - windowDecorationMargins().right()); + decorationPainter.drawImage(target, sourceImage, target); + + //Bottom + target.setX(0); + target.setY(sourceImage.height() - windowDecorationMargins().bottom()); + target.setWidth(sourceImage.width()); + target.setHeight(windowDecorationMargins().bottom()); + decorationPainter.drawImage(target, sourceImage, target); +} + void QWaylandShmBackingStore::done(void *data, wl_callback *callback, uint32_t time) { Q_UNUSED(time); @@ -269,7 +303,8 @@ void QWaylandShmBackingStore::done(void *data, wl_callback *callback, uint32_t t delete window->attached(); } - window->attachOffset(self->mFrontBuffer); + if (window->attached() != self->mFrontBuffer) + window->attachOffset(self->mFrontBuffer); if (self->mFrontBufferIsDirty && !self->mPainting) { self->mFrontBufferIsDirty = false; @@ -284,3 +319,4 @@ const struct wl_callback_listener QWaylandShmBackingStore::frameCallbackListener }; QT_END_NAMESPACE + diff --git a/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.h b/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.h index 1eadb5ed..60117342 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.h +++ b/src/plugins/platforms/wayland_common/qwaylandshmbackingstore.h @@ -94,6 +94,8 @@ public: void iterateBuffer(); private: + void updateDecorations(); + QWaylandDisplay *mDisplay; QWaylandShmBuffer *mFrontBuffer; QWaylandShmBuffer *mBackBuffer; diff --git a/src/plugins/platforms/wayland_common/qwaylandshmdecoration.cpp b/src/plugins/platforms/wayland_common/qwaylandshmdecoration.cpp deleted file mode 100644 index e6af4ab4..00000000 --- a/src/plugins/platforms/wayland_common/qwaylandshmdecoration.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwaylandshmdecoration.h" - -#include "qwaylandshmwindow.h" -#include "qwaylandshmbackingstore.h" - -QT_USE_NAMESPACE - -QWaylandShmDecoration::QWaylandShmDecoration(QWaylandShmWindow *window) - : QWaylandDecoration(window) -{ - -} - -QWaylandShmDecoration::~QWaylandShmDecoration() -{ -} - -void QWaylandShmDecoration::paintDecoration() -{ - QWaylandShmBackingStore *bs = static_cast<QWaylandShmWindow *>(waylandWindow())->backingStore(); - if (bs) { - paint(bs->entireSurface()); - } -} diff --git a/src/plugins/platforms/wayland_common/qwaylandshmdecoration.h b/src/plugins/platforms/wayland_common/qwaylandshmdecoration.h deleted file mode 100644 index 567e8755..00000000 --- a/src/plugins/platforms/wayland_common/qwaylandshmdecoration.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWAYLANDSHMDECORATION_H -#define QWAYLANDSHMDECORATION_H - -#include "qwaylanddecoration.h" - -QT_BEGIN_NAMESPACE - -class QWaylandShmWindow; - -class QWaylandShmDecoration : public QWaylandDecoration -{ -public: - QWaylandShmDecoration(QWaylandShmWindow *window); - ~QWaylandShmDecoration(); - - void paintDecoration(); - -}; - -QT_END_NAMESPACE - -#endif // QWAYLANDSHMDECORATION_H diff --git a/src/plugins/platforms/wayland_common/qwaylandshmwindow.cpp b/src/plugins/platforms/wayland_common/qwaylandshmwindow.cpp index ad2fd9a2..f4a0ede0 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshmwindow.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandshmwindow.cpp @@ -42,7 +42,6 @@ #include "qwaylandshmwindow.h" #include "qwaylandbuffer.h" -#include "qwaylandshmdecoration.h" #include <QtCore/QVector> @@ -70,9 +69,3 @@ void QWaylandShmWindow::setBackingStore(QWaylandShmBackingStore *backingStore) { mBackingStore = backingStore; } - -void QWaylandShmWindow::createDecorationInstance() -{ - new QWaylandShmDecoration(this); -} - diff --git a/src/plugins/platforms/wayland_common/qwaylandshmwindow.h b/src/plugins/platforms/wayland_common/qwaylandshmwindow.h index f28e1d50..ffd11c94 100644 --- a/src/plugins/platforms/wayland_common/qwaylandshmwindow.h +++ b/src/plugins/platforms/wayland_common/qwaylandshmwindow.h @@ -61,9 +61,6 @@ public: void setBackingStore(QWaylandShmBackingStore *backingStore); QWaylandShmBackingStore *backingStore() const; -protected: - void createDecorationInstance(); - private: QWaylandShmBackingStore *mBackingStore; }; diff --git a/src/plugins/platforms/wayland_common/qwaylandsubsurface.cpp b/src/plugins/platforms/wayland_common/qwaylandsubsurface.cpp index 0ec955a8..99713bb6 100644 --- a/src/plugins/platforms/wayland_common/qwaylandsubsurface.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandsubsurface.cpp @@ -43,42 +43,23 @@ #include "qwaylandwindow.h" -#include "wayland-sub-surface-extension-client-protocol.h" - #include <QtCore/QDebug> QT_USE_NAMESPACE -QWaylandSubSurfaceExtension::QWaylandSubSurfaceExtension(QWaylandDisplay *display, uint32_t id) -{ - m_sub_surface_extension = static_cast<struct wl_sub_surface_extension *>( - wl_registry_bind(display->wl_registry(), id, &wl_sub_surface_extension_interface, 1)); -} - -QWaylandSubSurface *QWaylandSubSurfaceExtension::getSubSurfaceAwareWindow(QWaylandWindow *window) -{ - struct wl_surface *surface = window->wl_surface(); - Q_ASSERT(surface); - struct wl_sub_surface *sub_surface = - wl_sub_surface_extension_get_sub_surface_aware_surface(m_sub_surface_extension,surface); - - return new QWaylandSubSurface(window,sub_surface); - -} - -QWaylandSubSurface::QWaylandSubSurface(QWaylandWindow *window, struct wl_sub_surface *sub_surface) - : m_window(window) - , m_sub_surface(sub_surface) +QWaylandSubSurface::QWaylandSubSurface(QWaylandWindow *window, struct ::qt_sub_surface *sub_surface) + : QtWayland::qt_sub_surface(sub_surface) + , m_window(window) { } void QWaylandSubSurface::setParent(const QWaylandWindow *parent) { - QWaylandSubSurface *parentSurface = parent? parent->subSurfaceWindow():0; + QWaylandSubSurface *parentSurface = parent ? parent->subSurfaceWindow() : 0; if (parentSurface) { int x = m_window->geometry().x() + parent->frameMargins().left(); int y = m_window->geometry().y() + parent->frameMargins().top(); - wl_sub_surface_attach_sub_surface(parentSurface->m_sub_surface,m_sub_surface,x,y); + parentSurface->attach_sub_surface(object(), x, y); } } diff --git a/src/plugins/platforms/wayland_common/qwaylandsubsurface.h b/src/plugins/platforms/wayland_common/qwaylandsubsurface.h index e594050e..10290d8c 100644 --- a/src/plugins/platforms/wayland_common/qwaylandsubsurface.h +++ b/src/plugins/platforms/wayland_common/qwaylandsubsurface.h @@ -46,34 +46,24 @@ #include <QtCore/qglobal.h> +#include <qwayland-sub-surface-extension.h> + QT_BEGIN_NAMESPACE class QWaylandDisplay; class QWaylandWindow; class QWaylandSubSurface; -class QWaylandSubSurfaceExtension -{ -public: - QWaylandSubSurfaceExtension(QWaylandDisplay *display, uint32_t id); - - QWaylandSubSurface *getSubSurfaceAwareWindow(QWaylandWindow *window); -private: - struct wl_sub_surface_extension *m_sub_surface_extension; -}; - -class QWaylandSubSurface +class QWaylandSubSurface : public QtWayland::qt_sub_surface { public: - QWaylandSubSurface(QWaylandWindow *window, struct wl_sub_surface *sub_surface); + QWaylandSubSurface(QWaylandWindow *window, struct ::qt_sub_surface *sub_surface); void setParent(const QWaylandWindow *parent); - void adjustPositionOfChildren(); private: QWaylandWindow *m_window; - struct wl_sub_surface *m_sub_surface; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland_common/qwaylandtouch.cpp b/src/plugins/platforms/wayland_common/qwaylandtouch.cpp index 26f57d57..b19165d6 100644 --- a/src/plugins/platforms/wayland_common/qwaylandtouch.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandtouch.cpp @@ -42,20 +42,17 @@ #include "qwaylandtouch.h" #include "qwaylandinputdevice.h" -#include "wayland-touch-extension-client-protocol.h" - QT_USE_NAMESPACE QWaylandTouchExtension::QWaylandTouchExtension(QWaylandDisplay *display, uint32_t id) - : mDisplay(display), + : QtWayland::qt_touch_extension(display->wl_registry(), id), + mDisplay(display), mTouchDevice(0), mPointsLeft(0), mFlags(0), mMouseSourceId(-1), mInputDevice(0) { - mTouch = static_cast<struct wl_touch_extension *>(wl_registry_bind(display->wl_registry(), id, &wl_touch_extension_interface, 1)); - wl_touch_extension_add_listener(mTouch, &touch_listener, this); } void QWaylandTouchExtension::registerDevice(int caps) @@ -71,53 +68,50 @@ static inline qreal fromFixed(int f) return f / qreal(10000); } -void QWaylandTouchExtension::handle_touch(void *data, wl_touch_extension *ext, uint32_t time, - uint32_t id, uint32_t state, int32_t x, int32_t y, - int32_t normalized_x, int32_t normalized_y, - int32_t width, int32_t height, uint32_t pressure, - int32_t velocity_x, int32_t velocity_y, - uint32_t flags, wl_array *rawdata) +void QWaylandTouchExtension::touch_extension_touch(uint32_t time, + uint32_t id, uint32_t state, int32_t x, int32_t y, + int32_t normalized_x, int32_t normalized_y, + int32_t width, int32_t height, uint32_t pressure, + int32_t velocity_x, int32_t velocity_y, + uint32_t flags, wl_array *rawdata) { - Q_UNUSED(ext); - QWaylandTouchExtension *self = static_cast<QWaylandTouchExtension *>(data); - - if (!self->mInputDevice) { - QList<QWaylandInputDevice *> inputDevices = self->mDisplay->inputDevices(); + if (!mInputDevice) { + QList<QWaylandInputDevice *> inputDevices = mDisplay->inputDevices(); if (inputDevices.isEmpty()) { qWarning("wl_touch_extension: handle_touch: No input devices"); return; } - self->mInputDevice = inputDevices.first(); + mInputDevice = inputDevices.first(); } - QWaylandWindow *win = self->mInputDevice->mTouchFocus; + QWaylandWindow *win = mInputDevice->mTouchFocus; if (!win) - win = self->mInputDevice->mPointerFocus; + win = mInputDevice->mPointerFocus; if (!win) - win = self->mInputDevice->mKeyboardFocus; + win = mInputDevice->mKeyboardFocus; if (!win || !win->window()) { qWarning("wl_touch_extension: handle_touch: No pointer focus"); return; } - self->mTargetWindow = win->window(); + mTargetWindow = win->window(); QWindowSystemInterface::TouchPoint tp; tp.id = id; tp.state = Qt::TouchPointState(int(state & 0xFFFF)); int sentPointCount = state >> 16; - if (!self->mPointsLeft) { + if (!mPointsLeft) { Q_ASSERT(sentPointCount > 0); - self->mPointsLeft = sentPointCount; + mPointsLeft = sentPointCount; } tp.flags = QTouchEvent::TouchPoint::InfoFlags(int(flags & 0xFFFF)); - if (!self->mTouchDevice) - self->registerDevice(flags >> 16); + if (!mTouchDevice) + registerDevice(flags >> 16); tp.area = QRectF(0, 0, fromFixed(width), fromFixed(height)); // Got surface-relative coords but need a (virtual) screen position. QPointF relPos = QPointF(fromFixed(x), fromFixed(y)); QPointF delta = relPos - relPos.toPoint(); - tp.area.moveCenter(self->mTargetWindow->mapToGlobal(relPos.toPoint()) + delta); + tp.area.moveCenter(mTargetWindow->mapToGlobal(relPos.toPoint()) + delta); tp.normalPosition.setX(fromFixed(normalized_x)); tp.normalPosition.setY(fromFixed(normalized_y)); @@ -135,11 +129,11 @@ void QWaylandTouchExtension::handle_touch(void *data, wl_touch_extension *ext, u } } - self->mTouchPoints.append(tp); - self->mTimestamp = time; + mTouchPoints.append(tp); + mTimestamp = time; - if (!--self->mPointsLeft) - self->sendTouchEvent(); + if (!--mPointsLeft) + sendTouchEvent(); } void QWaylandTouchExtension::sendTouchEvent() @@ -173,7 +167,7 @@ void QWaylandTouchExtension::sendTouchEvent() for (int i = 0; i < mTouchPoints.count(); ++i) states |= mTouchPoints.at(i).state; - if (mFlags & WL_TOUCH_EXTENSION_FLAGS_MOUSE_FROM_TOUCH) { + if (mFlags & QT_TOUCH_EXTENSION_FLAGS_MOUSE_FROM_TOUCH) { if (states == Qt::TouchPointPressed) mMouseSourceId = mTouchPoints.first().id; for (int i = 0; i < mTouchPoints.count(); ++i) { @@ -207,14 +201,7 @@ void QWaylandTouchExtension::touchCanceled() QWindowSystemInterface::handleMouseEvent(mTargetWindow, mTimestamp, mLastMouseLocal, mLastMouseGlobal, Qt::NoButton); } -void QWaylandTouchExtension::handle_configure(void *data, wl_touch_extension *ext, uint32_t flags) +void QWaylandTouchExtension::touch_extension_configure(uint32_t flags) { - Q_UNUSED(ext); - QWaylandTouchExtension *self = static_cast<QWaylandTouchExtension *>(data); - self->mFlags = flags; + mFlags = flags; } - -const struct wl_touch_extension_listener QWaylandTouchExtension::touch_listener = { - QWaylandTouchExtension::handle_touch, - QWaylandTouchExtension::handle_configure -}; diff --git a/src/plugins/platforms/wayland_common/qwaylandtouch.h b/src/plugins/platforms/wayland_common/qwaylandtouch.h index 9762af22..3762209d 100644 --- a/src/plugins/platforms/wayland_common/qwaylandtouch.h +++ b/src/plugins/platforms/wayland_common/qwaylandtouch.h @@ -45,11 +45,11 @@ #include "qwaylanddisplay.h" #include <qpa/qwindowsysteminterface.h> -class wl_touch_extension; +#include <qwayland-touch-extension.h> QT_BEGIN_NAMESPACE -class QWaylandTouchExtension +class QWaylandTouchExtension : public QtWayland::qt_touch_extension { public: QWaylandTouchExtension(QWaylandDisplay *display, uint32_t id); @@ -60,28 +60,22 @@ private: void registerDevice(int caps); QWaylandDisplay *mDisplay; - wl_touch_extension *mTouch; - static const struct wl_touch_extension_listener touch_listener; - static void handle_touch(void *data, - struct wl_touch_extension *ext, - uint32_t time, - uint32_t id, - uint32_t state, - int32_t x, - int32_t y, - int32_t normalized_x, - int32_t normalized_y, - int32_t width, - int32_t height, - uint32_t pressure, - int32_t velocity_x, - int32_t velocity_y, - uint32_t flags, - struct wl_array *rawdata); - static void handle_configure(void *data, - struct wl_touch_extension *ext, - uint32_t flags); + void touch_extension_touch(uint32_t time, + uint32_t id, + uint32_t state, + int32_t x, + int32_t y, + int32_t normalized_x, + int32_t normalized_y, + int32_t width, + int32_t height, + uint32_t pressure, + int32_t velocity_x, + int32_t velocity_y, + uint32_t flags, + struct wl_array *rawdata) Q_DECL_OVERRIDE; + void touch_extension_configure(uint32_t flags) Q_DECL_OVERRIDE; void sendTouchEvent(); diff --git a/src/plugins/platforms/wayland_common/qwaylandwindow.cpp b/src/plugins/platforms/wayland_common/qwaylandwindow.cpp index b71176d4..66622210 100644 --- a/src/plugins/platforms/wayland_common/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland_common/qwaylandwindow.cpp @@ -45,7 +45,6 @@ #include "qwaylanddisplay.h" #include "qwaylandinputdevice.h" #include "qwaylandscreen.h" -#include "qwaylandshell.h" #include "qwaylandshellsurface.h" #include "qwaylandextendedsurface.h" #include "qwaylandsubsurface.h" @@ -66,9 +65,9 @@ QT_USE_NAMESPACE QWaylandWindow::QWaylandWindow(QWindow *window) - : QPlatformWindow(window) + : QObject() + , QPlatformWindow(window) , mDisplay(QWaylandScreen::waylandScreenFromWindow(window)->display()) - , mSurface(mDisplay->createSurface(this)) , mShellSurface(0) , mExtendedWindow(0) , mSubSurfaceWindow(0) @@ -78,50 +77,51 @@ QWaylandWindow::QWaylandWindow(QWindow *window) , mBuffer(0) , mWaitingForFrameSync(false) , mFrameCallback(0) + , mResizeExposedSent(false) , mSentInitialResize(false) , mMouseDevice(0) , mMouseSerial(0) , mState(Qt::WindowNoState) { + init(mDisplay->createSurface(static_cast<QtWayland::wl_surface *>(this))); + static WId id = 1; mWindowId = id++; - if (mDisplay->shell()) - mShellSurface = mDisplay->shell()->getShellSurface(this); + if (mDisplay->shell() && !(window->flags() & Qt::BypassWindowManagerHint)) + mShellSurface = new QWaylandShellSurface(mDisplay->shell()->get_shell_surface(wl_surface()), this); if (mDisplay->windowExtension()) - mExtendedWindow = mDisplay->windowExtension()->getExtendedWindow(this); + mExtendedWindow = new QWaylandExtendedSurface(this, mDisplay->windowExtension()->get_extended_surface(wl_surface())); if (mDisplay->subSurfaceExtension()) - mSubSurfaceWindow = mDisplay->subSurfaceExtension()->getSubSurfaceAwareWindow(this); + mSubSurfaceWindow = new QWaylandSubSurface(this, mDisplay->subSurfaceExtension()->get_sub_surface_aware_surface(wl_surface())); -#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT - mDisplay->windowManagerIntegration()->mapClientToProcess(qApp->applicationPid()); - mDisplay->windowManagerIntegration()->authenticateWithToken(); -#endif - - // 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()); + 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()); + } - if (parent() && mSubSurfaceWindow) { - mSubSurfaceWindow->setParent(static_cast<const QWaylandWindow *>(parent())); + if (QPlatformWindow::parent() && mSubSurfaceWindow) { + mSubSurfaceWindow->setParent(static_cast<const QWaylandWindow *>(QPlatformWindow::parent())); } else if (window->transientParent()) { - if (window->type() != Qt::Popup) { + if (window->transientParent() && mShellSurface) mShellSurface->updateTransientParent(window->transientParent()); - } - } else { + } else if (mShellSurface) { mShellSurface->setTopLevel(); } setWindowFlags(window->flags()); + setGeometry(window->geometry()); + } QWaylandWindow::~QWaylandWindow() { - if (mSurface) { + if (isInitialized()) { delete mShellSurface; delete mExtendedWindow; - wl_surface_destroy(mSurface); + destroy(); } QList<QWaylandInputDevice *> inputDevices = mDisplay->inputDevices(); @@ -129,6 +129,11 @@ QWaylandWindow::~QWaylandWindow() inputDevices.at(i)->handleWindowDestroyed(this); } +QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface) +{ + return static_cast<QWaylandWindow *>(static_cast<QtWayland::wl_surface *>(wl_surface_get_user_data(surface))); +} + WId QWaylandWindow::winId() const { return mWindowId; @@ -148,9 +153,9 @@ void QWaylandWindow::setWindowTitle(const QString &title) QByteArray titleUtf8 = title.toUtf8(); mShellSurface->setTitle(titleUtf8.constData()); } - if (mWindowDecoration && window()->isVisible()) { - mWindowDecoration->paintDecoration(); - } + + if (mWindowDecoration && window()->isVisible()) + mWindowDecoration->update(); } void QWaylandWindow::setWindowIcon(const QIcon &icon) @@ -158,21 +163,25 @@ void QWaylandWindow::setWindowIcon(const QIcon &icon) mWindowIcon = icon; if (mWindowDecoration && window()->isVisible()) - mWindowDecoration->paintDecoration(); + mWindowDecoration->update(); } void QWaylandWindow::setGeometry(const QRect &rect) { QPlatformWindow::setGeometry(rect); - mDisplay->scheduleRedraw(this); + if (shellSurface() && window()->transientParent()) + shellSurface()->updateTransientParent(window()->transientParent()); + + if (mWindowDecoration && window()->isVisible()) + mWindowDecoration->update(); } void QWaylandWindow::setVisible(bool visible) { if (visible) { if (mBuffer) - wl_surface_attach(mSurface, mBuffer->buffer(), 0, 0); + attach(mBuffer->buffer(), 0, 0); if (window()->type() == Qt::Popup && transientParent()) { QWaylandWindow *parent = transientParent(); @@ -184,7 +193,6 @@ void QWaylandWindow::setVisible(bool visible) if (!mSentInitialResize) { QWindowSystemInterface::handleGeometryChange(window(), geometry()); - QWindowSystemInterface::flushWindowSystemEvents(); mSentInitialResize = true; } @@ -194,7 +202,7 @@ void QWaylandWindow::setVisible(bool visible) // QWaylandShmBackingStore::beginPaint(). } else { QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); - wl_surface_attach(mSurface, 0,0,0); + attach(static_cast<QWaylandBuffer *>(0), 0, 0); } damage(QRect(QPoint(0,0),geometry().size())); } @@ -212,46 +220,57 @@ bool QWaylandWindow::isExposed() const void QWaylandWindow::configure(uint32_t edges, int32_t width, int32_t height) { - Q_UNUSED(edges); + mConfigure.edges |= edges; + mConfigure.width = width; + mConfigure.height = height; - int widthWithoutMargins = qMax(width-(frameMargins().left() +frameMargins().right()),1); - int heightWithoutMargins = qMax(height-(frameMargins().top()+frameMargins().bottom()),1); + if (!mResizeExposedSent) { + mResizeExposedSent = true; + QMetaObject::invokeMethod(this, "doResize", Qt::QueuedConnection); + } +} + +void QWaylandWindow::doResize() +{ + mResizeExposedSent = false; + if (mConfigure.isEmpty()) { + return; + } + + int widthWithoutMargins = qMax(mConfigure.width-(frameMargins().left() +frameMargins().right()),1); + int heightWithoutMargins = qMax(mConfigure.height-(frameMargins().top()+frameMargins().bottom()),1); widthWithoutMargins = qMax(widthWithoutMargins, window()->minimumSize().width()); heightWithoutMargins = qMax(heightWithoutMargins, window()->minimumSize().height()); - QRect geometry = QRect(0,0, - widthWithoutMargins, heightWithoutMargins); + QRect geometry = QRect(0,0, widthWithoutMargins, heightWithoutMargins); int x = 0; int y = 0; QSize size = this->geometry().size(); - if (edges == WL_SHELL_SURFACE_RESIZE_LEFT || edges == WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT || - edges == WL_SHELL_SURFACE_RESIZE_TOP_LEFT) { + if (mConfigure.edges & WL_SHELL_SURFACE_RESIZE_LEFT) { x = size.width() - geometry.width(); } - if (edges == WL_SHELL_SURFACE_RESIZE_TOP || edges == WL_SHELL_SURFACE_RESIZE_TOP_LEFT || - edges == WL_SHELL_SURFACE_RESIZE_TOP_RIGHT) { + if (mConfigure.edges & WL_SHELL_SURFACE_RESIZE_TOP) { y = size.height() - geometry.height(); } mOffset += QPoint(x, y); + mResizeLock.lock(); setGeometry(geometry); + mResizeLock.unlock(); + + mConfigure.clear(); QWindowSystemInterface::handleGeometryChange(window(), geometry); + QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry)); QWindowSystemInterface::flushWindowSystemEvents(); } -void QWaylandWindow::redraw() -{ - -} - void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y) { mBuffer = buffer; - if (window()->isVisible()) { - wl_surface_attach(mSurface, mBuffer->buffer(), x, y); - } + if (window()->isVisible()) + attach(mBuffer->buffer(), x, y); } void QWaylandWindow::attachOffset(QWaylandBuffer *buffer) @@ -270,14 +289,13 @@ void QWaylandWindow::damage(const QRect &rect) //We have to do sync stuff before calling damage, or we might //get a frame callback before we get the timestamp if (!mWaitingForFrameSync) { - mFrameCallback = wl_surface_frame(mSurface); + mFrameCallback = frame(); wl_callback_add_listener(mFrameCallback,&QWaylandWindow::callbackListener,this); mWaitingForFrameSync = true; } - wl_surface_damage(mSurface, - rect.x(), rect.y(), rect.width(), rect.height()); - wl_surface_commit(mSurface); + damage(rect.x(), rect.y(), rect.width(), rect.height()); + commit(); } const wl_callback_listener QWaylandWindow::callbackListener = { @@ -297,8 +315,11 @@ void QWaylandWindow::frameCallback(void *data, struct wl_callback *callback, uin } } +QMutex QWaylandWindow::mFrameSyncMutex; + void QWaylandWindow::waitForFrameSync() { + QMutexLocker locker(&mFrameSyncMutex); if (!mWaitingForFrameSync) return; mDisplay->flushRequests(); @@ -384,14 +405,14 @@ bool QWaylandWindow::createDecoration() default: break; } - if (window()->flags() & Qt::FramelessWindowHint || isFullscreen()) { + if (window()->flags() & Qt::FramelessWindowHint || isFullscreen()) + decoration = false; + if (window()->flags() & Qt::BypassWindowManagerHint) decoration = false; - } if (decoration) { - if (!mWindowDecoration) { - createDecorationInstance(); - } + if (!mWindowDecoration) + mWindowDecoration = new QWaylandDecoration(this); } else { delete mWindowDecoration; mWindowDecoration = 0; @@ -416,8 +437,8 @@ void QWaylandWindow::setDecoration(QWaylandDecoration *decoration) QWaylandWindow *QWaylandWindow::topLevelWindow() { QWaylandWindow *w = this; - while (w->parent()) { - w = static_cast<QWaylandWindow *>(w->parent()); + while (w->QPlatformWindow::parent()) { + w = static_cast<QWaylandWindow *>(w->QPlatformWindow::parent()); } return w; } diff --git a/src/plugins/platforms/wayland_common/qwaylandwindow.h b/src/plugins/platforms/wayland_common/qwaylandwindow.h index 172728c9..3cd891f6 100644 --- a/src/plugins/platforms/wayland_common/qwaylandwindow.h +++ b/src/plugins/platforms/wayland_common/qwaylandwindow.h @@ -43,12 +43,15 @@ #define QWAYLANDWINDOW_H #include <QtCore/QWaitCondition> +#include <QtCore/QMutex> #include <QtGui/QIcon> #include <qpa/qplatformwindow.h> #include "qwaylanddisplay.h" +#include "qwayland-wayland.h" + struct wl_egl_window; QT_BEGIN_NAMESPACE @@ -60,9 +63,30 @@ class QWaylandExtendedSurface; class QWaylandSubSurface; class QWaylandDecoration; -class QWaylandWindow : public QPlatformWindow +class QWaylandWindowConfigure { public: + QWaylandWindowConfigure() + : width(0) + , height(0) + , edges(0) + { } + + void clear() + { width = height = edges = 0; } + + bool isEmpty() const + { return !height || !width; } + + int width; + int height; + uint32_t edges; +}; + +class QWaylandWindow : public QObject, public QPlatformWindow, public QtWayland::wl_surface +{ + Q_OBJECT +public: enum WindowType { Shm, Egl @@ -85,18 +109,24 @@ public: void configure(uint32_t edges, int32_t width, int32_t height); + using QtWayland::wl_surface::attach; void attach(QWaylandBuffer *buffer, int x, int y); void attachOffset(QWaylandBuffer *buffer); QWaylandBuffer *attached() const; QPoint attachOffset() const; + using QtWayland::wl_surface::damage; void damage(const QRect &rect); void waitForFrameSync(); QMargins frameMargins() const; - struct wl_surface *wl_surface() const { return mSurface; } + // 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; QWaylandExtendedSurface *extendedWindow() const; @@ -124,19 +154,21 @@ public: bool createDecoration(); - virtual void redraw(); - inline bool isMaximized() const { return mState == Qt::WindowMaximized; } inline bool isFullscreen() const { return mState == Qt::WindowFullScreen; } QWaylandWindow *topLevelWindow(); QWaylandWindow *transientParent() const; + QMutex *resizeMutex() { return &mResizeLock; } + +public slots: + void doResize(); + protected: virtual void createDecorationInstance() {} QWaylandDisplay *mDisplay; - struct wl_surface *mSurface; QWaylandShellSurface *mShellSurface; QWaylandExtendedSurface *mExtendedWindow; QWaylandSubSurface *mSubSurfaceWindow; @@ -151,6 +183,10 @@ protected: struct wl_callback *mFrameCallback; QWaitCondition mFrameSyncWait; + QMutex mResizeLock; + QWaylandWindowConfigure mConfigure; + bool mResizeExposedSent; + bool mSentInitialResize; QPoint mOffset; @@ -171,6 +207,7 @@ private: static const wl_callback_listener callbackListener; static void frameCallback(void *data, struct wl_callback *wl_callback, uint32_t time); + static QMutex mFrameSyncMutex; }; inline QIcon QWaylandWindow::windowIcon() const diff --git a/src/plugins/platforms/wayland_common/wayland_common.pri b/src/plugins/platforms/wayland_common/wayland_common.pri index e3a380ea..cc956a72 100644 --- a/src/plugins/platforms/wayland_common/wayland_common.pri +++ b/src/plugins/platforms/wayland_common/wayland_common.pri @@ -1,28 +1,10 @@ -QT += core-private gui-private platformsupport-private -CONFIG += link_pkgconfig qpa/genericunixfontdatabase +#This file(wayland_common.pri) is included from .pro files of GL integrations. -!equals(QT_WAYLAND_GL_CONFIG, nogl) { - DEFINES += QT_WAYLAND_GL_SUPPORT -} +include ($$PWD/wayland_common_share.pri) -config_xkbcommon { - !contains(QT_CONFIG, no-pkg-config) { - PKGCONFIG += xkbcommon - } else { - LIBS += -lxkbcommon - } -} else { - DEFINES += QT_NO_WAYLAND_XKB -} - -INCLUDEPATH += $$PWD $$PWD/../../../shared - -!contains(QT_CONFIG, no-pkg-config) { - PKGCONFIG += wayland-client wayland-cursor -} else { - LIBS += -lwayland-client -lwayland-cursor -} +INCLUDEPATH += $$PWD staticlib = $$shadowed($$PWD)/$${QMAKE_PREFIX_STATICLIB}wayland_common.$${QMAKE_EXTENSION_STATICLIB} LIBS += $$staticlib PRE_TARGETDEPS += $$staticlib + diff --git a/src/plugins/platforms/wayland_common/wayland_common.pro b/src/plugins/platforms/wayland_common/wayland_common.pro index 5c992b3c..4a1b0e88 100644 --- a/src/plugins/platforms/wayland_common/wayland_common.pro +++ b/src/plugins/platforms/wayland_common/wayland_common.pro @@ -1,22 +1,9 @@ TEMPLATE = lib CONFIG += staticlib -CONFIG += link_pkgconfig qpa/genericunixfontdatabase - -QT += core-private gui-private platformsupport-private - +include ($$PWD/wayland_common_share.pri) include (windowmanager_integration/windowmanager_integration.pri) -!equals(QT_WAYLAND_GL_CONFIG, nogl) { - DEFINES += QT_WAYLAND_GL_SUPPORT -} - -!config_xkbcommon { - DEFINES += QT_NO_WAYLAND_XKB -} - -INCLUDEPATH += ../../../shared - SOURCES += qwaylandintegration.cpp \ qwaylandnativeinterface.cpp \ qwaylandshmbackingstore.cpp \ @@ -31,7 +18,6 @@ SOURCES += qwaylandintegration.cpp \ qwaylanddataoffer.cpp \ qwaylanddatadevicemanager.cpp \ qwaylanddatasource.cpp \ - qwaylandshell.cpp \ qwaylandshellsurface.cpp \ qwaylandextendedoutput.cpp \ qwaylandextendedsurface.cpp \ @@ -40,7 +26,6 @@ SOURCES += qwaylandintegration.cpp \ qwaylandqtkey.cpp \ ../../../shared/qwaylandmimehelper.cpp \ qwaylanddecoration.cpp \ - qwaylandshmdecoration.cpp \ qwaylandeventthread.cpp HEADERS += qwaylandintegration.h \ @@ -58,7 +43,6 @@ HEADERS += qwaylandintegration.h \ qwaylanddataoffer.h \ qwaylanddatadevicemanager.h \ qwaylanddatasource.h \ - qwaylandshell.h \ qwaylandshellsurface.h \ qwaylandextendedoutput.h \ qwaylandextendedsurface.h \ @@ -67,7 +51,6 @@ HEADERS += qwaylandintegration.h \ qwaylandqtkey.h \ ../../../shared/qwaylandmimehelper.h \ qwaylanddecoration.h \ - qwaylandshmdecoration.h \ qwaylandeventthread.h contains(DEFINES, QT_WAYLAND_GL_SUPPORT) { @@ -75,9 +58,13 @@ contains(DEFINES, QT_WAYLAND_GL_SUPPORT) { HEADERS += qwaylandglintegration.h } -WAYLANDSOURCES += \ +WAYLANDCLIENTSOURCES += \ ../../../extensions/surface-extension.xml \ ../../../extensions/sub-surface-extension.xml \ ../../../extensions/output-extension.xml \ ../../../extensions/touch-extension.xml \ - ../../../extensions/qtkey-extension.xml + ../../../extensions/qtkey-extension.xml \ + +PLUGIN_TYPE = platforms + +load(qt_common) diff --git a/src/plugins/platforms/wayland_common/wayland_common_share.pri b/src/plugins/platforms/wayland_common/wayland_common_share.pri new file mode 100644 index 00000000..a9a990b4 --- /dev/null +++ b/src/plugins/platforms/wayland_common/wayland_common_share.pri @@ -0,0 +1,26 @@ +QT += core-private gui-private platformsupport-private +CONFIG += link_pkgconfig qpa/genericunixfontdatabase + +!equals(QT_WAYLAND_GL_CONFIG, nogl) { + DEFINES += QT_WAYLAND_GL_SUPPORT +} + +config_xkbcommon { + !contains(QT_CONFIG, no-pkg-config) { + PKGCONFIG += xkbcommon + } else { + LIBS += -lxkbcommon + } +} else { + DEFINES += QT_NO_WAYLAND_XKB +} + +!contains(QT_CONFIG, no-pkg-config) { + PKGCONFIG += wayland-client wayland-cursor +} else { + LIBS += -lwayland-client -lwayland-cursor +} + +INCLUDEPATH += $$PWD/../../../shared + +WAYLANDCLIENTSOURCES += ../../../3rdparty/protocol/wayland.xml diff --git a/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.cpp b/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.cpp index 68a7fdfa..673400bd 100644 --- a/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.cpp +++ b/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.cpp @@ -40,7 +40,6 @@ ****************************************************************************/ #include "qwaylandwindowmanagerintegration.h" -#include "wayland-windowmanager-client-protocol.h" #include "qwaylandscreen.h" #include "qwaylandwindow.h" @@ -62,7 +61,6 @@ public: QWaylandWindowManagerIntegrationPrivate(QWaylandDisplay *waylandDisplay); bool m_blockPropertyUpdates; QWaylandDisplay *m_waylandDisplay; - struct wl_windowmanager *m_waylandWindowManager; QHash<QWindow*, QVariantMap> m_queuedProperties; bool m_showIsFullScreen; }; @@ -70,23 +68,14 @@ public: QWaylandWindowManagerIntegrationPrivate::QWaylandWindowManagerIntegrationPrivate(QWaylandDisplay *waylandDisplay) : m_blockPropertyUpdates(false) , m_waylandDisplay(waylandDisplay) - , m_waylandWindowManager(0) , m_showIsFullScreen(false) { } -QWaylandWindowManagerIntegration *QWaylandWindowManagerIntegration::m_instance = 0; - -QWaylandWindowManagerIntegration *QWaylandWindowManagerIntegration::createIntegration(QWaylandDisplay *waylandDisplay) -{ - return new QWaylandWindowManagerIntegration(waylandDisplay); -} - QWaylandWindowManagerIntegration::QWaylandWindowManagerIntegration(QWaylandDisplay *waylandDisplay) : d_ptr(new QWaylandWindowManagerIntegrationPrivate(waylandDisplay)) { - m_instance = this; waylandDisplay->addRegistryListener(&wlHandleListenerGlobal, this); } @@ -95,83 +84,41 @@ QWaylandWindowManagerIntegration::~QWaylandWindowManagerIntegration() } -QWaylandWindowManagerIntegration *QWaylandWindowManagerIntegration::instance() -{ - return m_instance; -} - -struct wl_windowmanager *QWaylandWindowManagerIntegration::windowManager() const -{ - Q_D(const QWaylandWindowManagerIntegration); - return d->m_waylandWindowManager; -} - bool QWaylandWindowManagerIntegration::showIsFullScreen() const { Q_D(const QWaylandWindowManagerIntegration); return d->m_showIsFullScreen; } -void QWaylandWindowManagerIntegration::wlHandleListenerGlobal(void *data, wl_registry *registry, uint32_t id, const char *interface, uint32_t version) +void QWaylandWindowManagerIntegration::wlHandleListenerGlobal(void *data, wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) { Q_UNUSED(version); - if (strcmp(interface, "wl_windowmanager") == 0) { - QWaylandWindowManagerIntegration *integration = static_cast<QWaylandWindowManagerIntegration *>(data); - integration->d_ptr->m_waylandWindowManager = - static_cast<struct wl_windowmanager *>(wl_registry_bind(registry, id, &wl_windowmanager_interface, 1)); - wl_windowmanager_add_listener(integration->d_ptr->m_waylandWindowManager, &windowmanager_listener, integration); - } + if (interface == "wl_windowmanager") + static_cast<QWaylandWindowManagerIntegration *>(data)->init(registry, id); } -const struct wl_windowmanager_listener QWaylandWindowManagerIntegration::windowmanager_listener = { - QWaylandWindowManagerIntegration::handle_hints, - QWaylandWindowManagerIntegration::handle_quit -}; - -void QWaylandWindowManagerIntegration::handle_hints(void *data, wl_windowmanager *ext, int32_t showIsFullScreen) +void QWaylandWindowManagerIntegration::windowmanager_hints(int32_t showIsFullScreen) { - Q_UNUSED(ext); - QWaylandWindowManagerIntegration *self = static_cast<QWaylandWindowManagerIntegration *>(data); - self->d_func()->m_showIsFullScreen = showIsFullScreen; + Q_D(QWaylandWindowManagerIntegration); + d->m_showIsFullScreen = showIsFullScreen; } -void QWaylandWindowManagerIntegration::handle_quit(void *data, wl_windowmanager *ext) +void QWaylandWindowManagerIntegration::windowmanager_quit() { - Q_UNUSED(data); - Q_UNUSED(ext); QGuiApplication::quit(); } -void QWaylandWindowManagerIntegration::mapClientToProcess(long long processId) -{ - Q_D(QWaylandWindowManagerIntegration); - if (d->m_waylandWindowManager) - wl_windowmanager_map_client_to_process(d->m_waylandWindowManager, (uint32_t) processId); -} - -void QWaylandWindowManagerIntegration::authenticateWithToken(const QByteArray &token) -{ - Q_D(QWaylandWindowManagerIntegration); - QByteArray authToken = token; - if (authToken.isEmpty()) - authToken = qgetenv("WL_AUTHENTICATION_TOKEN"); - - if (d->m_waylandWindowManager && !authToken.isEmpty()) { - wl_windowmanager_authenticate_with_token(d->m_waylandWindowManager, authToken.constData()); - } -} void QWaylandWindowManagerIntegration::openUrl_helper(const QUrl &url) { - Q_D(QWaylandWindowManagerIntegration); - if (d->m_waylandWindowManager) { + if (isInitialized()) { QByteArray data = url.toString().toUtf8(); static const int chunkSize = 128; while (!data.isEmpty()) { QByteArray chunk = data.left(chunkSize); data = data.mid(chunkSize); - wl_windowmanager_open_url(d->m_waylandWindowManager, !data.isEmpty(), chunk.constData()); + open_url(!data.isEmpty(), QString::fromUtf8(chunk)); } } } diff --git a/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.h b/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.h index 9145401d..0982632d 100644 --- a/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.h +++ b/src/plugins/platforms/wayland_common/windowmanager_integration/qwaylandwindowmanagerintegration.h @@ -49,27 +49,22 @@ #include "qwaylanddisplay.h" #include <qpa/qplatformservices.h> +#include "qwayland-windowmanager.h" + QT_BEGIN_NAMESPACE class QWaylandWindow; class QWaylandWindowManagerIntegrationPrivate; -class QWaylandWindowManagerIntegration : public QObject, public QPlatformServices +class QWaylandWindowManagerIntegration : public QObject, public QPlatformServices, public QtWayland::qt_windowmanager { Q_OBJECT Q_DECLARE_PRIVATE(QWaylandWindowManagerIntegration) public: explicit QWaylandWindowManagerIntegration(QWaylandDisplay *waylandDisplay); virtual ~QWaylandWindowManagerIntegration(); - static QWaylandWindowManagerIntegration *createIntegration(QWaylandDisplay *waylandDisplay); - struct wl_windowmanager *windowManager() const; - - static QWaylandWindowManagerIntegration *instance(); - void mapSurfaceToProcess(struct wl_surface *surface, long long processId); - void mapClientToProcess(long long processId); - void authenticateWithToken(const QByteArray &token = QByteArray()); bool openUrl(const QUrl &url); bool openDocument(const QUrl &url); @@ -77,17 +72,12 @@ public: private: static void wlHandleListenerGlobal(void *data, wl_registry *registry, uint32_t id, - const char *interface, uint32_t version); + const QString &interface, uint32_t version); QScopedPointer<QWaylandWindowManagerIntegrationPrivate> d_ptr; - static QWaylandWindowManagerIntegration *m_instance; - - static const struct wl_windowmanager_listener windowmanager_listener; - static void handle_hints(void *data, - struct wl_windowmanager *ext, - int32_t showIsFullScreen); - static void handle_quit(void *data, struct wl_windowmanager *ext); + void windowmanager_hints(int32_t showIsFullScreen) Q_DECL_OVERRIDE; + void windowmanager_quit() Q_DECL_OVERRIDE; void openUrl_helper(const QUrl &url); }; diff --git a/src/plugins/platforms/wayland_common/windowmanager_integration/windowmanager_integration.pri b/src/plugins/platforms/wayland_common/windowmanager_integration/windowmanager_integration.pri index 57905ad9..9228358e 100644 --- a/src/plugins/platforms/wayland_common/windowmanager_integration/windowmanager_integration.pri +++ b/src/plugins/platforms/wayland_common/windowmanager_integration/windowmanager_integration.pri @@ -2,7 +2,7 @@ DEFINES += QT_WAYLAND_WINDOWMANAGER_SUPPORT contains(DEFINES, QT_WAYLAND_WINDOWMANAGER_SUPPORT) { - WAYLANDSOURCES += $$PWD/../../../../extensions/windowmanager.xml + WAYLANDCLIENTSOURCES += $$PWD/../../../../extensions/windowmanager.xml HEADERS += \ $$PWD/qwaylandwindowmanagerintegration.h |