summaryrefslogtreecommitdiffstats
path: root/src/compositor/extensions
diff options
context:
space:
mode:
Diffstat (limited to 'src/compositor/extensions')
-rw-r--r--src/compositor/extensions/extensions.pri10
-rw-r--r--src/compositor/extensions/qwaylandqtwindowmanager.cpp (renamed from src/compositor/extensions/qwaylandwindowmanagerextension.cpp)118
-rw-r--r--src/compositor/extensions/qwaylandqtwindowmanager.h (renamed from src/compositor/extensions/qwaylandwindowmanagerextension.h)21
-rw-r--r--src/compositor/extensions/qwaylandqtwindowmanager_p.h (renamed from src/compositor/extensions/qwaylandwindowmanagerextension_p.h)25
-rw-r--r--src/compositor/extensions/qwaylandquickshellsurfaceitem.h4
-rw-r--r--src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h4
-rw-r--r--src/compositor/extensions/qwaylandshellsurface.h7
-rw-r--r--src/compositor/extensions/qwaylandtextinput.cpp2
-rw-r--r--src/compositor/extensions/qwaylandtextinputmanager.cpp10
-rw-r--r--src/compositor/extensions/qwaylandtextinputmanager_p.h2
-rw-r--r--src/compositor/extensions/qwaylandwlshell.cpp103
-rw-r--r--src/compositor/extensions/qwaylandwlshell.h21
-rw-r--r--src/compositor/extensions/qwaylandwlshell_p.h11
-rw-r--r--src/compositor/extensions/qwaylandwlshellintegration.cpp41
-rw-r--r--src/compositor/extensions/qwaylandwlshellintegration_p.h12
-rw-r--r--src/compositor/extensions/qwaylandxdgshell.cpp217
-rw-r--r--src/compositor/extensions/qwaylandxdgshell.h50
-rw-r--r--src/compositor/extensions/qwaylandxdgshell_p.h18
-rw-r--r--src/compositor/extensions/qwaylandxdgshellintegration.cpp63
-rw-r--r--src/compositor/extensions/qwaylandxdgshellintegration_p.h22
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