summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJørgen Lind <jorgen.lind@theqtcompany.com>2015-07-30 12:06:24 +0200
committerJørgen Lind <jorgen.lind@theqtcompany.com>2015-08-28 13:09:41 +0200
commitfcd376a4ffb4a2efc8352ce1777e9f869e4e5206 (patch)
treeab6959cf4d777549dca119d318240b9b724860ce
parent400c6d24c2ca3215cd38a30cd3eb530c3b2e970c (diff)
Introducing QWaylandOutputSpace
Its purpose is to make it possible to have multiscreen environments, and also multiple multioutput environments It is also an abstraction to make it clear that outputs are arranged in a 2d space Change-Id: I418509996a03b2ca1a12aec9c9e25e143a15a10f
-rw-r--r--examples/wayland/pure-qml/qml/main.qml2
-rw-r--r--examples/wayland/qml-compositor/main.cpp10
-rw-r--r--examples/wayland/qwindow-compositor/qwindowcompositor.cpp8
-rw-r--r--examples/wayland/server-buffer/compositor/main.cpp6
-rw-r--r--src/compositor/compositor_api/compositor_api.pri7
-rw-r--r--src/compositor/compositor_api/qwaylandcompositor.cpp78
-rw-r--r--src/compositor/compositor_api/qwaylandcompositor.h33
-rw-r--r--src/compositor/compositor_api/qwaylandinput.cpp10
-rw-r--r--src/compositor/compositor_api/qwaylandinput.h4
-rw-r--r--src/compositor/compositor_api/qwaylandoutput.cpp28
-rw-r--r--src/compositor/compositor_api/qwaylandoutput.h10
-rw-r--r--src/compositor/compositor_api/qwaylandoutputspace.cpp191
-rw-r--r--src/compositor/compositor_api/qwaylandoutputspace.h106
-rw-r--r--src/compositor/compositor_api/qwaylandoutputspace_p.h121
-rw-r--r--src/compositor/compositor_api/qwaylandquickcompositor.cpp5
-rw-r--r--src/compositor/compositor_api/qwaylandquickcompositor.h3
-rw-r--r--src/compositor/compositor_api/qwaylandquickoutput.cpp4
-rw-r--r--src/compositor/compositor_api/qwaylandquickoutput.h2
-rw-r--r--src/compositor/compositor_api/qwaylandsurface.cpp6
-rw-r--r--src/compositor/compositor_api/qwaylandsurface.h2
-rw-r--r--src/compositor/compositor_api/qwaylandsurfaceview.cpp15
-rw-r--r--src/compositor/compositor_api/qwaylandsurfaceview.h3
-rw-r--r--src/compositor/compositor_api/qwaylandsurfaceview_p.h6
-rw-r--r--src/compositor/wayland_wrapper/qwlcompositor.cpp59
-rw-r--r--src/compositor/wayland_wrapper/qwlcompositor_p.h11
-rw-r--r--src/compositor/wayland_wrapper/qwldatadevice.cpp7
-rw-r--r--src/compositor/wayland_wrapper/qwldatadevice_p.h3
-rw-r--r--src/compositor/wayland_wrapper/qwlinputdevice.cpp11
-rw-r--r--src/compositor/wayland_wrapper/qwlinputdevice_p.h4
-rw-r--r--src/compositor/wayland_wrapper/qwloutput.cpp42
-rw-r--r--src/compositor/wayland_wrapper/qwloutput_p.h17
-rw-r--r--src/compositor/wayland_wrapper/qwlshellsurface.cpp4
-rw-r--r--src/imports/compositor/qwaylandquickcompositorplugin.cpp2
33 files changed, 650 insertions, 170 deletions
diff --git a/examples/wayland/pure-qml/qml/main.qml b/examples/wayland/pure-qml/qml/main.qml
index 8030f8efe..391f683e3 100644
--- a/examples/wayland/pure-qml/qml/main.qml
+++ b/examples/wayland/pure-qml/qml/main.qml
@@ -62,7 +62,7 @@ WaylandCompositor {
function addScreen() {
var screen = screenComponent.createObject(0, { "compositor" : compositor } );
- var output = compositor.addOutput(screen);
+ var output = compositor.primaryOutputSpace.addOutputWindow(screen);
output.automaticFrameCallbacks = true;
}
diff --git a/examples/wayland/qml-compositor/main.cpp b/examples/wayland/qml-compositor/main.cpp
index 489fac6e8..4cd1e791d 100644
--- a/examples/wayland/qml-compositor/main.cpp
+++ b/examples/wayland/qml-compositor/main.cpp
@@ -44,6 +44,7 @@
#include <QtCompositor/qwaylandsurfaceitem.h>
#include <QtCompositor/qwaylandoutput.h>
+#include <QtCompositor/qwaylandoutputspace.h>
#include <QGuiApplication>
#include <QTimer>
@@ -63,6 +64,7 @@ class QmlCompositor : public QQuickView
public:
QmlCompositor()
: m_fullscreenSurface(0)
+ , m_output(0)
{
m_compositor.setExtensionFlags(QWaylandCompositor::DefaultExtensions | QWaylandCompositor::SubSurfaceExtension);
m_compositor.create();
@@ -72,7 +74,7 @@ public:
setColor(Qt::black);
winId();
m_compositor.addDefaultShell();
- m_compositor.createOutput(this, "", "");
+ m_output = m_compositor.primaryOutputSpace()->addOutputWindow(this, "", "");
connect(this, SIGNAL(afterRendering()), this, SLOT(sendCallbacks()));
connect(&m_compositor, &QWaylandCompositor::surfaceCreated, this, &QmlCompositor::onSurfaceCreated);
@@ -124,9 +126,10 @@ private slots:
void sendCallbacks() {
if (m_fullscreenSurface)
- m_compositor.sendFrameCallbacks(QList<QWaylandSurface *>() << m_fullscreenSurface);
+ m_fullscreenSurface->sendFrameCallbacks();
+
else
- m_compositor.sendFrameCallbacks(m_compositor.surfaces());
+ m_output->sendFrameCallbacks();
}
void onSurfaceCreated(QWaylandSurface *surface) {
@@ -151,6 +154,7 @@ protected:
private:
QWaylandQuickCompositor m_compositor;
QWaylandQuickSurface *m_fullscreenSurface;
+ QWaylandOutput *m_output;
};
int main(int argc, char *argv[])
diff --git a/examples/wayland/qwindow-compositor/qwindowcompositor.cpp b/examples/wayland/qwindow-compositor/qwindowcompositor.cpp
index 5e7c8136c..50d24cffc 100644
--- a/examples/wayland/qwindow-compositor/qwindowcompositor.cpp
+++ b/examples/wayland/qwindow-compositor/qwindowcompositor.cpp
@@ -57,6 +57,7 @@
#include <QtCompositor/qwaylandbufferref.h>
#include <QtCompositor/qwaylandsurfaceview.h>
#include <QtCompositor/qwaylandoutput.h>
+#include <QtCompositor/qwaylandoutputspace.h>
QT_BEGIN_NAMESPACE
@@ -122,7 +123,8 @@ QWindowCompositor::QWindowCompositor(CompositorWindow *window)
setRetainedSelectionEnabled(true);
- createOutput(window, "", "");
+ primaryOutputSpace()->addOutputWindow(window, "", "");
+
addDefaultShell();
}
@@ -303,7 +305,7 @@ QWaylandSurfaceView *QWindowCompositor::viewAt(const QPointF &point, QPointF *lo
void QWindowCompositor::render()
{
m_window->makeCurrent();
- frameStarted();
+ primaryOutput()->frameStarted();
cleanupGraphicsResources();
@@ -324,7 +326,7 @@ void QWindowCompositor::render()
}
m_textureBlitter->release();
- sendFrameCallbacks(surfaces());
+ primaryOutput()->sendFrameCallbacks();
// N.B. Never call glFinish() here as the busylooping with vsync 'feature' of the nvidia binary driver is not desirable.
m_window->swapBuffers();
diff --git a/examples/wayland/server-buffer/compositor/main.cpp b/examples/wayland/server-buffer/compositor/main.cpp
index 50fc9d390..b34db1630 100644
--- a/examples/wayland/server-buffer/compositor/main.cpp
+++ b/examples/wayland/server-buffer/compositor/main.cpp
@@ -42,6 +42,7 @@
#include "qwaylandquickcompositor.h"
#include "qwaylandsurface.h"
#include "qwaylandsurfaceitem.h"
+#include "qwaylandoutputspace.h"
#include <QGuiApplication>
#include <QTimer>
@@ -83,7 +84,7 @@ public:
m_view.setResizeMode(QQuickView::SizeRootObjectToView);
m_view.setColor(Qt::black);
m_view.create();
- createOutput(&m_view, "", "");
+ m_output = primaryOutputSpace()->addOutputWindow(&m_view, "", "");
addDefaultShell();
connect(&m_view, &QQuickView::afterRendering, this, &QmlCompositor::sendCallbacks);
@@ -131,7 +132,7 @@ private slots:
}
void sendCallbacks() {
- sendFrameCallbacks(surfaces());
+ m_output->sendFrameCallbacks();
}
void initiateServerBuffer()
@@ -237,6 +238,7 @@ protected:
private:
QQuickView m_view;
+ QWaylandOutput *m_output;
QtWayland::ServerBuffer *m_server_buffer_32_bit;
ServerBufferItem *m_server_buffer_item_32_bit;
QtWayland::ServerBuffer *m_server_buffer_8_bit;
diff --git a/src/compositor/compositor_api/compositor_api.pri b/src/compositor/compositor_api/compositor_api.pri
index b134b5ef4..656f2e0c5 100644
--- a/src/compositor/compositor_api/compositor_api.pri
+++ b/src/compositor/compositor_api/compositor_api.pri
@@ -13,7 +13,9 @@ HEADERS += \
compositor_api/qwaylandsurfaceview.h \
compositor_api/qwaylandsurfaceview_p.h \
compositor_api/qwaylandglobalinterface.h \
- compositor_api/qwaylandsurfaceinterface.h
+ compositor_api/qwaylandsurfaceinterface.h \
+ compositor_api/qwaylandoutputspace.h \
+ compositor_api/qwaylandoutputspace_p.h
SOURCES += \
compositor_api/qwaylandcompositor.cpp \
@@ -26,7 +28,8 @@ SOURCES += \
compositor_api/qwaylandbufferref.cpp \
compositor_api/qwaylandsurfaceview.cpp \
compositor_api/qwaylandglobalinterface.cpp \
- compositor_api/qwaylandsurfaceinterface.cpp
+ compositor_api/qwaylandsurfaceinterface.cpp \
+ compositor_api/qwaylandoutputspace.cpp
QT += core-private
diff --git a/src/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp
index bcb373761..0c7342329 100644
--- a/src/compositor/compositor_api/qwaylandcompositor.cpp
+++ b/src/compositor/compositor_api/qwaylandcompositor.cpp
@@ -137,53 +137,57 @@ void QWaylandCompositor::destroyClient(QWaylandClient *client)
m_compositor->destroyClient(client);
}
-#if QT_DEPRECATED_SINCE(5, 5)
-void QWaylandCompositor::frameStarted()
+QList<QWaylandSurface *> QWaylandCompositor::surfacesForClient(QWaylandClient* client) const
{
- foreach (QWaylandOutput *output, outputs())
- output->frameStarted();
+ QList<QWaylandSurface *> surfs;
+ foreach (QWaylandSurface *surface, m_compositor->m_all_surfaces) {
+ if (surface->client() == client)
+ surfs.append(surface);
+ }
+ return surfs;
}
-void QWaylandCompositor::sendFrameCallbacks(QList<QWaylandSurface *> visibleSurfaces)
+QList<QWaylandSurface *> QWaylandCompositor::surfaces() const
{
- Q_FOREACH (QWaylandSurface *surface, visibleSurfaces) {
- surface->handle()->sendFrameCallback();
- }
+ return m_compositor->m_all_surfaces;
}
-QList<QWaylandSurface *> QWaylandCompositor::surfacesForClient(QWaylandClient* client) const
+QWaylandOutput *QWaylandCompositor::output(QWindow *window) const
{
- QList<QWaylandSurface *> surfs;
- foreach (QWaylandOutput *output, outputs())
- surfs.append(output->surfacesForClient(client));
- return surfs;
+ return m_compositor->output(window);
}
-#endif //QT_DEPRECATED_SINCE(5, 5)
+QWaylandOutput *QWaylandCompositor::primaryOutput() const
+{
+ return m_compositor->primaryOutput();
+}
-QList<QWaylandSurface *> QWaylandCompositor::surfaces() const
+QWaylandOutputSpace *QWaylandCompositor::primaryOutputSpace() const
{
- return m_compositor->m_all_surfaces;
+ return m_compositor->primaryOutputSpace();
}
-QList<QWaylandOutput *> QWaylandCompositor::outputs() const
+void QWaylandCompositor::setPrimaryOutputSpace(QWaylandOutputSpace *outputSpace)
{
- return m_compositor->outputs();
+ m_compositor->setPrimaryOutputSpace(outputSpace);
}
-QWaylandOutput *QWaylandCompositor::output(QWindow *window)
+void QWaylandCompositor::addOutputSpace(QWaylandOutputSpace *outputSpace)
{
- return m_compositor->output(window);
+ m_compositor->addOutputSpace(outputSpace);
}
-QWaylandOutput *QWaylandCompositor::primaryOutput() const
+void QWaylandCompositor::removeOutputSpace(QWaylandOutputSpace *outputSpace)
{
- return m_compositor->primaryOutput();
+ m_compositor->removeOutputSpace(outputSpace);
}
-void QWaylandCompositor::setPrimaryOutput(QWaylandOutput *output)
+QWaylandOutput *QWaylandCompositor::createOutput(QWaylandOutputSpace *outputSpace,
+ QWindow *window,
+ const QString &manufacturer,
+ const QString &model)
{
- m_compositor->setPrimaryOutput(output);
+ return new QWaylandOutput(outputSpace, window, manufacturer, model);
}
QWaylandSurface *QWaylandCompositor::createSurface(QWaylandClient *client, quint32 id, int version)
@@ -201,25 +205,6 @@ QWaylandSurfaceView *QWaylandCompositor::createView()
return new QWaylandSurfaceView();
}
-#if QT_DEPRECATED_SINCE(5, 5)
-QWaylandSurfaceView *QWaylandCompositor::pickView(const QPointF &globalPosition) const
-{
- Q_FOREACH (QWaylandOutput *output, outputs()) {
- // Skip coordinates not in output
- if (!QRectF(output->geometry()).contains(globalPosition))
- continue;
- output->pickView(globalPosition);
- }
-
- return Q_NULLPTR;
-}
-
-QPointF QWaylandCompositor::mapToView(QWaylandSurfaceView *surface, const QPointF &globalPosition) const
-{
- return globalPosition - surface->requestedPosition();
-}
-#endif //QT_DEPRECATED_SINCE(5, 5)
-
/*!
Override this to handle QDesktopServices::openUrl() requests from the clients.
@@ -379,11 +364,4 @@ QWaylandInputDevice *QWaylandCompositor::inputDeviceFor(QInputEvent *inputEvent)
return m_compositor->inputDeviceFor(inputEvent);
}
-QWaylandOutput *QWaylandCompositor::createOutput(QWindow *window,
- const QString &manufacturer,
- const QString &model)
-{
- return new QWaylandOutput(this, window, manufacturer, model);
-}
-
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandcompositor.h b/src/compositor/compositor_api/qwaylandcompositor.h
index dd1ce0abd..462f381c6 100644
--- a/src/compositor/compositor_api/qwaylandcompositor.h
+++ b/src/compositor/compositor_api/qwaylandcompositor.h
@@ -60,6 +60,7 @@ class QWaylandDrag;
class QWaylandGlobalInterface;
class QWaylandSurfaceView;
class QWaylandOutput;
+class QWaylandOutputSpace;
namespace QtWayland
{
@@ -72,7 +73,8 @@ class Q_COMPOSITOR_EXPORT QWaylandCompositor : public QObject
Q_PROPERTY(QByteArray socketName READ socketName WRITE setSocketName)
Q_PROPERTY(QWaylandCompositor::ExtensionFlags extensionFlags READ extensionFlags WRITE setExtensionFlags)
Q_PROPERTY(bool retainedSelection READ retainedSelectionEnabled WRITE setRetainedSelectionEnabled)
- Q_PROPERTY(QWaylandOutput *primaryOutput READ primaryOutput WRITE setPrimaryOutput NOTIFY primaryOutputChanged)
+ Q_PROPERTY(QWaylandOutputSpace *primaryOutputSpace READ primaryOutputSpace WRITE setPrimaryOutputSpace NOTIFY primaryOutputSpaceChanged)
+ Q_PROPERTY(QWaylandOutput *primaryOutput READ primaryOutput NOTIFY primaryOutputChanged);
public:
enum ExtensionFlag {
@@ -108,25 +110,16 @@ public:
Q_INVOKABLE void destroyClientForSurface(QWaylandSurface *surface);
Q_INVOKABLE void destroyClient(QWaylandClient *client);
-#if QT_DEPRECATED_SINCE(5, 5)
- QT_DEPRECATED void frameStarted();
- QT_DEPRECATED void sendFrameCallbacks(QList<QWaylandSurface *> visibleSurfaces);
-
- QT_DEPRECATED QList<QWaylandSurface *> surfacesForClient(QWaylandClient* client) const;
-#endif //QT_DEPRECATED_SINCE(5, 5)
-
- QT_DEPRECATED QList<QWaylandSurface *> surfaces() const;
+ QList<QWaylandSurface *> surfaces() const;
+ QList<QWaylandSurface *> surfacesForClient(QWaylandClient* client) const;
- Q_INVOKABLE QList<QWaylandOutput *> outputs() const;
- Q_INVOKABLE QWaylandOutput *output(QWindow *window);
+ QWaylandOutput *output(QWindow *window) const;
QWaylandOutput *primaryOutput() const;
- void setPrimaryOutput(QWaylandOutput *output);
-
-#if QT_DEPRECATED_SINCE(5, 5)
- Q_INVOKABLE virtual QWaylandSurfaceView *pickView(const QPointF &globalPosition) const;
- Q_INVOKABLE virtual QPointF mapToView(QWaylandSurfaceView *view, const QPointF &surfacePosition) const;
-#endif // QT_DEPRECATED_SINCE(5 5)
+ QWaylandOutputSpace *primaryOutputSpace() const;
+ void setPrimaryOutputSpace(QWaylandOutputSpace *outputSpace);
+ void addOutputSpace(QWaylandOutputSpace *outputSpace);
+ void removeOutputSpace(QWaylandOutputSpace *outputSpace);
virtual bool openUrl(QWaylandClient *client, const QUrl &url);
@@ -179,18 +172,22 @@ signals:
void currentCurserSurfaceRequest(QWaylandSurface *surface, int hotspotX, int hotspotY);
+ void primaryOutputSpaceChanged();
void primaryOutputChanged();
+ void outputSpacesChanged();
protected:
QWaylandCompositor(QtWayland::Compositor *dptr);
virtual void retainedSelectionReceived(QMimeData *mimeData);
- virtual QWaylandOutput *createOutput(QWindow *window,
+ virtual QWaylandOutput *createOutput(QWaylandOutputSpace *outputSpace,
+ QWindow *window,
const QString &manufacturer,
const QString &model);
virtual QWaylandSurface *createSurface(QWaylandClient *client, quint32 id, int version);
virtual QWaylandSurfaceView *createView();
friend class QtWayland::Compositor;
+ friend class QWaylandOutputSpacePrivate;
QtWayland::Compositor *m_compositor;
};
diff --git a/src/compositor/compositor_api/qwaylandinput.cpp b/src/compositor/compositor_api/qwaylandinput.cpp
index 305cbc2e5..34d4ac8ba 100644
--- a/src/compositor/compositor_api/qwaylandinput.cpp
+++ b/src/compositor/compositor_api/qwaylandinput.cpp
@@ -174,6 +174,16 @@ void QWaylandInputDevice::setMouseFocus(QWaylandSurfaceView *surface, const QPoi
d->setMouseFocus(surface,localPos,globalPos);
}
+QWaylandOutputSpace *QWaylandInputDevice::outputSpace() const
+{
+ return d->outputSpace();
+}
+
+void QWaylandInputDevice::setOutputSpace(QWaylandOutputSpace *outputSpace)
+{
+ d->setOutputSpace(outputSpace);
+}
+
QWaylandCompositor *QWaylandInputDevice::compositor() const
{
return d->compositor()->waylandCompositor();
diff --git a/src/compositor/compositor_api/qwaylandinput.h b/src/compositor/compositor_api/qwaylandinput.h
index a6e295929..013f6d789 100644
--- a/src/compositor/compositor_api/qwaylandinput.h
+++ b/src/compositor/compositor_api/qwaylandinput.h
@@ -51,6 +51,7 @@ class QKeyEvent;
class QTouchEvent;
class QWaylandSurfaceView;
class QInputEvent;
+class QWaylandOutputSpace;
namespace QtWayland {
class InputDevice;
@@ -119,6 +120,9 @@ public:
QWaylandSurfaceView *mouseFocus() const;
void setMouseFocus(QWaylandSurfaceView *surface, const QPointF &local_pos, const QPointF &global_pos = QPointF());
+ QWaylandOutputSpace *outputSpace() const;
+ void setOutputSpace(QWaylandOutputSpace *outputSpace);
+
QWaylandCompositor *compositor() const;
QtWayland::InputDevice *handle() const;
diff --git a/src/compositor/compositor_api/qwaylandoutput.cpp b/src/compositor/compositor_api/qwaylandoutput.cpp
index dffda876e..d94f38878 100644
--- a/src/compositor/compositor_api/qwaylandoutput.cpp
+++ b/src/compositor/compositor_api/qwaylandoutput.cpp
@@ -51,15 +51,13 @@
QT_BEGIN_NAMESPACE
-QWaylandOutput::QWaylandOutput(QWaylandCompositor *compositor, QWindow *window,
+QWaylandOutput::QWaylandOutput(QWaylandOutputSpace *outputSpace, QWindow *window,
const QString &manufacturer, const QString &model)
: QObject()
- , d_ptr(new QtWayland::Output(compositor->handle(), window))
+ , d_ptr(new QtWayland::Output(this, outputSpace, window))
{
- d_ptr->m_output = this;
d_ptr->setManufacturer(manufacturer);
d_ptr->setModel(model);
- d_ptr->compositor()->addOutput(this);
QObject::connect(window, &QWindow::widthChanged, this, &QWaylandOutput::setWidth);
QObject::connect(window, &QWindow::heightChanged, this, &QWaylandOutput::setHeight);
QObject::connect(window, &QObject::destroyed, this, &QWaylandOutput::windowDestroyed);
@@ -67,7 +65,7 @@ QWaylandOutput::QWaylandOutput(QWaylandCompositor *compositor, QWindow *window,
QWaylandOutput::~QWaylandOutput()
{
- d_ptr->compositor()->removeOutput(this);
+ d_ptr->outputSpace()->removeOutput(this);
}
QWaylandOutput *QWaylandOutput::fromResource(wl_resource *resource)
@@ -81,7 +79,18 @@ QWaylandOutput *QWaylandOutput::fromResource(wl_resource *resource)
if (!output)
return Q_NULLPTR;
- return output->output();
+ return output->waylandOutput();
+}
+
+void QWaylandOutput::setOutputSpace(QWaylandOutputSpace *outputSpace)
+{
+ Q_ASSERT(outputSpace);
+ d_ptr->setOutputSpace(outputSpace, true);
+}
+
+QWaylandOutputSpace *QWaylandOutput::outputSpace() const
+{
+ return d_ptr->outputSpace();
}
void QWaylandOutput::update()
@@ -94,7 +103,7 @@ void QWaylandOutput::update()
QWaylandCompositor *QWaylandOutput::compositor() const
{
- return d_ptr->compositor()->waylandCompositor();
+ return d_ptr->outputSpace()->compositor();
}
QString QWaylandOutput::manufacturer() const
@@ -263,11 +272,6 @@ void QWaylandOutput::sendFrameCallbacks()
d_ptr->sendFrameCallbacks();
}
-QList<QWaylandSurface *> QWaylandOutput::surfacesForClient(QWaylandClient *client) const
-{
- return d_ptr->surfacesForClient(client);
-}
-
QtWayland::Output *QWaylandOutput::handle() const
{
return d_ptr.data();
diff --git a/src/compositor/compositor_api/qwaylandoutput.h b/src/compositor/compositor_api/qwaylandoutput.h
index bc92fe5a4..c602bf223 100644
--- a/src/compositor/compositor_api/qwaylandoutput.h
+++ b/src/compositor/compositor_api/qwaylandoutput.h
@@ -53,6 +53,7 @@ class QWindow;
class QWaylandSurface;
class QWaylandSurfaceView;
class QWaylandClient;
+class QWaylandOutputSpace;
namespace QtWayland {
class Output;
@@ -74,6 +75,7 @@ class Q_COMPOSITOR_EXPORT QWaylandOutput : public QObject
Q_PROPERTY(QWaylandCompositor *compositor READ compositor CONSTANT)
Q_PROPERTY(QWindow *window READ window CONSTANT)
Q_PROPERTY(bool sizeFollowsWindow READ sizeFollowsWindow WRITE setSizeFollowsWindow NOTIFY sizeFollowsWindowChanged)
+ Q_PROPERTY(QWaylandOutputSpace *outputSpace READ outputSpace WRITE setOutputSpace NOTIFY outputSpaceChanged)
Q_ENUMS(Subpixel Transform)
public:
@@ -103,12 +105,15 @@ public:
int refreshRate;
};
- QWaylandOutput(QWaylandCompositor *compositor, QWindow *window,
+ QWaylandOutput(QWaylandOutputSpace *outputSpace, QWindow *window,
const QString &manufacturer, const QString &model);
~QWaylandOutput();
static QWaylandOutput *fromResource(wl_resource *resource);
+ void setOutputSpace(QWaylandOutputSpace *outputSpace);
+ QWaylandOutputSpace *outputSpace() const;
+
virtual void update();
QWaylandCompositor *compositor() const;
@@ -154,8 +159,6 @@ public:
void frameStarted();
void sendFrameCallbacks();
- QList<QWaylandSurface *> surfacesForClient(QWaylandClient *client) const;
-
QtWayland::Output *handle() const;
Q_INVOKABLE virtual QWaylandSurfaceView *pickView(const QPointF &outputPosition) const;
@@ -172,6 +175,7 @@ Q_SIGNALS:
void transformChanged();
void sizeFollowsWindowChanged();
void physicalSizeFollowsSizeChanged();
+ void outputSpaceChanged();
protected:
QScopedPointer<QtWayland::Output> d_ptr;
diff --git a/src/compositor/compositor_api/qwaylandoutputspace.cpp b/src/compositor/compositor_api/qwaylandoutputspace.cpp
new file mode 100644
index 000000000..3f78158d0
--- /dev/null
+++ b/src/compositor/compositor_api/qwaylandoutputspace.cpp
@@ -0,0 +1,191 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandoutputspace.h"
+#include "qwaylandoutputspace_p.h"
+#include "qwaylandcompositor.h"
+#include <QtCompositor/QWaylandSurfaceView>
+#include <QtCompositor/QWaylandOutput>
+
+QT_BEGIN_NAMESPACE
+
+QWaylandOutputSpace::QWaylandOutputSpace(QWaylandCompositor *compositor)
+ : QObject(*new QWaylandOutputSpacePrivate(compositor), compositor)
+{
+
+}
+
+QWaylandCompositor *QWaylandOutputSpace::compositor() const
+{
+ Q_D(const QWaylandOutputSpace);
+ return d->compositor;
+}
+
+QRect QWaylandOutputSpace::geometry() const
+{
+ Q_D(const QWaylandOutputSpace);
+ return d->geometry;
+}
+
+void QWaylandOutputSpace::setGeometry(const QRect &geometry)
+{
+ Q_D(QWaylandOutputSpace);
+ if (d->geometry == geometry || d->geometryConstraint == QWaylandOutputSpace::AutomaticBoundingRect)
+ return;
+ d->geometry = geometry;
+ emit geometryChanged();
+}
+
+void QWaylandOutputSpace::setGeometryConstraint(QWaylandOutputSpace::GeometryConstraint geometryConstraint)
+{
+ Q_D(QWaylandOutputSpace);
+ if (d->geometryConstraint == geometryConstraint)
+ return;
+ d->geometryConstraint = geometryConstraint;
+ emit geometryConstraintChanged();
+}
+
+QWaylandOutputSpace::GeometryConstraint QWaylandOutputSpace::geometryConstraint() const
+{
+ Q_D(const QWaylandOutputSpace);
+ return d->geometryConstraint;
+}
+
+QWaylandOutput *QWaylandOutputSpace::addOutputWindow(QWindow *outputWindow,
+ const QString &manufacturer,
+ const QString &model)
+{
+ Q_D(QWaylandOutputSpace);
+ return d->createAndAddOutput(outputWindow, manufacturer, model, false);
+}
+
+QWaylandOutput *QWaylandOutputSpace::addPrimaryOutputWindow(QWindow *outputWindow,
+ const QString &manufacturer,
+ const QString &model)
+{
+ Q_D(QWaylandOutputSpace);
+ return d->createAndAddOutput(outputWindow, manufacturer, model, true);
+}
+
+void QWaylandOutputSpace::addOutput(QWaylandOutput *output)
+{
+ Q_D(QWaylandOutputSpace);
+ d->addOutput(output, false);
+}
+
+void QWaylandOutputSpace::addPrimaryOutput(QWaylandOutput *output)
+{
+ Q_D(QWaylandOutputSpace);
+ d->addOutput(output, true);
+}
+
+void QWaylandOutputSpace::removeOutput(QWaylandOutput *output)
+{
+ Q_ASSERT(output);
+ Q_D(QWaylandOutputSpace);
+ if ( d->outputs.removeOne(output)) {
+ output->setOutputSpace(Q_NULLPTR);
+ d->adjustGeometry();
+ outputsChanged();
+ }
+}
+
+void QWaylandOutputSpace::setPrimaryOutput(QWaylandOutput *output)
+{
+ Q_D(QWaylandOutputSpace);
+ if (d->outputs.isEmpty() || d->outputs.first() == output)
+ return;
+
+ if (d->outputs.removeOne(output)) {
+ d->outputs.prepend(output);
+ primaryOutputChanged();
+ }
+}
+
+QWaylandOutput *QWaylandOutputSpace::output(QWindow *window) const
+{
+ Q_D(const QWaylandOutputSpace);
+ foreach (QWaylandOutput *output, d->outputs) {
+ if (output->window() == window)
+ return output;
+ }
+ return Q_NULLPTR;
+}
+
+QWaylandOutput *QWaylandOutputSpace::primaryOutput() const
+{
+ Q_D(const QWaylandOutputSpace);
+ if (d->outputs.isEmpty())
+ return Q_NULLPTR;
+
+ return d->outputs.first();
+}
+
+QList<QWaylandOutput *>QWaylandOutputSpace::outputs() const
+{
+ Q_D(const QWaylandOutputSpace);
+ return d->outputs;
+}
+
+QList<QWaylandOutput *>QWaylandOutputSpace::outputs(const QPoint &point) const
+{
+ Q_D(const QWaylandOutputSpace);
+ QList<QWaylandOutput *> retOutputs;
+ foreach (QWaylandOutput *output, d->outputs) {
+ if (output->geometry().contains(point))
+ retOutputs.append(output);
+ }
+ return retOutputs;
+}
+
+QWaylandSurfaceView *QWaylandOutputSpace::pickView(const QPointF &globalPosition) const
+{
+ Q_D(const QWaylandOutputSpace);
+ foreach (QWaylandOutput *output, d->outputs) {
+ if (!QRectF(output->geometry()).contains(globalPosition))
+ continue;
+ output->pickView(globalPosition);
+ }
+
+ return 0;
+}
+
+QPointF QWaylandOutputSpace::mapToView(QWaylandSurfaceView *view, const QPointF &globalPosition) const
+{
+ return globalPosition - (view->requestedPosition() + view->output()->geometry().topLeft());
+}
+
+QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandoutputspace.h b/src/compositor/compositor_api/qwaylandoutputspace.h
new file mode 100644
index 000000000..d8c40cf0c
--- /dev/null
+++ b/src/compositor/compositor_api/qwaylandoutputspace.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDOUTPUTSPACE_H
+#define QWAYLANDOUTPUTSPACE_H
+
+#include <QtCore/QObject>
+
+#include "qwaylandoutput.h"
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandOutputSpacePrivate;
+
+class Q_COMPOSITOR_EXPORT QWaylandOutputSpace : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QWaylandOutputSpace)
+
+ Q_ENUMS(GeometryConstraint)
+ Q_PROPERTY(GeometryConstraint geometryConstraint READ geometryConstraint WRITE setGeometryConstraint NOTIFY geometryConstraintChanged)
+ Q_PROPERTY(QRect geometry READ geometry WRITE setGeometry NOTIFY geometryChanged)
+ Q_PROPERTY(QWaylandOutput *primaryOutput READ primaryOutput WRITE setPrimaryOutput NOTIFY primaryOutputChanged)
+ Q_PROPERTY(QList<QWaylandOutput *> outputs READ outputs NOTIFY outputsChanged)
+public:
+ enum GeometryConstraint {
+ AutomaticBoundingRect,
+ FixedSize
+ };
+
+ QWaylandOutputSpace(QWaylandCompositor *compositor);
+
+ QWaylandCompositor *compositor() const;
+
+ QRect geometry() const;
+ void setGeometry(const QRect &geometry);
+
+ void setGeometryConstraint(GeometryConstraint geometryConstraint);
+ GeometryConstraint geometryConstraint() const;
+
+ Q_INVOKABLE QWaylandOutput *addOutputWindow(QWindow *outputWindow, const QString &manufacturer, const QString &model);
+ Q_INVOKABLE QWaylandOutput *addPrimaryOutputWindow(QWindow *outputWindow, const QString &manufacturer, const QString &model);
+ Q_INVOKABLE void addOutput(QWaylandOutput *output);
+ Q_INVOKABLE void addPrimaryOutput(QWaylandOutput *output);
+ Q_INVOKABLE void removeOutput(QWaylandOutput *output);
+
+ Q_INVOKABLE QWaylandOutput *output(QWindow *window) const;
+
+ QWaylandOutput *primaryOutput() const;
+ void setPrimaryOutput(QWaylandOutput *output);
+
+ Q_INVOKABLE QList<QWaylandOutput *>outputs() const;
+ Q_INVOKABLE QList<QWaylandOutput *>outputs(const QPoint &point) const;
+
+ Q_INVOKABLE QWaylandSurfaceView *pickView(const QPointF &globalPosition) const;
+ Q_INVOKABLE QPointF mapToView(QWaylandSurfaceView *view, const QPointF &surfacePosition) const;
+
+signals:
+ void surfaceRequestedPositionChanged(QWaylandSurface *surface, const QPointF &point);
+
+ void geometryConstraintChanged();
+ void geometryChanged();
+
+ void outputsChanged();
+ void primaryOutputChanged();
+
+private:
+ Q_DISABLE_COPY(QWaylandOutputSpace)
+};
+
+QT_END_NAMESPACE
+
+#endif /*QWAYLANDOUTPUTSPACE_H*/
diff --git a/src/compositor/compositor_api/qwaylandoutputspace_p.h b/src/compositor/compositor_api/qwaylandoutputspace_p.h
new file mode 100644
index 000000000..b0f33efbd
--- /dev/null
+++ b/src/compositor/compositor_api/qwaylandoutputspace_p.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDOUTPUTSPACE_P_H
+#define QWAYLANDOUTPUTSPACE_P_H
+
+#include <QtCore/private/qobject_p.h>
+
+#include "qwaylandoutputspace.h"
+#include "qwaylandcompositor.h"
+#include "wayland_wrapper/qwloutput_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandOutputSpacePrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QWaylandOutputSpace)
+
+public:
+ QWaylandOutputSpacePrivate(QWaylandCompositor *compositor)
+ : QObjectPrivate()
+ , compositor(compositor)
+ , geometryConstraint(QWaylandOutputSpace::AutomaticBoundingRect)
+ {
+
+ }
+
+ void emitSurfacePositionChanged(QWaylandSurface *surface, const QPointF &point)
+ {
+ Q_Q(QWaylandOutputSpace);
+ q->surfaceRequestedPositionChanged(surface, point);
+ }
+
+ void adjustGeometry()
+ {
+ if (geometryConstraint != QWaylandOutputSpace::AutomaticBoundingRect)
+ return;
+
+ QRect completeRect;
+ foreach(QWaylandOutput *output, outputs) {
+ if (completeRect.isNull())
+ completeRect = output->geometry();
+ else
+ completeRect = completeRect.united(output->geometry());
+ }
+ geometry = completeRect;
+ }
+
+ QWaylandOutput *createAndAddOutput(QWindow *window,
+ const QString &manufacturer,
+ const QString &model,
+ bool primary)
+ {
+ Q_Q(QWaylandOutputSpace);
+ QWaylandOutput *output = compositor->createOutput(q, window, manufacturer, model);
+ addOutput(output, primary);
+ return output;
+ }
+
+ void addOutput(QWaylandOutput *output, bool primary)
+ {
+ Q_Q(QWaylandOutputSpace);
+ Q_ASSERT(output);
+ Q_ASSERT(!outputs.contains(output));
+
+ output->handle()->setOutputSpace(q, false);
+
+ if (primary)
+ outputs.prepend(output);
+ else
+ outputs.append(output);
+ adjustGeometry();
+ q->outputsChanged();
+
+ }
+
+ static QWaylandOutputSpacePrivate *get(QWaylandOutputSpace *outputSpace) { return outputSpace->d_func(); }
+
+private:
+ QWaylandCompositor *compositor;
+ QRect geometry;
+ QWaylandOutputSpace::GeometryConstraint geometryConstraint;
+ QList<QWaylandOutput *> outputs;
+};
+
+QT_END_NAMESPACE
+
+#endif /*QWAYLANDOUTPUTSPACE_P_H*/
diff --git a/src/compositor/compositor_api/qwaylandquickcompositor.cpp b/src/compositor/compositor_api/qwaylandquickcompositor.cpp
index 7c37e6c59..39dae9461 100644
--- a/src/compositor/compositor_api/qwaylandquickcompositor.cpp
+++ b/src/compositor/compositor_api/qwaylandquickcompositor.cpp
@@ -99,7 +99,8 @@ void QWaylandQuickCompositor::setExposeDefaultShell(bool defaultShell)
m_exposeDefaultShell = defaultShell;
}
-QWaylandOutput *QWaylandQuickCompositor::createOutput(QWindow *window,
+QWaylandOutput *QWaylandQuickCompositor::createOutput(QWaylandOutputSpace *outputSpace,
+ QWindow *window,
const QString &manufacturer,
const QString &model)
{
@@ -109,7 +110,7 @@ QWaylandOutput *QWaylandQuickCompositor::createOutput(QWindow *window,
if (!quickWindow)
qFatal("%s: couldn't cast QWindow to QQuickWindow. All output windows must "
"be QQuickWindow derivates when using QWaylandQuickCompositor", Q_FUNC_INFO);
- QWaylandQuickOutput *output = new QWaylandQuickOutput(this, quickWindow, manufacturer, model);
+ QWaylandQuickOutput *output = new QWaylandQuickOutput(outputSpace, quickWindow, manufacturer, model);
QQmlEngine::setObjectOwnership(output, QQmlEngine::CppOwnership);
return output;
}
diff --git a/src/compositor/compositor_api/qwaylandquickcompositor.h b/src/compositor/compositor_api/qwaylandquickcompositor.h
index de4b2f2b7..defb04984 100644
--- a/src/compositor/compositor_api/qwaylandquickcompositor.h
+++ b/src/compositor/compositor_api/qwaylandquickcompositor.h
@@ -59,7 +59,8 @@ public:
bool exposeDefaultShell() const;
void setExposeDefaultShell(bool defaultShell);
- QWaylandOutput *createOutput(QWindow *window,
+ QWaylandOutput *createOutput(QWaylandOutputSpace *outputSpace,
+ QWindow *window,
const QString &manufacturer,
const QString &model) Q_DECL_OVERRIDE;
QWaylandSurfaceView *createView() Q_DECL_OVERRIDE;
diff --git a/src/compositor/compositor_api/qwaylandquickoutput.cpp b/src/compositor/compositor_api/qwaylandquickoutput.cpp
index d8341d60a..e51c8fd44 100644
--- a/src/compositor/compositor_api/qwaylandquickoutput.cpp
+++ b/src/compositor/compositor_api/qwaylandquickoutput.cpp
@@ -40,9 +40,9 @@
QT_BEGIN_NAMESPACE
-QWaylandQuickOutput::QWaylandQuickOutput(QWaylandCompositor *compositor, QQuickWindow *window,
+QWaylandQuickOutput::QWaylandQuickOutput(QWaylandOutputSpace *outputSpace, QQuickWindow *window,
const QString &manufacturer, const QString &model)
- : QWaylandOutput(compositor, window, manufacturer, model)
+ : QWaylandOutput(outputSpace, window, manufacturer, model)
, m_updateScheduled(false)
, m_automaticFrameCallbacks(false)
{
diff --git a/src/compositor/compositor_api/qwaylandquickoutput.h b/src/compositor/compositor_api/qwaylandquickoutput.h
index ea89d52ce..2de24f2f5 100644
--- a/src/compositor/compositor_api/qwaylandquickoutput.h
+++ b/src/compositor/compositor_api/qwaylandquickoutput.h
@@ -51,7 +51,7 @@ class Q_COMPOSITOR_EXPORT QWaylandQuickOutput : public QWaylandOutput
Q_OBJECT
Q_PROPERTY(bool automaticFrameCallbacks READ automaticFrameCallbacks WRITE setAutomaticFrameCallbacks)
public:
- QWaylandQuickOutput(QWaylandCompositor *compositor, QQuickWindow *window,
+ QWaylandQuickOutput(QWaylandOutputSpace *outputSpace, QQuickWindow *window,
const QString &manufacturer, const QString &model);
QQuickWindow *quickWindow() const;
diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp
index 9defe06f1..0f722f334 100644
--- a/src/compositor/compositor_api/qwaylandsurface.cpp
+++ b/src/compositor/compositor_api/qwaylandsurface.cpp
@@ -349,6 +349,12 @@ void QWaylandSurface::ping()
}
}
+void QWaylandSurface::sendFrameCallbacks()
+{
+ Q_D(QWaylandSurface);
+ d->sendFrameCallback();
+}
+
void QWaylandSurface::sendOnScreenVisibilityChange(bool visible)
{
setVisibility(visible ? QWindow::AutomaticVisibility : QWindow::Hidden);
diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h
index 5aa4232b2..30005e3f7 100644
--- a/src/compositor/compositor_api/qwaylandsurface.h
+++ b/src/compositor/compositor_api/qwaylandsurface.h
@@ -196,6 +196,8 @@ public:
Q_INVOKABLE void destroySurface();
Q_INVOKABLE void ping();
+ Q_INVOKABLE void sendFrameCallbacks();
+
void ref();
void deref();
void setMapped(bool mapped);
diff --git a/src/compositor/compositor_api/qwaylandsurfaceview.cpp b/src/compositor/compositor_api/qwaylandsurfaceview.cpp
index 74698ac07..cfb9aa2ea 100644
--- a/src/compositor/compositor_api/qwaylandsurfaceview.cpp
+++ b/src/compositor/compositor_api/qwaylandsurfaceview.cpp
@@ -123,6 +123,11 @@ QWaylandCompositor *QWaylandSurfaceView::compositor() const
void QWaylandSurfaceView::setRequestedPosition(const QPointF &pos)
{
d->requestedPos = pos;
+ if (d->shouldBroadcastRequestedPositionChanged()) {
+ Q_ASSERT(d->output->outputSpace());
+ QWaylandOutputSpacePrivate *outputSpacePriv = QWaylandOutputSpacePrivate::get(d->output->outputSpace());
+ outputSpacePriv->emitSurfacePositionChanged(d->surface, pos);
+ }
}
QPointF QWaylandSurfaceView::requestedPosition() const
@@ -170,6 +175,16 @@ void QWaylandSurfaceView::setLockedBuffer(bool locked)
d->lockedBuffer = locked;
}
+bool QWaylandSurfaceView::broadcastRequestedPositionChanged() const
+{
+ return d->broadcastRequestedPositionChanged;
+}
+
+void QWaylandSurfaceView::setBroadcastRequestedPositionChanged(bool broadcast)
+{
+ d->broadcastRequestedPositionChanged = broadcast;
+}
+
void QWaylandSurfaceView::waylandSurfaceChanged(QWaylandSurface *newSurface, QWaylandSurface *oldSurface)
{
if (d->output)
diff --git a/src/compositor/compositor_api/qwaylandsurfaceview.h b/src/compositor/compositor_api/qwaylandsurfaceview.h
index 17951d08d..07e8e661c 100644
--- a/src/compositor/compositor_api/qwaylandsurfaceview.h
+++ b/src/compositor/compositor_api/qwaylandsurfaceview.h
@@ -71,6 +71,9 @@ public:
bool lockedBuffer() const;
void setLockedBuffer(bool locked);
+
+ bool broadcastRequestedPositionChanged() const;
+ void setBroadcastRequestedPositionChanged(bool broadcast);
protected:
virtual void waylandSurfaceChanged(QWaylandSurface *newSurface, QWaylandSurface *oldSurface);
virtual void waylandSurfaceDestroyed();
diff --git a/src/compositor/compositor_api/qwaylandsurfaceview_p.h b/src/compositor/compositor_api/qwaylandsurfaceview_p.h
index cdcd91f03..3537ad679 100644
--- a/src/compositor/compositor_api/qwaylandsurfaceview_p.h
+++ b/src/compositor/compositor_api/qwaylandsurfaceview_p.h
@@ -61,6 +61,11 @@ public:
void markSurfaceAsDestroyed(QWaylandSurface *surface);
+ bool shouldBroadcastRequestedPositionChanged() const
+ {
+ return broadcastRequestedPositionChanged && output && surface && surface->primaryOutput() == output;
+ }
+
QWaylandSurfaceView *q_ptr;
QWaylandSurface *surface;
QWaylandOutput *output;
@@ -69,6 +74,7 @@ public:
QWaylandBufferRef currentBuffer;
QWaylandBufferRef nextBuffer;
bool lockedBuffer;
+ bool broadcastRequestedPositionChanged;
};
QT_END_NAMESPACE
diff --git a/src/compositor/wayland_wrapper/qwlcompositor.cpp b/src/compositor/wayland_wrapper/qwlcompositor.cpp
index 22573b1a2..e58c6e999 100644
--- a/src/compositor/wayland_wrapper/qwlcompositor.cpp
+++ b/src/compositor/wayland_wrapper/qwlcompositor.cpp
@@ -178,6 +178,7 @@ Compositor::Compositor(QWaylandCompositor *qt_compositor)
, m_retainSelection(false)
, m_initialized(false)
{
+ m_outputSpaces.append(new QWaylandOutputSpace(qt_compositor));
m_timer.start();
compositor = this;
@@ -237,7 +238,7 @@ Compositor::~Compositor()
qWarning("QWaylandCompositor::cleanupGraphicsResources() must be called manually");
qDeleteAll(m_clients);
- qDeleteAll(m_outputs);
+ qDeleteAll(m_outputSpaces);
delete m_surfaceExtension;
delete m_subSurfaceExtension;
@@ -256,56 +257,50 @@ uint Compositor::currentTimeMsecs() const
return m_timer.elapsed();
}
-QList<QWaylandOutput *> Compositor::outputs() const
-{
- return m_outputs;
-}
-
QWaylandOutput *Compositor::output(QWindow *window) const
{
- Q_FOREACH (QWaylandOutput *output, m_outputs) {
- if (output->window() == window)
+ foreach (QWaylandOutputSpace *outputSpace, m_outputSpaces) {
+ QWaylandOutput *output = outputSpace->output(window);
+ if (output)
return output;
}
return Q_NULLPTR;
}
-void Compositor::addOutput(QWaylandOutput *output)
+QWaylandOutput *Compositor::primaryOutput() const
{
- Q_ASSERT(output->handle());
-
- if (m_outputs.contains(output))
- return;
-
- m_outputs.append(output);
+ return primaryOutputSpace()->primaryOutput();
}
-void Compositor::removeOutput(QWaylandOutput *output)
+QWaylandOutputSpace *Compositor::primaryOutputSpace() const
{
- Q_ASSERT(output->handle());
-
- m_outputs.removeOne(output);
+ Q_ASSERT(!m_outputSpaces.isEmpty());
+ return m_outputSpaces.first();
}
-QWaylandOutput *Compositor::primaryOutput() const
+void Compositor::setPrimaryOutputSpace(QWaylandOutputSpace *outputSpace)
{
- if (m_outputs.size() == 0)
- return Q_NULLPTR;
- return m_outputs.at(0);
+ Q_ASSERT(!m_outputSpaces.isEmpty());
+ if (m_outputSpaces.first() == outputSpace)
+ return;
+ if (m_outputSpaces.removeOne(outputSpace)) {
+ m_outputSpaces.prepend(outputSpace);
+ waylandCompositor()->primaryOutputSpaceChanged();
+ }
}
-void Compositor::setPrimaryOutput(QWaylandOutput *output)
+void Compositor::addOutputSpace(QWaylandOutputSpace *outputSpace)
{
- Q_ASSERT(output->handle());
-
- int i = m_outputs.indexOf(output);
- if (i <= 0)
- return;
+ Q_ASSERT(!m_outputSpaces.contains(outputSpace));
+ m_outputSpaces.append(outputSpace);
+ waylandCompositor()->outputSpacesChanged();
+}
- m_outputs.removeAt(i);
- m_outputs.prepend(output);
- emit m_qt_compositor->primaryOutputChanged();
+void Compositor::removeOutputSpace(QWaylandOutputSpace *outputSpace)
+{
+ if (m_outputSpaces.removeOne(outputSpace))
+ waylandCompositor()->outputSpacesChanged();
}
void Compositor::processWaylandEvents()
diff --git a/src/compositor/wayland_wrapper/qwlcompositor_p.h b/src/compositor/wayland_wrapper/qwlcompositor_p.h
index a9d7f99f9..304cb94f7 100644
--- a/src/compositor/wayland_wrapper/qwlcompositor_p.h
+++ b/src/compositor/wayland_wrapper/qwlcompositor_p.h
@@ -105,14 +105,13 @@ public:
uint currentTimeMsecs() const;
- QList<QWaylandOutput *> outputs() const;
QWaylandOutput *output(QWindow *window) const;
- void addOutput(QWaylandOutput *output);
- void removeOutput(QWaylandOutput *output);
-
QWaylandOutput *primaryOutput() const;
- void setPrimaryOutput(QWaylandOutput *output);
+ QWaylandOutputSpace *primaryOutputSpace() const;
+ void setPrimaryOutputSpace(QWaylandOutputSpace *outputSpace);
+ void addOutputSpace(QWaylandOutputSpace *outputSpace);
+ void removeOutputSpace(QWaylandOutputSpace *outputSpace);
ClientBufferIntegration *clientBufferIntegration() const;
ServerBufferIntegration *serverBufferIntegration() const;
@@ -183,7 +182,7 @@ protected:
QList<QWaylandInputDevice *> m_inputDevices;
/* Output */
- QList<QWaylandOutput *> m_outputs;
+ QList<QWaylandOutputSpace *> m_outputSpaces;
QList<QWaylandSurface *> m_all_surfaces;
diff --git a/src/compositor/wayland_wrapper/qwldatadevice.cpp b/src/compositor/wayland_wrapper/qwldatadevice.cpp
index 73a93a8c8..c3a059f74 100644
--- a/src/compositor/wayland_wrapper/qwldatadevice.cpp
+++ b/src/compositor/wayland_wrapper/qwldatadevice.cpp
@@ -131,10 +131,10 @@ void DataDevice::sourceDestroyed(DataSource *source)
void DataDevice::focus()
{
- QWaylandSurfaceView *focus = m_compositor->waylandCompositor()->pickView(m_pointer->currentPosition());
+ QWaylandSurfaceView *focus = outputSpace()->pickView(m_pointer->currentPosition());
if (focus != m_dragFocus)
- setDragFocus(focus, m_compositor->waylandCompositor()->mapToView(focus, m_pointer->currentPosition()));
+ setDragFocus(focus, outputSpace()->mapToView(focus, m_pointer->currentPosition()));
}
void DataDevice::motion(uint32_t time)
@@ -144,8 +144,7 @@ void DataDevice::motion(uint32_t time)
}
if (m_dragFocusResource && m_dragFocus) {
- const QPointF &surfacePoint = m_compositor->waylandCompositor()->mapToView(m_dragFocus, m_pointer->currentPosition());
- qDebug() << Q_FUNC_INFO << m_pointer->currentPosition() << surfacePoint;
+ const QPointF &surfacePoint = outputSpace()->mapToView(m_dragFocus, m_pointer->currentPosition());
send_motion(m_dragFocusResource->handle, time,
wl_fixed_from_double(surfacePoint.x()), wl_fixed_from_double(surfacePoint.y()));
}
diff --git a/src/compositor/wayland_wrapper/qwldatadevice_p.h b/src/compositor/wayland_wrapper/qwldatadevice_p.h
index 051e1eb3e..59a9d2b27 100644
--- a/src/compositor/wayland_wrapper/qwldatadevice_p.h
+++ b/src/compositor/wayland_wrapper/qwldatadevice_p.h
@@ -38,7 +38,9 @@
#define WLDATADEVICE_H
#include <QtCompositor/private/qwayland-server-wayland.h>
+#include <qwlinputdevice_p.h>
#include <qwlpointer_p.h>
+#include <QtCompositor/QWaylandOutputSpace>
QT_BEGIN_NAMESPACE
@@ -72,6 +74,7 @@ protected:
void data_device_set_selection(Resource *resource, struct ::wl_resource *source, uint32_t serial) Q_DECL_OVERRIDE;
private:
+ QWaylandOutputSpace *outputSpace() const { return m_inputDevice->handle()->outputSpace(); }
Compositor *m_compositor;
InputDevice *m_inputDevice;
diff --git a/src/compositor/wayland_wrapper/qwlinputdevice.cpp b/src/compositor/wayland_wrapper/qwlinputdevice.cpp
index 5986b66ba..a4af463f7 100644
--- a/src/compositor/wayland_wrapper/qwlinputdevice.cpp
+++ b/src/compositor/wayland_wrapper/qwlinputdevice.cpp
@@ -60,6 +60,7 @@ InputDevice::InputDevice(QWaylandInputDevice *handle, Compositor *compositor, QW
, m_handle(handle)
, m_dragHandle(new QWaylandDrag(this))
, m_compositor(compositor)
+ , m_outputSpace(compositor->primaryOutputSpace())
, m_capabilities(caps)
, m_pointer(m_capabilities & QWaylandInputDevice::Pointer ? new Pointer(m_compositor, this) : 0)
, m_keyboard(m_capabilities & QWaylandInputDevice::Keyboard ? new Keyboard(m_compositor, this) : 0)
@@ -366,6 +367,16 @@ const DataDevice *InputDevice::dataDevice() const
return m_data_device.data();
}
+QWaylandOutputSpace *InputDevice::outputSpace() const
+{
+ return m_outputSpace;
+}
+
+void InputDevice::setOutputSpace(QWaylandOutputSpace *outputSpace)
+{
+ m_outputSpace = outputSpace;
+}
+
}
QT_END_NAMESPACE
diff --git a/src/compositor/wayland_wrapper/qwlinputdevice_p.h b/src/compositor/wayland_wrapper/qwlinputdevice_p.h
index b6637eaa2..da59dd208 100644
--- a/src/compositor/wayland_wrapper/qwlinputdevice_p.h
+++ b/src/compositor/wayland_wrapper/qwlinputdevice_p.h
@@ -103,6 +103,9 @@ public:
void clientRequestedDataDevice(DataDeviceManager *dndSelection, struct wl_client *client, uint32_t id);
const DataDevice *dataDevice() const;
+ QWaylandOutputSpace *outputSpace() const;
+ void setOutputSpace(QWaylandOutputSpace *outputSpace);
+
Compositor *compositor() const;
QWaylandInputDevice *handle() const;
QWaylandDrag *dragHandle() const;
@@ -128,6 +131,7 @@ private:
QWaylandInputDevice *m_handle;
QScopedPointer<QWaylandDrag> m_dragHandle;
Compositor *m_compositor;
+ QWaylandOutputSpace *m_outputSpace;
QWaylandInputDevice::CapabilityFlags m_capabilities;
QScopedPointer<Pointer> m_pointer;
diff --git a/src/compositor/wayland_wrapper/qwloutput.cpp b/src/compositor/wayland_wrapper/qwloutput.cpp
index 32a42b74e..76acfb2b5 100644
--- a/src/compositor/wayland_wrapper/qwloutput.cpp
+++ b/src/compositor/wayland_wrapper/qwloutput.cpp
@@ -99,11 +99,11 @@ static QtWaylandServer::wl_output::transform toWlTransform(const QWaylandOutput:
return QtWaylandServer::wl_output::transform_normal;
}
-Output::Output(Compositor *compositor, QWindow *window)
- : QtWaylandServer::wl_output(compositor->wl_display(), 2)
- , m_compositor(compositor)
+Output::Output(QWaylandOutput *output, QWaylandOutputSpace *outputSpace, QWindow *window)
+ : QtWaylandServer::wl_output(outputSpace->compositor()->waylandDisplay(), 2)
, m_window(window)
- , m_output(Q_NULLPTR)
+ , m_output(output)
+ , m_outputSpace(Q_NULLPTR)
, m_position(QPoint())
, m_availableGeometry(QRect())
, m_physicalSize(QSize())
@@ -114,6 +114,7 @@ Output::Output(Compositor *compositor, QWindow *window)
{
m_mode.size = window ? window->size() : QSize();
m_mode.refreshRate = 60;
+ setOutputSpace(outputSpace, false);
qRegisterMetaType<QWaylandOutput::Mode>("WaylandOutput::Mode");
}
@@ -289,6 +290,24 @@ void Output::setScaleFactor(int scale)
}
}
+void Output::setOutputSpace(QWaylandOutputSpace *outputSpace, bool setOutputSpace)
+{
+ if (m_outputSpace == outputSpace)
+ return;
+
+ if (m_outputSpace) {
+ m_outputSpace->removeOutput(waylandOutput());
+ }
+
+ m_outputSpace = outputSpace;
+
+ if (outputSpace && setOutputSpace) {
+ outputSpace->addOutput(waylandOutput());
+ }
+
+ waylandOutput()->outputSpaceChanged();
+}
+
OutputResource *Output::outputForClient(wl_client *client) const
{
return static_cast<OutputResource *>(resourceMap().value(client));
@@ -327,20 +346,7 @@ void Output::sendFrameCallbacks()
|| surfacemapper.surface->primaryOutput()->handle() == this))
surfacemapper.surface->handle()->sendFrameCallback();
}
- wl_display_flush_clients(m_compositor->wl_display());
-}
-
-QList<QWaylandSurface *> Output::surfacesForClient(QWaylandClient *client) const
-{
- QList<QWaylandSurface *> result;
-
- for (int i = 0; i < m_surfaceViews.size(); i ++) {
- if (m_surfaceViews.at(i).surface
- && m_surfaceViews.at(i).surface->client() == client)
- result.append(result);
- }
-
- return result;
+ wl_display_flush_clients(compositor()->waylandDisplay());
}
void Output::addView(QWaylandSurfaceView *view)
diff --git a/src/compositor/wayland_wrapper/qwloutput_p.h b/src/compositor/wayland_wrapper/qwloutput_p.h
index 30052c3b3..917240c1f 100644
--- a/src/compositor/wayland_wrapper/qwloutput_p.h
+++ b/src/compositor/wayland_wrapper/qwloutput_p.h
@@ -44,6 +44,8 @@
#include <QtCore/QList>
#include <QtCore/QVector>
+#include <QtCompositor/QWaylandOutputSpace>
+
#include <QtCompositor/private/qwayland-server-wayland.h>
#include <QtCompositor/qwaylandoutput.h>
@@ -74,11 +76,11 @@ struct OutputResource : public QtWaylandServer::wl_output::Resource
class Output : public QtWaylandServer::wl_output
{
public:
- explicit Output(Compositor *compositor, QWindow *window = 0);
+ Output(QWaylandOutput *output, QWaylandOutputSpace *outputSpace, QWindow *window);
- Compositor *compositor() const { return m_compositor; }
+ QWaylandCompositor *compositor() const { return m_outputSpace->compositor(); }
- QWaylandOutput *output() const { return m_output; }
+ QWaylandOutput *waylandOutput() const { return m_output; }
QString manufacturer() const { return m_manufacturer; }
void setManufacturer(const QString &manufacturer);
@@ -115,11 +117,12 @@ public:
int scaleFactor() const { return m_scaleFactor; }
void setScaleFactor(int scale);
+ void setOutputSpace(QWaylandOutputSpace *outputSpace, bool setOutputSpace);
+ QWaylandOutputSpace *outputSpace() const { return m_outputSpace; }
+
void frameStarted();
void sendFrameCallbacks();
- QList<QWaylandSurface *> surfacesForClient(QWaylandClient *client) const;
-
void addView(QWaylandSurfaceView *view);
void addView(QWaylandSurfaceView *view, QWaylandSurface *surface);
void removeView(QWaylandSurfaceView *view);
@@ -130,8 +133,6 @@ public:
OutputResource *outputForClient(struct wl_client *client) const;
- QWaylandOutput *waylandOutput() const { return m_output; }
-
void output_bind_resource(Resource *resource) Q_DECL_OVERRIDE;
Resource *output_allocate() Q_DECL_OVERRIDE { return new OutputResource; }
@@ -139,9 +140,9 @@ public:
private:
friend class QT_PREPEND_NAMESPACE(QWaylandOutput);
- Compositor *m_compositor;
QWindow *m_window;
QWaylandOutput *m_output;
+ QWaylandOutputSpace *m_outputSpace;
QString m_manufacturer;
QString m_model;
QPoint m_position;
diff --git a/src/compositor/wayland_wrapper/qwlshellsurface.cpp b/src/compositor/wayland_wrapper/qwlshellsurface.cpp
index bc75ab4c3..2fe666442 100644
--- a/src/compositor/wayland_wrapper/qwlshellsurface.cpp
+++ b/src/compositor/wayland_wrapper/qwlshellsurface.cpp
@@ -295,7 +295,7 @@ void ShellSurface::shell_surface_set_fullscreen(Resource *resource,
: Q_NULLPTR;
if (!output) {
// Look for an output that can contain this surface
- Q_FOREACH (QWaylandOutput *curOutput, m_surface->compositor()->outputs()) {
+ Q_FOREACH (QWaylandOutput *curOutput, m_surface->compositor()->primaryOutputSpace()->outputs()) {
if (curOutput->geometry().size().width() >= m_surface->size().width() &&
curOutput->geometry().size().height() >= m_surface->size().height()) {
output = curOutput;
@@ -343,7 +343,7 @@ void ShellSurface::shell_surface_set_maximized(Resource *resource,
: Q_NULLPTR;
if (!output) {
// Look for an output that can contain this surface
- Q_FOREACH (QWaylandOutput *curOutput, m_surface->compositor()->outputs()) {
+ Q_FOREACH (QWaylandOutput *curOutput, m_surface->compositor()->primaryOutputSpace()->outputs()) {
if (curOutput->geometry().size().width() >= m_surface->size().width() &&
curOutput->geometry().size().height() >= m_surface->size().height()) {
output = curOutput;
diff --git a/src/imports/compositor/qwaylandquickcompositorplugin.cpp b/src/imports/compositor/qwaylandquickcompositorplugin.cpp
index c73f9a1e0..1ed4c1392 100644
--- a/src/imports/compositor/qwaylandquickcompositorplugin.cpp
+++ b/src/imports/compositor/qwaylandquickcompositorplugin.cpp
@@ -44,6 +44,7 @@
#include <QtCompositor/QWaylandQuickSurface>
#include <QtCompositor/QWaylandClient>
#include <QtCompositor/QWaylandOutput>
+#include <QtCompositor/QWaylandOutputSpace>
#include <QtCompositor/private/qwlcompositor_p.h>
@@ -153,6 +154,7 @@ public:
qmlRegisterUncreatableType<QWaylandQuickSurface>(uri, 1, 0, "WaylandQuickSurface", QObject::tr("Cannot create instance of WaylandQuickSurface"));
qmlRegisterUncreatableType<QWaylandClient>(uri, 1, 0, "WaylandClient", QObject::tr("Cannot create instance of WaylandClient"));
qmlRegisterUncreatableType<QWaylandOutput>(uri, 1, 0, "WaylandOutput", QObject::tr("Cannot create instance of WaylandOutput"));
+ qmlRegisterUncreatableType<QWaylandOutputSpace>(uri, 1, 0, "WaylandOutputSpace", QObject::tr("Cannot create instance of WaylandOutputSpace"));
}
};
//![class decl]