diff options
author | Giulio Camuffo <giulio.camuffo@jollamobile.com> | 2014-07-01 15:56:11 +0300 |
---|---|---|
committer | Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> | 2014-08-07 07:59:00 +0200 |
commit | d107e2ba88e44590f77c608073eee6429f3d3a8c (patch) | |
tree | 5b96804a31b04c8f17fff03907815f9a90fc24ab /src | |
parent | 3419c5a868b6f528cfb17ee19261c937163ea7e0 (diff) |
Add a way to have out of source shell integrations
Some platforms (especially non-desktop ones) may use a custom
Wayland shell extension, more tailored to the form factor than
the generic and desktoppy wl_shell or xdg_shell. Instead of stuffing
N protocol implementations in the QPA plugin use a plugin architecture
to allow them to live out of tree.
When creating a shell surface the QT_WAYLAND_SHELL_INTEGRATION env
variable will be checked, and if it points to a valid plugin that
will be used to create the shell surface, falling back to wl_shell
or xdg_shell if no plugin is specified.
Change-Id: I05019174bb915199dd726f5fdcc0385ef846e8de
Reviewed-by: Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
Reviewed-by: Philippe Coval <rzr@gna.org>
Reviewed-by: Jan Arne Petersen <jan.petersen@kdab.com>
Reviewed-by: Gunnar Sletta <gunnar.sletta@jollamobile.com>
Diffstat (limited to 'src')
22 files changed, 618 insertions, 79 deletions
diff --git a/src/client/client.pro b/src/client/client.pro index 1d89619c0..6aaa25419 100644 --- a/src/client/client.pro +++ b/src/client/client.pro @@ -107,3 +107,4 @@ HEADERS += qwaylandintegration_p.h \ qwaylanddatadevice_p.h \ include(hardwareintegration/hardwareintegration.pri) +include(shellintegration/shellintegration.pri) diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp index 459c7f461..5764d3110 100644 --- a/src/client/qwaylanddisplay.cpp +++ b/src/client/qwaylanddisplay.cpp @@ -51,8 +51,11 @@ #include "qwaylanddatadevicemanager_p.h" #include "qwaylandhardwareintegration_p.h" #include "qwaylandxdgshell_p.h" +#include "qwaylandxdgsurface_p.h" +#include "qwaylandwlshellsurface_p.h" #include "qwaylandwindowmanagerintegration_p.h" +#include "qwaylandshellintegration_p.h" #include "qwaylandextendedoutput_p.h" #include "qwaylandextendedsurface_p.h" @@ -79,6 +82,20 @@ struct wl_surface *QWaylandDisplay::createSurface(void *handle) return surface; } +QWaylandShellSurface *QWaylandDisplay::createShellSurface(QWaylandWindow *window) +{ + if (mWaylandIntegration->shellIntegration()) + return mWaylandIntegration->shellIntegration()->createShellSurface(window); + + if (shellXdg()) { + return new QWaylandXdgSurface(shellXdg()->get_xdg_surface(window->object()), window); + } else if (shell()) { + return new QWaylandWlShellSurface(shell()->get_shell_surface(window->object()), window); + } + + return Q_NULLPTR; +} + QWaylandClientBufferIntegration * QWaylandDisplay::clientBufferIntegration() const { return mWaylandIntegration->clientBufferIntegration(); diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h index f1b35a712..6ed30d195 100644 --- a/src/client/qwaylanddisplay_p.h +++ b/src/client/qwaylanddisplay_p.h @@ -73,6 +73,7 @@ class QWaylandEventThread; class QWaylandIntegration; class QWaylandHardwareIntegration; class QWaylandXdgShell; +class QWaylandShellSurface; namespace QtWayland { class qt_output_extension; @@ -101,6 +102,7 @@ public: QWaylandScreen *screenForOutput(struct wl_output *output) const; struct wl_surface *createSurface(void *handle); + QWaylandShellSurface *createShellSurface(QWaylandWindow *window); QWaylandClientBufferIntegration *clientBufferIntegration() const; @@ -142,6 +144,7 @@ public: RegistryGlobal(uint32_t id_, const QString &interface_, uint32_t version_, struct ::wl_registry *registry_) : id(id_), interface(interface_), version(version_), registry(registry_) { } }; + QList<RegistryGlobal> globals() const { return mGlobals; } /* wl_registry_add_listener does not add but rather sets a listener, so this function is used * to enable many listeners at once. */ diff --git a/src/client/qwaylandextendedsurface.cpp b/src/client/qwaylandextendedsurface.cpp index b2b22688c..e589698ef 100644 --- a/src/client/qwaylandextendedsurface.cpp +++ b/src/client/qwaylandextendedsurface.cpp @@ -53,8 +53,8 @@ QT_BEGIN_NAMESPACE -QWaylandExtendedSurface::QWaylandExtendedSurface(QWaylandWindow *window, struct ::qt_extended_surface *extended_surface) - : QtWayland::qt_extended_surface(extended_surface) +QWaylandExtendedSurface::QWaylandExtendedSurface(QWaylandWindow *window) + : QtWayland::qt_extended_surface(window->display()->windowExtension()->get_extended_surface(window->object())) , m_window(window) { } @@ -71,11 +71,6 @@ void QWaylandExtendedSurface::updateGenericProperty(const QString &name, const Q ds << value; update_generic_property(name, byteValue); - - m_properties.insert(name, value); - QWaylandNativeInterface *nativeInterface = static_cast<QWaylandNativeInterface *>( - QGuiApplication::platformNativeInterface()); - nativeInterface->emitWindowPropertyChanged(m_window, name); } void QWaylandExtendedSurface::setContentOrientationMask(Qt::ScreenOrientations mask) @@ -94,21 +89,6 @@ void QWaylandExtendedSurface::setContentOrientationMask(Qt::ScreenOrientations m set_content_orientation_mask(wlmask); } -QVariantMap QWaylandExtendedSurface::properties() const -{ - return m_properties; -} - -QVariant QWaylandExtendedSurface::property(const QString &name) -{ - return m_properties.value(name); -} - -QVariant QWaylandExtendedSurface::property(const QString &name, const QVariant &defaultValue) -{ - return m_properties.value(name,defaultValue); -} - void QWaylandExtendedSurface::extended_surface_onscreen_visibility(int32_t visibility) { m_window->window()->setVisibility(static_cast<QWindow::Visibility>(visibility)); @@ -122,11 +102,7 @@ void QWaylandExtendedSurface::extended_surface_set_generic_property(const QStrin QDataStream ds(data); ds >> variantValue; - m_properties.insert(name, variantValue); - - QWaylandNativeInterface *nativeInterface = static_cast<QWaylandNativeInterface *>( - QGuiApplication::platformNativeInterface()); - nativeInterface->emitWindowPropertyChanged(m_window, name); + m_window->setProperty(name, variantValue); } void QWaylandExtendedSurface::extended_surface_close() diff --git a/src/client/qwaylandextendedsurface_p.h b/src/client/qwaylandextendedsurface_p.h index 2b559a93b..1d966292c 100644 --- a/src/client/qwaylandextendedsurface_p.h +++ b/src/client/qwaylandextendedsurface_p.h @@ -58,17 +58,13 @@ class QWaylandWindow; class Q_WAYLAND_CLIENT_EXPORT QWaylandExtendedSurface : public QtWayland::qt_extended_surface { public: - QWaylandExtendedSurface(QWaylandWindow *window, struct ::qt_extended_surface *extended_surface); + QWaylandExtendedSurface(QWaylandWindow *window); ~QWaylandExtendedSurface(); void setContentOrientationMask(Qt::ScreenOrientations mask); void updateGenericProperty(const QString &name, const QVariant &value); - QVariantMap properties() const; - QVariant property(const QString &name); - QVariant property(const QString &name, const QVariant &defaultValue); - Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags); private: diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp index 02b7e56c6..85300a130 100644 --- a/src/client/qwaylandintegration.cpp +++ b/src/client/qwaylandintegration.cpp @@ -72,6 +72,9 @@ #include "qwaylandserverbufferintegration_p.h" #include "qwaylandserverbufferintegrationfactory_p.h" +#include "qwaylandshellintegration_p.h" +#include "qwaylandshellintegrationfactory_p.h" + QT_BEGIN_NAMESPACE class GenericWaylandTheme: public QGenericUnixTheme @@ -108,6 +111,7 @@ public: QWaylandIntegration::QWaylandIntegration() : mClientBufferIntegration(0) + , mShellIntegration(Q_NULLPTR) , mFontDb(new QGenericUnixFontDatabase()) , mNativeInterface(new QWaylandNativeInterface(this)) #ifndef QT_NO_ACCESSIBILITY @@ -117,6 +121,7 @@ QWaylandIntegration::QWaylandIntegration() #endif , mClientBufferIntegrationInitialized(false) , mServerBufferIntegrationInitialized(false) + , mShellIntegrationInitialized(false) { mDisplay = new QWaylandDisplay(this); mClipboard = new QWaylandClipboard(mDisplay); @@ -260,6 +265,14 @@ QWaylandServerBufferIntegration *QWaylandIntegration::serverBufferIntegration() return mServerBufferIntegration; } +QWaylandShellIntegration *QWaylandIntegration::shellIntegration() const +{ + if (!mShellIntegrationInitialized) + const_cast<QWaylandIntegration *>(this)->initializeShellIntegration(); + + return mShellIntegration; +} + void QWaylandIntegration::initializeClientBufferIntegration() { mClientBufferIntegrationInitialized = true; @@ -321,4 +334,28 @@ void QWaylandIntegration::initializeServerBufferIntegration() qWarning("Failed to load server buffer integration %s\n", qPrintable(targetKey)); } +void QWaylandIntegration::initializeShellIntegration() +{ + mShellIntegrationInitialized = true; + + QByteArray integrationName = qgetenv("QT_WAYLAND_SHELL_INTEGRATION"); + QString targetKey = QString::fromLocal8Bit(integrationName); + + if (targetKey.isEmpty()) { + return; + } + + QStringList keys = QWaylandShellIntegrationFactory::keys(); + if (keys.contains(targetKey)) { + mShellIntegration = QWaylandShellIntegrationFactory::create(targetKey, QStringList()); + } + if (mShellIntegration && mShellIntegration->initialize(mDisplay)) { + qDebug("Using the '%s' shell integration", qPrintable(targetKey)); + } else { + delete mShellIntegration; + mShellIntegration = Q_NULLPTR; + qWarning("Failed to load shell integration %s", qPrintable(targetKey)); + } +} + QT_END_NAMESPACE diff --git a/src/client/qwaylandintegration_p.h b/src/client/qwaylandintegration_p.h index 7c062c0ee..025e0b4df 100644 --- a/src/client/qwaylandintegration_p.h +++ b/src/client/qwaylandintegration_p.h @@ -51,6 +51,7 @@ class QWaylandBuffer; class QWaylandDisplay; class QWaylandClientBufferIntegration; class QWaylandServerBufferIntegration; +class QWaylandShellIntegration; class Q_WAYLAND_CLIENT_EXPORT QWaylandIntegration : public QPlatformIntegration { @@ -90,12 +91,15 @@ public: virtual QWaylandClientBufferIntegration *clientBufferIntegration() const; virtual QWaylandServerBufferIntegration *serverBufferIntegration() const; + virtual QWaylandShellIntegration *shellIntegration() const; protected: QWaylandClientBufferIntegration *mClientBufferIntegration; QWaylandServerBufferIntegration *mServerBufferIntegration; + QWaylandShellIntegration *mShellIntegration; private: void initializeClientBufferIntegration(); void initializeServerBufferIntegration(); + void initializeShellIntegration(); QPlatformFontDatabase *mFontDb; QPlatformClipboard *mClipboard; QPlatformDrag *mDrag; @@ -105,6 +109,7 @@ private: QPlatformAccessibility *mAccessibility; bool mClientBufferIntegrationInitialized; bool mServerBufferIntegrationInitialized; + bool mShellIntegrationInitialized; }; QT_END_NAMESPACE diff --git a/src/client/qwaylandnativeinterface.cpp b/src/client/qwaylandnativeinterface.cpp index e3d6fef4a..3d714c2fb 100644 --- a/src/client/qwaylandnativeinterface.cpp +++ b/src/client/qwaylandnativeinterface.cpp @@ -99,34 +99,25 @@ void *QWaylandNativeInterface::nativeResourceForScreen(const QByteArray &resourc QVariantMap QWaylandNativeInterface::windowProperties(QPlatformWindow *window) const { QWaylandWindow *waylandWindow = static_cast<QWaylandWindow *>(window); - if (QWaylandExtendedSurface *extendedWindow = waylandWindow->extendedWindow()) - return extendedWindow->properties(); - return QVariantMap(); + return waylandWindow->properties(); } - QVariant QWaylandNativeInterface::windowProperty(QPlatformWindow *window, const QString &name) const { QWaylandWindow *waylandWindow = static_cast<QWaylandWindow *>(window); - if (QWaylandExtendedSurface *extendedWindow = waylandWindow->extendedWindow()) - return extendedWindow->property(name); - return QVariant(); + return waylandWindow->property(name); } QVariant QWaylandNativeInterface::windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const { QWaylandWindow *waylandWindow = static_cast<QWaylandWindow *>(window); - if (QWaylandExtendedSurface *extendedWindow = waylandWindow->extendedWindow()) { - return extendedWindow->property(name,defaultValue); - } - return defaultValue; + return waylandWindow->property(name, defaultValue); } void QWaylandNativeInterface::setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value) { QWaylandWindow *wlWindow = static_cast<QWaylandWindow*>(window); - if (QWaylandExtendedSurface *extendedWindow = wlWindow->extendedWindow()) - extendedWindow->updateGenericProperty(name,value); + wlWindow->sendProperty(name, value); } void QWaylandNativeInterface::emitWindowPropertyChanged(QPlatformWindow *window, const QString &name) diff --git a/src/client/qwaylandshellsurface.cpp b/src/client/qwaylandshellsurface.cpp index 80e509b15..d68ae1b5d 100644 --- a/src/client/qwaylandshellsurface.cpp +++ b/src/client/qwaylandshellsurface.cpp @@ -40,3 +40,20 @@ ****************************************************************************/ #include "qwaylandshellsurface_p.h" +#include "qwaylandwindow_p.h" +#include "qwaylandextendedsurface_p.h" + +QWaylandShellSurface::QWaylandShellSurface(QWaylandWindow *window) + : m_window(window) +{ +} + +void QWaylandShellSurface::setWindowFlags(Qt::WindowFlags flags) +{ +} + +void QWaylandShellSurface::sendProperty(const QString &name, const QVariant &value) +{ + Q_UNUSED(name) + Q_UNUSED(value) +} diff --git a/src/client/qwaylandshellsurface_p.h b/src/client/qwaylandshellsurface_p.h index 2f59f60c1..6f2336162 100644 --- a/src/client/qwaylandshellsurface_p.h +++ b/src/client/qwaylandshellsurface_p.h @@ -51,6 +51,7 @@ QT_BEGIN_NAMESPACE +class QVariant; class QWaylandWindow; class QWaylandInputDevice; class QWindow; @@ -58,6 +59,7 @@ class QWindow; class Q_WAYLAND_CLIENT_EXPORT QWaylandShellSurface { public: + explicit QWaylandShellSurface(QWaylandWindow *window); virtual ~QWaylandShellSurface() {} virtual void resize(QWaylandInputDevice * /*inputDevice*/, enum wl_shell_surface_resize /*edges*/) {} @@ -66,7 +68,19 @@ public: virtual void setTitle(const QString & /*title*/) {} virtual void setAppId(const QString & /*appId*/) {} -private: + virtual void setWindowFlags(Qt::WindowFlags flags); + + virtual bool isExposed() const { return true; } + + virtual void raise() {} + virtual void lower() {} + virtual void setContentOrientationMask(Qt::ScreenOrientations orientation) { Q_UNUSED(orientation) } + + virtual void sendProperty(const QString &name, const QVariant &value); + + inline QWaylandWindow *window() { return m_window; } + +protected: virtual void setMaximized() {} virtual void setFullscreen() {} virtual void setNormal() {} @@ -74,6 +88,9 @@ private: virtual void setTopLevel() {} virtual void updateTransientParent(QWindow * /*parent*/) {} + +private: + QWaylandWindow *m_window; friend class QWaylandWindow; }; diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index c61574529..a6190c0d1 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -48,10 +48,10 @@ #include "qwaylandshellsurface_p.h" #include "qwaylandwlshellsurface_p.h" #include "qwaylandxdgsurface_p.h" -#include "qwaylandextendedsurface_p.h" #include "qwaylandsubsurface_p.h" #include "qwaylanddecoration_p.h" #include "qwaylandwindowmanagerintegration_p.h" +#include "qwaylandnativeinterface_p.h" #include <QtCore/QFileInfo> #include <QtCore/QPointer> @@ -72,7 +72,6 @@ QWaylandWindow::QWaylandWindow(QWindow *window) , mScreen(QWaylandScreen::waylandScreenFromWindow(window)) , mDisplay(mScreen->display()) , mShellSurface(0) - , mExtendedWindow(0) , mSubSurfaceWindow(0) , mWindowDecoration(0) , mMouseEventsInContentArea(false) @@ -95,21 +94,13 @@ QWaylandWindow::QWaylandWindow(QWindow *window) static WId id = 1; mWindowId = id++; - if (!(window->flags() & Qt::BypassWindowManagerHint)) { - if (mDisplay->shellXdg()) { - if (window->type() & Qt::Window) { - mShellSurface = new QWaylandXdgSurface(mDisplay->shellXdg()->get_xdg_surface(object()), this); - } - } else if (mDisplay->shell() && window->type() & Qt::Window) { - mShellSurface = new QWaylandWlShellSurface(mDisplay->shell()->get_shell_surface(object()), this); - } - } - - if (mDisplay->windowExtension()) - mExtendedWindow = new QWaylandExtendedSurface(this, mDisplay->windowExtension()->get_extended_surface(object())); if (mDisplay->subSurfaceExtension()) mSubSurfaceWindow = new QWaylandSubSurface(this, mDisplay->subSurfaceExtension()->get_sub_surface_aware_surface(object())); + if (!(window->flags() & Qt::BypassWindowManagerHint)) { + mShellSurface = mDisplay->createShellSurface(this); + } + if (mShellSurface) { // Set initial surface title mShellSurface->setTitle(window->title()); @@ -141,7 +132,6 @@ QWaylandWindow::~QWaylandWindow() { if (isInitialized()) { delete mShellSurface; - delete mExtendedWindow; destroy(); } if (mFrameCallback) @@ -221,10 +211,10 @@ void QWaylandWindow::setGeometry(const QRect &rect) else QWindowSystemInterface::handleGeometryChange(window(), geometry()); - QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); - mSentInitialResize = true; } + + QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); } void QWaylandWindow::setVisible(bool visible) @@ -261,15 +251,15 @@ void QWaylandWindow::setVisible(bool visible) void QWaylandWindow::raise() { - if (mExtendedWindow) - mExtendedWindow->raise(); + if (mShellSurface) + mShellSurface->raise(); } void QWaylandWindow::lower() { - if (mExtendedWindow) - mExtendedWindow->lower(); + if (mShellSurface) + mShellSurface->lower(); } void QWaylandWindow::configure(uint32_t edges, int32_t width, int32_t height) @@ -423,11 +413,6 @@ QWaylandShellSurface *QWaylandWindow::shellSurface() const return mShellSurface; } -QWaylandExtendedSurface *QWaylandWindow::extendedWindow() const -{ - return mExtendedWindow; -} - QWaylandSubSurface *QWaylandWindow::subSurfaceWindow() const { return mSubSurfaceWindow; @@ -461,8 +446,8 @@ void QWaylandWindow::handleContentOrientationChange(Qt::ScreenOrientation orient void QWaylandWindow::setOrientationMask(Qt::ScreenOrientations mask) { - if (mExtendedWindow) - mExtendedWindow->setContentOrientationMask(mask); + if (mShellSurface) + mShellSurface->setContentOrientationMask(mask); } void QWaylandWindow::setWindowState(Qt::WindowState state) @@ -473,8 +458,8 @@ void QWaylandWindow::setWindowState(Qt::WindowState state) void QWaylandWindow::setWindowFlags(Qt::WindowFlags flags) { - if (mExtendedWindow) - mExtendedWindow->setWindowFlags(flags); + if (mShellSurface) + mShellSurface->setWindowFlags(flags); } bool QWaylandWindow::createDecoration() @@ -643,6 +628,13 @@ void QWaylandWindow::requestActivateWindow() // we rely on compositor setting keyboard focus based on window stacking. } +bool QWaylandWindow::isExposed() const +{ + if (mShellSurface) + return window()->isVisible() && mShellSurface->isExposed(); + return QPlatformWindow::isExposed(); +} + bool QWaylandWindow::setMouseGrabEnabled(bool grab) { if (window()->type() != Qt::Popup) { @@ -683,4 +675,37 @@ bool QWaylandWindow::setWindowStateInternal(Qt::WindowState state) return true; } +void QWaylandWindow::sendProperty(const QString &name, const QVariant &value) +{ + m_properties.insert(name, value); + QWaylandNativeInterface *nativeInterface = static_cast<QWaylandNativeInterface *>( + QGuiApplication::platformNativeInterface()); + nativeInterface->emitWindowPropertyChanged(this, name); + if (mShellSurface) + mShellSurface->sendProperty(name, value); +} + +void QWaylandWindow::setProperty(const QString &name, const QVariant &value) +{ + m_properties.insert(name, value); + QWaylandNativeInterface *nativeInterface = static_cast<QWaylandNativeInterface *>( + QGuiApplication::platformNativeInterface()); + nativeInterface->emitWindowPropertyChanged(this, name); +} + +QVariantMap QWaylandWindow::properties() const +{ + return m_properties; +} + +QVariant QWaylandWindow::property(const QString &name) +{ + return m_properties.value(name); +} + +QVariant QWaylandWindow::property(const QString &name, const QVariant &defaultValue) +{ + return m_properties.value(name, defaultValue); +} + QT_END_NAMESPACE diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h index 2ca47d590..9c0be84c6 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -45,6 +45,7 @@ #include <QtCore/QWaitCondition> #include <QtCore/QMutex> #include <QtGui/QIcon> +#include <QtCore/QVariant> #include <qpa/qplatformwindow.h> @@ -58,7 +59,6 @@ QT_BEGIN_NAMESPACE class QWaylandDisplay; class QWaylandBuffer; class QWaylandShellSurface; -class QWaylandExtendedSurface; class QWaylandSubSurface; class QWaylandDecoration; class QWaylandInputDevice; @@ -125,8 +125,8 @@ public: static QWaylandWindow *fromWlSurface(::wl_surface *surface); + QWaylandDisplay *display() const { return mDisplay; } QWaylandShellSurface *shellSurface() const; - QWaylandExtendedSurface *extendedWindow() const; QWaylandSubSurface *subSurfaceWindow() const; QWaylandScreen *screen() const { return mScreen; } @@ -140,6 +140,7 @@ public: void lower() Q_DECL_OVERRIDE; void requestActivateWindow() Q_DECL_OVERRIDE; + bool isExposed() const Q_DECL_OVERRIDE; QWaylandDecoration *decoration() const; void setDecoration(QWaylandDecoration *decoration); @@ -171,6 +172,13 @@ public: bool setMouseGrabEnabled(bool grab); static QWaylandWindow *mouseGrab() { return mMouseGrab; } + void sendProperty(const QString &name, const QVariant &value); + void setProperty(const QString &name, const QVariant &value); + + QVariantMap properties() const; + QVariant property(const QString &name); + QVariant property(const QString &name, const QVariant &defaultValue); + public slots: void requestResize(); @@ -178,7 +186,6 @@ protected: QWaylandScreen *mScreen; QWaylandDisplay *mDisplay; QWaylandShellSurface *mShellSurface; - QWaylandExtendedSurface *mExtendedWindow; QWaylandSubSurface *mSubSurfaceWindow; QWaylandDecoration *mWindowDecoration; @@ -198,6 +205,7 @@ protected: bool mCanResize; bool mResizeDirty; bool mResizeAfterSwap; + QVariantMap m_properties; bool mSentInitialResize; QPoint mOffset; diff --git a/src/client/qwaylandwlshellsurface.cpp b/src/client/qwaylandwlshellsurface.cpp index 4b73ec232..a8e89ec98 100644 --- a/src/client/qwaylandwlshellsurface.cpp +++ b/src/client/qwaylandwlshellsurface.cpp @@ -46,6 +46,7 @@ #include "qwaylandinputdevice_p.h" #include "qwaylanddecoration_p.h" #include "qwaylandscreen_p.h" +#include "qwaylandextendedsurface_p.h" #include <QtCore/QDebug> @@ -53,15 +54,20 @@ QT_BEGIN_NAMESPACE QWaylandWlShellSurface::QWaylandWlShellSurface(struct ::wl_shell_surface *shell_surface, QWaylandWindow *window) : QtWayland::wl_shell_surface(shell_surface) + , QWaylandShellSurface(window) , m_window(window) , m_maximized(false) , m_fullscreen(false) + , m_extendedWindow(Q_NULLPTR) { + if (window->display()->windowExtension()) + m_extendedWindow = new QWaylandExtendedSurface(window); } QWaylandWlShellSurface::~QWaylandWlShellSurface() { wl_shell_surface_destroy(object()); + delete m_extendedWindow; } void QWaylandWlShellSurface::resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges) @@ -87,6 +93,36 @@ void QWaylandWlShellSurface::setAppId(const QString & appId) return QtWayland::wl_shell_surface::set_class(appId); } +void QWaylandWlShellSurface::raise() +{ + if (m_extendedWindow) + m_extendedWindow->raise(); +} + +void QWaylandWlShellSurface::lower() +{ + if (m_extendedWindow) + m_extendedWindow->lower(); +} + +void QWaylandWlShellSurface::setContentOrientationMask(Qt::ScreenOrientations orientation) +{ + if (m_extendedWindow) + m_extendedWindow->setContentOrientationMask(orientation); +} + +void QWaylandWlShellSurface::setWindowFlags(Qt::WindowFlags flags) +{ + if (m_extendedWindow) + m_extendedWindow->setWindowFlags(flags); +} + +void QWaylandWlShellSurface::sendProperty(const QString &name, const QVariant &value) +{ + if (m_extendedWindow) + m_extendedWindow->updateGenericProperty(name, value); +} + void QWaylandWlShellSurface::setMaximized() { m_maximized = true; diff --git a/src/client/qwaylandwlshellsurface_p.h b/src/client/qwaylandwlshellsurface_p.h index d02bb7bfe..8d6e298b9 100644 --- a/src/client/qwaylandwlshellsurface_p.h +++ b/src/client/qwaylandwlshellsurface_p.h @@ -55,6 +55,7 @@ QT_BEGIN_NAMESPACE class QWaylandWindow; class QWaylandInputDevice; class QWindow; +class QWaylandExtendedSurface; class Q_WAYLAND_CLIENT_EXPORT QWaylandWlShellSurface : public QtWayland::wl_shell_surface , public QWaylandShellSurface @@ -72,6 +73,12 @@ public: void setTitle(const QString & title) Q_DECL_OVERRIDE; void setAppId(const QString &appId) Q_DECL_OVERRIDE; + void raise() Q_DECL_OVERRIDE; + void lower() Q_DECL_OVERRIDE; + void setContentOrientationMask(Qt::ScreenOrientations orientation) Q_DECL_OVERRIDE; + void setWindowFlags(Qt::WindowFlags flags) Q_DECL_OVERRIDE; + void sendProperty(const QString &name, const QVariant &value) Q_DECL_OVERRIDE; + private: void setMaximized() Q_DECL_OVERRIDE; void setFullscreen() Q_DECL_OVERRIDE; @@ -86,6 +93,7 @@ private: bool m_maximized; bool m_fullscreen; QSize m_size; + QWaylandExtendedSurface *m_extendedWindow; void shell_surface_ping(uint32_t serial) Q_DECL_OVERRIDE; void shell_surface_configure(uint32_t edges, diff --git a/src/client/qwaylandxdgsurface.cpp b/src/client/qwaylandxdgsurface.cpp index 5fb74d25b..126c9db72 100644 --- a/src/client/qwaylandxdgsurface.cpp +++ b/src/client/qwaylandxdgsurface.cpp @@ -46,6 +46,7 @@ #include "qwaylandinputdevice_p.h" #include "qwaylanddecoration_p.h" #include "qwaylandscreen_p.h" +#include "qwaylandextendedsurface_p.h" #include <QtCore/QDebug> @@ -53,16 +54,21 @@ QT_BEGIN_NAMESPACE QWaylandXdgSurface::QWaylandXdgSurface(struct ::xdg_surface *xdg_surface, QWaylandWindow *window) : QtWayland::xdg_surface(xdg_surface) + , QWaylandShellSurface(window) , m_window(window) , m_maximized(false) , m_minimized(false) , m_fullscreen(false) + , m_extendedWindow(Q_NULLPTR) { + if (window->display()->windowExtension()) + m_extendedWindow = new QWaylandExtendedSurface(window); } QWaylandXdgSurface::~QWaylandXdgSurface() { xdg_surface_destroy(object()); + delete m_extendedWindow; } void QWaylandXdgSurface::resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges) @@ -160,6 +166,36 @@ void QWaylandXdgSurface::setAppId(const QString & appId) return QtWayland::xdg_surface::set_app_id(appId); } +void QWaylandXdgSurface::raise() +{ + if (m_extendedWindow) + m_extendedWindow->raise(); +} + +void QWaylandXdgSurface::lower() +{ + if (m_extendedWindow) + m_extendedWindow->lower(); +} + +void QWaylandXdgSurface::setContentOrientationMask(Qt::ScreenOrientations orientation) +{ + if (m_extendedWindow) + m_extendedWindow->setContentOrientationMask(orientation); +} + +void QWaylandXdgSurface::setWindowFlags(Qt::WindowFlags flags) +{ + if (m_extendedWindow) + m_extendedWindow->setWindowFlags(flags); +} + +void QWaylandXdgSurface::sendProperty(const QString &name, const QVariant &value) +{ + if (m_extendedWindow) + m_extendedWindow->updateGenericProperty(name, value); +} + void QWaylandXdgSurface::xdg_surface_configure(int32_t width, int32_t height) { m_window->configure(0 , width, height); diff --git a/src/client/qwaylandxdgsurface_p.h b/src/client/qwaylandxdgsurface_p.h index d2a154ef0..635c9496a 100644 --- a/src/client/qwaylandxdgsurface_p.h +++ b/src/client/qwaylandxdgsurface_p.h @@ -55,6 +55,7 @@ QT_BEGIN_NAMESPACE class QWaylandWindow; class QWaylandInputDevice; class QWindow; +class QWaylandExtendedSurface; class Q_WAYLAND_CLIENT_EXPORT QWaylandXdgSurface : public QtWayland::xdg_surface , public QWaylandShellSurface @@ -74,6 +75,12 @@ public: void setTitle(const QString &title) Q_DECL_OVERRIDE; void setAppId(const QString &appId) Q_DECL_OVERRIDE; + void raise() Q_DECL_OVERRIDE; + void lower() Q_DECL_OVERRIDE; + void setContentOrientationMask(Qt::ScreenOrientations orientation) Q_DECL_OVERRIDE; + void setWindowFlags(Qt::WindowFlags flags) Q_DECL_OVERRIDE; + void sendProperty(const QString &name, const QVariant &value) Q_DECL_OVERRIDE; + bool isFullscreen() const { return m_fullscreen; } bool isMaximized() const { return m_maximized; } @@ -92,6 +99,7 @@ private: bool m_minimized; bool m_fullscreen; QSize m_size; + QWaylandExtendedSurface *m_extendedWindow; void xdg_surface_configure(int32_t width, int32_t height) Q_DECL_OVERRIDE; diff --git a/src/client/shellintegration/qwaylandshellintegration_p.h b/src/client/shellintegration/qwaylandshellintegration_p.h new file mode 100644 index 000000000..45a78199c --- /dev/null +++ b/src/client/shellintegration/qwaylandshellintegration_p.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Jolla Ltd +** 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 QWAYLANDSHELLINTEGRATION_H +#define QWAYLANDSHELLINTEGRATION_H + +#include <QtCore/qglobal.h> +#include <QtWaylandClient/private/qwaylandclientexport_p.h> + +QT_BEGIN_NAMESPACE + +class QWaylandWindow; +class QWaylandDisplay; +class QWaylandShellSurface; + +class Q_WAYLAND_CLIENT_EXPORT QWaylandShellIntegration +{ +public: + QWaylandShellIntegration() {} + virtual ~QWaylandShellIntegration() {} + + virtual bool initialize(QWaylandDisplay *display) = 0; + virtual QWaylandShellSurface *createShellSurface(QWaylandWindow *window) = 0; +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDSHELLINTEGRATION_H diff --git a/src/client/shellintegration/qwaylandshellintegrationfactory.cpp b/src/client/shellintegration/qwaylandshellintegrationfactory.cpp new file mode 100644 index 000000000..f780409e1 --- /dev/null +++ b/src/client/shellintegration/qwaylandshellintegrationfactory.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Jolla Ltd +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module 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 "qwaylandshellintegrationfactory_p.h" +#include "qwaylandshellintegrationplugin_p.h" +#include "qwaylandshellintegration_p.h" +#include <QtCore/private/qfactoryloader_p.h> +#include <QtCore/QCoreApplication> +#include <QtCore/QDir> + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_LIBRARY +Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, + (QWaylandShellIntegrationFactoryInterface_iid, QLatin1String("/wayland-shell-integration"), Qt::CaseInsensitive)) +Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, directLoader, + (QWaylandShellIntegrationFactoryInterface_iid, QLatin1String(""), Qt::CaseInsensitive)) +#endif + +QStringList QWaylandShellIntegrationFactory::keys(const QString &pluginPath) +{ +#ifndef QT_NO_LIBRARY + QStringList list; + if (!pluginPath.isEmpty()) { + QCoreApplication::addLibraryPath(pluginPath); + list = directLoader()->keyMap().values(); + if (!list.isEmpty()) { + const QString postFix = QStringLiteral(" (from ") + + QDir::toNativeSeparators(pluginPath) + + QLatin1Char(')'); + const QStringList::iterator end = list.end(); + for (QStringList::iterator it = list.begin(); it != end; ++it) + (*it).append(postFix); + } + } + list.append(loader()->keyMap().values()); + return list; +#else + return QStringList(); +#endif +} + +QWaylandShellIntegration *QWaylandShellIntegrationFactory::create(const QString &name, const QStringList &args, const QString &pluginPath) +{ +#ifndef QT_NO_LIBRARY + // Try loading the plugin from platformPluginPath first: + if (!pluginPath.isEmpty()) { + QCoreApplication::addLibraryPath(pluginPath); + if (QWaylandShellIntegration *ret = qLoadPlugin1<QWaylandShellIntegration, QWaylandShellIntegrationPlugin>(directLoader(), name, args)) + return ret; + } + if (QWaylandShellIntegration *ret = qLoadPlugin1<QWaylandShellIntegration, QWaylandShellIntegrationPlugin>(loader(), name, args)) + return ret; +#endif + return Q_NULLPTR; +} + +QT_END_NAMESPACE diff --git a/src/client/shellintegration/qwaylandshellintegrationfactory_p.h b/src/client/shellintegration/qwaylandshellintegrationfactory_p.h new file mode 100644 index 000000000..415067ef8 --- /dev/null +++ b/src/client/shellintegration/qwaylandshellintegrationfactory_p.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Jolla Ltd +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module 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 QWAYLANDSHELLINTEGRATIONFACTORY_H +#define QWAYLANDSHELLINTEGRATIONFACTORY_H + +#include <QtWaylandClient/private/qwaylandclientexport_p.h> +#include <QtCore/QStringList> + +QT_BEGIN_NAMESPACE + +class QWaylandShellIntegration; + +class Q_WAYLAND_CLIENT_EXPORT QWaylandShellIntegrationFactory +{ +public: + static QStringList keys(const QString &pluginPath = QString()); + static QWaylandShellIntegration *create(const QString &name, const QStringList &args, const QString &pluginPath = QString()); +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDSHELLINTEGRATIONFACTORY_H diff --git a/src/client/shellintegration/qwaylandshellintegrationplugin.cpp b/src/client/shellintegration/qwaylandshellintegrationplugin.cpp new file mode 100644 index 000000000..05b5e91ad --- /dev/null +++ b/src/client/shellintegration/qwaylandshellintegrationplugin.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Jolla Ltd +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module 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 "qwaylandshellintegrationplugin_p.h" + +QT_BEGIN_NAMESPACE + +QWaylandShellIntegrationPlugin::QWaylandShellIntegrationPlugin(QObject *parent) + : QObject(parent) +{ +} + +QWaylandShellIntegrationPlugin::~QWaylandShellIntegrationPlugin() +{ +} + +QT_END_NAMESPACE diff --git a/src/client/shellintegration/qwaylandshellintegrationplugin_p.h b/src/client/shellintegration/qwaylandshellintegrationplugin_p.h new file mode 100644 index 000000000..7d01fb4e5 --- /dev/null +++ b/src/client/shellintegration/qwaylandshellintegrationplugin_p.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Jolla Ltd +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module 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 QWAYLANDSHELLINTEGRATIONPLUGIN_H +#define QWAYLANDSHELLINTEGRATIONPLUGIN_H + +#include <QtWaylandClient/private/qwaylandclientexport_p.h> + +#include <QtCore/qplugin.h> +#include <QtCore/qfactoryinterface.h> +#include <QtCore/QObject> + +QT_BEGIN_NAMESPACE + +class QWaylandShellIntegration; + +#define QWaylandShellIntegrationFactoryInterface_iid "org.qt-project.Qt.WaylandClient.QWaylandShellIntegrationFactoryInterface.5.3" + +class Q_WAYLAND_CLIENT_EXPORT QWaylandShellIntegrationPlugin : public QObject +{ + Q_OBJECT +public: + explicit QWaylandShellIntegrationPlugin(QObject *parent = 0); + ~QWaylandShellIntegrationPlugin(); + + virtual QWaylandShellIntegration *create(const QString &key, const QStringList ¶mList) = 0; +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDSHELLINTEGRATIONPLUGIN_H diff --git a/src/client/shellintegration/shellintegration.pri b/src/client/shellintegration/shellintegration.pri new file mode 100644 index 000000000..de889a47a --- /dev/null +++ b/src/client/shellintegration/shellintegration.pri @@ -0,0 +1,11 @@ +INCLUDEPATH += $$PWD + +SOURCES += \ + $$PWD/qwaylandshellintegrationplugin.cpp \ + $$PWD/qwaylandshellintegrationfactory.cpp + +HEADERS += \ + $$PWD/qwaylandshellintegration_p.h \ + $$PWD/qwaylandshellintegrationplugin_p.h \ + $$PWD/qwaylandshellintegrationfactory_p.h + |