summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Griebl <robert.griebl@pelagicore.com>2017-02-23 12:05:07 +0100
committerThomas Senyk <thomas.senyk@pelagicore.com>2017-02-27 12:34:17 +0000
commit7af779444377576cdd3dea96db387f8841c80eb9 (patch)
treed78e3fadff8918c44d9036e71435171f8c95a2fe
parent23a0e5a929b5b03f91ae532a765e2b7a543c3a99 (diff)
downloadqtapplicationmanager-7af779444377576cdd3dea96db387f8841c80eb9.tar.gz
Refactored the old and the new Wayland compositor into one .h/.cpp file
We get a lot more #ifdefs this way, but at least nobody can forget the old compositor that easily now when doing changes to the current one. Also, those ifdefs should be gone when we can drop 5.6 support (hopefully when 5.9 is released). As an added bonus, the compositor is now working again with Qt 5.6. Change-Id: I456cc211aca26d2f17c4466568d7dd620779ed63 Reviewed-by: Thomas Senyk <thomas.senyk@pelagicore.com>
-rw-r--r--src/window-lib/waylandcompositor-old.cpp189
-rw-r--r--src/window-lib/waylandcompositor.cpp305
-rw-r--r--src/window-lib/waylandcompositor.h99
-rw-r--r--src/window-lib/waylandcompositor_p.h (renamed from src/window-lib/waylandcompositor-old.h)56
-rw-r--r--src/window-lib/waylandwindow.cpp23
-rw-r--r--src/window-lib/window-lib.pro7
-rw-r--r--src/window-lib/window.h9
-rw-r--r--src/window-lib/windowmanager.cpp6
-rw-r--r--src/window-lib/windowmanager.h28
9 files changed, 317 insertions, 405 deletions
diff --git a/src/window-lib/waylandcompositor-old.cpp b/src/window-lib/waylandcompositor-old.cpp
deleted file mode 100644
index 2b59a184..00000000
--- a/src/window-lib/waylandcompositor-old.cpp
+++ /dev/null
@@ -1,189 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Pelagicore AG
-** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Pelagicore Application Manager.
-**
-** $QT_BEGIN_LICENSE:LGPL-QTAS$
-** Commercial License Usage
-** Licensees holding valid commercial Qt Automotive Suite licenses may use
-** this file in accordance with the commercial license agreement provided
-** with the Software or, alternatively, in accordance with the terms
-** contained in a written agreement between you and The Qt Company. For
-** licensing terms and conditions see https://www.qt.io/terms-conditions.
-** For further information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-** SPDX-License-Identifier: LGPL-3.0
-**
-****************************************************************************/
-
-#include <QWaylandQuickSurface>
-#include <QWaylandSurfaceItem>
-#if QT_VERSION >= QT_VERSION_CHECK(5,5,0)
-# include <QWaylandOutput>
-# include <QWaylandClient>
-#endif
-#include <QQuickView>
-
-#include "global.h"
-#include "waylandwindow.h"
-#include "applicationmanager.h"
-#include "waylandcompositor-old.h"
-
-QT_BEGIN_NAMESPACE_AM
-
-Surface::Surface(QWaylandSurface *s)
- : m_item(0)
-{
- m_surface = s;
- QObject::connect(s, &QObject::destroyed, [this]() { delete this; });
-}
-
-QQuickItem *Surface::item() const { return m_item; }
-
-void Surface::takeFocus() { m_item->takeFocus(); }
-
-void Surface::ping() { m_surface->ping(); }
-
-qint64 Surface::processId() const
-{
-#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
- return m_surface->client()->processId();
-#else
- return m_surface->processId();
-#endif
-}
-
-QWindow *Surface::outputWindow() const
-{
-#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
- if (QWaylandOutput *o = m_surface->mainOutput())
- return o->window();
- return 0;
-#else
- return m_surface->compositor()->window();
-#endif
-}
-
-QVariantMap Surface::windowProperties() const { return m_surface->windowProperties(); }
-
-void Surface::setWindowProperty(const QString &n, const QVariant &v) { m_surface->setWindowProperty(n, v); }
-
-void Surface::connectPong(const std::function<void ()> &cb)
-{
- QObject::connect(m_surface, &QWaylandSurface::pong, cb);
-}
-
-void Surface::connectWindowPropertyChanged(const std::function<void (const QString &, const QVariant &)> &cb)
-{
- QObject::connect(m_surface, &QWaylandSurface::windowPropertyChanged, cb);
-}
-
-WaylandCompositor::WaylandCompositor(QQuickWindow *window, const QString &waylandSocketName, WindowManager *manager)
-#if QT_VERSION >= QT_VERSION_CHECK(5,5,0)
- : QWaylandQuickCompositor(qPrintable(waylandSocketName), DefaultExtensions | SubSurfaceExtension)
-#else
- : QWaylandQuickCompositor(window, qPrintable(waylandSocketName), DefaultExtensions | SubSurfaceExtension)
-#endif
- , m_manager(manager)
-{
- registerOutputWindow(window);
-
- window->winId();
- addDefaultShell();
-
- QObject::connect(window, &QQuickWindow::beforeSynchronizing, [this]() { frameStarted(); });
- QObject::connect(window, &QQuickWindow::afterRendering, [this]() { sendCallbacks(); });
- setOutputGeometry(window->geometry());
-}
-
-void WaylandCompositor::registerOutputWindow(QQuickWindow *window)
-{
-#if QT_VERSION >= QT_VERSION_CHECK(5,5,0)
- createOutput(window, QString(), QString());
- window->winId();
-#else
- Q_UNUSED(window)
-#endif
-}
-
-void WaylandCompositor::surfaceCreated(QWaylandSurface *surface)
-{
- Surface *s = new Surface(surface);
- m_manager->waylandSurfaceCreated(s);
- QObject::connect(surface, &QWaylandSurface::mapped, [s, surface, this]() {
- s->m_item = static_cast<QWaylandSurfaceItem *>(surface->views().at(0));
- s->m_item->setResizeSurfaceToItem(true);
- s->m_item->setTouchEventsEnabled(true);
- m_manager->waylandSurfaceMapped(s);
- });
- QObject::connect(surface, &QWaylandSurface::unmapped, [s, this]() { m_manager->waylandSurfaceUnmapped(s); });
- QObject::connect(surface, &QWaylandSurface::surfaceDestroyed, [s, this]() { m_manager->waylandSurfaceDestroyed(s); });
-
-}
-
-#if QT_VERSION < QT_VERSION_CHECK(5,5,0)
-bool WaylandCompositor::openUrl(WaylandClient *client, const QUrl &url)
-{
- QList<QWaylandSurface *> surfaces = surfacesForClient(client);
- qint64 pid = surfaces.isEmpty() ? 0 : surfaces.at(0)->processId();
-#else
-bool WaylandCompositor::openUrl(QWaylandClient *client, const QUrl &url)
-{
- qint64 pid = client->processId();
-#endif
- if (ApplicationManager::instance()->fromProcessId(pid))
- return ApplicationManager::instance()->openUrl(url.toString());
- return false;
-}
-
-QWaylandSurface *WaylandCompositor::waylandSurfaceFromItem(QQuickItem *surfaceItem) const
-{
- if (QWaylandSurfaceItem *item = qobject_cast<QWaylandSurfaceItem *>(surfaceItem))
- return item->surface();
- return 0;
-}
-
-void WaylandCompositor::sendCallbacks()
-{
- QList<QWaylandSurface *> listToSend;
-
- // TODO: optimize! no need to send this to hidden/minimized/offscreen/etc. surfaces
- foreach (const Window *win, m_manager->windows()) {
- if (!win->isClosing() && !win->isInProcess()) {
- if (QWaylandSurface *surface = waylandSurfaceFromItem(win->windowItem())) {
- listToSend << surface;
- }
- }
- }
-
- if (!listToSend.isEmpty()) {
- //qCDebug(LogWayland) << "sending callbacks to clients: " << listToSend; // note: debug-level 6 needs to be enabled manually...
- sendFrameCallbacks(listToSend);
- }
-}
-
-QT_END_NAMESPACE_AM
diff --git a/src/window-lib/waylandcompositor.cpp b/src/window-lib/waylandcompositor.cpp
index e3943d86..e16eca5c 100644
--- a/src/window-lib/waylandcompositor.cpp
+++ b/src/window-lib/waylandcompositor.cpp
@@ -40,142 +40,209 @@
**
****************************************************************************/
-#include <QWaylandOutput>
-#include <QWaylandWlShell>
-#include <QWaylandQuickOutput>
-#if QT_VERSION < QT_VERSION_CHECK(5, 8, 0)
-# include <QWaylandWindowManagerExtension>
-typedef QWaylandWindowManagerExtension QWaylandQtWindowManager;
-#else
-# include <QWaylandQtWindowManager>
-#endif
-#include <private/qwlextendedsurface_p.h>
-#include <QWaylandTextInputManager>
#include <QQuickView>
+#include <QWaylandOutput>
+#include "global.h"
#include "windowmanager.h"
+#include "application.h"
#include "applicationmanager.h"
-#include "global.h"
#include "waylandcompositor.h"
+#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
+# include <QWaylandQuickSurface>
+# include <QWaylandSurfaceItem>
+# include <QWaylandClient>
+
+# include "window.h"
+#else
+# include <QWaylandWlShell>
+# include <QWaylandQuickOutput>
+# include <QWaylandTextInputManager>
+# include <private/qwlextendedsurface_p.h>
+# if QT_VERSION < QT_VERSION_CHECK(5, 8, 0)
+# include <QWaylandWindowManagerExtension>
+typedef QWaylandWindowManagerExtension QWaylandQtWindowManager;
+# else
+# include <QWaylandQtWindowManager>
+# endif
+# include "waylandcompositor_p.h"
+#endif
+
QT_BEGIN_NAMESPACE_AM
-void Surface::setShellSurface(QWaylandWlShellSurface *ss)
+#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
+WindowSurface::WindowSurface(QWaylandSurface *surface)
+ : m_item(nullptr)
+ , m_surface(surface)
{
- m_shellSurface = ss;
- m_item = new SurfaceQuickItem(this);
+ connect(m_surface, &QObject::destroyed, [this]() { delete this; });
+ connect(m_surface, &QWaylandSurface::pong, this, &WindowSurface::pong);
+ connect(m_surface, &QWaylandSurface::windowPropertyChanged, this, &WindowSurface::windowPropertyChanged);
+}
+#else
+
+WindowSurface::WindowSurface(QWaylandCompositor *comp, QWaylandClient *client, uint id, int version)
+ : QWaylandQuickSurface(comp, client, id, version)
+ , m_surface(this)
+{ }
+
+void WindowSurface::setShellSurface(QWaylandWlShellSurface *shellSurface)
+{
+ m_shellSurface = shellSurface;
+ connect(m_shellSurface, &QWaylandWlShellSurface::pong,
+ this, &WindowSurface::pong);
+ m_item = new WindowSurfaceQuickItem(this);
}
-void Surface::setExtendedSurface(QtWayland::ExtendedSurface *ext)
+void WindowSurface::setExtendedSurface(QtWayland::ExtendedSurface *extendedSurface)
{
- m_ext = ext;
+ m_extendedSurface = extendedSurface;
+ if (m_extendedSurface) {
+ connect(m_extendedSurface, &QtWayland::ExtendedSurface::windowPropertyChanged,
+ this, &WindowSurface::windowPropertyChanged);
+ }
+}
+
+QWaylandWlShellSurface *WindowSurface::shellSurface() const
+{
+ return m_shellSurface;
}
-QWaylandWlShellSurface *Surface::shellSurface() const { return m_shellSurface; }
+#endif
-QtWayland::ExtendedSurface *Surface::extendedSurface() const { return m_ext; }
-void Surface::takeFocus()
+QWaylandSurface *WindowSurface::surface() const
{
- m_item->takeFocus();
+ return m_surface;
}
-void Surface::ping() { m_shellSurface->ping(); }
+QQuickItem *WindowSurface::item() const
+{
+ return m_item;
+}
-qint64 Surface::processId() const { return m_surface->client()->processId(); }
+qint64 WindowSurface::processId() const
+{
+ return m_surface->client()->processId();
+}
-QWindow *Surface::outputWindow() const
+QWindow *WindowSurface::outputWindow() const
{
-#if QT_VERSION < QT_VERSION_CHECK(5, 8, 0)
+#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
+ if (QWaylandOutput *o = m_surface->mainOutput())
+ return o->window();
+#elif QT_VERSION < QT_VERSION_CHECK(5, 8, 0)
if (QWaylandView *v = m_surface->throttlingView())
+ return v->output()->window();
#else
if (QWaylandView *v = m_surface->primaryView())
-#endif
return v->output()->window();
- return 0;
+#endif
+ return nullptr;
}
-QVariantMap Surface::windowProperties() const { return m_ext ? m_ext->windowProperties() : QVariantMap(); }
-
-void Surface::setWindowProperty(const QString &n, const QVariant &v)
+void WindowSurface::takeFocus()
{
- if (m_ext)
- m_ext->setWindowProperty(n, v);
+ m_item->takeFocus();
}
-void Surface::connectPong(const std::function<void ()> &cb)
+void WindowSurface::ping()
{
- connect(m_shellSurface, &QWaylandWlShellSurface::pong, cb);
+#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
+ m_surface->ping();
+#else
+ m_shellSurface->ping();
+#endif
}
-void Surface::connectWindowPropertyChanged(const std::function<void (const QString &, const QVariant &)> &cb)
+QVariantMap WindowSurface::windowProperties() const
{
- if (m_ext)
- connect(m_ext, &QtWayland::ExtendedSurface::windowPropertyChanged, cb);
+#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
+ return m_surface->windowProperties();
+#else
+ return m_extendedSurface ? m_extendedSurface->windowProperties() : QVariantMap();
+#endif
}
-QQuickItem *Surface::item() const
+void WindowSurface::setWindowProperty(const QString &name, const QVariant &value)
{
- return m_item;
+#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
+ m_surface->setWindowProperty(name, value);
+#else
+ if (m_extendedSurface)
+ m_extendedSurface->setWindowProperty(name, value);
+#endif
}
+#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
-SurfaceQuickItem::SurfaceQuickItem(Surface *s)
+WindowSurfaceQuickItem::WindowSurfaceQuickItem(WindowSurface *windowSurface)
: QWaylandQuickItem()
- , m_surface(s)
+ , m_windowSurface(windowSurface)
{
- setSurface(s);
+ setSurface(windowSurface);
setTouchEventsEnabled(true);
setSizeFollowsSurface(false);
}
-void SurfaceQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+void WindowSurfaceQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
if (newGeometry.isValid()) {
- qCDebug(LogWayland) << "sendConfigure" << m_surface << newGeometry.size() << "(PID:" << m_surface->client()->processId() << ")";
- m_surface->shellSurface()->sendConfigure(newGeometry.size().toSize(), QWaylandWlShellSurface::NoneEdge);
+ const Application *app = nullptr; // prevent expensive lookup when not printing qDebugs
+ qCDebug(LogWayland) << "Sending geometry change request to Wayland client for surface"
+ << m_windowSurface->item() << "old:" << oldGeometry.size() << "new:"
+ << newGeometry.size() << "of"
+ << ((app = ApplicationManager::instance()->fromProcessId(m_windowSurface->client()->processId()))
+ ? app->id() : QString::fromLatin1("pid: %1").arg(m_windowSurface->client()->processId()));
+ m_windowSurface->shellSurface()->sendConfigure(newGeometry.size().toSize(), QWaylandWlShellSurface::NoneEdge);
}
QWaylandQuickItem::geometryChanged(newGeometry, oldGeometry);
}
-Surface::Surface(QWaylandCompositor *comp, QWaylandClient *client, uint id, int version)
- : QWaylandQuickSurface(comp, client, id, version)
- , m_item(0)
- , m_shellSurface(0)
- , m_ext(0)
-{
- m_surface = this;
-}
+#endif // QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+
WaylandCompositor::WaylandCompositor(QQuickWindow *window, const QString &waylandSocketName, WindowManager *manager)
- : QWaylandQuickCompositor()
+#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
+ : QWaylandQuickCompositor(qPrintable(waylandSocketName), DefaultExtensions | SubSurfaceExtension)
, m_manager(manager)
+{
+ registerOutputWindow(window);
+ window->winId();
+ addDefaultShell();
+ QObject::connect(window, &QQuickWindow::beforeSynchronizing, [this]() { frameStarted(); });
+ QObject::connect(window, &QQuickWindow::afterRendering, [this]() { sendCallbacks(); });
+ setOutputGeometry(window->geometry());
+
+#else // QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
+ : QWaylandQuickCompositor()
, m_shell(new QWaylandWlShell(this))
, m_surfExt(new QtWayland::SurfaceExtensionGlobal(this))
, m_textInputManager(new QWaylandTextInputManager(this))
+ , m_manager(manager)
{
setSocketName(waylandSocketName.toUtf8());
-
registerOutputWindow(window);
-#if QT_VERSION < QT_VERSION_CHECK(5, 8, 0)
+# if QT_VERSION < QT_VERSION_CHECK(5, 8, 0)
connect(this, &QWaylandCompositor::createSurface, this, &WaylandCompositor::doCreateSurface);
-#else
+# else
connect(this, &QWaylandCompositor::surfaceRequested, this, &WaylandCompositor::doCreateSurface);
-#endif
+# endif
connect(this, &QWaylandCompositor::surfaceCreated, [this](QWaylandSurface *s) {
connect(s, &QWaylandSurface::surfaceDestroyed, this, [this, s]() {
- m_manager->waylandSurfaceDestroyed(static_cast<Surface *>(s));
+ m_manager->waylandSurfaceDestroyed(static_cast<WindowSurface *>(s));
});
- m_manager->waylandSurfaceCreated(static_cast<Surface *>(s));
+ m_manager->waylandSurfaceCreated(static_cast<WindowSurface *>(s));
});
-#if QT_VERSION < QT_VERSION_CHECK(5, 8, 0)
+# if QT_VERSION < QT_VERSION_CHECK(5, 8, 0)
connect(m_shell, &QWaylandWlShell::createShellSurface, this, &WaylandCompositor::createShellSurface);
-#else
+# else
connect(m_shell, &QWaylandWlShell::wlShellSurfaceRequested, this, &WaylandCompositor::createShellSurface);
-#endif
+# endif
connect(m_surfExt, &QtWayland::SurfaceExtensionGlobal::extendedSurfaceReady, this, &WaylandCompositor::extendedSurfaceReady);
auto wmext = new QWaylandQtWindowManager(this);
@@ -185,56 +252,126 @@ WaylandCompositor::WaylandCompositor(QQuickWindow *window, const QString &waylan
});
create();
+#endif // QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
}
void WaylandCompositor::registerOutputWindow(QQuickWindow* window)
{
+#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
+ createOutput(window, QString(), QString());
+#else
auto output = new QWaylandQuickOutput(this, window);
output->setSizeFollowsWindow(true);
m_outputs.append(output);
-
+#endif
window->winId();
}
+QWaylandSurface *WaylandCompositor::waylandSurfaceFromItem(QQuickItem *surfaceItem) const
+{
+ // QWaylandQuickItem::surface() will return a nullptr to WindowManager::waylandSurfaceDestroyed,
+ // if the app crashed. We return our internal copy of that surface pointer instead.
+#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
+ if (QWaylandSurfaceItem *item = qobject_cast<QWaylandSurfaceItem *>(surfaceItem))
+ return item->surface();
+#else
+ if (WindowSurfaceQuickItem *item = qobject_cast<WindowSurfaceQuickItem *>(surfaceItem))
+ return item->m_windowSurface->surface();
+#endif
+ return nullptr;
+}
+
+#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+
void WaylandCompositor::doCreateSurface(QWaylandClient *client, uint id, int version)
{
- new Surface(this, client, id, version);
+ (void) new WindowSurface(this, client, id, version);
}
void WaylandCompositor::createShellSurface(QWaylandSurface *surface, const QWaylandResource &resource)
{
- Surface *s = static_cast<Surface *>(surface);
-
- qCDebug(LogWayland) << "createShellSurface" << s << "(PID:" << s->client()->processId() << ")";
- QWaylandWlShellSurface *ss = new QWaylandWlShellSurface(m_shell, s, resource);
- s->setShellSurface(ss);
+ WindowSurface *windowSurface = static_cast<WindowSurface *>(surface);
+ QWaylandWlShellSurface *ss = new QWaylandWlShellSurface(m_shell, windowSurface, resource);
+ windowSurface->setShellSurface(ss);
#if QT_VERSION < QT_VERSION_CHECK(5, 8, 0)
- connect(s, &QWaylandSurface::mappedChanged, this, [this, s]() {
- if (s->isMapped())
+ connect(windowSurface, &QWaylandSurface::mappedChanged, this, [this, windowSurface]() {
+ if (windowSurface->isMapped())
#else
- connect(s, &QWaylandSurface::hasContentChanged, this, [this, s]() {
- if (s->hasContent())
+ connect(windowSurface, &QWaylandSurface::hasContentChanged, this, [this, windowSurface]() {
+ if (windowSurface->hasContent())
#endif
- m_manager->waylandSurfaceMapped(s);
+ m_manager->waylandSurfaceMapped(windowSurface);
else
- m_manager->waylandSurfaceUnmapped(s);
+ m_manager->waylandSurfaceUnmapped(windowSurface);
});
}
void WaylandCompositor::extendedSurfaceReady(QtWayland::ExtendedSurface *ext, QWaylandSurface *surface)
{
- Surface *surf = static_cast<Surface *>(surface);
- surf->setExtendedSurface(ext);
+ WindowSurface *windowSurface = static_cast<WindowSurface *>(surface);
+ windowSurface->setExtendedSurface(ext);
}
-QWaylandSurface *WaylandCompositor::waylandSurfaceFromItem(QQuickItem *surfaceItem) const
+#else // if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+
+void WaylandCompositor::surfaceCreated(QWaylandSurface *surface)
{
- // QWaylandQuickItem::surface() will return a nullptr to WindowManager::waylandSurfaceDestroyed,
- // if the app crashed. We return our internal copy of that surface pointer instead.
- if (SurfaceQuickItem *item = qobject_cast<SurfaceQuickItem *>(surfaceItem))
- return item->m_surface->surface();
- return nullptr;
+ WindowSurface *windowSurface = new WindowSurface(surface);
+ m_manager->waylandSurfaceCreated(windowSurface);
+ QObject::connect(surface, &QWaylandSurface::mapped, [windowSurface, surface, this]() {
+ windowSurface->m_item = static_cast<QWaylandSurfaceItem *>(surface->views().at(0));
+ windowSurface->m_item->setResizeSurfaceToItem(true);
+ windowSurface->m_item->setTouchEventsEnabled(true);
+ m_manager->waylandSurfaceMapped(windowSurface);
+ });
+ QObject::connect(surface, &QWaylandSurface::unmapped, [windowSurface, this]() {
+ m_manager->waylandSurfaceUnmapped(windowSurface);
+ });
+ QObject::connect(surface, &QWaylandSurface::surfaceDestroyed, [windowSurface, this]() {
+ m_manager->waylandSurfaceDestroyed(windowSurface);
+ });
+
+}
+
+bool WaylandCompositor::openUrl(QWaylandClient *client, const QUrl &url)
+{
+ if (ApplicationManager::instance()->fromProcessId(client->processId()))
+ return ApplicationManager::instance()->openUrl(url.toString());
+ return false;
+}
+
+void WaylandCompositor::sendCallbacks()
+{
+ QList<QWaylandSurface *> listToSend;
+
+ // TODO: optimize! no need to send this to hidden/minimized/offscreen/etc. surfaces
+ foreach (const Window *win, m_manager->windows()) {
+ if (!win->isClosing() && !win->isInProcess()) {
+ if (QWaylandSurface *surface = waylandSurfaceFromItem(win->windowItem())) {
+ listToSend << surface;
+ }
+ }
+ }
+
+ if (!listToSend.isEmpty())
+ sendFrameCallbacks(listToSend);
+}
+
+const char *WaylandCompositor::socketName() const
+{
+ static QByteArray sn;
+ if (sn.isEmpty()) {
+ sn = QWaylandCompositor::socketName();
+ if (sn.isEmpty()) {
+ sn = qgetenv("WAYLAND_DISPLAY");
+ if (sn.isEmpty())
+ sn = "wayland-0";
+ }
+ }
+ return sn.constData();
}
+#endif // if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+
QT_END_NAMESPACE_AM
diff --git a/src/window-lib/waylandcompositor.h b/src/window-lib/waylandcompositor.h
index dbb59e5f..15f393d8 100644
--- a/src/window-lib/waylandcompositor.h
+++ b/src/window-lib/waylandcompositor.h
@@ -42,12 +42,13 @@
#pragma once
-#include <QWaylandQuickSurface>
-#include <QWaylandQuickItem>
#include <QWaylandQuickCompositor>
-
#include <QtAppManWindow/windowmanager.h>
+#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+# include <QWaylandQuickSurface>
+# include <QWaylandQuickItem>
+
QT_FORWARD_DECLARE_CLASS(QWaylandResource)
QT_FORWARD_DECLARE_CLASS(QWaylandWlShell)
QT_FORWARD_DECLARE_CLASS(QWaylandWlShellSurface)
@@ -59,72 +60,98 @@ class SurfaceExtensionGlobal;
}
QT_END_NAMESPACE
+#else // QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+# include <QtAppManWindow/windowmanager.h>
+
+QT_FORWARD_DECLARE_CLASS(QWaylandSurfaceItem)
+
+#endif // QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+
QT_BEGIN_NAMESPACE_AM
-class SurfaceQuickItem;
+class WindowSurfaceQuickItem;
-class Surface : public QWaylandQuickSurface, public WindowSurface
+// A WindowSurface object exists for every Wayland surface created in the Wayland server.
+// Not every WindowSurface maybe an application's Window though - those that are, are available
+// through the WindowManager model.
+
+#if QT_VERSION < QT_VERSION_CHECK(5, 7, 0)
+class WindowSurface : public QObject
{
Q_OBJECT
+public:
+ WindowSurface(QWaylandSurface *surface);
+
+private:
+ QWaylandSurfaceItem *m_item;
+#else
+class WindowSurface : public QWaylandQuickSurface
+{
+ Q_OBJECT
public:
- Surface(QWaylandCompositor *comp, QWaylandClient *client, uint id, int version);
+ WindowSurface(QWaylandCompositor *comp, QWaylandClient *client, uint id, int version);
+ QWaylandWlShellSurface *shellSurface() const;
+private:
void setShellSurface(QWaylandWlShellSurface *ss);
void setExtendedSurface(QtWayland::ExtendedSurface *e);
- QWaylandWlShellSurface *shellSurface() const;
- QtWayland::ExtendedSurface *extendedSurface() const;
+private:
+ WindowSurfaceQuickItem *m_item = nullptr;
+ QWaylandWlShellSurface *m_shellSurface = nullptr;
+ QtWayland::ExtendedSurface *m_extendedSurface = nullptr;
+#endif
- QQuickItem *item() const override;
+public:
+ QWaylandSurface *surface() const;
+ QQuickItem *item() const;
+ qint64 processId() const;
+ QWindow *outputWindow() const;
- void takeFocus() override;
- void ping() override;
- qint64 processId() const override;
- QWindow *outputWindow() const override;
+ void takeFocus();
+ void ping();
- QVariantMap windowProperties() const override;
- void setWindowProperty(const QString &n, const QVariant &v) override;
+ QVariantMap windowProperties() const;
+ void setWindowProperty(const QString &name, const QVariant &value);
- void connectPong(const std::function<void ()> &cb) override;
- void connectWindowPropertyChanged(const std::function<void (const QString &, const QVariant &)> &cb) override;
+signals:
+ void pong();
+ void windowPropertyChanged(const QString &name, const QVariant &value);
private:
- SurfaceQuickItem *m_item;
- QWaylandWlShellSurface *m_shellSurface;
- QtWayland::ExtendedSurface *m_ext;
-};
+ QWaylandSurface *m_surface;
-class SurfaceQuickItem : public QWaylandQuickItem
-{
- Q_OBJECT
-
-public:
- SurfaceQuickItem(Surface *s);
-
- void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
-
- Surface *m_surface;
+ friend class WaylandCompositor;
};
-
class WaylandCompositor : public QWaylandQuickCompositor
{
public:
WaylandCompositor(QQuickWindow* window, const QString &waylandSocketName, WindowManager *manager);
-
void registerOutputWindow(QQuickWindow *window);
+ QWaylandSurface *waylandSurfaceFromItem(QQuickItem *surfaceItem) const;
+
+protected:
+#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
void doCreateSurface(QWaylandClient *client, uint id, int version);
void createShellSurface(QWaylandSurface *surface, const QWaylandResource &resource);
void extendedSurfaceReady(QtWayland::ExtendedSurface *ext, QWaylandSurface *surface);
- QWaylandSurface *waylandSurfaceFromItem(QQuickItem *surfaceItem) const;
-private:
- WindowManager *m_manager;
QWaylandWlShell *m_shell;
QVector<QWaylandOutput *> m_outputs;
QtWayland::SurfaceExtensionGlobal *m_surfExt;
QWaylandTextInputManager *m_textInputManager;
+#else
+ void surfaceCreated(QWaylandSurface *surface) override;
+ bool openUrl(QWaylandClient *client, const QUrl &url) override;
+ void sendCallbacks();
+public:
+ const char *socketName() const; // we need to shadow the base class' version, since it is broken
+#endif // QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+
+private:
+ WindowManager *m_manager;
};
QT_END_NAMESPACE_AM
diff --git a/src/window-lib/waylandcompositor-old.h b/src/window-lib/waylandcompositor_p.h
index 84fce64b..90e5724a 100644
--- a/src/window-lib/waylandcompositor-old.h
+++ b/src/window-lib/waylandcompositor_p.h
@@ -42,59 +42,25 @@
#pragma once
-#include <QWaylandQuickCompositor>
+#include "global.h"
-#include <QtAppManWindow/windowmanager.h>
-
-QT_FORWARD_DECLARE_CLASS(QWaylandSurfaceItem)
+#if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+# include <QWaylandQuickItem>
QT_BEGIN_NAMESPACE_AM
-class SurfaceQuickItem;
+class WindowSurface;
-class Surface : public WindowSurface
+class WindowSurfaceQuickItem : public QWaylandQuickItem
{
-public:
- Surface(QWaylandSurface *s);
-
- QQuickItem *item() const override;
-
- void takeFocus() override;
- void ping() override;
- qint64 processId() const override;
- QWindow *outputWindow() const override;
-
- QVariantMap windowProperties() const override;
- void setWindowProperty(const QString &n, const QVariant &v) override;
+ Q_OBJECT
- void connectPong(const std::function<void ()> &cb) override;
- void connectWindowPropertyChanged(const std::function<void (const QString &, const QVariant &)> &cb) override;
-
- QWaylandSurfaceItem *m_item;
-};
-
-
-class WaylandCompositor : public QWaylandQuickCompositor
-{
public:
- WaylandCompositor(QQuickWindow *window, const QString &waylandSocketName, WindowManager *manager);
-
- void registerOutputWindow(QQuickWindow *window);
-
- void surfaceCreated(QWaylandSurface *surface) override;
-
-#if QT_VERSION < QT_VERSION_CHECK(5,5,0)
- bool openUrl(WaylandClient *client, const QUrl &url) override;
-#else
- bool openUrl(QWaylandClient *client, const QUrl &url) override;
-#endif
-
- QWaylandSurface *waylandSurfaceFromItem(QQuickItem *surfaceItem) const;
-
- void sendCallbacks();
-
-private:
- WindowManager *m_manager;
+ WindowSurfaceQuickItem(WindowSurface *windowSurface);
+ void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+ WindowSurface *m_windowSurface;
};
QT_END_NAMESPACE_AM
+
+#endif
diff --git a/src/window-lib/waylandwindow.cpp b/src/window-lib/waylandwindow.cpp
index f716a39d..a54c40b1 100644
--- a/src/window-lib/waylandwindow.cpp
+++ b/src/window-lib/waylandwindow.cpp
@@ -41,11 +41,12 @@
#if defined(AM_MULTI_PROCESS)
-#include "waylandwindow.h"
+#include "global.h"
#include "applicationmanager.h"
#include "application.h"
-#include "global.h"
#include "windowmanager.h"
+#include "waylandwindow.h"
+#include "waylandcompositor.h"
QT_BEGIN_NAMESPACE_AM
@@ -56,8 +57,10 @@ WaylandWindow::WaylandWindow(const Application *app, WindowSurface *surf)
, m_surface(surf)
{
if (surf && surf->item()) {
- surf->connectPong([this]() { pongReceived(); });
- surf->connectWindowPropertyChanged([this](const QString &n, const QVariant &v) { emit windowPropertyChanged(n, v); });
+ connect(surf, &WindowSurface::pong,
+ this, &WaylandWindow::pongReceived);
+ connect(surf, &WindowSurface::windowPropertyChanged,
+ this, &WaylandWindow::windowPropertyChanged);
m_pingTimer->setInterval(1000);
m_pingTimer->setSingleShot(true);
@@ -107,9 +110,8 @@ void WaylandWindow::pingTimeout()
{
m_pingTimer->stop();
m_pongTimer->start();
- if (m_surface) {
+ if (m_surface)
m_surface->ping();
- }
}
bool WaylandWindow::setWindowProperty(const QString &name, const QVariant &value)
@@ -117,9 +119,8 @@ bool WaylandWindow::setWindowProperty(const QString &name, const QVariant &value
if (m_surface) {
QVariant oldValue = m_surface->windowProperties().value(name);
- if (oldValue != value) {
+ if (oldValue != value)
m_surface->setWindowProperty(name, value);
- }
return true;
}
return false;
@@ -127,17 +128,15 @@ bool WaylandWindow::setWindowProperty(const QString &name, const QVariant &value
QVariant WaylandWindow::windowProperty(const QString &name) const
{
- if (m_surface) {
+ if (m_surface)
return m_surface->windowProperties().value(name);
- }
return QVariant();
}
QVariantMap WaylandWindow::windowProperties() const
{
- if (m_surface) {
+ if (m_surface)
return m_surface->windowProperties();
- }
return QVariantMap();
}
diff --git a/src/window-lib/window-lib.pro b/src/window-lib/window-lib.pro
index 3210b7c3..2ae95783 100644
--- a/src/window-lib/window-lib.pro
+++ b/src/window-lib/window-lib.pro
@@ -17,13 +17,13 @@ CONFIG *= static internal_module
multi-process:!headless {
qtHaveModule(waylandcompositor) {
QT *= waylandcompositor waylandcompositor-private
- HEADERS += waylandcompositor.h
+ HEADERS += waylandcompositor.h waylandcompositor_p.h
SOURCES += waylandcompositor.cpp
PKGCONFIG += wayland-server
} else:qtHaveModule(compositor) {
QT *= compositor
- HEADERS += waylandcompositor-old.h
- SOURCES += waylandcompositor-old.cpp
+ HEADERS += waylandcompositor.h
+ SOURCES += waylandcompositor.cpp
}
}
@@ -41,3 +41,4 @@ multi-process:!headless {
windowmanager.cpp \
load(qt_module)
+
diff --git a/src/window-lib/window.h b/src/window-lib/window.h
index b1147e38..fbcda864 100644
--- a/src/window-lib/window.h
+++ b/src/window-lib/window.h
@@ -52,6 +52,11 @@ QT_BEGIN_NAMESPACE_AM
class Application;
class WindowPrivate;
+// A Window object exists for every application window that is managed by the application-manager
+// and has been shown (mapped) at least once.
+// In the Wayland case, every Window is a surface, but not every surface is a Window. That's why
+// there is a separate WindowSurface class in waylandcompositor.h.
+
class Window : public QObject
{
Q_OBJECT
@@ -71,10 +76,6 @@ public:
virtual QVariant windowProperty(const QString &name) const = 0;
virtual QVariantMap windowProperties() const = 0;
- // we cannot directly derive from QObject here, so we have to fake connect/disconnect
- void connectWindowPropertyChanged(QObject *target, const char *member, Qt::ConnectionType type = Qt::AutoConnection);
- void disconnectWindowPropertyChanged(QObject *target, const char *member = 0);
-
signals:
void windowPropertyChanged(const QString &name, const QVariant &value);
diff --git a/src/window-lib/windowmanager.cpp b/src/window-lib/windowmanager.cpp
index cea0bf8c..eabf95af 100644
--- a/src/window-lib/windowmanager.cpp
+++ b/src/window-lib/windowmanager.cpp
@@ -53,11 +53,7 @@
#endif
#if defined(AM_MULTI_PROCESS)
-# if defined(QT_WAYLANDCOMPOSITOR_LIB)
-# include "waylandcompositor.h"
-# elif defined(QT_COMPOSITOR_LIB)
-# include "waylandcompositor-old.h"
-# endif
+# include "waylandcompositor.h"
#endif
#include "global.h"
diff --git a/src/window-lib/windowmanager.h b/src/window-lib/windowmanager.h
index 13999648..e5721d66 100644
--- a/src/window-lib/windowmanager.h
+++ b/src/window-lib/windowmanager.h
@@ -60,38 +60,12 @@ QT_FORWARD_DECLARE_CLASS(QWindow)
QT_BEGIN_NAMESPACE_AM
class Window;
+class WindowSurface;
class WindowManagerPrivate;
class Application;
class AbstractRuntime;
class WaylandCompositor;
-#if defined(AM_MULTI_PROCESS)
-
-class WindowSurface
-{
-public:
- virtual ~WindowSurface() {}
- QWaylandSurface *surface() const { return m_surface; }
-
- virtual QQuickItem *item() const = 0;
-
- virtual void takeFocus() = 0;
- virtual void ping() = 0;
- virtual qint64 processId() const = 0;
- virtual QWindow *outputWindow() const = 0;
-
- virtual QVariantMap windowProperties() const = 0;
- virtual void setWindowProperty(const QString &name, const QVariant &value) = 0;
-
- virtual void connectPong(const std::function<void ()> &cb) = 0;
- virtual void connectWindowPropertyChanged(const std::function<void (const QString &name, const QVariant &value)> &cb) = 0;
-
-protected:
- QWaylandSurface *m_surface;
-};
-
-#endif
-
class WindowManager : public QAbstractListModel, protected QDBusContext
{
Q_OBJECT