summaryrefslogtreecommitdiffstats
path: root/src/compositor
diff options
context:
space:
mode:
Diffstat (limited to 'src/compositor')
-rw-r--r--src/compositor/compositor_api/qwaylandbufferref.h3
-rw-r--r--src/compositor/compositor_api/qwaylandcompositor.cpp1
-rw-r--r--src/compositor/compositor_api/qwaylandcompositor.h17
-rw-r--r--src/compositor/compositor_api/qwaylandquicksurface.cpp22
-rw-r--r--src/compositor/compositor_api/qwaylandsurface.cpp32
-rw-r--r--src/compositor/compositor_api/qwaylandsurface.h12
-rw-r--r--src/compositor/compositor_api/qwaylandsurfaceinterface.cpp6
-rw-r--r--src/compositor/compositor_api/qwaylandsurfaceitem.cpp4
-rw-r--r--src/compositor/wayland_wrapper/qwlcompositor.cpp58
-rw-r--r--src/compositor/wayland_wrapper/qwlcompositor_p.h4
-rw-r--r--src/compositor/wayland_wrapper/qwlextendedoutput.cpp71
-rw-r--r--src/compositor/wayland_wrapper/qwlextendedoutput_p.h87
-rw-r--r--src/compositor/wayland_wrapper/qwlextendedsurface.cpp5
-rw-r--r--src/compositor/wayland_wrapper/qwlextendedsurface_p.h2
-rw-r--r--src/compositor/wayland_wrapper/qwlkeyboard.cpp34
-rw-r--r--src/compositor/wayland_wrapper/qwlkeyboard_p.h10
-rw-r--r--src/compositor/wayland_wrapper/qwloutput.cpp1
-rw-r--r--src/compositor/wayland_wrapper/qwloutput_p.h4
-rw-r--r--src/compositor/wayland_wrapper/qwlshellsurface.cpp15
-rw-r--r--src/compositor/wayland_wrapper/qwlsurface.cpp44
-rw-r--r--src/compositor/wayland_wrapper/qwlsurface_p.h69
-rw-r--r--src/compositor/wayland_wrapper/wayland_wrapper.pri5
22 files changed, 272 insertions, 234 deletions
diff --git a/src/compositor/compositor_api/qwaylandbufferref.h b/src/compositor/compositor_api/qwaylandbufferref.h
index 213474fab..103a1b388 100644
--- a/src/compositor/compositor_api/qwaylandbufferref.h
+++ b/src/compositor/compositor_api/qwaylandbufferref.h
@@ -65,7 +65,8 @@ public:
#ifdef QT_COMPOSITOR_WAYLAND_GL
/**
* There must be a GL context bound when calling this function.
- * It is responsibility of the caller to call destroyTexture() later.
+ * The texture will be automatically destroyed when the last QWaylandBufferRef
+ * referring to the same underlying buffer will be destroyed or reset.
*/
GLuint createTexture();
void destroyTexture();
diff --git a/src/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp
index 28e8f9d4a..04d1c4aed 100644
--- a/src/compositor/compositor_api/qwaylandcompositor.cpp
+++ b/src/compositor/compositor_api/qwaylandcompositor.cpp
@@ -140,6 +140,7 @@ QList<QWaylandSurface *> QWaylandCompositor::surfaces() const
{
QList<QtWayland::Surface *> surfaces = m_compositor->surfaces();
QList<QWaylandSurface *> surfs;
+ surfs.reserve(surfaces.count());
foreach (QtWayland::Surface *s, surfaces)
surfs << s->waylandSurface();
return surfs;
diff --git a/src/compositor/compositor_api/qwaylandcompositor.h b/src/compositor/compositor_api/qwaylandcompositor.h
index fe48db06d..1817fa07d 100644
--- a/src/compositor/compositor_api/qwaylandcompositor.h
+++ b/src/compositor/compositor_api/qwaylandcompositor.h
@@ -75,15 +75,14 @@ class Q_COMPOSITOR_EXPORT QWaylandCompositor
public:
enum ExtensionFlag {
WindowManagerExtension = 0x01,
- OutputExtension = 0x02,
- SurfaceExtension = 0x04,
- QtKeyExtension = 0x08,
- TouchExtension = 0x10,
- SubSurfaceExtension = 0x20,
- TextInputExtension = 0x40,
- HardwareIntegrationExtension = 0x80,
-
- DefaultExtensions = WindowManagerExtension | OutputExtension | SurfaceExtension | QtKeyExtension | TouchExtension | HardwareIntegrationExtension
+ SurfaceExtension = 0x02,
+ QtKeyExtension = 0x04,
+ TouchExtension = 0x08,
+ SubSurfaceExtension = 0x10,
+ TextInputExtension = 0x20,
+ HardwareIntegrationExtension = 0x40,
+
+ DefaultExtensions = WindowManagerExtension | SurfaceExtension | QtKeyExtension | TouchExtension | HardwareIntegrationExtension
};
Q_DECLARE_FLAGS(ExtensionFlags, ExtensionFlag)
diff --git a/src/compositor/compositor_api/qwaylandquicksurface.cpp b/src/compositor/compositor_api/qwaylandquicksurface.cpp
index ef78c8849..c8edcb6bc 100644
--- a/src/compositor/compositor_api/qwaylandquicksurface.cpp
+++ b/src/compositor/compositor_api/qwaylandquicksurface.cpp
@@ -73,19 +73,12 @@ public:
void createTexture()
{
- if (bufferRef)
- bufferRef.destroyTexture();
bufferRef = nextBuffer;
+ delete texture;
+ texture = 0;
QQuickWindow *window = static_cast<QQuickWindow *>(surface->mainOutput()->window());
-
- // If the next buffer is NULL do not delete the current texture. If the client called
- // attach(0) the surface is going to be unmapped anyway, if instead the client attached
- // a valid buffer but died before we got here we want to keep the old buffer around
- // in case some destroy animation is run.
- if (bufferRef) {
- delete texture;
-
+ if (nextBuffer) {
if (bufferRef.isShm()) {
texture = window->createTextureFromImage(bufferRef.image());
} else {
@@ -101,6 +94,12 @@ public:
update = false;
}
+ void unmap() Q_DECL_OVERRIDE
+ {
+ nextBuffer = QWaylandBufferRef();
+ update = true;
+ }
+
void invalidateTexture()
{
if (bufferRef)
@@ -141,9 +140,6 @@ public:
void surface_commit(Resource *resource) Q_DECL_OVERRIDE
{
- if (m_pending.newlyAttached) {
- buffer->update = true;
- }
QWaylandSurfacePrivate::surface_commit(resource);
Q_FOREACH (QtWayland::Output *output, outputs())
diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp
index e5ecb15b4..a8dc41fd5 100644
--- a/src/compositor/compositor_api/qwaylandsurface.cpp
+++ b/src/compositor/compositor_api/qwaylandsurface.cpp
@@ -71,7 +71,7 @@ QWaylandSurfacePrivate::QWaylandSurfacePrivate(wl_client *wlClient, quint32 id,
, closing(false)
, refCount(1)
, client(QWaylandClient::fromWlClient(wlClient))
- , windowType(QWaylandSurface::WindowType::None)
+ , windowType(QWaylandSurface::None)
{}
@@ -322,7 +322,9 @@ QList<QWaylandOutput *> QWaylandSurface::outputs() const
Q_D(const QWaylandSurface);
QList<QWaylandOutput *> list;
- Q_FOREACH (QtWayland::Output *output, d->outputs())
+ const QList<QtWayland::Output *> outputs = d->outputs();
+ list.reserve(outputs.count());
+ Q_FOREACH (QtWayland::Output *output, outputs)
list.append(output->waylandOutput());
return list;
}
@@ -509,4 +511,30 @@ void QWaylandSurfacePrivate::setType(QWaylandSurface::WindowType type)
}
}
+class QWaylandUnmapLockPrivate
+{
+public:
+ QWaylandSurface *surface;
+};
+
+/*!
+ Constructs a QWaylandUnmapLock object.
+
+ The lock will act on the \a surface parameter, and will prevent the surface to
+ be unmapped, retaining the last valid buffer when the client attachs a NULL buffer.
+ The lock will be automatically released when deleted.
+*/
+QWaylandUnmapLock::QWaylandUnmapLock(QWaylandSurface *surface)
+ : d(new QWaylandUnmapLockPrivate)
+{
+ d->surface = surface;
+ surface->handle()->addUnmapLock(this);
+}
+
+QWaylandUnmapLock::~QWaylandUnmapLock()
+{
+ d->surface->handle()->removeUnmapLock(this);
+ delete d;
+}
+
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h
index 653d74c1b..db1e1fb44 100644
--- a/src/compositor/compositor_api/qwaylandsurface.h
+++ b/src/compositor/compositor_api/qwaylandsurface.h
@@ -77,6 +77,7 @@ public:
protected:
virtual void attach(const QWaylandBufferRef &ref) = 0;
+ virtual void unmap() = 0;
friend class QtWayland::Surface;
};
@@ -261,6 +262,17 @@ Q_SIGNALS:
friend class QtWayland::Surface;
};
+class QWaylandUnmapLockPrivate;
+class Q_COMPOSITOR_EXPORT QWaylandUnmapLock
+{
+public:
+ QWaylandUnmapLock(QWaylandSurface *surface);
+ ~QWaylandUnmapLock();
+
+private:
+ QWaylandUnmapLockPrivate *const d;
+};
+
QT_END_NAMESPACE
#endif // QWAYLANDSURFACE_H
diff --git a/src/compositor/compositor_api/qwaylandsurfaceinterface.cpp b/src/compositor/compositor_api/qwaylandsurfaceinterface.cpp
index 355777377..cddd231dd 100644
--- a/src/compositor/compositor_api/qwaylandsurfaceinterface.cpp
+++ b/src/compositor/compositor_api/qwaylandsurfaceinterface.cpp
@@ -110,7 +110,7 @@ int QWaylandSurfaceOp::type() const
QWaylandSurfaceSetVisibilityOp::QWaylandSurfaceSetVisibilityOp(QWindow::Visibility visibility)
- : QWaylandSurfaceOp(Type::SetVisibility)
+ : QWaylandSurfaceOp(QWaylandSurfaceOp::SetVisibility)
, m_visibility(visibility)
{
}
@@ -121,7 +121,7 @@ QWindow::Visibility QWaylandSurfaceSetVisibilityOp::visibility() const
}
QWaylandSurfaceResizeOp::QWaylandSurfaceResizeOp(const QSize &size)
- : QWaylandSurfaceOp(Type::Resize)
+ : QWaylandSurfaceOp(QWaylandSurfaceOp::Resize)
, m_size(size)
{
}
@@ -132,7 +132,7 @@ QSize QWaylandSurfaceResizeOp::size() const
}
QWaylandSurfacePingOp::QWaylandSurfacePingOp(uint32_t serial)
- : QWaylandSurfaceOp(Type::Ping)
+ : QWaylandSurfaceOp(QWaylandSurfaceOp::Ping)
, m_serial(serial)
{
}
diff --git a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp
index 93cfaf008..0c48df382 100644
--- a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp
+++ b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp
@@ -364,9 +364,7 @@ void QWaylandSurfaceItem::updateTexture(bool changed)
if (!m_provider)
m_provider = new QWaylandSurfaceTextureProvider();
- bool mapped = surface() && surface()->isMapped();
- if (mapped)
- m_provider->t = static_cast<QWaylandQuickSurface *>(surface())->texture();
+ m_provider->t = static_cast<QWaylandQuickSurface *>(surface())->texture();
m_provider->smooth = smooth();
if (m_newTexture || changed)
emit m_provider->textureChanged();
diff --git a/src/compositor/wayland_wrapper/qwlcompositor.cpp b/src/compositor/wayland_wrapper/qwlcompositor.cpp
index f057542ca..f8c8bdc1f 100644
--- a/src/compositor/wayland_wrapper/qwlcompositor.cpp
+++ b/src/compositor/wayland_wrapper/qwlcompositor.cpp
@@ -49,7 +49,6 @@
#include "qwaylandcompositor.h"
#include "qwldatadevicemanager_p.h"
#include "qwldatadevice_p.h"
-#include "qwlextendedoutput_p.h"
#include "qwlextendedsurface_p.h"
#include "qwlsubsurface_p.h"
#include "qwlshellsurface_p.h"
@@ -64,6 +63,7 @@
#include "qwaylandsurfaceview.h"
#include "qwaylandshmformathelper.h"
#include "qwaylandoutput.h"
+#include "qwlkeyboard_p.h"
#include <QWindow>
#include <QSocketNotifier>
@@ -99,12 +99,61 @@
#include "hardware_integration/qwlclientbufferintegrationfactory_p.h"
#include "hardware_integration/qwlserverbufferintegrationfactory_p.h"
+#include "../shared/qwaylandxkb.h"
+
QT_BEGIN_NAMESPACE
namespace QtWayland {
static Compositor *compositor;
+class WindowSystemEventHandler : public QWindowSystemEventHandler
+{
+public:
+ WindowSystemEventHandler(Compositor *c) : compositor(c) {}
+ bool sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e) Q_DECL_OVERRIDE
+ {
+ if (e->type == QWindowSystemInterfacePrivate::Key) {
+ QWindowSystemInterfacePrivate::KeyEvent *ke = static_cast<QWindowSystemInterfacePrivate::KeyEvent *>(e);
+ Keyboard *keyb = compositor->defaultInputDevice()->keyboardDevice();
+
+ uint32_t code = ke->nativeScanCode;
+ bool isDown = ke->keyType == QEvent::KeyPress;
+
+#ifndef QT_NO_WAYLAND_XKB
+ QString text;
+ Qt::KeyboardModifiers modifiers = QWaylandXkb::modifiers(keyb->xkbState());
+
+ const xkb_keysym_t sym = xkb_state_key_get_one_sym(keyb->xkbState(), code);
+ uint utf32 = xkb_keysym_to_utf32(sym);
+ if (utf32)
+ text = QString::fromUcs4(&utf32, 1);
+ int qtkey = QWaylandXkb::keysymToQtKey(sym, modifiers, text);
+
+ ke->key = qtkey;
+ ke->modifiers = modifiers;
+ ke->nativeVirtualKey = sym;
+ ke->nativeModifiers = keyb->xkbModsMask();
+ ke->unicode = text;
+#endif
+ if (!ke->repeat)
+ keyb->keyEvent(code, isDown ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED);
+
+ QWindowSystemEventHandler::sendEvent(e);
+
+ if (!ke->repeat) {
+ keyb->updateKeymap();
+ keyb->updateModifierState(code, isDown ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED);
+ }
+ } else {
+ QWindowSystemEventHandler::sendEvent(e);
+ }
+ return true;
+ }
+
+ Compositor *compositor;
+};
+
Compositor *Compositor::instance()
{
return compositor;
@@ -123,17 +172,19 @@ Compositor::Compositor(QWaylandCompositor *qt_compositor, QWaylandCompositor::Ex
, m_server_buffer_integration(0)
#endif
, m_windowManagerIntegration(0)
- , m_outputExtension(0)
, m_surfaceExtension(0)
, m_subSurfaceExtension(0)
, m_touchExtension(0)
, m_qtkeyExtension(0)
, m_textInputManager()
, m_inputPanel()
+ , m_eventHandler(new WindowSystemEventHandler(this))
, m_retainSelection(false)
{
m_timer.start();
compositor = this;
+
+ QWindowSystemInterfacePrivate::installWindowSystemEventHandler(m_eventHandler.data());
}
void Compositor::init()
@@ -187,7 +238,6 @@ Compositor::~Compositor()
qDeleteAll(m_outputs);
- delete m_outputExtension;
delete m_surfaceExtension;
delete m_subSurfaceExtension;
delete m_touchExtension;
@@ -360,8 +410,6 @@ void Compositor::initializeHardwareIntegration()
void Compositor::initializeExtensions()
{
- if (m_extensions & QWaylandCompositor::OutputExtension)
- m_outputExtension = new OutputExtensionGlobal(this);
if (m_extensions & QWaylandCompositor::SurfaceExtension)
m_surfaceExtension = new SurfaceExtensionGlobal(this);
if (m_extensions & QWaylandCompositor::SubSurfaceExtension)
diff --git a/src/compositor/wayland_wrapper/qwlcompositor_p.h b/src/compositor/wayland_wrapper/qwlcompositor_p.h
index 1efbd2ee3..7360e7dca 100644
--- a/src/compositor/wayland_wrapper/qwlcompositor_p.h
+++ b/src/compositor/wayland_wrapper/qwlcompositor_p.h
@@ -66,6 +66,7 @@ class WindowManagerServerIntegration;
class QMimeData;
class QPlatformScreenBuffer;
class QWaylandSurface;
+class QWindowSystemEventHandler;
namespace QtWayland {
@@ -74,7 +75,6 @@ class SurfaceBuffer;
class InputDevice;
class DataDeviceManager;
class OutputGlobal;
-class OutputExtensionGlobal;
class SurfaceExtensionGlobal;
class SubSurfaceExtensionGlobal;
class TouchExtensionGlobal;
@@ -214,7 +214,6 @@ protected:
//extensions
WindowManagerServerIntegration *m_windowManagerIntegration;
- OutputExtensionGlobal *m_outputExtension;
SurfaceExtensionGlobal *m_surfaceExtension;
SubSurfaceExtensionGlobal *m_subSurfaceExtension;
TouchExtensionGlobal *m_touchExtension;
@@ -222,6 +221,7 @@ protected:
QScopedPointer<TextInputManager> m_textInputManager;
QScopedPointer<InputPanel> m_inputPanel;
QList<QWaylandGlobalInterface *> m_globals;
+ QScopedPointer<QWindowSystemEventHandler> m_eventHandler;
static void bind_func(struct wl_client *client, void *data,
uint32_t version, uint32_t id);
diff --git a/src/compositor/wayland_wrapper/qwlextendedoutput.cpp b/src/compositor/wayland_wrapper/qwlextendedoutput.cpp
deleted file mode 100644
index dbcbb57b8..000000000
--- a/src/compositor/wayland_wrapper/qwlextendedoutput.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Qt Compositor.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwlextendedoutput_p.h"
-
-#include "qwlcompositor_p.h"
-#include "qwlsurface_p.h"
-#include "qwloutput_p.h"
-
-QT_BEGIN_NAMESPACE
-
-namespace QtWayland {
-
-OutputExtensionGlobal::OutputExtensionGlobal(Compositor *compositor)
- : QtWaylandServer::qt_output_extension(compositor->wl_display(), 1)
- , m_compositor(compositor)
-{
-}
-
-void OutputExtensionGlobal::output_extension_get_extended_output(qt_output_extension::Resource *resource, uint32_t id, wl_resource *output_resource)
-{
- OutputResource *output = static_cast<OutputResource *>(Output::Resource::fromResource(output_resource));
- Q_ASSERT(output->extendedOutput == 0);
-
- ExtendedOutput *extendedOutput = static_cast<ExtendedOutput *>(qt_extended_output::add(resource->client(), id));
-
- Q_ASSERT(!output->extendedOutput);
- output->extendedOutput = extendedOutput;
- extendedOutput->output = output;
-}
-
-}
-
-QT_END_NAMESPACE
diff --git a/src/compositor/wayland_wrapper/qwlextendedoutput_p.h b/src/compositor/wayland_wrapper/qwlextendedoutput_p.h
deleted file mode 100644
index 8d030dd95..000000000
--- a/src/compositor/wayland_wrapper/qwlextendedoutput_p.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Qt Compositor.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef WLEXTENDEDOUTPUT_H
-#define WLEXTENDEDOUTPUT_H
-
-#include "wayland-server.h"
-
-#include <QtCompositor/qwaylandexport.h>
-
-#include <QtCore/qnamespace.h>
-
-#include <QtCompositor/private/qwayland-server-output-extension.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace QtWayland {
-
-class Compositor;
-class OutputResource;
-
-class ExtendedOutput : public QtWaylandServer::qt_extended_output::Resource
-{
-public:
- ExtendedOutput() : output(0) {}
-
- OutputResource *output;
-};
-
-class OutputExtensionGlobal : public QtWaylandServer::qt_output_extension, public QtWaylandServer::qt_extended_output
-{
-public:
- OutputExtensionGlobal(Compositor *compositor);
-
-private:
- Compositor *m_compositor;
-
- qt_extended_output::Resource *extended_output_allocate() Q_DECL_OVERRIDE { return new ExtendedOutput; }
-
- void output_extension_get_extended_output(qt_output_extension::Resource *resource,
- uint32_t id,
- struct wl_resource *output_resource) Q_DECL_OVERRIDE;
-};
-
-
-}
-
-QT_END_NAMESPACE
-
-#endif // WLEXTENDEDOUTPUT_H
diff --git a/src/compositor/wayland_wrapper/qwlextendedsurface.cpp b/src/compositor/wayland_wrapper/qwlextendedsurface.cpp
index 1c6a14172..50cc5bb7e 100644
--- a/src/compositor/wayland_wrapper/qwlextendedsurface.cpp
+++ b/src/compositor/wayland_wrapper/qwlextendedsurface.cpp
@@ -85,11 +85,10 @@ void ExtendedSurface::sendGenericProperty(const QString &name, const QVariant &v
}
-void ExtendedSurface::setVisibility(QWindow::Visibility visibility, bool updateClient)
+void ExtendedSurface::setVisibility(QWindow::Visibility visibility)
{
// If this change came from the client, we shouldn't update it
- if (updateClient)
- send_onscreen_visibility(visibility);
+ send_onscreen_visibility(visibility);
}
void ExtendedSurface::setParentSurface(Surface *surface)
diff --git a/src/compositor/wayland_wrapper/qwlextendedsurface_p.h b/src/compositor/wayland_wrapper/qwlextendedsurface_p.h
index e3c370091..8af6232a6 100644
--- a/src/compositor/wayland_wrapper/qwlextendedsurface_p.h
+++ b/src/compositor/wayland_wrapper/qwlextendedsurface_p.h
@@ -80,7 +80,7 @@ public:
void sendGenericProperty(const QString &name, const QVariant &variant);
- void setVisibility(QWindow::Visibility visibility, bool updateClient = true);
+ void setVisibility(QWindow::Visibility visibility);
void setSubSurface(ExtendedSurface *subSurface,int x, int y);
void removeSubSurface(ExtendedSurface *subSurfaces);
diff --git a/src/compositor/wayland_wrapper/qwlkeyboard.cpp b/src/compositor/wayland_wrapper/qwlkeyboard.cpp
index 59b69a3cf..060965663 100644
--- a/src/compositor/wayland_wrapper/qwlkeyboard.cpp
+++ b/src/compositor/wayland_wrapper/qwlkeyboard.cpp
@@ -146,7 +146,15 @@ void Keyboard::setFocus(Surface* surface)
void Keyboard::setKeymap(const QWaylandKeymap &keymap)
{
m_keymap = keymap;
- m_pendingKeymap = true;
+
+ // If there is no key currently pressed, update right away the keymap
+ // Otherwise, delay the update when keys are released
+ // see http://lists.freedesktop.org/archives/wayland-devel/2013-October/011395.html
+ if (m_keys.isEmpty()) {
+ updateKeymap();
+ } else {
+ m_pendingKeymap = true;
+ }
}
void Keyboard::focusDestroyed(void *data)
@@ -216,17 +224,9 @@ void Keyboard::key(uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
}
}
-void Keyboard::sendKeyEvent(uint code, uint32_t state)
+void Keyboard::keyEvent(uint code, uint32_t state)
{
- // There must be no keys pressed when changing the keymap,
- // see http://lists.freedesktop.org/archives/wayland-devel/2013-October/011395.html
- if (m_pendingKeymap && m_keys.isEmpty())
- updateKeymap();
-
- uint32_t time = m_compositor->currentTimeMsecs();
- uint32_t serial = wl_display_next_serial(m_compositor->wl_display());
uint key = code - 8;
- m_grab->key(serial, time, key, state);
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
m_keys << key;
} else {
@@ -236,7 +236,14 @@ void Keyboard::sendKeyEvent(uint code, uint32_t state)
}
}
}
- updateModifierState(code, state);
+}
+
+void Keyboard::sendKeyEvent(uint code, uint32_t state)
+{
+ uint32_t time = m_compositor->currentTimeMsecs();
+ uint32_t serial = wl_display_next_serial(m_compositor->wl_display());
+ uint key = code - 8;
+ m_grab->key(serial, time, key, state);
}
void Keyboard::modifiers(uint32_t serial, uint32_t mods_depressed,
@@ -280,6 +287,11 @@ void Keyboard::updateModifierState(uint code, uint32_t state)
void Keyboard::updateKeymap()
{
+ // There must be no keys pressed when changing the keymap,
+ // see http://lists.freedesktop.org/archives/wayland-devel/2013-October/011395.html
+ if (!m_pendingKeymap || !m_keys.isEmpty())
+ return;
+
m_pendingKeymap = false;
#ifndef QT_NO_WAYLAND_XKB
if (!m_context)
diff --git a/src/compositor/wayland_wrapper/qwlkeyboard_p.h b/src/compositor/wayland_wrapper/qwlkeyboard_p.h
index 2ace8c000..c4df31266 100644
--- a/src/compositor/wayland_wrapper/qwlkeyboard_p.h
+++ b/src/compositor/wayland_wrapper/qwlkeyboard_p.h
@@ -99,10 +99,18 @@ public:
void modifiers(uint32_t serial, uint32_t mods_depressed,
uint32_t mods_latched, uint32_t mods_locked, uint32_t group);
+ void keyEvent(uint code, uint32_t state);
+ void updateModifierState(uint code, uint32_t state);
+ void updateKeymap();
+
void startGrab(KeyboardGrabber *grab);
void endGrab();
KeyboardGrabber *currentGrab() const;
+#ifndef QT_NO_WAYLAND_XKB
+ struct xkb_state *xkbState() const { return m_state; }
+ uint32_t xkbModsMask() const { return m_modsDepressed | m_modsLatched | m_modsLocked; }
+#endif
Q_SIGNALS:
void focusChanged(Surface *surface);
@@ -114,8 +122,6 @@ protected:
private:
void sendKeyEvent(uint code, uint32_t state);
- void updateModifierState(uint code, uint32_t state);
- void updateKeymap();
void focusDestroyed(void *data);
#ifndef QT_NO_WAYLAND_XKB
diff --git a/src/compositor/wayland_wrapper/qwloutput.cpp b/src/compositor/wayland_wrapper/qwloutput.cpp
index ba9338d34..0cbe166e2 100644
--- a/src/compositor/wayland_wrapper/qwloutput.cpp
+++ b/src/compositor/wayland_wrapper/qwloutput.cpp
@@ -42,7 +42,6 @@
#include "qwloutput_p.h"
#include "qwlcompositor_p.h"
-#include "qwlextendedoutput_p.h"
#include "qwlsurface_p.h"
#include <QtGui/QWindow>
diff --git a/src/compositor/wayland_wrapper/qwloutput_p.h b/src/compositor/wayland_wrapper/qwloutput_p.h
index 1bf6e01f6..b85081e80 100644
--- a/src/compositor/wayland_wrapper/qwloutput_p.h
+++ b/src/compositor/wayland_wrapper/qwloutput_p.h
@@ -57,12 +57,10 @@ class QWindow;
namespace QtWayland {
class Compositor;
-class ExtendedOutput;
struct OutputResource : public QtWaylandServer::wl_output::Resource
{
- OutputResource() : extendedOutput(0) {}
- ExtendedOutput *extendedOutput;
+ OutputResource() {}
};
class Output : public QtWaylandServer::wl_output
diff --git a/src/compositor/wayland_wrapper/qwlshellsurface.cpp b/src/compositor/wayland_wrapper/qwlshellsurface.cpp
index beb11d095..b2725462b 100644
--- a/src/compositor/wayland_wrapper/qwlshellsurface.cpp
+++ b/src/compositor/wayland_wrapper/qwlshellsurface.cpp
@@ -254,8 +254,7 @@ void ShellSurface::shell_surface_set_toplevel(Resource *resource)
setSurfaceType(QWaylandSurface::Toplevel);
- if (m_surface->extendedSurface())
- m_surface->extendedSurface()->setVisibility(QWindow::Windowed, false);
+ m_surface->setVisibility(QWindow::Windowed);
}
void ShellSurface::shell_surface_set_transient(Resource *resource,
@@ -275,8 +274,7 @@ void ShellSurface::shell_surface_set_transient(Resource *resource,
setSurfaceType(QWaylandSurface::Transient);
- if (m_surface->extendedSurface())
- m_surface->extendedSurface()->setVisibility(QWindow::AutomaticVisibility, false);
+ m_surface->setVisibility(QWindow::AutomaticVisibility);
}
void ShellSurface::shell_surface_set_fullscreen(Resource *resource,
@@ -310,8 +308,7 @@ void ShellSurface::shell_surface_set_fullscreen(Resource *resource,
m_view->setPos(output->geometry().topLeft());
send_configure(resize_bottom_right, outputSize.width(), outputSize.height());
- if (m_surface->extendedSurface())
- m_surface->extendedSurface()->setVisibility(QWindow::FullScreen, false);
+ m_surface->setVisibility(QWindow::FullScreen);
}
void ShellSurface::shell_surface_set_popup(Resource *resource, wl_resource *input_device, uint32_t serial, wl_resource *parent, int32_t x, int32_t y, uint32_t flags)
@@ -329,8 +326,7 @@ void ShellSurface::shell_surface_set_popup(Resource *resource, wl_resource *inpu
setSurfaceType(QWaylandSurface::Popup);
- if (m_surface->extendedSurface())
- m_surface->extendedSurface()->setVisibility(QWindow::AutomaticVisibility, false);
+ m_surface->setVisibility(QWindow::AutomaticVisibility);
}
void ShellSurface::shell_surface_set_maximized(Resource *resource,
@@ -360,8 +356,7 @@ void ShellSurface::shell_surface_set_maximized(Resource *resource,
m_view->setPos(output->availableGeometry().topLeft());
send_configure(resize_bottom_right, outputSize.width(), outputSize.height());
- if (m_surface->extendedSurface())
- m_surface->extendedSurface()->setVisibility(QWindow::Maximized, false);
+ m_surface->setVisibility(QWindow::Maximized);
}
void ShellSurface::shell_surface_pong(Resource *resource,
diff --git a/src/compositor/wayland_wrapper/qwlsurface.cpp b/src/compositor/wayland_wrapper/qwlsurface.cpp
index 2b7f21aee..d23c6aeb0 100644
--- a/src/compositor/wayland_wrapper/qwlsurface.cpp
+++ b/src/compositor/wayland_wrapper/qwlsurface.cpp
@@ -129,6 +129,8 @@ Surface::Surface(struct wl_client *client, uint32_t id, int version, QWaylandCom
, m_destroyed(false)
, m_contentOrientation(Qt::PrimaryOrientation)
, m_visibility(QWindow::Hidden)
+ , m_role(0)
+ , m_roleHandler(0)
{
m_pending.buffer = 0;
m_pending.newlyAttached = false;
@@ -150,6 +152,17 @@ Surface::~Surface()
c->destroy();
}
+bool Surface::setRole(const SurfaceRole *role, wl_resource *errorResource, uint32_t errorCode)
+{
+ if (m_role && m_role != role) {
+ wl_resource_post_error(errorResource, errorCode, "Cannot assign role %s to wl_surface@%d, already has role %s\n", role->name,
+ wl_resource_get_id(resource()->handle), m_role->name);
+ return false;
+ }
+ m_role = role;
+ return true;
+}
+
void Surface::setTransientOffset(qreal x, qreal y)
{
m_transientOffset.setX(x);
@@ -187,7 +200,7 @@ bool Surface::isYInverted() const
bool Surface::mapped() const
{
- return m_buffer ? bool(m_buffer->waylandBufferHandle()) : false;
+ return !m_unmapLocks.isEmpty() || (m_buffer && bool(m_buffer->waylandBufferHandle()));
}
QSize Surface::size() const
@@ -353,7 +366,8 @@ void Surface::setBackBuffer(SurfaceBuffer *buffer)
if (m_buffer) {
bool valid = m_buffer->waylandBufferHandle() != 0;
- setSize(valid ? m_buffer->size() : QSize());
+ if (valid)
+ setSize(m_buffer->size());
m_damage = m_damage.intersected(QRect(QPoint(), m_size));
emit m_waylandSurface->damaged(m_damage);
@@ -374,6 +388,20 @@ void Surface::setMapped(bool mapped)
}
}
+void Surface::addUnmapLock(QWaylandUnmapLock *l)
+{
+ m_unmapLocks << l;
+}
+
+void Surface::removeUnmapLock(QWaylandUnmapLock *l)
+{
+ m_unmapLocks.removeOne(l);
+ if (!mapped() && m_attacher) {
+ setSize(QSize());
+ m_attacher->unmap();
+ }
+}
+
SurfaceBuffer *Surface::createSurfaceBuffer(struct ::wl_resource *buffer)
{
SurfaceBuffer *newBuffer = 0;
@@ -468,9 +496,17 @@ void Surface::surface_commit(Resource *)
setBackBuffer(m_pending.buffer);
m_bufferRef = QWaylandBufferRef(m_buffer);
- if (m_attacher)
- m_attacher->attach(m_bufferRef);
+ if (m_attacher) {
+ if (m_bufferRef) {
+ m_attacher->attach(m_bufferRef);
+ } else if (!mapped()) {
+ setSize(QSize());
+ m_attacher->unmap();
+ }
+ }
emit m_waylandSurface->configure(m_bufferRef);
+ if (m_roleHandler)
+ m_roleHandler->configure(m_pending.offset.x(), m_pending.offset.y());
}
m_pending.buffer = 0;
diff --git a/src/compositor/wayland_wrapper/qwlsurface_p.h b/src/compositor/wayland_wrapper/qwlsurface_p.h
index 103b5994a..d08fb4cd6 100644
--- a/src/compositor/wayland_wrapper/qwlsurface_p.h
+++ b/src/compositor/wayland_wrapper/qwlsurface_p.h
@@ -65,6 +65,8 @@ QT_BEGIN_NAMESPACE
class QTouchEvent;
+class QWaylandUnmapLock;
+
namespace QtWayland {
class Compositor;
@@ -74,12 +76,20 @@ class InputPanelSurface;
class SubSurface;
class FrameCallback;
+class SurfaceRole;
+class RoleBase;
+
class Q_COMPOSITOR_EXPORT Surface : public QtWaylandServer::wl_surface
{
public:
Surface(struct wl_client *client, uint32_t id, int version, QWaylandCompositor *compositor, QWaylandSurface *surface);
~Surface();
+ bool setRole(const SurfaceRole *role, wl_resource *errorResource, uint32_t errorCode);
+ const SurfaceRole *role() const { return m_role; }
+ template<class T>
+ bool setRoleHandler(T *handler);
+
static Surface *fromResource(struct ::wl_resource *resource);
QWaylandSurface::Type type() const;
@@ -141,7 +151,11 @@ public:
void releaseSurfaces();
void frameStarted();
+ void addUnmapLock(QWaylandUnmapLock *l);
+ void removeUnmapLock(QWaylandUnmapLock *l);
+
void setMapped(bool mapped);
+ void setVisibility(QWindow::Visibility visibility) { m_visibility = visibility; }
inline bool isDestroyed() const { return m_destroyed; }
@@ -176,6 +190,7 @@ protected:
QWaylandBufferRef m_bufferRef;
bool m_surfaceMapped;
QWaylandBufferAttacher *m_attacher;
+ QVector<QWaylandUnmapLock *> m_unmapLocks;
struct {
SurfaceBuffer *buffer;
@@ -211,12 +226,66 @@ protected:
Qt::ScreenOrientation m_contentOrientation;
QWindow::Visibility m_visibility;
+ const SurfaceRole *m_role;
+ RoleBase *m_roleHandler;
+
void setBackBuffer(SurfaceBuffer *buffer);
SurfaceBuffer *createSurfaceBuffer(struct ::wl_resource *buffer);
friend class QWaylandSurface;
+ friend class RoleBase;
+};
+
+class SurfaceRole
+{
+public:
+ const char *name;
+};
+
+class RoleBase
+{
+public:
+ virtual ~RoleBase() {
+ if (m_surface) {
+ m_surface->m_roleHandler = 0; m_surface = 0;
+ }
+ }
+
+protected:
+ RoleBase() : m_surface(0) {}
+ static inline RoleBase *roleOf(Surface *s) { return s->m_roleHandler; }
+
+ virtual void configure(int dx, int dy) = 0;
+
+private:
+ Surface *m_surface;
+ friend class Surface;
+};
+
+template<class T>
+class SurfaceRoleHandler : public RoleBase
+{
+public:
+ static T *get(Surface *surface) {
+ if (surface->role() == T::role()) {
+ return static_cast<T *>(roleOf(surface));
+ }
+ return 0;
+ }
};
+template<class T>
+bool Surface::setRoleHandler(T *handler)
+{
+ RoleBase *base = handler;
+ if (m_role == T::role()) {
+ m_roleHandler = base;
+ base->m_surface = this;
+ return true;
+ }
+ return false;
+}
+
}
QT_END_NAMESPACE
diff --git a/src/compositor/wayland_wrapper/wayland_wrapper.pri b/src/compositor/wayland_wrapper/wayland_wrapper.pri
index ac34ae283..eb66f6949 100644
--- a/src/compositor/wayland_wrapper/wayland_wrapper.pri
+++ b/src/compositor/wayland_wrapper/wayland_wrapper.pri
@@ -2,7 +2,6 @@ CONFIG += wayland-scanner
WAYLANDSERVERSOURCES += \
../extensions/surface-extension.xml \
../extensions/sub-surface-extension.xml \
- ../extensions/output-extension.xml \
../extensions/touch-extension.xml \
../extensions/qtkey-extension.xml \
../extensions/windowmanager.xml \
@@ -17,7 +16,6 @@ HEADERS += \
wayland_wrapper/qwldataoffer_p.h \
wayland_wrapper/qwldatasource_p.h \
wayland_wrapper/qwldisplay_p.h \
- wayland_wrapper/qwlextendedoutput_p.h \
wayland_wrapper/qwlextendedsurface_p.h \
wayland_wrapper/qwlinputdevice_p.h \
wayland_wrapper/qwlinputmethod_p.h \
@@ -38,6 +36,7 @@ HEADERS += \
wayland_wrapper/qwltextinputmanager_p.h \
wayland_wrapper/qwltouch_p.h \
wayland_wrapper/qwllistener_p.h \
+ ../shared/qwaylandxkb.h \
SOURCES += \
wayland_wrapper/qwlcompositor.cpp \
@@ -46,7 +45,6 @@ SOURCES += \
wayland_wrapper/qwldataoffer.cpp \
wayland_wrapper/qwldatasource.cpp \
wayland_wrapper/qwldisplay.cpp \
- wayland_wrapper/qwlextendedoutput.cpp \
wayland_wrapper/qwlextendedsurface.cpp \
wayland_wrapper/qwlinputdevice.cpp \
wayland_wrapper/qwlinputmethod.cpp \
@@ -67,6 +65,7 @@ SOURCES += \
wayland_wrapper/qwltextinputmanager.cpp \
wayland_wrapper/qwltouch.cpp \
wayland_wrapper/qwllistener.cpp \
+ ../shared/qwaylandxkb.cpp \
INCLUDEPATH += wayland_wrapper