diff options
Diffstat (limited to 'src/compositor/extensions')
20 files changed, 542 insertions, 219 deletions
diff --git a/src/compositor/extensions/extensions.pri b/src/compositor/extensions/extensions.pri index 4894eb3c4..bb0abe885 100644 --- a/src/compositor/extensions/extensions.pri +++ b/src/compositor/extensions/extensions.pri @@ -5,7 +5,7 @@ WAYLANDSERVERSOURCES += \ ../extensions/surface-extension.xml \ ../extensions/touch-extension.xml \ ../extensions/qtkey-extension.xml \ - ../extensions/windowmanager.xml \ + ../extensions/qt-windowmanager.xml \ ../3rdparty/protocol/text-input-unstable-v2.xml \ ../3rdparty/protocol/xdg-shell.xml \ @@ -19,8 +19,8 @@ HEADERS += \ extensions/qwaylandtextinput_p.h \ extensions/qwaylandtextinputmanager.h \ extensions/qwaylandtextinputmanager_p.h \ - extensions/qwaylandwindowmanagerextension.h \ - extensions/qwaylandwindowmanagerextension_p.h \ + extensions/qwaylandqtwindowmanager.h \ + extensions/qwaylandqtwindowmanager_p.h \ extensions/qwaylandxdgshell.h \ extensions/qwaylandxdgshell_p.h \ extensions/qwaylandshellsurface.h \ @@ -32,10 +32,10 @@ SOURCES += \ extensions/qwaylandwlshell.cpp \ extensions/qwaylandtextinput.cpp \ extensions/qwaylandtextinputmanager.cpp \ - extensions/qwaylandwindowmanagerextension.cpp \ + extensions/qwaylandqtwindowmanager.cpp \ extensions/qwaylandxdgshell.cpp \ -qtHaveModule(quick) { +qtHaveModule(quick):contains(QT_CONFIG, opengl) { HEADERS += \ extensions/qwaylandquickshellsurfaceitem.h \ extensions/qwaylandquickshellsurfaceitem_p.h \ diff --git a/src/compositor/extensions/qwaylandwindowmanagerextension.cpp b/src/compositor/extensions/qwaylandqtwindowmanager.cpp index 1e7ed2892..f82a8e46f 100644 --- a/src/compositor/extensions/qwaylandwindowmanagerextension.cpp +++ b/src/compositor/extensions/qwaylandqtwindowmanager.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtWaylandCompositor module of the Qt Toolkit. @@ -34,115 +35,116 @@ ** ****************************************************************************/ -#include "qwaylandwindowmanagerextension.h" -#include "qwaylandwindowmanagerextension_p.h" +#include <QtCore/QObject> +#include <QtCore/QUrl> #include <QtWaylandCompositor/QWaylandCompositor> #include <QtWaylandCompositor/QWaylandClient> -#include <QtCore/QUrl> +#include "qwaylandqtwindowmanager.h" +#include "qwaylandqtwindowmanager_p.h" QT_BEGIN_NAMESPACE -QWaylandWindowManagerExtension::QWaylandWindowManagerExtension() - : QWaylandCompositorExtensionTemplate<QWaylandWindowManagerExtension>(*new QWaylandWindowManagerExtensionPrivate) +QWaylandQtWindowManagerPrivate::QWaylandQtWindowManagerPrivate() + : QWaylandCompositorExtensionPrivate() + , qt_windowmanager() + , showIsFullScreen(false) { } -QWaylandWindowManagerExtension::QWaylandWindowManagerExtension(QWaylandCompositor *compositor) - : QWaylandCompositorExtensionTemplate<QWaylandWindowManagerExtension>(compositor, *new QWaylandWindowManagerExtensionPrivate) +void QWaylandQtWindowManagerPrivate::windowmanager_bind_resource(Resource *resource) { + send_hints(resource->handle, static_cast<int32_t>(showIsFullScreen)); } -QWaylandWindowManagerExtensionPrivate::QWaylandWindowManagerExtensionPrivate() - : QWaylandCompositorExtensionPrivate() - , QtWaylandServer::qt_windowmanager() - , showIsFullScreen(false) +void QWaylandQtWindowManagerPrivate::windowmanager_destroy_resource(Resource *resource) +{ + urls.remove(resource); +} + +void QWaylandQtWindowManagerPrivate::windowmanager_open_url(Resource *resource, uint32_t remaining, const QString &newUrl) +{ + Q_Q(QWaylandQtWindowManager); + + QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(q->extensionContainer()); + if (!compositor) { + qWarning() << "Failed to find QWaylandCompositor from QWaylandQtWindowManager::windowmanager_open_url()"; + return; + } + + QString url = urls.value(resource, QString()); + + url.append(newUrl); + + if (remaining) + urls.insert(resource, url); + else { + urls.remove(resource); + q->openUrl(QWaylandClient::fromWlClient(compositor, resource->client()), QUrl(url)); + } +} + +QWaylandQtWindowManager::QWaylandQtWindowManager() + : QWaylandCompositorExtensionTemplate<QWaylandQtWindowManager>(*new QWaylandQtWindowManagerPrivate()) { } -bool QWaylandWindowManagerExtension::showIsFullScreen() const +QWaylandQtWindowManager::QWaylandQtWindowManager(QWaylandCompositor *compositor) + : QWaylandCompositorExtensionTemplate<QWaylandQtWindowManager>(compositor, *new QWaylandQtWindowManagerPrivate()) { - Q_D(const QWaylandWindowManagerExtension); +} + +bool QWaylandQtWindowManager::showIsFullScreen() const +{ + Q_D(const QWaylandQtWindowManager); return d->showIsFullScreen; } -void QWaylandWindowManagerExtension::setShowIsFullScreen(bool value) +void QWaylandQtWindowManager::setShowIsFullScreen(bool value) { - Q_D(QWaylandWindowManagerExtension); + Q_D(QWaylandQtWindowManager); if (d->showIsFullScreen == value) return; d->showIsFullScreen = value; - Q_FOREACH (QWaylandWindowManagerExtensionPrivate::Resource *resource, d->resourceMap().values()) { + Q_FOREACH (QWaylandQtWindowManagerPrivate::Resource *resource, d->resourceMap().values()) { d->send_hints(resource->handle, static_cast<int32_t>(d->showIsFullScreen)); } Q_EMIT showIsFullScreenChanged(); } -void QWaylandWindowManagerExtension::sendQuitMessage(wl_client *client) +void QWaylandQtWindowManager::sendQuitMessage(QWaylandClient *client) { - Q_D(QWaylandWindowManagerExtension); - QWaylandWindowManagerExtensionPrivate::Resource *resource = d->resourceMap().value(client); + Q_D(QWaylandQtWindowManager); + QWaylandQtWindowManagerPrivate::Resource *resource = d->resourceMap().value(client->client()); if (resource) d->send_quit(resource->handle); } -void QWaylandWindowManagerExtension::initialize() +void QWaylandQtWindowManager::initialize() { - Q_D(QWaylandWindowManagerExtension); + Q_D(QWaylandQtWindowManager); QWaylandCompositorExtensionTemplate::initialize(); QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer()); if (!compositor) { - qWarning() << "Failed to find QWaylandCompositor when initializing QWaylandWindowManagerExtension"; + qWarning() << "Failed to find QWaylandCompositor when initializing QWaylandQtWindowManager"; return; } d->init(compositor->display(), 1); } -void QWaylandWindowManagerExtensionPrivate::windowmanager_bind_resource(Resource *resource) -{ - send_hints(resource->handle, static_cast<int32_t>(showIsFullScreen)); -} - -void QWaylandWindowManagerExtensionPrivate::windowmanager_destroy_resource(Resource *resource) -{ - urls.remove(resource); -} - -void QWaylandWindowManagerExtensionPrivate::windowmanager_open_url(Resource *resource, uint32_t remaining, const QString &newUrl) -{ - Q_Q(QWaylandWindowManagerExtension); - - QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(q->extensionContainer()); - if (!compositor) { - qWarning() << "Failed to find QWaylandCompositor from QWaylandWindowManagerExtension::windowmanager_open_url()"; - return; - } - - QString url = urls.value(resource, QString()); - - url.append(newUrl); - - if (remaining) - urls.insert(resource, url); - else { - urls.remove(resource); - q->openUrl(QWaylandClient::fromWlClient(compositor, resource->client()), QUrl(url)); - } -} - -const struct wl_interface *QWaylandWindowManagerExtension::interface() +const struct wl_interface *QWaylandQtWindowManager::interface() { - return QWaylandWindowManagerExtensionPrivate::interface(); + return QWaylandQtWindowManagerPrivate::interface(); } -QByteArray QWaylandWindowManagerExtension::interfaceName() +QByteArray QWaylandQtWindowManager::interfaceName() { - return QWaylandWindowManagerExtensionPrivate::interfaceName(); + return QWaylandQtWindowManagerPrivate::interfaceName(); } QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandwindowmanagerextension.h b/src/compositor/extensions/qwaylandqtwindowmanager.h index 184bcc3c5..4d3951025 100644 --- a/src/compositor/extensions/qwaylandwindowmanagerextension.h +++ b/src/compositor/extensions/qwaylandqtwindowmanager.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtWaylandCompositor module of the Qt Toolkit. @@ -34,8 +35,8 @@ ** ****************************************************************************/ -#ifndef WAYLANDWINDOWMANAGERINTEGRATION_H -#define WAYLANDWINDOWMANAGERINTEGRATION_H +#ifndef QWAYLANDQTWINDOWMANAGER_H +#define QWAYLANDQTWINDOWMANAGER_H #include <QtWaylandCompositor/QWaylandCompositorExtension> #include <QtWaylandCompositor/QWaylandClient> @@ -44,23 +45,21 @@ QT_BEGIN_NAMESPACE -class QWaylandCompositor; +class QWaylandQtWindowManagerPrivate; -class QWaylandWindowManagerExtensionPrivate; - -class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWindowManagerExtension : public QWaylandCompositorExtensionTemplate<QWaylandWindowManagerExtension> +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQtWindowManager : public QWaylandCompositorExtensionTemplate<QWaylandQtWindowManager> { Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandQtWindowManager) Q_PROPERTY(bool showIsFullScreen READ showIsFullScreen WRITE setShowIsFullScreen NOTIFY showIsFullScreenChanged) - Q_DECLARE_PRIVATE(QWaylandWindowManagerExtension) public: - QWaylandWindowManagerExtension(); - explicit QWaylandWindowManagerExtension(QWaylandCompositor *compositor); + QWaylandQtWindowManager(); + explicit QWaylandQtWindowManager(QWaylandCompositor *compositor); bool showIsFullScreen() const; void setShowIsFullScreen(bool value); - void sendQuitMessage(wl_client *client); + void sendQuitMessage(QWaylandClient *client); void initialize() Q_DECL_OVERRIDE; @@ -74,4 +73,4 @@ Q_SIGNALS: QT_END_NAMESPACE -#endif // WAYLANDWINDOWMANAGERINTEGRATION_H +#endif // QWAYLANDQTWINDOWMANAGER_H diff --git a/src/compositor/extensions/qwaylandwindowmanagerextension_p.h b/src/compositor/extensions/qwaylandqtwindowmanager_p.h index 9573855d5..a6df2138f 100644 --- a/src/compositor/extensions/qwaylandwindowmanagerextension_p.h +++ b/src/compositor/extensions/qwaylandqtwindowmanager_p.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtWaylandCompositor module of the Qt Toolkit. @@ -34,8 +35,14 @@ ** ****************************************************************************/ -#ifndef QWAYLANDWINDOWMANAGEREXTENSION_P_H -#define QWAYLANDWINDOWMANAGEREXTENSION_P_H +#ifndef QWAYLANDQTWINDOWMANAGER_P_H +#define QWAYLANDQTWINDOWMANAGER_P_H + +#include <QtCore/QMap> + +#include <QtWaylandCompositor/QWaylandQtWindowManager> +#include <QtWaylandCompositor/private/qwaylandcompositorextension_p.h> +#include <QtWaylandCompositor/private/qwayland-server-qt-windowmanager.h> // // W A R N I N G @@ -48,21 +55,15 @@ // We mean it. // -#include <QtWaylandCompositor/private/qwaylandcompositorextension_p.h> - -#include <QtWaylandCompositor/private/qwayland-server-windowmanager.h> - -#include <QMap> - QT_BEGIN_NAMESPACE -class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWindowManagerExtensionPrivate +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQtWindowManagerPrivate : public QWaylandCompositorExtensionPrivate , public QtWaylandServer::qt_windowmanager { - Q_DECLARE_PUBLIC(QWaylandWindowManagerExtension) + Q_DECLARE_PUBLIC(QWaylandQtWindowManager) public: - QWaylandWindowManagerExtensionPrivate(); + QWaylandQtWindowManagerPrivate(); protected: void windowmanager_bind_resource(Resource *resource) Q_DECL_OVERRIDE; @@ -76,4 +77,4 @@ private: QT_END_NAMESPACE -#endif /*QWAYLANDWINDOWMANAGEREXTENSION_P_H*/ +#endif // QWAYLANDQTWINDOWMANAGER_P_H diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem.h b/src/compositor/extensions/qwaylandquickshellsurfaceitem.h index e233c99e5..f72b970c2 100644 --- a/src/compositor/extensions/qwaylandquickshellsurfaceitem.h +++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem.h @@ -51,8 +51,6 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQuickShellSurfaceItem : public QWaylan Q_DECLARE_PRIVATE(QWaylandQuickShellSurfaceItem) Q_PROPERTY(QWaylandShellSurface *shellSurface READ shellSurface WRITE setShellSurface NOTIFY shellSurfaceChanged) Q_PROPERTY(QQuickItem *moveItem READ moveItem WRITE setMoveItem NOTIFY moveItemChanged) - - QWaylandQuickShellSurfaceItem(QWaylandQuickShellSurfaceItemPrivate &dd, QQuickItem *parent); public: QWaylandQuickShellSurfaceItem(QQuickItem *parent = nullptr); @@ -67,6 +65,8 @@ Q_SIGNALS: void moveItemChanged(); protected: + QWaylandQuickShellSurfaceItem(QWaylandQuickShellSurfaceItemPrivate &dd, QQuickItem *parent); + void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; }; diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h b/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h index c39a1cd08..3cd9bf228 100644 --- a/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h +++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h @@ -40,6 +40,8 @@ #include <QtWaylandCompositor/private/qwaylandquickitem_p.h> #include <QtCore/QBasicTimer> +#include <functional> + QT_BEGIN_NAMESPACE // @@ -83,7 +85,7 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQuickShellEventFilter : public QObject { Q_OBJECT public: - typedef void (*CallbackFunction)(void); + typedef std::function<void()> CallbackFunction; static void startFilter(QWaylandClient *client, CallbackFunction closePopupCallback); static void cancelFilter(); diff --git a/src/compositor/extensions/qwaylandshellsurface.h b/src/compositor/extensions/qwaylandshellsurface.h index 1e9fcb5ab..e8c75327c 100644 --- a/src/compositor/extensions/qwaylandshellsurface.h +++ b/src/compositor/extensions/qwaylandshellsurface.h @@ -49,13 +49,20 @@ class QWaylandShellSurfaceTemplatePrivate; class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandShellSurface : public QWaylandCompositorExtension { Q_OBJECT + Q_PROPERTY(Qt::WindowType windowType READ windowType NOTIFY windowTypeChanged) public: +#ifdef QT_WAYLAND_COMPOSITOR_QUICK virtual QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) = 0; +#endif QWaylandShellSurface(QWaylandObject *waylandObject) : QWaylandCompositorExtension(waylandObject) {} + virtual Qt::WindowType windowType() const { return Qt::WindowType::Window; } protected: QWaylandShellSurface(QWaylandCompositorExtensionPrivate &dd) : QWaylandCompositorExtension(dd){} QWaylandShellSurface(QWaylandObject *container, QWaylandCompositorExtensionPrivate &dd) : QWaylandCompositorExtension(container, dd) {} + +Q_SIGNALS: + void windowTypeChanged(); }; template <typename T> diff --git a/src/compositor/extensions/qwaylandtextinput.cpp b/src/compositor/extensions/qwaylandtextinput.cpp index 973308f2f..14dafaab0 100644 --- a/src/compositor/extensions/qwaylandtextinput.cpp +++ b/src/compositor/extensions/qwaylandtextinput.cpp @@ -38,7 +38,7 @@ #include "qwaylandtextinput_p.h" #include <QtWaylandCompositor/QWaylandCompositor> -#include <QtWaylandCompositor/private/qwaylandinput_p.h> +#include <QtWaylandCompositor/private/qwaylandseat_p.h> #include "qwaylandsurface.h" #include "qwaylandview.h" diff --git a/src/compositor/extensions/qwaylandtextinputmanager.cpp b/src/compositor/extensions/qwaylandtextinputmanager.cpp index 9dd7ace8f..7be00b6dd 100644 --- a/src/compositor/extensions/qwaylandtextinputmanager.cpp +++ b/src/compositor/extensions/qwaylandtextinputmanager.cpp @@ -38,7 +38,7 @@ #include "qwaylandtextinputmanager_p.h" #include <QtWaylandCompositor/QWaylandCompositor> -#include <QtWaylandCompositor/QWaylandInputDevice> +#include <QtWaylandCompositor/QWaylandSeat> #include "qwaylandtextinput.h" @@ -50,14 +50,14 @@ QWaylandTextInputManagerPrivate::QWaylandTextInputManagerPrivate() { } -void QWaylandTextInputManagerPrivate::zwp_text_input_manager_v2_get_text_input(Resource *resource, uint32_t id, struct ::wl_resource *seat) +void QWaylandTextInputManagerPrivate::zwp_text_input_manager_v2_get_text_input(Resource *resource, uint32_t id, struct ::wl_resource *seatResource) { Q_Q(QWaylandTextInputManager); QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(q->extensionContainer()); - QWaylandInputDevice *inputDevice = QWaylandInputDevice::fromSeatResource(seat); - QWaylandTextInput *textInput = QWaylandTextInput::findIn(inputDevice); + QWaylandSeat *seat = QWaylandSeat::fromSeatResource(seatResource); + QWaylandTextInput *textInput = QWaylandTextInput::findIn(seat); if (!textInput) { - textInput = new QWaylandTextInput(inputDevice, compositor); + textInput = new QWaylandTextInput(seat, compositor); } textInput->add(resource->client(), id, wl_resource_get_version(resource->handle)); } diff --git a/src/compositor/extensions/qwaylandtextinputmanager_p.h b/src/compositor/extensions/qwaylandtextinputmanager_p.h index 4af717096..955a5cc8a 100644 --- a/src/compositor/extensions/qwaylandtextinputmanager_p.h +++ b/src/compositor/extensions/qwaylandtextinputmanager_p.h @@ -61,7 +61,7 @@ public: QWaylandTextInputManagerPrivate(); protected: - void zwp_text_input_manager_v2_get_text_input(Resource *resource, uint32_t id, struct ::wl_resource *seat) Q_DECL_OVERRIDE; + void zwp_text_input_manager_v2_get_text_input(Resource *resource, uint32_t id, struct ::wl_resource *seatResource) Q_DECL_OVERRIDE; }; QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandwlshell.cpp b/src/compositor/extensions/qwaylandwlshell.cpp index c79ddac7c..a1313a6c2 100644 --- a/src/compositor/extensions/qwaylandwlshell.cpp +++ b/src/compositor/extensions/qwaylandwlshell.cpp @@ -38,7 +38,9 @@ #include "qwaylandwlshell.h" #include "qwaylandwlshell_p.h" +#ifdef QT_WAYLAND_COMPOSITOR_QUICK #include "qwaylandwlshellintegration_p.h" +#endif #include <QtWaylandCompositor/QWaylandCompositor> #include <QtWaylandCompositor/QWaylandView> @@ -77,16 +79,23 @@ void QWaylandWlShellPrivate::shell_get_shell_surface(Resource *resource, uint32_ if (!surface->setRole(QWaylandWlShellSurface::role(), displayRes, WL_DISPLAY_ERROR_INVALID_OBJECT)) return; - emit q->createShellSurface(surface, shellSurfaceResource); + emit q->wlShellSurfaceRequested(surface, shellSurfaceResource); QWaylandWlShellSurface *shellSurface = QWaylandWlShellSurface::fromResource(shellSurfaceResource.resource()); if (!shellSurface) { - // A QWaylandShellSurface was not created in response to the createShellSurface signal - // we create one as fallback here instead. + // A QWaylandWlShellSurface was not created in response to the wlShellSurfaceRequested + // signal, so we create one as fallback here instead. shellSurface = new QWaylandWlShellSurface(q, surface, shellSurfaceResource); } - emit q->shellSurfaceCreated(shellSurface); + m_shellSurfaces.append(shellSurface); + emit q->wlShellSurfaceCreated(shellSurface); +} + +void QWaylandWlShellPrivate::unregisterShellSurface(QWaylandWlShellSurface *shellSurface) +{ + if (!m_shellSurfaces.removeOne(shellSurface)) + qWarning("Unexpected state. Can't find registered shell surface."); } QWaylandWlShellSurfacePrivate::QWaylandWlShellSurfacePrivate() @@ -95,6 +104,7 @@ QWaylandWlShellSurfacePrivate::QWaylandWlShellSurfacePrivate() , m_shell(Q_NULLPTR) , m_surface(Q_NULLPTR) , m_focusPolicy(QWaylandWlShellSurface::DefaultFocus) + , m_windowType(Qt::WindowType::Window) { } @@ -108,6 +118,16 @@ void QWaylandWlShellSurfacePrivate::ping(uint32_t serial) send_ping(serial); } +void QWaylandWlShellSurfacePrivate::setWindowType(Qt::WindowType windowType) +{ + if (m_windowType == windowType) + return; + m_windowType = windowType; + + Q_Q(QWaylandWlShellSurface); + emit q->windowTypeChanged(); +} + void QWaylandWlShellSurfacePrivate::shell_surface_destroy_resource(Resource *) { Q_Q(QWaylandWlShellSurface); @@ -123,7 +143,7 @@ void QWaylandWlShellSurfacePrivate::shell_surface_move(Resource *resource, Q_UNUSED(serial); Q_Q(QWaylandWlShellSurface); - QWaylandInputDevice *input_device = QWaylandInputDevice::fromSeatResource(input_device_super); + QWaylandSeat *input_device = QWaylandSeat::fromSeatResource(input_device_super); emit q->startMove(input_device); } @@ -136,7 +156,7 @@ void QWaylandWlShellSurfacePrivate::shell_surface_resize(Resource *resource, Q_UNUSED(serial); Q_Q(QWaylandWlShellSurface); - QWaylandInputDevice *input_device = QWaylandInputDevice::fromSeatResource(input_device_super); + QWaylandSeat *input_device = QWaylandSeat::fromSeatResource(input_device_super); emit q->startResize(input_device, QWaylandWlShellSurface::ResizeEdge(edges)); } @@ -145,6 +165,7 @@ void QWaylandWlShellSurfacePrivate::shell_surface_set_toplevel(Resource *resourc Q_UNUSED(resource); Q_Q(QWaylandWlShellSurface); setFocusPolicy(QWaylandWlShellSurface::DefaultFocus); + setWindowType(Qt::WindowType::Window); emit q->setDefaultToplevel(); } @@ -162,6 +183,7 @@ void QWaylandWlShellSurfacePrivate::shell_surface_set_transient(Resource *resour flags & WL_SHELL_SURFACE_TRANSIENT_INACTIVE ? QWaylandWlShellSurface::NoKeyboardFocus : QWaylandWlShellSurface::DefaultFocus; setFocusPolicy(focusPolicy); + setWindowType(Qt::WindowType::SubWindow); emit q->setTransient(parent_surface, QPoint(x,y), focusPolicy); } @@ -178,6 +200,7 @@ void QWaylandWlShellSurfacePrivate::shell_surface_set_fullscreen(Resource *resou QWaylandOutput *output = output_resource ? QWaylandOutput::fromResource(output_resource) : Q_NULLPTR; + setWindowType(Qt::WindowType::Window); emit q->setFullScreen(QWaylandWlShellSurface::FullScreenMethod(method), framerate, output); } @@ -188,8 +211,9 @@ void QWaylandWlShellSurfacePrivate::shell_surface_set_popup(Resource *resource, Q_UNUSED(flags); Q_Q(QWaylandWlShellSurface); setFocusPolicy(QWaylandWlShellSurface::DefaultFocus); - QWaylandInputDevice *input = QWaylandInputDevice::fromSeatResource(input_device); + QWaylandSeat *input = QWaylandSeat::fromSeatResource(input_device); QWaylandSurface *parentSurface = QWaylandSurface::fromResource(parent); + setWindowType(Qt::WindowType::Popup); emit q->setPopup(input, parentSurface, QPoint(x,y)); } @@ -203,6 +227,7 @@ void QWaylandWlShellSurfacePrivate::shell_surface_set_maximized(Resource *resour QWaylandOutput *output = output_resource ? QWaylandOutput::fromResource(output_resource) : Q_NULLPTR; + setWindowType(Qt::WindowType::Window); emit q->setMaximized(output); } @@ -308,6 +333,23 @@ void QWaylandWlShell::initialize() d->init(compositor->display(), 1); } +QList<QWaylandWlShellSurface *> QWaylandWlShell::shellSurfaces() const +{ + Q_D(const QWaylandWlShell); + return d->m_shellSurfaces; +} + +QList<QWaylandWlShellSurface *> QWaylandWlShell::shellSurfacesForClient(QWaylandClient *client) const +{ + Q_D(const QWaylandWlShell); + QList<QWaylandWlShellSurface *> surfsForClient; + Q_FOREACH (QWaylandWlShellSurface *shellSurface, d->m_shellSurfaces) { + if (shellSurface->surface()->client() == client) + surfsForClient.append(shellSurface); + } + return surfsForClient; +} + /*! * Returns the Wayland interface for the QWaylandWlShell. */ @@ -317,7 +359,7 @@ const struct wl_interface *QWaylandWlShell::interface() } /*! - * \qmlsignal void QtWaylandCompositor::WlShell::createShellSurface(object surface, object client, int id) + * \qmlsignal void QtWaylandCompositor::WlShell::wlShellSurfaceRequested(object surface, object client, int id) * * This signal is emitted when the \a client has requested a \c wl_shell_surface to be associated * with \a surface, which is identified by \a id. The handler for this signal is @@ -326,7 +368,7 @@ const struct wl_interface *QWaylandWlShell::interface() */ /*! - * \fn void QWaylandWlShell::createShellSurface(QWaylandSurface *surface, const QWaylandResource &resource) + * \fn void QWaylandWlShell::wlShellSurfaceRequested(QWaylandSurface *surface, const QWaylandResource &resource) * * Constructs a QWaylandSurface, assigns it to \a surface and initializes it with the given \a resource. */ @@ -382,6 +424,12 @@ QWaylandWlShellSurface::QWaylandWlShellSurface(QWaylandWlShell *shell, QWaylandS initialize(shell, surface, res); } +QWaylandWlShellSurface::~QWaylandWlShellSurface() +{ + Q_D(QWaylandWlShellSurface); + QWaylandWlShellPrivate::get(d->m_shell)->unregisterShellSurface(this); +} + /*! * \qmlmethod void QtWaylandCompositor::WlShellSurface::initialize(object shell, object surface, object client, int id) * @@ -399,6 +447,7 @@ void QWaylandWlShellSurface::initialize(QWaylandWlShell *shell, QWaylandSurface d->init(resource.resource()); setExtensionContainer(surface); emit surfaceChanged(); + emit shellChanged(); QWaylandCompositorExtension::initialize(); } @@ -493,10 +542,12 @@ void QWaylandWlShellSurface::sendPopupDone() d->send_popup_done(); } +#ifdef QT_WAYLAND_COMPOSITOR_QUICK QWaylandQuickShellIntegration *QWaylandWlShellSurface::createIntegration(QWaylandQuickShellSurfaceItem *item) { return new QtWayland::WlShellIntegration(item); } +#endif /*! * \qmlproperty object QtWaylandCompositor::WlShellSurface::surface @@ -516,6 +567,23 @@ QWaylandSurface *QWaylandWlShellSurface::surface() const } /*! + * \qmlproperty object QtWaylandCompositor::WlShellSurface::shell + * + * This property holds the shell associated with this WlShellSurface. + */ + +/*! + * \property QWaylandWlShellSurface::shell + * + * This property holds the shell associated with this QWaylandWlShellSurface. + */ +QWaylandWlShell *QWaylandWlShellSurface::shell() const +{ + Q_D(const QWaylandWlShellSurface); + return d->m_shell; +} + +/*! * \enum QWaylandWlShellSurface::FocusPolicy * * This enum type is used to specify the focus policy of a shell surface. @@ -542,6 +610,23 @@ QWaylandWlShellSurface::FocusPolicy QWaylandWlShellSurface::focusPolicy() const } /*! + * \qmlproperty enum QtWaylandCompositor::WlShellSurface::windowType + * + * This property holds the window type of the WlShellSurface. + */ + +/*! + * \property QWaylandWlShellSurface::windowType + * + * This property holds the window type of the QWaylandWlShellSurface. + */ +Qt::WindowType QWaylandWlShellSurface::windowType() const +{ + Q_D(const QWaylandWlShellSurface); + return d->m_windowType; +} + +/*! * \qmlproperty string QtWaylandCompositor::WlShellSurface::title * * This property holds the title of the WlShellSurface. diff --git a/src/compositor/extensions/qwaylandwlshell.h b/src/compositor/extensions/qwaylandwlshell.h index 5bddd4f7b..c2d40a87c 100644 --- a/src/compositor/extensions/qwaylandwlshell.h +++ b/src/compositor/extensions/qwaylandwlshell.h @@ -49,7 +49,7 @@ class QWaylandWlShellPrivate; class QWaylandWlShellSurfacePrivate; class QWaylandSurface; class QWaylandClient; -class QWaylandInputDevice; +class QWaylandSeat; class QWaylandOutput; class QWaylandSurfaceRole; class QWaylandWlShellSurface; @@ -63,13 +63,15 @@ public: QWaylandWlShell(QWaylandCompositor *compositor); void initialize() Q_DECL_OVERRIDE; + QList<QWaylandWlShellSurface *> shellSurfaces() const; + QList<QWaylandWlShellSurface *> shellSurfacesForClient(QWaylandClient* client) const; static const struct wl_interface *interface(); static QByteArray interfaceName(); Q_SIGNALS: - void createShellSurface(QWaylandSurface *surface, const QWaylandResource &resource); - void shellSurfaceCreated(QWaylandWlShellSurface *shellSurface); + void wlShellSurfaceRequested(QWaylandSurface *surface, const QWaylandResource &resource); + void wlShellSurfaceCreated(QWaylandWlShellSurface *shellSurface); }; class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWlShellSurface : public QWaylandShellSurfaceTemplate<QWaylandWlShellSurface> @@ -77,6 +79,7 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWlShellSurface : public QWaylandShellS Q_OBJECT Q_DECLARE_PRIVATE(QWaylandWlShellSurface) Q_PROPERTY(QWaylandSurface *surface READ surface NOTIFY surfaceChanged) + Q_PROPERTY(QWaylandWlShell *shell READ shell NOTIFY shellChanged) Q_PROPERTY(QString title READ title NOTIFY titleChanged) Q_PROPERTY(QString className READ className NOTIFY classNameChanged) Q_PROPERTY(FocusPolicy focusPolicy READ focusPolicy NOTIFY focusPolicyChanged) @@ -111,6 +114,7 @@ public: QWaylandWlShellSurface(); QWaylandWlShellSurface(QWaylandWlShell *shell, QWaylandSurface *surface, const QWaylandResource &resource); + virtual ~QWaylandWlShellSurface(); Q_INVOKABLE void initialize(QWaylandWlShell *shell, QWaylandSurface *surface, const QWaylandResource &resource); @@ -118,8 +122,10 @@ public: QString className() const; QWaylandSurface *surface() const; + QWaylandWlShell *shell() const; FocusPolicy focusPolicy() const; + Qt::WindowType windowType() const override; static const struct wl_interface *interface(); static QByteArray interfaceName(); @@ -131,24 +137,27 @@ public: Q_INVOKABLE void sendConfigure(const QSize &size, ResizeEdge edges); Q_INVOKABLE void sendPopupDone(); +#ifdef QT_WAYLAND_COMPOSITOR_QUICK QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) Q_DECL_OVERRIDE; +#endif public Q_SLOTS: void ping(); Q_SIGNALS: void surfaceChanged(); + void shellChanged(); void titleChanged(); void classNameChanged(); void focusPolicyChanged(); void pong(); - void startMove(QWaylandInputDevice *inputDevice); - void startResize(QWaylandInputDevice *inputDevice, ResizeEdge edges); + void startMove(QWaylandSeat *seat); + void startResize(QWaylandSeat *seat, ResizeEdge edges); void setDefaultToplevel(); void setTransient(QWaylandSurface *parentSurface, const QPoint &relativeToParent, FocusPolicy focusPolicy); void setFullScreen(FullScreenMethod method, uint framerate, QWaylandOutput *output); - void setPopup(QWaylandInputDevice *inputDevice, QWaylandSurface *parentSurface, const QPoint &relativeToParent); + void setPopup(QWaylandSeat *seat, QWaylandSurface *parentSurface, const QPoint &relativeToParent); void setMaximized(QWaylandOutput *output); private: diff --git a/src/compositor/extensions/qwaylandwlshell_p.h b/src/compositor/extensions/qwaylandwlshell_p.h index 39ed645c1..e840a01fe 100644 --- a/src/compositor/extensions/qwaylandwlshell_p.h +++ b/src/compositor/extensions/qwaylandwlshell_p.h @@ -41,7 +41,7 @@ #include <QtWaylandCompositor/qwaylandsurface.h> #include <QtWaylandCompositor/private/qwaylandcompositorextension_p.h> #include <QtWaylandCompositor/QWaylandWlShellSurface> -#include <QtWaylandCompositor/QWaylandInputDevice> +#include <QtWaylandCompositor/QWaylandSeat> #include <wayland-server.h> #include <QHash> @@ -70,10 +70,15 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWlShellPrivate Q_DECLARE_PUBLIC(QWaylandWlShell) public: QWaylandWlShellPrivate(); + + void unregisterShellSurface(QWaylandWlShellSurface *shellSurface); + static QWaylandWlShellPrivate *get(QWaylandWlShell *shell) { return shell->d_func(); } protected: void shell_get_shell_surface(Resource *resource, uint32_t id, struct ::wl_resource *surface) Q_DECL_OVERRIDE; + + QList<QWaylandWlShellSurface *> m_shellSurfaces; }; class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWlShellSurfacePrivate @@ -97,6 +102,9 @@ public: m_focusPolicy = focusPolicy; emit q->focusPolicyChanged(); } + + void setWindowType(Qt::WindowType windowType); + private: QWaylandWlShell *m_shell; QWaylandSurface *m_surface; @@ -106,6 +114,7 @@ private: QString m_title; QString m_className; QWaylandWlShellSurface::FocusPolicy m_focusPolicy; + Qt::WindowType m_windowType; void shell_surface_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; diff --git a/src/compositor/extensions/qwaylandwlshellintegration.cpp b/src/compositor/extensions/qwaylandwlshellintegration.cpp index a1ef5f32a..1acc01dd7 100644 --- a/src/compositor/extensions/qwaylandwlshellintegration.cpp +++ b/src/compositor/extensions/qwaylandwlshellintegration.cpp @@ -39,7 +39,7 @@ #include <QtWaylandCompositor/QWaylandCompositor> #include <QtWaylandCompositor/QWaylandWlShellSurface> #include <QtWaylandCompositor/QWaylandQuickShellSurfaceItem> -#include <QtWaylandCompositor/QWaylandInputDevice> +#include <QtWaylandCompositor/QWaylandSeat> QT_BEGIN_NAMESPACE @@ -60,28 +60,39 @@ WlShellIntegration::WlShellIntegration(QWaylandQuickShellSurfaceItem *item) connect(m_shellSurface, &QWaylandWlShellSurface::destroyed, this, &WlShellIntegration::handleShellSurfaceDestroyed); } -void WlShellIntegration::handleStartMove(QWaylandInputDevice *inputDevice) +void WlShellIntegration::handleStartMove(QWaylandSeat *seat) { grabberState = GrabberState::Move; - moveState.inputDevice = inputDevice; + moveState.seat = seat; moveState.initialized = false; } -void WlShellIntegration::handleStartResize(QWaylandInputDevice *inputDevice, QWaylandWlShellSurface::ResizeEdge edges) +void WlShellIntegration::handleStartResize(QWaylandSeat *seat, QWaylandWlShellSurface::ResizeEdge edges) { grabberState = GrabberState::Resize; - resizeState.inputDevice = inputDevice; + resizeState.seat = seat; resizeState.resizeEdges = edges; float scaleFactor = m_item->view()->output()->scaleFactor(); resizeState.initialSize = m_shellSurface->surface()->size() / scaleFactor; resizeState.initialized = false; } -void WlShellIntegration::handleSetPopup(QWaylandInputDevice *inputDevice, QWaylandSurface *parent, const QPoint &relativeToParent) +void WlShellIntegration::handleSetPopup(QWaylandSeat *seat, QWaylandSurface *parent, const QPoint &relativeToParent) { - Q_UNUSED(inputDevice); + Q_UNUSED(seat); + + // Find the parent item on the same output + QWaylandQuickShellSurfaceItem *parentItem = nullptr; + Q_FOREACH (QWaylandView *view, parent->views()) { + if (view->output() == m_item->view()->output()) { + QWaylandQuickShellSurfaceItem *item = qobject_cast<QWaylandQuickShellSurfaceItem*>(view->renderObject()); + if (item) { + parentItem = item; + break; + } + } + } - QWaylandQuickShellSurfaceItem* parentItem = qobject_cast<QWaylandQuickShellSurfaceItem*>(parent->views().first()->renderObject()); if (parentItem) { // Clear all the transforms for this ShellSurfaceItem. They are not // applicable when the item becomes a child to a surface that has its @@ -100,8 +111,8 @@ void WlShellIntegration::handleSetPopup(QWaylandInputDevice *inputDevice, QWayla if (!popupShellSurfaces.contains(m_shellSurface)) { popupShellSurfaces.append(m_shellSurface); - QObject::connect(m_shellSurface->surface(), &QWaylandSurface::mappedChanged, - this, &WlShellIntegration::handleSurfaceUnmapped); + QObject::connect(m_shellSurface->surface(), &QWaylandSurface::hasContentChanged, + this, &WlShellIntegration::handleSurfaceHasContentChanged); } } @@ -109,8 +120,8 @@ void WlShellIntegration::handlePopupClosed() { handlePopupRemoved(); if (m_shellSurface) - QObject::disconnect(m_shellSurface->surface(), &QWaylandSurface::mappedChanged, - this, &WlShellIntegration::handleSurfaceUnmapped); + QObject::disconnect(m_shellSurface->surface(), &QWaylandSurface::hasContentChanged, + this, &WlShellIntegration::handleSurfaceHasContentChanged); } void WlShellIntegration::handlePopupRemoved() @@ -130,7 +141,7 @@ void WlShellIntegration::handleShellSurfaceDestroyed() m_shellSurface = nullptr; } -void WlShellIntegration::handleSurfaceUnmapped() +void WlShellIntegration::handleSurfaceHasContentChanged() { if (!m_shellSurface || !m_shellSurface->surface()->size().isEmpty()) return; @@ -147,7 +158,7 @@ void WlShellIntegration::adjustOffsetForNextFrame(const QPointF &offset) bool WlShellIntegration::mouseMoveEvent(QMouseEvent *event) { if (grabberState == GrabberState::Resize) { - Q_ASSERT(resizeState.inputDevice == m_item->compositor()->inputDeviceFor(event)); + Q_ASSERT(resizeState.seat == m_item->compositor()->seatFor(event)); if (!resizeState.initialized) { resizeState.initialMousePos = event->windowPos(); resizeState.initialized = true; @@ -158,7 +169,7 @@ bool WlShellIntegration::mouseMoveEvent(QMouseEvent *event) QSize newSize = m_shellSurface->sizeForResize(resizeState.initialSize, delta, resizeState.resizeEdges); m_shellSurface->sendConfigure(newSize, resizeState.resizeEdges); } else if (grabberState == GrabberState::Move) { - Q_ASSERT(moveState.inputDevice == m_item->compositor()->inputDeviceFor(event)); + Q_ASSERT(moveState.seat == m_item->compositor()->seatFor(event)); QQuickItem *moveItem = m_item->moveItem(); if (!moveState.initialized) { moveState.initialOffset = moveItem->mapFromItem(nullptr, event->windowPos()); diff --git a/src/compositor/extensions/qwaylandwlshellintegration_p.h b/src/compositor/extensions/qwaylandwlshellintegration_p.h index 3f063af39..f68040cdf 100644 --- a/src/compositor/extensions/qwaylandwlshellintegration_p.h +++ b/src/compositor/extensions/qwaylandwlshellintegration_p.h @@ -65,11 +65,11 @@ public: bool mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; private Q_SLOTS: - void handleStartMove(QWaylandInputDevice *inputDevice); - void handleStartResize(QWaylandInputDevice *inputDevice, QWaylandWlShellSurface::ResizeEdge edges); - void handleSetPopup(QWaylandInputDevice *inputDevice, QWaylandSurface *parent, const QPoint &relativeToParent); + void handleStartMove(QWaylandSeat *seat); + void handleStartResize(QWaylandSeat *seat, QWaylandWlShellSurface::ResizeEdge edges); + void handleSetPopup(QWaylandSeat *seat, QWaylandSurface *parent, const QPoint &relativeToParent); void handleShellSurfaceDestroyed(); - void handleSurfaceUnmapped(); + void handleSurfaceHasContentChanged(); void adjustOffsetForNextFrame(const QPointF &offset); private: @@ -88,12 +88,12 @@ private: QWaylandWlShellSurface *m_shellSurface; GrabberState grabberState; struct { - QWaylandInputDevice *inputDevice; + QWaylandSeat *seat; QPointF initialOffset; bool initialized; } moveState; struct { - QWaylandInputDevice *inputDevice; + QWaylandSeat *seat; QWaylandWlShellSurface::ResizeEdge resizeEdges; QSizeF initialSize; QPointF initialMousePos; diff --git a/src/compositor/extensions/qwaylandxdgshell.cpp b/src/compositor/extensions/qwaylandxdgshell.cpp index b5346036a..ab2c60ecc 100644 --- a/src/compositor/extensions/qwaylandxdgshell.cpp +++ b/src/compositor/extensions/qwaylandxdgshell.cpp @@ -36,13 +36,16 @@ #include "qwaylandxdgshell.h" #include "qwaylandxdgshell_p.h" + +#ifdef QT_WAYLAND_COMPOSITOR_QUICK #include "qwaylandxdgshellintegration_p.h" +#endif #include <QtWaylandCompositor/QWaylandCompositor> #include <QtWaylandCompositor/QWaylandSurface> #include <QtWaylandCompositor/QWaylandSurfaceRole> #include <QtWaylandCompositor/QWaylandResource> -#include <QtWaylandCompositor/QWaylandInputDevice> +#include <QtWaylandCompositor/QWaylandSeat> #include <QtCore/QObject> @@ -147,11 +150,11 @@ void QWaylandXdgShellPrivate::xdg_shell_get_xdg_surface(Resource *resource, uint QWaylandResource xdgSurfaceResource(wl_resource_create(resource->client(), &xdg_surface_interface, wl_resource_get_version(resource->handle), id)); - emit q->createXdgSurface(surface, xdgSurfaceResource); + emit q->xdgSurfaceRequested(surface, xdgSurfaceResource); QWaylandXdgSurface *xdgSurface = QWaylandXdgSurface::fromResource(xdgSurfaceResource.resource()); if (!xdgSurface) { - // A QWaylandXdgSurface was not created in response to the createXdgSurface signal, so we + // A QWaylandXdgSurface was not created in response to the xdgSurfaceRequested signal, so we // create one as fallback here instead. xdgSurface = new QWaylandXdgSurface(q, surface, xdgSurfaceResource); } @@ -171,7 +174,7 @@ void QWaylandXdgShellPrivate::xdg_shell_use_unstable_version(Resource *resource, void QWaylandXdgShellPrivate::xdg_shell_get_xdg_popup(Resource *resource, uint32_t id, wl_resource *surface_res, wl_resource *parent, - wl_resource *seat, uint32_t serial, + wl_resource *seatResource, uint32_t serial, int32_t x, int32_t y) { Q_UNUSED(serial); @@ -191,15 +194,15 @@ void QWaylandXdgShellPrivate::xdg_shell_get_xdg_popup(Resource *resource, uint32 QWaylandResource xdgPopupResource (wl_resource_create(resource->client(), &xdg_popup_interface, wl_resource_get_version(resource->handle), id)); - QWaylandInputDevice *inputDevice = QWaylandInputDevice::fromSeatResource(seat); + QWaylandSeat *seat = QWaylandSeat::fromSeatResource(seatResource); QPoint position(x, y); - emit q->createXdgPopup(surface, parentSurface, inputDevice, position, xdgPopupResource); + emit q->xdgPopupRequested(surface, parentSurface, seat, position, xdgPopupResource); QWaylandXdgPopup *xdgPopup = QWaylandXdgPopup::fromResource(xdgPopupResource.resource()); if (!xdgPopup) { - // A QWaylandXdgPopup was not created in response to the createXdgPopup signal, so we + // A QWaylandXdgPopup was not created in response to the xdgPopupRequested signal, so we // create one as fallback here instead. - xdgPopup = new QWaylandXdgPopup(q, surface, parentSurface, xdgPopupResource); + xdgPopup = new QWaylandXdgPopup(q, surface, parentSurface, position, xdgPopupResource); } registerXdgPopup(xdgPopup); @@ -221,6 +224,7 @@ QWaylandXdgSurfacePrivate::QWaylandXdgSurfacePrivate() , xdg_surface() , m_surface(nullptr) , m_parentSurface(nullptr) + , m_windowType(UnknownWindowType) , m_unsetWindowGeometry(true) , m_lastAckedConfigure({{}, QSize(0, 0), 0}) { @@ -246,6 +250,27 @@ void QWaylandXdgSurfacePrivate::handleFocusReceived() q->sendConfigure(current.size, current.states); } +QRect QWaylandXdgSurfacePrivate::calculateFallbackWindowGeometry() const +{ + // TODO: The unset window geometry should include subsurfaces as well, so this solution + // won't work too well on those kinds of clients. + return QRect(QPoint(0, 0), m_surface->size() / m_surface->bufferScale()); +} + +void QWaylandXdgSurfacePrivate::updateFallbackWindowGeometry() +{ + Q_Q(QWaylandXdgSurface); + if (!m_unsetWindowGeometry) + return; + + const QRect unsetGeometry = calculateFallbackWindowGeometry(); + if (unsetGeometry == m_windowGeometry) + return; + + m_windowGeometry = unsetGeometry; + emit q->windowGeometryChanged(); +} + void QWaylandXdgSurfacePrivate::xdg_surface_destroy_resource(Resource *resource) { Q_UNUSED(resource); @@ -265,7 +290,7 @@ void QWaylandXdgSurfacePrivate::xdg_surface_move(Resource *resource, wl_resource Q_UNUSED(serial); Q_Q(QWaylandXdgSurface); - QWaylandInputDevice *input_device = QWaylandInputDevice::fromSeatResource(seat); + QWaylandSeat *input_device = QWaylandSeat::fromSeatResource(seat); emit q->startMove(input_device); } @@ -276,7 +301,7 @@ void QWaylandXdgSurfacePrivate::xdg_surface_resize(Resource *resource, wl_resour Q_UNUSED(serial); Q_Q(QWaylandXdgSurface); - QWaylandInputDevice *input_device = QWaylandInputDevice::fromSeatResource(seat); + QWaylandSeat *input_device = QWaylandSeat::fromSeatResource(seat); emit q->startResize(input_device, QWaylandXdgSurface::ResizeEdge(edges)); } @@ -325,12 +350,22 @@ void QWaylandXdgSurfacePrivate::xdg_surface_set_parent(Resource *resource, wl_re QWaylandXdgSurfacePrivate::Resource::fromResource(parent)->xdg_surface_object)->q_func(); } - if (m_parentSurface == parentSurface) - return; - Q_Q(QWaylandXdgSurface); - m_parentSurface = parentSurface; - emit q->parentSurfaceChanged(); + + if (m_parentSurface != parentSurface) { + m_parentSurface = parentSurface; + emit q->parentSurfaceChanged(); + } + + if (m_parentSurface && m_windowType != TransientWindowType) { + // There's a parent now, which means the surface is transient + m_windowType = TransientWindowType; + emit q->setTransient(); + } else if (!m_parentSurface && m_windowType != TopLevelWindowType) { + // When the surface has no parent it is toplevel + m_windowType = TopLevelWindowType; + emit q->setTopLevel(); + } } void QWaylandXdgSurfacePrivate::xdg_surface_set_app_id(Resource *resource, const QString &app_id) @@ -343,15 +378,15 @@ void QWaylandXdgSurfacePrivate::xdg_surface_set_app_id(Resource *resource, const emit q->appIdChanged(); } -void QWaylandXdgSurfacePrivate::xdg_surface_show_window_menu(Resource *resource, wl_resource *seat, +void QWaylandXdgSurfacePrivate::xdg_surface_show_window_menu(Resource *resource, wl_resource *seatResource, uint32_t serial, int32_t x, int32_t y) { Q_UNUSED(resource); Q_UNUSED(serial); QPoint position(x, y); - auto inputDevice = QWaylandInputDevice::fromSeatResource(seat); + auto seat = QWaylandSeat::fromSeatResource(seatResource); Q_Q(QWaylandXdgSurface); - emit q->showWindowMenu(inputDevice, position); + emit q->showWindowMenu(seat, position); } void QWaylandXdgSurfacePrivate::xdg_surface_ack_configure(Resource *resource, uint32_t serial) @@ -490,10 +525,10 @@ void QWaylandXdgShell::initialize() } d->init(compositor->display(), 1); - handleDefaultInputDeviceChanged(compositor->defaultInputDevice(), nullptr); + handleSeatChanged(compositor->defaultSeat(), nullptr); - connect(compositor, &QWaylandCompositor::defaultInputDeviceChanged, - this, &QWaylandXdgShell::handleDefaultInputDeviceChanged); + connect(compositor, &QWaylandCompositor::defaultSeatChanged, + this, &QWaylandXdgShell::handleSeatChanged); } /*! @@ -548,15 +583,15 @@ void QWaylandXdgShell::closeAllPopups() } } -void QWaylandXdgShell::handleDefaultInputDeviceChanged(QWaylandInputDevice *newDevice, QWaylandInputDevice *oldDevice) +void QWaylandXdgShell::handleSeatChanged(QWaylandSeat *newSeat, QWaylandSeat *oldSeat) { - if (oldDevice != nullptr) { - disconnect(oldDevice, &QWaylandInputDevice::keyboardFocusChanged, + if (oldSeat != nullptr) { + disconnect(oldSeat, &QWaylandSeat::keyboardFocusChanged, this, &QWaylandXdgShell::handleFocusChanged); } - if (newDevice != nullptr) { - connect(newDevice, &QWaylandInputDevice::keyboardFocusChanged, + if (newSeat != nullptr) { + connect(newSeat, &QWaylandSeat::keyboardFocusChanged, this, &QWaylandXdgShell::handleFocusChanged); } } @@ -590,6 +625,20 @@ void QWaylandXdgShell::handleFocusChanged(QWaylandSurface *newSurface, QWaylandS */ /*! + * \qmlsignal QtWaylandCompositor::XdgSurface::setTopLevel() + * + * This signal is emitted when the parent surface is unset, effectively + * making the window top level. + */ + +/*! + * \qmlsignal QtWaylandCompositor::XdgSurface::setTransient() + * + * This signal is emitted when the parent surface is set, effectively + * making the window transient. + */ + +/*! * Constructs a QWaylandXdgSurface. */ QWaylandXdgSurface::QWaylandXdgSurface() @@ -625,8 +674,10 @@ void QWaylandXdgSurface::initialize(QWaylandXdgShell *xdgShell, QWaylandSurface d->m_surface = surface; d->init(resource.resource()); setExtensionContainer(surface); - d->m_windowGeometry = QRect(QPoint(0,0), surface->size()); + d->m_windowGeometry = d->calculateFallbackWindowGeometry(); connect(surface, &QWaylandSurface::sizeChanged, this, &QWaylandXdgSurface::handleSurfaceSizeChanged); + connect(surface, &QWaylandSurface::bufferScaleChanged, this, &QWaylandXdgSurface::handleBufferScaleChanged); + emit shellChanged(); emit surfaceChanged(); emit windowGeometryChanged(); QWaylandCompositorExtension::initialize(); @@ -652,12 +703,30 @@ QList<int> QWaylandXdgSurface::statesAsInts() const void QWaylandXdgSurface::handleSurfaceSizeChanged() { Q_D(QWaylandXdgSurface); - if (d->m_unsetWindowGeometry && d->m_windowGeometry.size() != surface()->size()) { - // TODO: The unset window geometry should include subsurfaces as well, so this solution - // won't work too well on those kinds of clients. - d->m_windowGeometry.setSize(surface()->size()); - emit windowGeometryChanged(); - } + d->updateFallbackWindowGeometry(); +} + +void QWaylandXdgSurface::handleBufferScaleChanged() +{ + Q_D(QWaylandXdgSurface); + d->updateFallbackWindowGeometry(); +} + +/*! + * \qmlproperty object QtWaylandCompositor::XdgSurface::shell + * + * This property holds the shell associated with this XdgSurface. + */ + +/*! + * \property QWaylandXdgSurface::shell + * + * This property holds the shell associated with this QWaylandXdgSurface. + */ +QWaylandXdgShell *QWaylandXdgSurface::shell() const +{ + Q_D(const QWaylandXdgSurface); + return d->m_xdgShell; } /*! @@ -681,12 +750,22 @@ QWaylandSurface *QWaylandXdgSurface::surface() const * \qmlproperty object QtWaylandCompositor::XdgSurface::parentSurface * * This property holds the XdgSurface parent of this XdgSurface. + * When a parent surface is set, the parentSurfaceChanged() signal + * is guaranteed to be emitted before setTopLevel() and setTransient(). + * + * \sa QtWaylandCompositor::XdgSurface::setTopLevel() + * \sa QtWaylandCompositor::XdgSurface::setTransient() */ /*! * \property QWaylandXdgSurface::parentSurface * * This property holds the XdgSurface parent of this XdgSurface. + * When a parent surface is set, the parentSurfaceChanged() signal + * is guaranteed to be emitted before setTopLevel() and setTransient(). + * + * \sa QWaylandXdgSurface::setTopLevel() + * \sa QWaylandXdgSurface::setTransient() */ QWaylandXdgSurface *QWaylandXdgSurface::parentSurface() const { @@ -867,7 +946,7 @@ void QWaylandXdgSurface::sendClose() d->send_close(); } -uint QWaylandXdgSurface::requestMaximized(const QSize &size) +uint QWaylandXdgSurface::sendMaximized(const QSize &size) { Q_D(QWaylandXdgSurface); QWaylandXdgSurfacePrivate::ConfigureEvent conf = d->lastSentConfigure(); @@ -880,7 +959,7 @@ uint QWaylandXdgSurface::requestMaximized(const QSize &size) return sendConfigure(size, conf.states); } -uint QWaylandXdgSurface::requestUnMaximized(const QSize &size) +uint QWaylandXdgSurface::sendUnmaximized(const QSize &size) { Q_D(QWaylandXdgSurface); QWaylandXdgSurfacePrivate::ConfigureEvent conf = d->lastSentConfigure(); @@ -892,7 +971,7 @@ uint QWaylandXdgSurface::requestUnMaximized(const QSize &size) return sendConfigure(size, conf.states); } -uint QWaylandXdgSurface::requestFullscreen(const QSize &size) +uint QWaylandXdgSurface::sendFullscreen(const QSize &size) { Q_D(QWaylandXdgSurface); QWaylandXdgSurfacePrivate::ConfigureEvent conf = d->lastSentConfigure(); @@ -905,7 +984,7 @@ uint QWaylandXdgSurface::requestFullscreen(const QSize &size) return sendConfigure(size, conf.states); } -uint QWaylandXdgSurface::requestResizing(const QSize &maxSize) +uint QWaylandXdgSurface::sendResizing(const QSize &maxSize) { Q_D(QWaylandXdgSurface); QWaylandXdgSurfacePrivate::ConfigureEvent conf = d->lastSentConfigure(); @@ -918,10 +997,12 @@ uint QWaylandXdgSurface::requestResizing(const QSize &maxSize) return sendConfigure(maxSize, conf.states); } +#ifdef QT_WAYLAND_COMPOSITOR_QUICK QWaylandQuickShellIntegration *QWaylandXdgSurface::createIntegration(QWaylandQuickShellSurfaceItem *item) { return new QtWayland::XdgShellIntegration(item); } +#endif /*! * \class QWaylandXdgPopup @@ -940,7 +1021,7 @@ QWaylandQuickShellIntegration *QWaylandXdgSurface::createIntegration(QWaylandQui * Constructs a QWaylandXdgPopup. */ QWaylandXdgPopup::QWaylandXdgPopup() - : QWaylandCompositorExtensionTemplate<QWaylandXdgPopup>(*new QWaylandXdgPopupPrivate) + : QWaylandShellSurfaceTemplate<QWaylandXdgPopup>(*new QWaylandXdgPopupPrivate) { } @@ -949,10 +1030,10 @@ QWaylandXdgPopup::QWaylandXdgPopup() * given \a parentSurface and \a resource. */ QWaylandXdgPopup::QWaylandXdgPopup(QWaylandXdgShell *xdgShell, QWaylandSurface *surface, - QWaylandSurface *parentSurface, const QWaylandResource &resource) - : QWaylandCompositorExtensionTemplate<QWaylandXdgPopup>(*new QWaylandXdgPopupPrivate) + QWaylandSurface *parentSurface, const QPoint &position, const QWaylandResource &resource) + : QWaylandShellSurfaceTemplate<QWaylandXdgPopup>(*new QWaylandXdgPopupPrivate) { - initialize(xdgShell, surface, parentSurface, resource); + initialize(xdgShell, surface, parentSurface, position, resource); } /*! @@ -966,21 +1047,40 @@ QWaylandXdgPopup::QWaylandXdgPopup(QWaylandXdgShell *xdgShell, QWaylandSurface * * Initializes the QWaylandXdgPopup, associating it with the given \a shell \a surface, * \a parentSurface and \a resource. */ -void QWaylandXdgPopup::initialize(QWaylandXdgShell *shell, QWaylandSurface *surface, - QWaylandSurface *parentSurface, const QWaylandResource &resource) +void QWaylandXdgPopup::initialize(QWaylandXdgShell *shell, QWaylandSurface *surface, QWaylandSurface *parentSurface, + const QPoint& position, const QWaylandResource &resource) { Q_D(QWaylandXdgPopup); d->m_surface = surface; d->m_parentSurface = parentSurface; d->m_xdgShell = shell; + d->m_position = position; d->init(resource.resource()); setExtensionContainer(surface); + emit shellChanged(); emit surfaceChanged(); emit parentSurfaceChanged(); QWaylandCompositorExtension::initialize(); } /*! + * \qmlproperty object QtWaylandCompositor::XdgPopup::shell + * + * This property holds the shell associated with this XdgPopup. + */ + +/*! + * \property QWaylandXdgPopup::shell + * + * This property holds the shell associated with this QWaylandXdgPopup. + */ +QWaylandXdgShell *QWaylandXdgPopup::shell() const +{ + Q_D(const QWaylandXdgPopup); + return d->m_xdgShell; +} + +/*! * \qmlproperty object QtWaylandCompositor::XdgPopup::surface * * This property holds the surface associated with this XdgPopup. @@ -1015,12 +1115,34 @@ QWaylandSurface *QWaylandXdgPopup::parentSurface() const return d->m_parentSurface; } + +/*! + * \qmlproperty object QtWaylandCompositor::XdgPopup::position + * + * This property holds the location of the upper left corner of the surface + * relative to the upper left corner of the parent surface, in surface local + * coordinates. + */ + +/*! + * \property QWaylandXdgPopup::position + * + * This property holds the location of the upper left corner of the surface + * relative to the upper left corner of the parent surface, in surface local + * coordinates. + */ +QPoint QWaylandXdgPopup::position() const +{ + Q_D(const QWaylandXdgPopup); + return d->m_position; +} + /*! * \internal */ void QWaylandXdgPopup::initialize() { - QWaylandCompositorExtensionTemplate::initialize(); + QWaylandCompositorExtension::initialize(); } /*! @@ -1058,4 +1180,11 @@ void QWaylandXdgPopup::sendPopupDone() d->send_popup_done(); } +#ifdef QT_WAYLAND_COMPOSITOR_QUICK +QWaylandQuickShellIntegration *QWaylandXdgPopup::createIntegration(QWaylandQuickShellSurfaceItem *item) +{ + return new QtWayland::XdgPopupIntegration(item); +} +#endif + QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandxdgshell.h b/src/compositor/extensions/qwaylandxdgshell.h index c11ca1f3a..4a1ec5d06 100644 --- a/src/compositor/extensions/qwaylandxdgshell.h +++ b/src/compositor/extensions/qwaylandxdgshell.h @@ -55,7 +55,7 @@ class QWaylandXdgPopupPrivate; class QWaylandSurface; class QWaylandSurfaceRole; -class QWaylandInputDevice; +class QWaylandSeat; class QWaylandOutput; class QWaylandClient; @@ -77,14 +77,14 @@ public Q_SLOTS: void closeAllPopups(); Q_SIGNALS: - void createXdgSurface(QWaylandSurface *surface, const QWaylandResource &resource); + void xdgSurfaceRequested(QWaylandSurface *surface, const QWaylandResource &resource); void xdgSurfaceCreated(QWaylandXdgSurface *xdgSurface); void xdgPopupCreated(QWaylandXdgPopup *xdgPopup); - void createXdgPopup(QWaylandSurface *surface, QWaylandSurface *parent, QWaylandInputDevice *seat, const QPoint &position, const QWaylandResource &resource); + void xdgPopupRequested(QWaylandSurface *surface, QWaylandSurface *parent, QWaylandSeat *seat, const QPoint &position, const QWaylandResource &resource); void pong(uint serial); private Q_SLOTS: - void handleDefaultInputDeviceChanged(QWaylandInputDevice *newDevice, QWaylandInputDevice *oldDevice); + void handleSeatChanged(QWaylandSeat *newSeat, QWaylandSeat *oldSeat); void handleFocusChanged(QWaylandSurface *newSurface, QWaylandSurface *oldSurface); }; @@ -93,6 +93,7 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgSurface : public QWaylandShellSurfa { Q_OBJECT Q_DECLARE_PRIVATE(QWaylandXdgSurface) + Q_PROPERTY(QWaylandXdgShell *shell READ shell NOTIFY shellChanged) Q_PROPERTY(QWaylandSurface *surface READ surface NOTIFY surfaceChanged) Q_PROPERTY(QWaylandXdgSurface *parentSurface READ parentSurface NOTIFY parentSurfaceChanged) Q_PROPERTY(QString title READ title NOTIFY titleChanged) @@ -141,6 +142,8 @@ public: bool resizing() const; bool activated() const; + QWaylandXdgShell *shell() const; + QWaylandSurface *surface() const; QWaylandXdgSurface *parentSurface() const; @@ -154,14 +157,17 @@ public: Q_INVOKABLE uint sendConfigure(const QSize &size, const QVector<State> &states); Q_INVOKABLE void sendClose(); - Q_INVOKABLE uint requestMaximized(const QSize &size); - Q_INVOKABLE uint requestUnMaximized(const QSize &size = QSize(0, 0)); - Q_INVOKABLE uint requestFullscreen(const QSize &size); - Q_INVOKABLE uint requestResizing(const QSize &maxSize); + Q_INVOKABLE uint sendMaximized(const QSize &size); + Q_INVOKABLE uint sendUnmaximized(const QSize &size = QSize(0, 0)); + Q_INVOKABLE uint sendFullscreen(const QSize &size); + Q_INVOKABLE uint sendResizing(const QSize &maxSize); +#ifdef QT_WAYLAND_COMPOSITOR_QUICK QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) Q_DECL_OVERRIDE; +#endif Q_SIGNALS: + void shellChanged(); void surfaceChanged(); void titleChanged(); void windowGeometryChanged(); @@ -174,9 +180,11 @@ Q_SIGNALS: void resizingChanged(); void activatedChanged(); - void showWindowMenu(QWaylandInputDevice *inputDevice, const QPoint &localSurfacePosition); - void startMove(QWaylandInputDevice *inputDevice); - void startResize(QWaylandInputDevice *inputDevice, ResizeEdge edges); + void showWindowMenu(QWaylandSeat *seat, const QPoint &localSurfacePosition); + void startMove(QWaylandSeat *seat); + void startResize(QWaylandSeat *seat, ResizeEdge edges); + void setTopLevel(); + void setTransient(); void setMaximized(); void unsetMaximized(); void setFullscreen(QWaylandOutput *output); @@ -190,24 +198,33 @@ private: private Q_SLOTS: void handleSurfaceSizeChanged(); + void handleBufferScaleChanged(); }; -class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgPopup : public QWaylandCompositorExtensionTemplate<QWaylandXdgPopup> +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgPopup : public QWaylandShellSurfaceTemplate<QWaylandXdgPopup> { Q_OBJECT Q_DECLARE_PRIVATE(QWaylandXdgPopup) + Q_PROPERTY(QWaylandXdgShell *shell READ shell NOTIFY shellChanged) Q_PROPERTY(QWaylandSurface *surface READ surface NOTIFY surfaceChanged) Q_PROPERTY(QWaylandSurface *parentSurface READ parentSurface NOTIFY parentSurfaceChanged) + Q_PROPERTY(QPoint position READ position) public: QWaylandXdgPopup(); - QWaylandXdgPopup(QWaylandXdgShell *xdgShell, QWaylandSurface *surface, QWaylandSurface *parentSurface, const QWaylandResource &resource); + QWaylandXdgPopup(QWaylandXdgShell *xdgShell, QWaylandSurface *surface, QWaylandSurface *parentSurface, + const QPoint &position, const QWaylandResource &resource); + + Qt::WindowType windowType() const override { return Qt::WindowType::Popup; } Q_INVOKABLE void initialize(QWaylandXdgShell *shell, QWaylandSurface *surface, - QWaylandSurface *parentSurface, const QWaylandResource &resource); + QWaylandSurface *parentSurface, const QPoint &position, const QWaylandResource &resource); + + QWaylandXdgShell *shell() const; QWaylandSurface *surface() const; QWaylandSurface *parentSurface() const; + QPoint position() const; static const struct wl_interface *interface(); static QByteArray interfaceName(); @@ -216,7 +233,12 @@ public: Q_INVOKABLE void sendPopupDone(); +#ifdef QT_WAYLAND_COMPOSITOR_QUICK + QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) Q_DECL_OVERRIDE; +#endif + Q_SIGNALS: + void shellChanged(); void surfaceChanged(); void parentSurfaceChanged(); diff --git a/src/compositor/extensions/qwaylandxdgshell_p.h b/src/compositor/extensions/qwaylandxdgshell_p.h index 3165eb7ca..d7244c704 100644 --- a/src/compositor/extensions/qwaylandxdgshell_p.h +++ b/src/compositor/extensions/qwaylandxdgshell_p.h @@ -73,19 +73,19 @@ public: bool isValidPopupParent(QWaylandSurface *parentSurface) const; QWaylandXdgPopup *topmostPopupForClient(struct wl_client* client) const; -private: QSet<uint32_t> m_pings; QMultiMap<struct wl_client *, QWaylandXdgSurface *> m_xdgSurfaces; QMultiMap<struct wl_client *, QWaylandXdgPopup *> m_xdgPopups; QWaylandXdgSurface *xdgSurfaceFromSurface(QWaylandSurface *surface); +protected: void xdg_shell_destroy(Resource *resource) Q_DECL_OVERRIDE; void xdg_shell_get_xdg_surface(Resource *resource, uint32_t id, struct ::wl_resource *surface) Q_DECL_OVERRIDE; void xdg_shell_use_unstable_version(Resource *resource, int32_t version) Q_DECL_OVERRIDE; void xdg_shell_get_xdg_popup(Resource *resource, uint32_t id, struct ::wl_resource *surface, - struct ::wl_resource *parent, struct ::wl_resource *seat, + struct ::wl_resource *parent, struct ::wl_resource *seatResource, uint32_t serial, int32_t x, int32_t y) Q_DECL_OVERRIDE; void xdg_shell_pong(Resource *resource, uint32_t serial) Q_DECL_OVERRIDE; }; @@ -99,6 +99,12 @@ public: QWaylandXdgSurfacePrivate(); static QWaylandXdgSurfacePrivate *get(QWaylandXdgSurface *xdgSurface) { return xdgSurface->d_func(); } + enum WindowType { + UnknownWindowType, + TopLevelWindowType, + TransientWindowType + }; + struct ConfigureEvent { QVector<uint> states; QSize size; @@ -107,12 +113,16 @@ public: void handleFocusLost(); void handleFocusReceived(); + QRect calculateFallbackWindowGeometry() const; + void updateFallbackWindowGeometry(); private: QWaylandXdgShell *m_xdgShell; QWaylandSurface *m_surface; QWaylandXdgSurface *m_parentSurface; + WindowType m_windowType; + QString m_title; QString m_appId; QRect m_windowGeometry; @@ -137,7 +147,7 @@ private: void xdg_surface_set_minimized(Resource *resource) Q_DECL_OVERRIDE; void xdg_surface_set_parent(Resource *resource, struct ::wl_resource *parent) Q_DECL_OVERRIDE; void xdg_surface_set_app_id(Resource *resource, const QString &app_id) Q_DECL_OVERRIDE; - void xdg_surface_show_window_menu(Resource *resource, struct ::wl_resource *seat, + void xdg_surface_show_window_menu(Resource *resource, struct ::wl_resource *seatResource, uint32_t serial, int32_t x, int32_t y) Q_DECL_OVERRIDE; void xdg_surface_ack_configure(Resource *resource, uint32_t serial) Q_DECL_OVERRIDE; void xdg_surface_set_title(Resource *resource, const QString &title) Q_DECL_OVERRIDE; @@ -157,10 +167,10 @@ public: QWaylandXdgPopupPrivate(); static QWaylandXdgPopupPrivate *get(QWaylandXdgPopup *xdgPopup) { return xdgPopup->d_func(); } -private: QWaylandSurface *m_surface; QWaylandSurface *m_parentSurface; QWaylandXdgShell *m_xdgShell; + QPoint m_position; void xdg_popup_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; void xdg_popup_destroy(xdg_popup::Resource *resource) Q_DECL_OVERRIDE; diff --git a/src/compositor/extensions/qwaylandxdgshellintegration.cpp b/src/compositor/extensions/qwaylandxdgshellintegration.cpp index ab10011e6..90c7a7b36 100644 --- a/src/compositor/extensions/qwaylandxdgshellintegration.cpp +++ b/src/compositor/extensions/qwaylandxdgshellintegration.cpp @@ -38,8 +38,10 @@ #include <QtWaylandCompositor/QWaylandQuickShellSurfaceItem> #include <QtWaylandCompositor/QWaylandCompositor> -#include <QtWaylandCompositor/QWaylandInputDevice> +#include <QtWaylandCompositor/QWaylandSeat> +#include <QtWaylandCompositor/private/qwaylandxdgshell_p.h> #include <QMouseEvent> +#include <QGuiApplication> QT_BEGIN_NAMESPACE @@ -64,18 +66,17 @@ XdgShellIntegration::XdgShellIntegration(QWaylandQuickShellSurfaceItem *item) bool XdgShellIntegration::mouseMoveEvent(QMouseEvent *event) { if (grabberState == GrabberState::Resize) { - Q_ASSERT(resizeState.inputDevice == m_item->compositor()->inputDeviceFor(event)); + Q_ASSERT(resizeState.seat == m_item->compositor()->seatFor(event)); if (!resizeState.initialized) { resizeState.initialMousePos = event->windowPos(); resizeState.initialized = true; return true; } - float scaleFactor = m_item->view()->output()->scaleFactor(); - QPointF delta = (event->windowPos() - resizeState.initialMousePos) / scaleFactor; + QPointF delta = m_item->mapToSurface(event->windowPos() - resizeState.initialMousePos); QSize newSize = m_xdgSurface->sizeForResize(resizeState.initialWindowSize, delta, resizeState.resizeEdges); - m_xdgSurface->requestResizing(newSize); + m_xdgSurface->sendResizing(newSize); } else if (grabberState == GrabberState::Move) { - Q_ASSERT(moveState.inputDevice == m_item->compositor()->inputDeviceFor(event)); + Q_ASSERT(moveState.seat == m_item->compositor()->seatFor(event)); QQuickItem *moveItem = m_item->moveItem(); if (!moveState.initialized) { moveState.initialOffset = moveItem->mapFromItem(nullptr, event->windowPos()); @@ -95,7 +96,7 @@ bool XdgShellIntegration::mouseReleaseEvent(QMouseEvent *event) Q_UNUSED(event); if (grabberState == GrabberState::Resize) { - m_xdgSurface->requestUnMaximized(); + m_xdgSurface->sendUnmaximized(); grabberState = GrabberState::Default; return true; } else if (grabberState == GrabberState::Move) { @@ -105,20 +106,20 @@ bool XdgShellIntegration::mouseReleaseEvent(QMouseEvent *event) return false; } -void XdgShellIntegration::handleStartMove(QWaylandInputDevice *inputDevice) +void XdgShellIntegration::handleStartMove(QWaylandSeat *seat) { grabberState = GrabberState::Move; - moveState.inputDevice = inputDevice; + moveState.seat = seat; moveState.initialized = false; } -void XdgShellIntegration::handleStartResize(QWaylandInputDevice *inputDevice, QWaylandXdgSurface::ResizeEdge edges) +void XdgShellIntegration::handleStartResize(QWaylandSeat *seat, QWaylandXdgSurface::ResizeEdge edges) { grabberState = GrabberState::Resize; - resizeState.inputDevice = inputDevice; + resizeState.seat = seat; resizeState.resizeEdges = edges; resizeState.initialWindowSize = m_xdgSurface->windowGeometry().size(); - resizeState.initialPosition = m_item->position(); + resizeState.initialPosition = m_item->moveItem()->position(); resizeState.initialSurfaceSize = m_item->surface()->size(); resizeState.initialized = false; } @@ -126,24 +127,24 @@ void XdgShellIntegration::handleStartResize(QWaylandInputDevice *inputDevice, QW void XdgShellIntegration::handleSetMaximized() { maximizeState.initialWindowSize = m_xdgSurface->windowGeometry().size(); - maximizeState.initialPosition = m_item->position(); + maximizeState.initialPosition = m_item->moveItem()->position(); - QWaylandOutput *output = m_item->compositor()->outputs().first(); - m_xdgSurface->requestMaximized(output->geometry().size() / output->scaleFactor()); + QWaylandOutput *output = m_item->view()->output(); + m_xdgSurface->sendMaximized(output->availableGeometry().size() / output->scaleFactor()); } void XdgShellIntegration::handleUnsetMaximized() { - m_xdgSurface->requestUnMaximized(maximizeState.initialWindowSize); + m_xdgSurface->sendUnmaximized(maximizeState.initialWindowSize); } void XdgShellIntegration::handleMaximizedChanged() { if (m_xdgSurface->maximized()) { - QWaylandOutput *output = m_item->compositor()->outputs().first(); - m_item->setPosition(output->geometry().topLeft()); + QWaylandOutput *output = m_item->view()->output(); + m_item->moveItem()->setPosition(output->position() + output->availableGeometry().topLeft()); } else { - m_item->setPosition(maximizeState.initialPosition); + m_item->moveItem()->setPosition(maximizeState.initialPosition); } } @@ -163,10 +164,32 @@ void XdgShellIntegration::handleSurfaceSizeChanged() if (resizeState.resizeEdges & QWaylandXdgSurface::ResizeEdge::LeftEdge) x += resizeState.initialSurfaceSize.width() - m_item->surface()->size().width(); - m_item->setPosition(QPointF(x, y)); + m_item->moveItem()->setPosition(QPointF(x, y)); } } +XdgPopupIntegration::XdgPopupIntegration(QWaylandQuickShellSurfaceItem *item) + : QWaylandQuickShellIntegration (item) + , m_xdgPopup(qobject_cast<QWaylandXdgPopup *>(item->shellSurface())) + , m_xdgShell(QWaylandXdgPopupPrivate::get(m_xdgPopup)->m_xdgShell) +{ + item->setSurface(m_xdgPopup->surface()); + item->moveItem()->setPosition(QPointF(m_xdgPopup->position() * item->view()->output()->scaleFactor())); + + QWaylandClient *client = m_xdgPopup->surface()->client(); + QWaylandQuickShellEventFilter::startFilter(client, [&]() { m_xdgShell->closeAllPopups(); }); + + connect(m_xdgPopup, &QWaylandXdgPopup::destroyed, this, &XdgPopupIntegration::handlePopupDestroyed); +} + +void XdgPopupIntegration::handlePopupDestroyed() +{ + QWaylandXdgShellPrivate *shellPrivate = QWaylandXdgShellPrivate::get(m_xdgShell); + auto popups = shellPrivate->m_xdgPopups; + if (popups.isEmpty()) + QWaylandQuickShellEventFilter::cancelFilter(); +} + } QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandxdgshellintegration_p.h b/src/compositor/extensions/qwaylandxdgshellintegration_p.h index df2fa8b8d..8a000ff6a 100644 --- a/src/compositor/extensions/qwaylandxdgshellintegration_p.h +++ b/src/compositor/extensions/qwaylandxdgshellintegration_p.h @@ -64,8 +64,8 @@ public: bool mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; private Q_SLOTS: - void handleStartMove(QWaylandInputDevice *inputDevice); - void handleStartResize(QWaylandInputDevice *inputDevice, QWaylandXdgSurface::ResizeEdge edges); + void handleStartMove(QWaylandSeat *seat); + void handleStartResize(QWaylandSeat *seat, QWaylandXdgSurface::ResizeEdge edges); void handleSetMaximized(); void handleUnsetMaximized(); void handleMaximizedChanged(); @@ -83,13 +83,13 @@ private: GrabberState grabberState; struct { - QWaylandInputDevice *inputDevice; + QWaylandSeat *seat; QPointF initialOffset; bool initialized; } moveState; struct { - QWaylandInputDevice *inputDevice; + QWaylandSeat *seat; QWaylandXdgSurface::ResizeEdge resizeEdges; QSizeF initialWindowSize; QPointF initialMousePos; @@ -104,6 +104,20 @@ private: } maximizeState; }; +class XdgPopupIntegration : public QWaylandQuickShellIntegration +{ + Q_OBJECT +public: + XdgPopupIntegration(QWaylandQuickShellSurfaceItem *item); + +private Q_SLOTS: + void handlePopupDestroyed(); + +private: + QWaylandXdgPopup *m_xdgPopup; + QWaylandXdgShell *m_xdgShell; +}; + } QT_END_NAMESPACE |