summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@theqtcompany.com>2014-11-15 18:52:23 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-11-15 18:52:23 +0100
commit6b8b6b80a1852c1e4d0a626129d4382d11423a54 (patch)
tree499a3b70704680f03841acb4c170af2e57fd1358 /src
parentadc12b2ef322e59a7c65600da91e8b642a94b187 (diff)
parent4613291e8c1717d8d3316b2c0b1f2c6c96bdc56f (diff)
Merge "Merge branch '5.4' into dev" into refs/staging/dev
Diffstat (limited to 'src')
-rw-r--r--src/client/client.pro11
-rw-r--r--src/client/inputdeviceintegration/qwaylandinputdeviceintegration_p.h2
-rw-r--r--src/client/qwaylandabstractdecoration.cpp187
-rw-r--r--src/client/qwaylandabstractdecoration_p.h (renamed from src/client/qwaylanddecoration_p.h)79
-rw-r--r--src/client/qwaylandcursor.cpp8
-rw-r--r--src/client/qwaylanddatadevice.cpp3
-rw-r--r--src/client/qwaylanddatadevice_p.h2
-rw-r--r--src/client/qwaylanddecorationfactory.cpp97
-rw-r--r--src/client/qwaylanddecorationfactory_p.h61
-rw-r--r--src/client/qwaylanddecorationplugin.cpp54
-rw-r--r--src/client/qwaylanddecorationplugin_p.h69
-rw-r--r--src/client/qwaylanddisplay.cpp25
-rw-r--r--src/client/qwaylanddisplay_p.h3
-rw-r--r--src/client/qwaylandeventthread.cpp11
-rw-r--r--src/client/qwaylandeventthread_p.h3
-rw-r--r--src/client/qwaylandinputdevice.cpp15
-rw-r--r--src/client/qwaylandinputdevice_p.h2
-rw-r--r--src/client/qwaylandintegration.cpp8
-rw-r--r--src/client/qwaylandintegration_p.h4
-rw-r--r--src/client/qwaylandscreen.cpp56
-rw-r--r--src/client/qwaylandscreen_p.h3
-rw-r--r--src/client/qwaylandshmbackingstore.cpp17
-rw-r--r--src/client/qwaylandshmbackingstore_p.h7
-rw-r--r--src/client/qwaylandwindow.cpp60
-rw-r--r--src/client/qwaylandwindow_p.h8
-rw-r--r--src/client/qwaylandwlshellsurface.cpp2
-rw-r--r--src/client/qwaylandxdgshell.cpp1
-rw-r--r--src/client/qwaylandxdgsurface.cpp2
-rw-r--r--src/compositor/compositor_api/qwaylandquickcompositor.cpp2
-rw-r--r--src/compositor/compositor_api/qwaylandquicksurface.cpp8
-rw-r--r--src/compositor/compositor_api/qwaylandquicksurface.h2
-rw-r--r--src/compositor/compositor_api/qwaylandsurface.cpp17
-rw-r--r--src/compositor/compositor_api/qwaylandsurface.h4
-rw-r--r--src/compositor/compositor_api/qwaylandsurface_p.h2
-rw-r--r--src/compositor/hardware_integration/qwlhwintegration.cpp2
-rw-r--r--src/compositor/wayland_wrapper/qwlcompositor.cpp6
-rw-r--r--src/compositor/wayland_wrapper/qwldatadevicemanager.cpp2
-rw-r--r--src/compositor/wayland_wrapper/qwldataoffer.cpp2
-rw-r--r--src/compositor/wayland_wrapper/qwldatasource.cpp2
-rw-r--r--src/compositor/wayland_wrapper/qwlextendedoutput.cpp4
-rw-r--r--src/compositor/wayland_wrapper/qwlextendedsurface.cpp26
-rw-r--r--src/compositor/wayland_wrapper/qwlextendedsurface_p.h3
-rw-r--r--src/compositor/wayland_wrapper/qwlinputdevice.cpp10
-rw-r--r--src/compositor/wayland_wrapper/qwlinputmethod.cpp2
-rw-r--r--src/compositor/wayland_wrapper/qwlinputmethodcontext.cpp2
-rw-r--r--src/compositor/wayland_wrapper/qwlinputpanel.cpp2
-rw-r--r--src/compositor/wayland_wrapper/qwlinputpanelsurface.cpp2
-rw-r--r--src/compositor/wayland_wrapper/qwlkeyboard.cpp40
-rw-r--r--src/compositor/wayland_wrapper/qwloutput.cpp13
-rw-r--r--src/compositor/wayland_wrapper/qwlqtkey.cpp2
-rw-r--r--src/compositor/wayland_wrapper/qwlqttouch.cpp2
-rw-r--r--src/compositor/wayland_wrapper/qwlregion.cpp2
-rw-r--r--src/compositor/wayland_wrapper/qwlshellsurface.cpp19
-rw-r--r--src/compositor/wayland_wrapper/qwlshellsurface_p.h1
-rw-r--r--src/compositor/wayland_wrapper/qwlsurface.cpp7
-rw-r--r--src/compositor/wayland_wrapper/qwlsurface_p.h2
-rw-r--r--src/compositor/wayland_wrapper/qwltextinput.cpp2
-rw-r--r--src/compositor/wayland_wrapper/qwltextinputmanager.cpp2
-rw-r--r--src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.cpp2
-rw-r--r--src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp8
-rw-r--r--src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.h2
-rw-r--r--src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp1
-rw-r--r--src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp376
-rw-r--r--src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h14
-rw-r--r--src/hardwareintegration/compositor/brcm-egl/brcmbuffer.cpp2
-rw-r--r--src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.cpp2
-rw-r--r--src/hardwareintegration/compositor/drm-egl-server/drmeglserverbufferintegration.cpp4
-rw-r--r--src/hardwareintegration/compositor/libhybris-egl-server/libhybriseglserverbufferintegration.cpp4
-rw-r--r--src/hardwareintegration/compositor/xcomposite_share/xcompositebuffer.cpp2
-rw-r--r--src/hardwareintegration/compositor/xcomposite_share/xcompositehandler.cpp2
-rw-r--r--src/plugins/decorations/bradient/bradient.json3
-rw-r--r--src/plugins/decorations/bradient/bradient.pro17
-rw-r--r--src/plugins/decorations/bradient/main.cpp (renamed from src/client/qwaylanddecoration.cpp)219
-rw-r--r--src/plugins/decorations/decorations.pro3
-rw-r--r--src/plugins/plugins.pro5
-rw-r--r--src/qtwaylandscanner/qtwaylandscanner.cpp51
76 files changed, 1211 insertions, 498 deletions
diff --git a/src/client/client.pro b/src/client/client.pro
index 22271ee45..ef3cff054 100644
--- a/src/client/client.pro
+++ b/src/client/client.pro
@@ -5,7 +5,8 @@ QT_FOR_PRIVATE += platformsupport-private
MODULE=waylandclient
MODULE_PLUGIN_TYPES = \
wayland-graphics-integration-client \
- wayland-inputdevice-integration
+ wayland-inputdevice-integration \
+ wayland-decoration-client
load(qt_module)
@@ -71,7 +72,9 @@ SOURCES += qwaylandintegration.cpp \
qwaylandtouch.cpp \
qwaylandqtkey.cpp \
../shared/qwaylandmimehelper.cpp \
- qwaylanddecoration.cpp \
+ qwaylandabstractdecoration.cpp \
+ qwaylanddecorationfactory.cpp \
+ qwaylanddecorationplugin.cpp \
qwaylandeventthread.cpp\
qwaylandwindowmanagerintegration.cpp \
qwaylandinputcontext.cpp \
@@ -102,7 +105,9 @@ HEADERS += qwaylandintegration_p.h \
qwaylandtouch_p.h \
qwaylandqtkey_p.h \
../shared/qwaylandmimehelper.h \
- qwaylanddecoration_p.h \
+ qwaylandabstractdecoration_p.h \
+ qwaylanddecorationfactory_p.h \
+ qwaylanddecorationplugin_p.h \
qwaylandeventthread_p.h \
qwaylandwindowmanagerintegration_p.h \
qwaylandinputcontext_p.h \
diff --git a/src/client/inputdeviceintegration/qwaylandinputdeviceintegration_p.h b/src/client/inputdeviceintegration/qwaylandinputdeviceintegration_p.h
index 255a66854..5fa187e69 100644
--- a/src/client/inputdeviceintegration/qwaylandinputdeviceintegration_p.h
+++ b/src/client/inputdeviceintegration/qwaylandinputdeviceintegration_p.h
@@ -56,7 +56,7 @@ public:
QWaylandInputDeviceIntegration() {}
virtual ~QWaylandInputDeviceIntegration() {}
- virtual QWaylandInputDevice *createInputDevice(QWaylandDisplay *d, uint32_t id) = 0;
+ virtual QWaylandInputDevice *createInputDevice(QWaylandDisplay *d, int version, uint32_t id) = 0;
};
QT_END_NAMESPACE
diff --git a/src/client/qwaylandabstractdecoration.cpp b/src/client/qwaylandabstractdecoration.cpp
new file mode 100644
index 000000000..e4b81bb83
--- /dev/null
+++ b/src/client/qwaylandabstractdecoration.cpp
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Robin Burchell <robin.burchell@viroteck.net>
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandabstractdecoration_p.h"
+
+#include <private/qobject_p.h>
+#include "qwaylandwindow_p.h"
+#include "qwaylandshellsurface_p.h"
+#include "qwaylandinputdevice_p.h"
+#include "qwaylandscreen_p.h"
+
+#include <QtGui/QImage>
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandAbstractDecorationPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QWaylandAbstractDecoration)
+
+public:
+ QWaylandAbstractDecorationPrivate();
+ ~QWaylandAbstractDecorationPrivate();
+
+ QWindow *m_window;
+ QWaylandWindow *m_wayland_window;
+
+ bool m_isDirty;
+ QImage m_decorationContentImage;
+
+ Qt::MouseButtons m_mouseButtons;
+};
+
+QWaylandAbstractDecorationPrivate::QWaylandAbstractDecorationPrivate()
+ : m_window(0)
+ , m_wayland_window(0)
+ , m_isDirty(true)
+ , m_decorationContentImage(0)
+ , m_mouseButtons(Qt::NoButton)
+{
+}
+
+QWaylandAbstractDecorationPrivate::~QWaylandAbstractDecorationPrivate()
+{
+}
+
+QWaylandAbstractDecoration::QWaylandAbstractDecoration()
+ : QObject(*new QWaylandAbstractDecorationPrivate)
+{
+}
+
+QWaylandAbstractDecoration::~QWaylandAbstractDecoration()
+{
+}
+
+// we do this as a setter to get around plugin factory creates not really
+// being a great way to pass arguments
+void QWaylandAbstractDecoration::setWaylandWindow(QWaylandWindow *window)
+{
+ Q_D(QWaylandAbstractDecoration);
+
+ // double initialization is probably not great
+ Q_ASSERT(!d->m_window && !d->m_wayland_window);
+
+ d->m_window = window->window();
+ d->m_wayland_window = window;
+}
+
+const QImage &QWaylandAbstractDecoration::contentImage()
+{
+ Q_D(QWaylandAbstractDecoration);
+ if (d->m_isDirty) {
+ //Update the decoration backingstore
+
+ d->m_decorationContentImage = QImage(window()->frameGeometry().size(), QImage::Format_ARGB32_Premultiplied);
+ d->m_decorationContentImage.fill(Qt::transparent);
+ this->paint(&d->m_decorationContentImage);
+
+ d->m_isDirty = false;
+ }
+
+ return d->m_decorationContentImage;
+}
+
+void QWaylandAbstractDecoration::update()
+{
+ Q_D(QWaylandAbstractDecoration);
+ d->m_isDirty = true;
+}
+
+void QWaylandAbstractDecoration::setMouseButtons(Qt::MouseButtons mb)
+{
+ Q_D(QWaylandAbstractDecoration);
+ d->m_mouseButtons = mb;
+}
+
+void QWaylandAbstractDecoration::startResize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize resize, Qt::MouseButtons buttons)
+{
+ Q_D(QWaylandAbstractDecoration);
+ if (isLeftClicked(buttons)) {
+ d->m_wayland_window->shellSurface()->resize(inputDevice, resize);
+ inputDevice->removeMouseButtonFromState(Qt::LeftButton);
+ }
+}
+
+void QWaylandAbstractDecoration::startMove(QWaylandInputDevice *inputDevice, Qt::MouseButtons buttons)
+{
+ Q_D(QWaylandAbstractDecoration);
+ if (isLeftClicked(buttons)) {
+ d->m_wayland_window->shellSurface()->move(inputDevice);
+ inputDevice->removeMouseButtonFromState(Qt::LeftButton);
+ }
+}
+
+bool QWaylandAbstractDecoration::isLeftClicked(Qt::MouseButtons newMouseButtonState)
+{
+ Q_D(QWaylandAbstractDecoration);
+ if ((!d->m_mouseButtons & Qt::LeftButton) && (newMouseButtonState & Qt::LeftButton))
+ return true;
+ return false;
+}
+
+bool QWaylandAbstractDecoration::isLeftReleased(Qt::MouseButtons newMouseButtonState)
+{
+ Q_D(QWaylandAbstractDecoration);
+ if ((d->m_mouseButtons & Qt::LeftButton) && !(newMouseButtonState & Qt::LeftButton))
+ return true;
+ return false;
+}
+
+bool QWaylandAbstractDecoration::isDirty() const
+{
+ Q_D(const QWaylandAbstractDecoration);
+ return d->m_isDirty;
+}
+
+QWindow *QWaylandAbstractDecoration::window() const
+{
+ Q_D(const QWaylandAbstractDecoration);
+ return d->m_window;
+}
+
+QWaylandWindow *QWaylandAbstractDecoration::waylandWindow() const
+{
+ Q_D(const QWaylandAbstractDecoration);
+ return d->m_wayland_window;
+}
+
+QT_END_NAMESPACE
diff --git a/src/client/qwaylanddecoration_p.h b/src/client/qwaylandabstractdecoration_p.h
index c240b9c9d..6171cab14 100644
--- a/src/client/qwaylanddecoration_p.h
+++ b/src/client/qwaylandabstractdecoration_p.h
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2014 Robin Burchell <robin.burchell@viroteck.net>
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
@@ -39,8 +40,8 @@
**
****************************************************************************/
-#ifndef QWAYLANDDECORATION_H
-#define QWAYLANDDECORATION_H
+#ifndef QWAYLANDABSTRACTDECORATION_H
+#define QWAYLANDABSTRACTDECORATION_H
#include <QtCore/QMargins>
#include <QtCore/QPointF>
@@ -64,77 +65,41 @@ class QEvent;
class QWaylandScreen;
class QWaylandWindow;
class QWaylandInputDevice;
+class QWaylandAbstractDecorationPrivate;
-class Q_WAYLAND_CLIENT_EXPORT QWaylandDecoration
+class Q_WAYLAND_CLIENT_EXPORT QWaylandAbstractDecoration : public QObject
{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QWaylandAbstractDecoration)
public:
- QWaylandDecoration(QWaylandWindow *window);
- virtual ~QWaylandDecoration();
+ QWaylandAbstractDecoration();
+ virtual ~QWaylandAbstractDecoration();
+
+ void setWaylandWindow(QWaylandWindow *window);
+ QWaylandWindow *waylandWindow() const;
void update();
bool isDirty() const;
- bool handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,Qt::MouseButtons b,Qt::KeyboardModifiers mods);
- bool handleTouch(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::TouchPointState state, Qt::KeyboardModifiers mods);
- bool inMouseButtonPressedState() const;
-
- void startResize(QWaylandInputDevice *inputDevice,enum wl_shell_surface_resize resize, Qt::MouseButtons buttons);
- void startMove(QWaylandInputDevice *inputDevice, Qt::MouseButtons buttons);
- QMargins margins() const;
+ virtual QMargins margins() const = 0;
QWindow *window() const;
- QWaylandWindow *waylandWindow() const;
const QImage &contentImage();
+ virtual bool handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,Qt::MouseButtons b,Qt::KeyboardModifiers mods) = 0;
+ virtual bool handleTouch(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::TouchPointState state, Qt::KeyboardModifiers mods) = 0;
+
protected:
- void paint(QPaintDevice *device);
+ virtual void paint(QPaintDevice *device) = 0;
+
+ void setMouseButtons(Qt::MouseButtons mb);
-private:
- void processMouseTop(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods);
- void processMouseBottom(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods);
- void processMouseLeft(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods);
- void processMouseRight(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods);
+ void startResize(QWaylandInputDevice *inputDevice,enum wl_shell_surface_resize resize, Qt::MouseButtons buttons);
+ void startMove(QWaylandInputDevice *inputDevice, Qt::MouseButtons buttons);
bool isLeftClicked(Qt::MouseButtons newMouseButtonState);
bool isLeftReleased(Qt::MouseButtons newMouseButtonState);
-
- QRectF closeButtonRect() const;
- QRectF maximizeButtonRect() const;
- QRectF minimizeButtonRect() const;
-
- QWindow *m_window;
- QWaylandWindow *m_wayland_window;
-
- bool m_isDirty;
- QImage m_decorationContentImage;
-
- QMargins m_margins;
- Qt::MouseButtons m_mouseButtons;
-
- QColor m_foregroundColor;
- QColor m_backgroundColor;
- QStaticText m_windowTitle;
};
-inline bool QWaylandDecoration::isDirty() const
-{
- return m_isDirty;
-}
-
-inline QMargins QWaylandDecoration::margins() const
-{
- return m_margins;
-}
-
-inline QWindow *QWaylandDecoration::window() const
-{
- return m_window;
-}
-
-inline QWaylandWindow *QWaylandDecoration::waylandWindow() const
-{
- return m_wayland_window;
-}
-
QT_END_NAMESPACE
-#endif // QWAYLANDDECORATION_H
+#endif // QWAYLANDABSTRACTDECORATION_H
diff --git a/src/client/qwaylandcursor.cpp b/src/client/qwaylandcursor.cpp
index 90789b0df..2a1339a79 100644
--- a/src/client/qwaylandcursor.cpp
+++ b/src/client/qwaylandcursor.cpp
@@ -66,12 +66,15 @@ QWaylandCursor::QWaylandCursor(QWaylandScreen *screen)
if (!hasCursorSize || cursorSize <= 0)
cursorSize = 32;
mCursorTheme = wl_cursor_theme_load(cursorTheme, cursorSize, mDisplay->shm());
+ if (!mCursorTheme)
+ qDebug() << "Could not load theme" << cursorTheme;
initCursorMap();
}
QWaylandCursor::~QWaylandCursor()
{
- wl_cursor_theme_destroy(mCursorTheme);
+ if (mCursorTheme)
+ wl_cursor_theme_destroy(mCursorTheme);
}
struct wl_cursor_image *QWaylandCursor::cursorImage(Qt::CursorShape newShape)
@@ -160,6 +163,9 @@ wl_cursor *QWaylandCursor::requestCursor(WaylandCursor shape)
//If the cursor has not been loaded already, load it
if (!cursor) {
+ if (!mCursorTheme)
+ return NULL;
+
QList<QByteArray> cursorNames = mCursorNamesMap.values(shape);
foreach (QByteArray name, cursorNames) {
cursor = wl_cursor_theme_get_cursor(mCursorTheme, name.constData());
diff --git a/src/client/qwaylanddatadevice.cpp b/src/client/qwaylanddatadevice.cpp
index 74f879f97..83e74ce6c 100644
--- a/src/client/qwaylanddatadevice.cpp
+++ b/src/client/qwaylanddatadevice.cpp
@@ -60,6 +60,7 @@
QWaylandDataDevice::QWaylandDataDevice(QWaylandDataDeviceManager *manager, QWaylandInputDevice *inputDevice)
: QtWayland::wl_data_device(manager->get_data_device(inputDevice->wl_seat()))
, m_display(manager->display())
+ , m_inputDevice(inputDevice)
, m_enterSerial(0)
, m_dragWindow(0)
, m_dragPoint()
@@ -92,7 +93,7 @@ void QWaylandDataDevice::setSelectionSource(QWaylandDataSource *source)
m_selectionSource.reset(source);
if (source)
connect(source, &QWaylandDataSource::cancelled, this, &QWaylandDataDevice::selectionSourceCancelled);
- set_selection(source ? source->object() : 0, 0 /* TODO m_display->serial() */);
+ set_selection(source ? source->object() : Q_NULLPTR, m_inputDevice->serial());
}
QWaylandDataOffer *QWaylandDataDevice::dragOffer() const
diff --git a/src/client/qwaylanddatadevice_p.h b/src/client/qwaylanddatadevice_p.h
index dae91290e..ef82d84dd 100644
--- a/src/client/qwaylanddatadevice_p.h
+++ b/src/client/qwaylanddatadevice_p.h
@@ -88,7 +88,7 @@ private Q_SLOTS:
private:
QWaylandDisplay *m_display;
-
+ QWaylandInputDevice *m_inputDevice;
uint32_t m_enterSerial;
QWindow *m_dragWindow;
QPoint m_dragPoint;
diff --git a/src/client/qwaylanddecorationfactory.cpp b/src/client/qwaylanddecorationfactory.cpp
new file mode 100644
index 000000000..6f1f74693
--- /dev/null
+++ b/src/client/qwaylanddecorationfactory.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Robin Burchell <robin.burchell@viroteck.net>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylanddecorationfactory_p.h"
+#include "qwaylanddecorationplugin_p.h"
+
+#include <QtCore/private/qfactoryloader_p.h>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDir>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_LIBRARY
+Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
+ (QWaylandDecorationFactoryInterface_iid, QLatin1String("/wayland-decoration-client"), Qt::CaseInsensitive))
+Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, directLoader,
+ (QWaylandDecorationFactoryInterface_iid, QLatin1String(""), Qt::CaseInsensitive))
+#endif
+
+QStringList QWaylandDecorationFactory::keys(const QString &pluginPath)
+{
+#ifndef QT_NO_LIBRARY
+ QStringList list;
+ if (!pluginPath.isEmpty()) {
+ QCoreApplication::addLibraryPath(pluginPath);
+ list = directLoader()->keyMap().values();
+ if (!list.isEmpty()) {
+ const QString postFix = QStringLiteral(" (from ")
+ + QDir::toNativeSeparators(pluginPath)
+ + QLatin1Char(')');
+ const QStringList::iterator end = list.end();
+ for (QStringList::iterator it = list.begin(); it != end; ++it)
+ (*it).append(postFix);
+ }
+ }
+ list.append(loader()->keyMap().values());
+ return list;
+#else
+ return QStringList();
+#endif
+}
+
+QWaylandAbstractDecoration *QWaylandDecorationFactory::create(const QString &name, const QStringList &args, const QString &pluginPath)
+{
+#ifndef QT_NO_LIBRARY
+ // Try loading the plugin from platformPluginPath first:
+ if (!pluginPath.isEmpty()) {
+ QCoreApplication::addLibraryPath(pluginPath);
+ if (QWaylandAbstractDecoration *ret = qLoadPlugin1<QWaylandAbstractDecoration, QWaylandDecorationPlugin>(directLoader(), name, args))
+ return ret;
+ }
+ if (QWaylandAbstractDecoration *ret = qLoadPlugin1<QWaylandAbstractDecoration, QWaylandDecorationPlugin>(loader(), name, args))
+ return ret;
+#endif
+
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/client/qwaylanddecorationfactory_p.h b/src/client/qwaylanddecorationfactory_p.h
new file mode 100644
index 000000000..a7729bcaf
--- /dev/null
+++ b/src/client/qwaylanddecorationfactory_p.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Robin Burchell <robin.burchell@viroteck.net>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDDECORATIONFACTORY_H
+#define QWAYLANDDECORATIONFACTORY_H
+
+#include <QtWaylandClient/private/qwaylandclientexport_p.h>
+#include <QtCore/QStringList>
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandAbstractDecoration;
+
+class Q_WAYLAND_CLIENT_EXPORT QWaylandDecorationFactory
+{
+public:
+ static QStringList keys(const QString &pluginPath = QString());
+ static QWaylandAbstractDecoration *create(const QString &name, const QStringList &args, const QString &pluginPath = QString());
+};
+
+QT_END_NAMESPACE
+
+#endif // QWAYLANDDECORATIONFACTORY_H
diff --git a/src/client/qwaylanddecorationplugin.cpp b/src/client/qwaylanddecorationplugin.cpp
new file mode 100644
index 000000000..edad5f5f0
--- /dev/null
+++ b/src/client/qwaylanddecorationplugin.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Robin Burchell <robin.burchell@viroteck.net>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylanddecorationplugin_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QWaylandDecorationPlugin::QWaylandDecorationPlugin(QObject *parent)
+ : QObject(parent)
+{
+}
+QWaylandDecorationPlugin::~QWaylandDecorationPlugin()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/client/qwaylanddecorationplugin_p.h b/src/client/qwaylanddecorationplugin_p.h
new file mode 100644
index 000000000..6ed8935db
--- /dev/null
+++ b/src/client/qwaylanddecorationplugin_p.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Robin Burchell <robin.burchell@viroteck.net>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDDECORATIONPLUGIN_H
+#define QWAYLANDDECORATIONPLUGIN_H
+
+#include <QtWaylandClient/private/qwaylandclientexport_p.h>
+
+#include <QtCore/qplugin.h>
+#include <QtCore/qfactoryinterface.h>
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandAbstractDecoration;
+
+#define QWaylandDecorationFactoryInterface_iid "org.qt-project.Qt.WaylandClient.QWaylandDecorationFactoryInterface.5.4"
+
+class Q_WAYLAND_CLIENT_EXPORT QWaylandDecorationPlugin : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QWaylandDecorationPlugin(QObject *parent = 0);
+ ~QWaylandDecorationPlugin();
+
+ virtual QWaylandAbstractDecoration *create(const QString &key, const QStringList &paramList) = 0;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWAYLANDDECORATIONPLUGIN_H
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
index c4a702d74..023050326 100644
--- a/src/client/qwaylanddisplay.cpp
+++ b/src/client/qwaylanddisplay.cpp
@@ -159,6 +159,7 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration)
init(registry);
connect(mEventThreadObject, SIGNAL(newEventsRead()), this, SLOT(flushRequests()));
+ connect(mEventThreadObject, &QWaylandEventThread::fatalError, this, &QWaylandDisplay::exitWithError);
mWindowManagerIntegration.reset(new QWaylandWindowManagerIntegration(this));
@@ -177,8 +178,10 @@ QWaylandDisplay::~QWaylandDisplay(void)
void QWaylandDisplay::flushRequests()
{
- if (wl_display_dispatch_queue_pending(mDisplay, mEventQueue) < 0)
- mEventThreadObject->checkErrorAndExit();
+ if (wl_display_dispatch_queue_pending(mDisplay, mEventQueue) < 0) {
+ mEventThreadObject->checkError();
+ exitWithError();
+ }
wl_display_flush(mDisplay);
}
@@ -186,8 +189,15 @@ void QWaylandDisplay::flushRequests()
void QWaylandDisplay::blockingReadEvents()
{
- if (wl_display_dispatch_queue(mDisplay, mEventQueue) < 0)
- mEventThreadObject->checkErrorAndExit();
+ if (wl_display_dispatch_queue(mDisplay, mEventQueue) < 0) {
+ mEventThreadObject->checkError();
+ exitWithError();
+ }
+}
+
+void QWaylandDisplay::exitWithError()
+{
+ ::exit(1);
}
QWaylandScreen *QWaylandDisplay::screenForOutput(struct wl_output *output) const
@@ -226,13 +236,14 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
struct ::wl_registry *registry = object();
if (interface == QStringLiteral("wl_output")) {
- QWaylandScreen *screen = new QWaylandScreen(this, id);
+ QWaylandScreen *screen = new QWaylandScreen(this, version, id);
mScreens.append(screen);
// We need to get the output events before creating surfaces
forceRoundTrip();
mWaylandIntegration->screenAdded(screen);
} else if (interface == QStringLiteral("wl_compositor")) {
- mCompositor.init(registry, id, 3);
+ mCompositorVersion = qMin((int)version, 3);
+ mCompositor.init(registry, id, mCompositorVersion);
} else if (interface == QStringLiteral("wl_shm")) {
mShm = static_cast<struct wl_shm *>(wl_registry_bind(registry, id, &wl_shm_interface,1));
} else if (interface == QStringLiteral("xdg_shell")
@@ -241,7 +252,7 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
} else if (interface == QStringLiteral("wl_shell")){
mShell.reset(new QtWayland::wl_shell(registry, id, 1));
} else if (interface == QStringLiteral("wl_seat")) {
- QWaylandInputDevice *inputDevice = mWaylandIntegration->createInputDevice(this, id);
+ QWaylandInputDevice *inputDevice = mWaylandIntegration->createInputDevice(this, version, id);
mInputDevices.append(inputDevice);
} else if (interface == QStringLiteral("wl_data_device_manager")) {
mDndSelectionHandler.reset(new QWaylandDataDeviceManager(this, id));
diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h
index 05bd7f15a..2f12ee7f9 100644
--- a/src/client/qwaylanddisplay_p.h
+++ b/src/client/qwaylanddisplay_p.h
@@ -117,6 +117,7 @@ public:
const struct wl_compositor *wl_compositor() const { return mCompositor.object(); }
QtWayland::wl_compositor *compositor() { return &mCompositor; }
+ int compositorVersion() const { return mCompositorVersion; }
QtWayland::wl_shell *shell() { return mShell.data(); }
QtWayland::xdg_shell *shellXdg();
@@ -165,6 +166,7 @@ public slots:
private:
void waitForScreens();
+ void exitWithError();
struct Listener {
RegistryListener listener;
@@ -198,6 +200,7 @@ private:
int mWritableNotificationFd;
bool mScreensInitialized;
QList<RegistryGlobal> mGlobals;
+ int mCompositorVersion;
void registry_global(uint32_t id, const QString &interface, uint32_t version) Q_DECL_OVERRIDE;
void registry_global_remove(uint32_t id) Q_DECL_OVERRIDE;
diff --git a/src/client/qwaylandeventthread.cpp b/src/client/qwaylandeventthread.cpp
index b7266765e..22efd6a2a 100644
--- a/src/client/qwaylandeventthread.cpp
+++ b/src/client/qwaylandeventthread.cpp
@@ -73,7 +73,7 @@ void QWaylandEventThread::displayConnect()
// ### be careful what you do, this function may also be called from other
// threads to clean up & exit.
-void QWaylandEventThread::checkErrorAndExit()
+void QWaylandEventThread::checkError() const
{
int ecode = wl_display_get_error(m_display);
if ((ecode == EPIPE || ecode == ECONNRESET)) {
@@ -82,13 +82,16 @@ void QWaylandEventThread::checkErrorAndExit()
} else {
qErrnoWarning(ecode, "The Wayland connection experienced a fatal error");
}
- ::exit(1);
}
void QWaylandEventThread::readWaylandEvents()
{
- if (wl_display_dispatch(m_display) < 0)
- checkErrorAndExit();
+ if (wl_display_dispatch(m_display) < 0) {
+ checkError();
+ m_readNotifier->setEnabled(false);
+ emit fatalError();
+ return;
+ }
emit newEventsRead();
}
diff --git a/src/client/qwaylandeventthread_p.h b/src/client/qwaylandeventthread_p.h
index d51d627b9..2df4b05c2 100644
--- a/src/client/qwaylandeventthread_p.h
+++ b/src/client/qwaylandeventthread_p.h
@@ -63,7 +63,7 @@ public:
wl_display *display() const;
- void checkErrorAndExit();
+ void checkError() const;
private slots:
void readWaylandEvents();
@@ -72,6 +72,7 @@ private slots:
signals:
void newEventsRead();
+ void fatalError();
private:
diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp
index 4f72d6146..43c5807d4 100644
--- a/src/client/qwaylandinputdevice.cpp
+++ b/src/client/qwaylandinputdevice.cpp
@@ -157,9 +157,9 @@ QWaylandInputDevice::Touch::~Touch()
wl_touch_destroy(object());
}
-QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, uint32_t id)
+QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, int version, uint32_t id)
: QObject()
- , QtWayland::wl_seat(display->wl_registry(), id, 2)
+ , QtWayland::wl_seat(display->wl_registry(), id, qMin(version, 2))
, mQDisplay(display)
, mDisplay(display->wl_display())
, mCaps(0)
@@ -771,6 +771,17 @@ void QWaylandInputDevice::Keyboard::repeatKey()
{
mRepeatTimer.setInterval(25);
QWindowSystemInterface::handleExtendedKeyEvent(mFocus->window(),
+ mRepeatTime, QEvent::KeyRelease, mRepeatKey,
+ modifiers(),
+ mRepeatCode,
+#ifndef QT_NO_WAYLAND_XKB
+ mRepeatSym, mNativeModifiers,
+#else
+ 0, 0,
+#endif
+ mRepeatText, true);
+
+ QWindowSystemInterface::handleExtendedKeyEvent(mFocus->window(),
mRepeatTime, QEvent::KeyPress, mRepeatKey,
modifiers(),
mRepeatCode,
diff --git a/src/client/qwaylandinputdevice_p.h b/src/client/qwaylandinputdevice_p.h
index 0c6ecfb64..f1c264545 100644
--- a/src/client/qwaylandinputdevice_p.h
+++ b/src/client/qwaylandinputdevice_p.h
@@ -81,7 +81,7 @@ public:
class Pointer;
class Touch;
- QWaylandInputDevice(QWaylandDisplay *display, uint32_t id);
+ QWaylandInputDevice(QWaylandDisplay *display, int version, uint32_t id);
~QWaylandInputDevice();
uint32_t capabilities() const { return mCaps; }
diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp
index ad99c67b9..27613eef7 100644
--- a/src/client/qwaylandintegration.cpp
+++ b/src/client/qwaylandintegration.cpp
@@ -181,12 +181,14 @@ QPlatformWindow *QWaylandIntegration::createPlatformWindow(QWindow *window) cons
return new QWaylandShmWindow(window);
}
+#ifndef QT_NO_OPENGL
QPlatformOpenGLContext *QWaylandIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
if (mDisplay->clientBufferIntegration())
return mDisplay->clientBufferIntegration()->createPlatformOpenGLContext(context->format(), context->shareHandle());
return 0;
}
+#endif // QT_NO_OPENGL
QPlatformBackingStore *QWaylandIntegration::createPlatformBackingStore(QWindow *window) const
{
@@ -367,12 +369,12 @@ void QWaylandIntegration::initializeShellIntegration()
}
}
-QWaylandInputDevice *QWaylandIntegration::createInputDevice(QWaylandDisplay *display, uint32_t id)
+QWaylandInputDevice *QWaylandIntegration::createInputDevice(QWaylandDisplay *display, int version, uint32_t id)
{
if (mInputDeviceIntegration) {
- return mInputDeviceIntegration->createInputDevice(display, id);
+ return mInputDeviceIntegration->createInputDevice(display, version, id);
}
- return new QWaylandInputDevice(display, id);
+ return new QWaylandInputDevice(display, version, id);
}
void QWaylandIntegration::initializeInputDeviceIntegration()
diff --git a/src/client/qwaylandintegration_p.h b/src/client/qwaylandintegration_p.h
index 9741b1a78..c0909418e 100644
--- a/src/client/qwaylandintegration_p.h
+++ b/src/client/qwaylandintegration_p.h
@@ -63,7 +63,9 @@ public:
bool hasCapability(QPlatformIntegration::Capability cap) const;
QPlatformWindow *createPlatformWindow(QWindow *window) const;
+#ifndef QT_NO_OPENGL
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
+#endif
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
QAbstractEventDispatcher *createEventDispatcher() const;
@@ -91,7 +93,7 @@ public:
QPlatformTheme *createPlatformTheme(const QString &name) const;
- QWaylandInputDevice *createInputDevice(QWaylandDisplay *display, uint32_t id);
+ QWaylandInputDevice *createInputDevice(QWaylandDisplay *display, int version, uint32_t id);
virtual QWaylandClientBufferIntegration *clientBufferIntegration() const;
virtual QWaylandServerBufferIntegration *serverBufferIntegration() const;
diff --git a/src/client/qwaylandscreen.cpp b/src/client/qwaylandscreen.cpp
index 88667ae0d..6e48c442e 100644
--- a/src/client/qwaylandscreen.cpp
+++ b/src/client/qwaylandscreen.cpp
@@ -53,14 +53,15 @@
QT_BEGIN_NAMESPACE
-QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, uint32_t id)
+QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, int version, uint32_t id)
: QPlatformScreen()
- , QtWayland::wl_output(waylandDisplay->wl_registry(), id, 2)
+ , QtWayland::wl_output(waylandDisplay->wl_registry(), id, qMin(version, 2))
, m_outputId(id)
, mWaylandDisplay(waylandDisplay)
, mExtendedOutput(0)
, mDepth(32)
, mRefreshRate(60000)
+ , mTransform(-1)
, mFormat(QImage::Format_ARGB32_Premultiplied)
, mOutputName(QStringLiteral("Screen%1").arg(id))
, m_orientation(Qt::PrimaryOrientation)
@@ -178,29 +179,7 @@ void QWaylandScreen::output_geometry(int32_t x, int32_t y,
Q_UNUSED(subpixel);
Q_UNUSED(make);
- bool isPortrait = height > width;
- switch (transform) {
- case WL_OUTPUT_TRANSFORM_NORMAL:
- m_orientation = isPortrait ? Qt::PortraitOrientation : Qt::LandscapeOrientation;
- break;
- case WL_OUTPUT_TRANSFORM_90:
- m_orientation = isPortrait ? Qt::InvertedLandscapeOrientation : Qt::PortraitOrientation;
- break;
- case WL_OUTPUT_TRANSFORM_180:
- m_orientation = isPortrait ? Qt::InvertedPortraitOrientation : Qt::InvertedLandscapeOrientation;
- break;
- case WL_OUTPUT_TRANSFORM_270:
- m_orientation = isPortrait ? Qt::LandscapeOrientation : Qt::InvertedPortraitOrientation;
- break;
- // Ignore these ones, at least for now
- case WL_OUTPUT_TRANSFORM_FLIPPED:
- case WL_OUTPUT_TRANSFORM_FLIPPED_90:
- case WL_OUTPUT_TRANSFORM_FLIPPED_180:
- case WL_OUTPUT_TRANSFORM_FLIPPED_270:
- break;
- }
-
- QWindowSystemInterface::handleScreenOrientationChange(screen(), m_orientation);
+ mTransform = transform;
if (!model.isEmpty())
mOutputName = model;
@@ -214,6 +193,33 @@ void QWaylandScreen::output_done()
// the done event is sent after all the geometry and the mode events are sent,
// and the last mode event to be sent is the active one, so we can trust the
// values of mGeometry and mRefreshRate here
+
+ if (mTransform >= 0) {
+ bool isPortrait = mGeometry.height() > mGeometry.width();
+ switch (mTransform) {
+ case WL_OUTPUT_TRANSFORM_NORMAL:
+ m_orientation = isPortrait ? Qt::PortraitOrientation : Qt::LandscapeOrientation;
+ break;
+ case WL_OUTPUT_TRANSFORM_90:
+ m_orientation = isPortrait ? Qt::InvertedLandscapeOrientation : Qt::PortraitOrientation;
+ break;
+ case WL_OUTPUT_TRANSFORM_180:
+ m_orientation = isPortrait ? Qt::InvertedPortraitOrientation : Qt::InvertedLandscapeOrientation;
+ break;
+ case WL_OUTPUT_TRANSFORM_270:
+ m_orientation = isPortrait ? Qt::LandscapeOrientation : Qt::InvertedPortraitOrientation;
+ break;
+ // Ignore these ones, at least for now
+ case WL_OUTPUT_TRANSFORM_FLIPPED:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_180:
+ case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+ break;
+ }
+
+ QWindowSystemInterface::handleScreenOrientationChange(screen(), m_orientation);
+ mTransform = -1;
+ }
QWindowSystemInterface::handleScreenGeometryChange(screen(), mGeometry, mGeometry);
QWindowSystemInterface::handleScreenRefreshRateChange(screen(), refreshRate());
}
diff --git a/src/client/qwaylandscreen_p.h b/src/client/qwaylandscreen_p.h
index 866ac26ea..d3173e0c9 100644
--- a/src/client/qwaylandscreen_p.h
+++ b/src/client/qwaylandscreen_p.h
@@ -56,7 +56,7 @@ class QWaylandExtendedOutput;
class Q_WAYLAND_CLIENT_EXPORT QWaylandScreen : public QPlatformScreen, QtWayland::wl_output
{
public:
- QWaylandScreen(QWaylandDisplay *waylandDisplay, uint32_t id);
+ QWaylandScreen(QWaylandDisplay *waylandDisplay, int version, uint32_t id);
~QWaylandScreen();
QWaylandDisplay *display() const;
@@ -103,6 +103,7 @@ private:
QRect mGeometry;
int mDepth;
int mRefreshRate;
+ int mTransform;
QImage::Format mFormat;
QSize mPhysicalSize;
QString mOutputName;
diff --git a/src/client/qwaylandshmbackingstore.cpp b/src/client/qwaylandshmbackingstore.cpp
index 14e1285d3..d407335d3 100644
--- a/src/client/qwaylandshmbackingstore.cpp
+++ b/src/client/qwaylandshmbackingstore.cpp
@@ -42,7 +42,7 @@
#include "qwaylandwindow_p.h"
#include "qwaylanddisplay_p.h"
#include "qwaylandscreen_p.h"
-#include "qwaylanddecoration_p.h"
+#include "qwaylandabstractdecoration_p.h"
#include <QtCore/qdebug.h>
#include <QtGui/QPainter>
@@ -140,6 +140,9 @@ QWaylandShmBackingStore::QWaylandShmBackingStore(QWindow *window)
QWaylandShmBackingStore::~QWaylandShmBackingStore()
{
+ if (QWaylandWindow *w = waylandWindow())
+ w->setBackingStore(Q_NULLPTR);
+
if (mFrameCallback)
wl_callback_destroy(mFrameCallback);
@@ -175,6 +178,14 @@ void QWaylandShmBackingStore::endPaint()
waylandWindow()->setCanResize(true);
}
+void QWaylandShmBackingStore::hidden()
+{
+ if (mFrameCallback) {
+ wl_callback_destroy(mFrameCallback);
+ mFrameCallback = Q_NULLPTR;
+ }
+}
+
void QWaylandShmBackingStore::ensureSize()
{
waylandWindow()->setBackingStore(this);
@@ -295,7 +306,7 @@ void QWaylandShmBackingStore::updateDecorations()
decorationPainter.drawImage(target, sourceImage, target);
}
-QWaylandDecoration *QWaylandShmBackingStore::windowDecoration() const
+QWaylandAbstractDecoration *QWaylandShmBackingStore::windowDecoration() const
{
return waylandWindow()->decoration();
}
@@ -312,6 +323,7 @@ QWaylandWindow *QWaylandShmBackingStore::waylandWindow() const
return static_cast<QWaylandWindow *>(window()->handle());
}
+#ifndef QT_NO_OPENGL
QImage QWaylandShmBackingStore::toImage() const
{
// Invoked from QPlatformBackingStore::composeAndFlush() that is called
@@ -320,6 +332,7 @@ QImage QWaylandShmBackingStore::toImage() const
return *contentSurface();
}
+#endif // QT_NO_OPENGL
void QWaylandShmBackingStore::done(void *data, wl_callback *callback, uint32_t time)
{
diff --git a/src/client/qwaylandshmbackingstore_p.h b/src/client/qwaylandshmbackingstore_p.h
index 33f363f68..1212e52fe 100644
--- a/src/client/qwaylandshmbackingstore_p.h
+++ b/src/client/qwaylandshmbackingstore_p.h
@@ -51,7 +51,7 @@
QT_BEGIN_NAMESPACE
class QWaylandDisplay;
-class QWaylandDecoration;
+class QWaylandAbstractDecoration;
class QWaylandWindow;
class Q_WAYLAND_CLIENT_EXPORT QWaylandShmBuffer : public QWaylandBuffer {
@@ -82,8 +82,9 @@ public:
void resize(const QSize &size);
void beginPaint(const QRegion &);
void endPaint();
+ void hidden();
- QWaylandDecoration *windowDecoration() const;
+ QWaylandAbstractDecoration *windowDecoration() const;
QMargins windowDecorationMargins() const;
QImage *entireSurface() const;
@@ -93,7 +94,9 @@ public:
QWaylandWindow *waylandWindow() const;
void iterateBuffer();
+#ifndef QT_NO_OPENGL
QImage toImage() const Q_DECL_OVERRIDE;
+#endif
private:
void updateDecorations();
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
index ec00d1af6..9f7bdda1f 100644
--- a/src/client/qwaylandwindow.cpp
+++ b/src/client/qwaylandwindow.cpp
@@ -50,9 +50,11 @@
#include "qwaylandwlshellsurface_p.h"
#include "qwaylandxdgsurface_p.h"
#include "qwaylandsubsurface_p.h"
-#include "qwaylanddecoration_p.h"
+#include "qwaylandabstractdecoration_p.h"
#include "qwaylandwindowmanagerintegration_p.h"
#include "qwaylandnativeinterface_p.h"
+#include "qwaylanddecorationfactory_p.h"
+#include "qwaylandshmbackingstore_p.h"
#include <QtCore/QFileInfo>
#include <QtCore/QPointer>
@@ -90,6 +92,7 @@ QWaylandWindow::QWaylandWindow(QWindow *window)
, mMouseSerial(0)
, mState(Qt::WindowNoState)
, mMask()
+ , mBackingStore(Q_NULLPTR)
{
init(mDisplay->createSurface(static_cast<QtWayland::wl_surface *>(this)));
@@ -249,6 +252,9 @@ void QWaylandWindow::setVisible(bool visible)
if (!deleteGuard.isNull()) {
attach(static_cast<QWaylandBuffer *>(0), 0, 0);
commit();
+ if (mBackingStore) {
+ mBackingStore->hidden();
+ }
}
}
}
@@ -443,6 +449,9 @@ QWaylandSubSurface *QWaylandWindow::subSurfaceWindow() const
void QWaylandWindow::handleContentOrientationChange(Qt::ScreenOrientation orientation)
{
+ if (mDisplay->compositorVersion() < 2)
+ return;
+
wl_output_transform transform;
bool isPortrait = window()->screen() && window()->screen()->primaryOrientation() == Qt::PortraitOrientation;
switch (orientation) {
@@ -506,6 +515,7 @@ bool QWaylandWindow::createDecoration()
if (!mDisplay->supportsWindowDecoration())
return false;
+ static bool decorationPluginFailed = false;
bool decoration = false;
switch (window()->type()) {
case Qt::Window:
@@ -523,9 +533,40 @@ bool QWaylandWindow::createDecoration()
if (window()->flags() & Qt::BypassWindowManagerHint)
decoration = false;
- if (decoration) {
- if (!mWindowDecoration)
- mWindowDecoration = new QWaylandDecoration(this);
+ if (decoration && !decorationPluginFailed) {
+ if (!mWindowDecoration) {
+ QStringList decorations = QWaylandDecorationFactory::keys();
+ if (decorations.empty()) {
+ qWarning() << "No decoration plugins available. Running with no decorations.";
+ decorationPluginFailed = true;
+ return false;
+ }
+
+ QString targetKey;
+ QByteArray decorationPluginName = qgetenv("QT_WAYLAND_DECORATION");
+ if (!decorationPluginName.isEmpty()) {
+ targetKey = QString::fromLocal8Bit(decorationPluginName);
+ if (!decorations.contains(targetKey)) {
+ qWarning() << "Requested decoration " << targetKey << " not found, falling back to default";
+ targetKey = QString(); // fallthrough
+ }
+ }
+
+ if (targetKey.isEmpty())
+ targetKey = decorations.first(); // first come, first served.
+
+
+ mWindowDecoration = QWaylandDecorationFactory::create(targetKey, QStringList());
+ if (!mWindowDecoration) {
+ qWarning() << "Could not create decoration from factory! Running with no decorations.";
+ decorationPluginFailed = true;
+ return false;
+ }
+ mWindowDecoration->setWaylandWindow(this);
+ if (subSurfaceWindow()) {
+ subSurfaceWindow()->adjustPositionOfChildren();
+ }
+ }
} else {
delete mWindowDecoration;
mWindowDecoration = 0;
@@ -534,19 +575,11 @@ bool QWaylandWindow::createDecoration()
return mWindowDecoration;
}
-QWaylandDecoration *QWaylandWindow::decoration() const
+QWaylandAbstractDecoration *QWaylandWindow::decoration() const
{
return mWindowDecoration;
}
-void QWaylandWindow::setDecoration(QWaylandDecoration *decoration)
-{
- mWindowDecoration = decoration;
- if (subSurfaceWindow()) {
- subSurfaceWindow()->adjustPositionOfChildren();
- }
-}
-
static QWindow *topLevelWindow(QWindow *window)
{
while (QWindow *parent = window->parent())
@@ -695,7 +728,6 @@ bool QWaylandWindow::setWindowStateInternal(Qt::WindowState state)
// QPlatformWindow::setWindowState returns, so we cannot rely on QWindow::windowState
// here. We use then this mState variable.
mState = state;
- createDecoration();
if (mShellSurface) {
switch (state) {
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
index 7da43c7b9..0c55cd88d 100644
--- a/src/client/qwaylandwindow_p.h
+++ b/src/client/qwaylandwindow_p.h
@@ -60,7 +60,7 @@ class QWaylandDisplay;
class QWaylandBuffer;
class QWaylandShellSurface;
class QWaylandSubSurface;
-class QWaylandDecoration;
+class QWaylandAbstractDecoration;
class QWaylandInputDevice;
class QWaylandScreen;
class QWaylandShmBackingStore;
@@ -146,9 +146,7 @@ public:
bool isExposed() const Q_DECL_OVERRIDE;
void unfocus();
- QWaylandDecoration *decoration() const;
- void setDecoration(QWaylandDecoration *decoration);
-
+ QWaylandAbstractDecoration *decoration() const;
void handleMouse(QWaylandInputDevice *inputDevice,
ulong timestamp,
@@ -201,7 +199,7 @@ protected:
QWaylandShellSurface *mShellSurface;
QWaylandSubSurface *mSubSurfaceWindow;
- QWaylandDecoration *mWindowDecoration;
+ QWaylandAbstractDecoration *mWindowDecoration;
bool mMouseEventsInContentArea;
Qt::MouseButtons mMousePressedInContentArea;
Qt::CursorShape m_cursorShape;
diff --git a/src/client/qwaylandwlshellsurface.cpp b/src/client/qwaylandwlshellsurface.cpp
index a8e89ec98..86115fa38 100644
--- a/src/client/qwaylandwlshellsurface.cpp
+++ b/src/client/qwaylandwlshellsurface.cpp
@@ -44,7 +44,7 @@
#include "qwaylanddisplay_p.h"
#include "qwaylandwindow_p.h"
#include "qwaylandinputdevice_p.h"
-#include "qwaylanddecoration_p.h"
+#include "qwaylandabstractdecoration_p.h"
#include "qwaylandscreen_p.h"
#include "qwaylandextendedsurface_p.h"
diff --git a/src/client/qwaylandxdgshell.cpp b/src/client/qwaylandxdgshell.cpp
index 8a96a0304..f31d63f42 100644
--- a/src/client/qwaylandxdgshell.cpp
+++ b/src/client/qwaylandxdgshell.cpp
@@ -44,7 +44,6 @@
#include "qwaylanddisplay_p.h"
#include "qwaylandwindow_p.h"
#include "qwaylandinputdevice_p.h"
-#include "qwaylanddecoration_p.h"
#include "qwaylandscreen_p.h"
#include <QtCore/QDebug>
diff --git a/src/client/qwaylandxdgsurface.cpp b/src/client/qwaylandxdgsurface.cpp
index 126c9db72..318ff86d9 100644
--- a/src/client/qwaylandxdgsurface.cpp
+++ b/src/client/qwaylandxdgsurface.cpp
@@ -44,7 +44,7 @@
#include "qwaylanddisplay_p.h"
#include "qwaylandwindow_p.h"
#include "qwaylandinputdevice_p.h"
-#include "qwaylanddecoration_p.h"
+#include "qwaylandabstractdecoration_p.h"
#include "qwaylandscreen_p.h"
#include "qwaylandextendedsurface_p.h"
diff --git a/src/compositor/compositor_api/qwaylandquickcompositor.cpp b/src/compositor/compositor_api/qwaylandquickcompositor.cpp
index cccca2e7a..1333100c6 100644
--- a/src/compositor/compositor_api/qwaylandquickcompositor.cpp
+++ b/src/compositor/compositor_api/qwaylandquickcompositor.cpp
@@ -61,7 +61,7 @@ public:
void compositor_create_surface(Resource *resource, uint32_t id) Q_DECL_OVERRIDE
{
- QWaylandQuickSurface *surface = new QWaylandQuickSurface(resource->client(), id, static_cast<QWaylandQuickCompositor *>(m_qt_compositor));
+ QWaylandQuickSurface *surface = new QWaylandQuickSurface(resource->client(), id, wl_resource_get_version(resource->handle), static_cast<QWaylandQuickCompositor *>(m_qt_compositor));
m_surfaces << surface->handle();
//BUG: This may not be an on-screen window surface though
m_qt_compositor->surfaceCreated(surface);
diff --git a/src/compositor/compositor_api/qwaylandquicksurface.cpp b/src/compositor/compositor_api/qwaylandquicksurface.cpp
index 1ce229d21..ae3dfbb5d 100644
--- a/src/compositor/compositor_api/qwaylandquicksurface.cpp
+++ b/src/compositor/compositor_api/qwaylandquicksurface.cpp
@@ -124,8 +124,8 @@ public:
class QWaylandQuickSurfacePrivate : public QWaylandSurfacePrivate
{
public:
- QWaylandQuickSurfacePrivate(wl_client *client, quint32 id, QWaylandQuickCompositor *c, QWaylandQuickSurface *surf)
- : QWaylandSurfacePrivate(client, id, c, surf)
+ QWaylandQuickSurfacePrivate(wl_client *client, quint32 id, int version, QWaylandQuickCompositor *c, QWaylandQuickSurface *surf)
+ : QWaylandSurfacePrivate(client, id, version, c, surf)
, buffer(new BufferAttacher)
, compositor(c)
, useTextureAlpha(true)
@@ -158,8 +158,8 @@ public:
bool clientRenderingEnabled;
};
-QWaylandQuickSurface::QWaylandQuickSurface(wl_client *client, quint32 id, QWaylandQuickCompositor *compositor)
- : QWaylandSurface(new QWaylandQuickSurfacePrivate(client, id, compositor, this))
+QWaylandQuickSurface::QWaylandQuickSurface(wl_client *client, quint32 id, int version, QWaylandQuickCompositor *compositor)
+ : QWaylandSurface(new QWaylandQuickSurfacePrivate(client, id, version, compositor, this))
{
Q_D(QWaylandQuickSurface);
d->buffer->surface = this;
diff --git a/src/compositor/compositor_api/qwaylandquicksurface.h b/src/compositor/compositor_api/qwaylandquicksurface.h
index 63a25b3de..d65a98273 100644
--- a/src/compositor/compositor_api/qwaylandquicksurface.h
+++ b/src/compositor/compositor_api/qwaylandquicksurface.h
@@ -62,7 +62,7 @@ class Q_COMPOSITOR_EXPORT QWaylandQuickSurface : public QWaylandSurface
Q_PROPERTY(bool clientRenderingEnabled READ clientRenderingEnabled WRITE setClientRenderingEnabled NOTIFY clientRenderingEnabledChanged)
Q_PROPERTY(QObject *windowProperties READ windowPropertyMap CONSTANT)
public:
- QWaylandQuickSurface(wl_client *client, quint32 id, QWaylandQuickCompositor *compositor);
+ QWaylandQuickSurface(wl_client *client, quint32 id, int version, QWaylandQuickCompositor *compositor);
~QWaylandQuickSurface();
QSGTexture *texture() const;
diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp
index 9e1ffc546..b5c38d88e 100644
--- a/src/compositor/compositor_api/qwaylandsurface.cpp
+++ b/src/compositor/compositor_api/qwaylandsurface.cpp
@@ -63,8 +63,8 @@
QT_BEGIN_NAMESPACE
-QWaylandSurfacePrivate::QWaylandSurfacePrivate(wl_client *wlClient, quint32 id, QWaylandCompositor *compositor, QWaylandSurface *surface)
- : QtWayland::Surface(wlClient, id, compositor, surface)
+QWaylandSurfacePrivate::QWaylandSurfacePrivate(wl_client *wlClient, quint32 id, int version, QWaylandCompositor *compositor, QWaylandSurface *surface)
+ : QtWayland::Surface(wlClient, id, version, compositor, surface)
, closing(false)
, refCount(1)
, client(QWaylandClient::fromWlClient(wlClient))
@@ -73,8 +73,8 @@ QWaylandSurfacePrivate::QWaylandSurfacePrivate(wl_client *wlClient, quint32 id,
-QWaylandSurface::QWaylandSurface(wl_client *client, quint32 id, QWaylandCompositor *compositor)
- : QObject(*new QWaylandSurfacePrivate(client, id, compositor, this))
+QWaylandSurface::QWaylandSurface(wl_client *client, quint32 id, int version, QWaylandCompositor *compositor)
+ : QObject(*new QWaylandSurfacePrivate(client, id, version, compositor, this))
{
}
@@ -330,14 +330,7 @@ void QWaylandSurface::destroySurface()
{
QWaylandSurfaceOp op(QWaylandSurfaceOp::Close);
if (!sendInterfaceOp(op))
- destroySurfaceByForce();
-}
-
-void QWaylandSurface::destroySurfaceByForce()
-{
- Q_D(QWaylandSurface);
- wl_resource *surface_resource = d->resource()->handle;
- wl_resource_destroy(surface_resource);
+ emit surfaceDestroyed();
}
/*!
diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h
index aa5cfeeb8..4b802d778 100644
--- a/src/compositor/compositor_api/qwaylandsurface.h
+++ b/src/compositor/compositor_api/qwaylandsurface.h
@@ -93,7 +93,6 @@ class Q_COMPOSITOR_EXPORT QWaylandSurface : public QObject
Q_PROPERTY(QString title READ title NOTIFY titleChanged)
Q_PROPERTY(Qt::ScreenOrientations orientationUpdateMask READ orientationUpdateMask NOTIFY orientationUpdateMaskChanged)
Q_PROPERTY(QWindow::Visibility visibility READ visibility WRITE setVisibility NOTIFY visibilityChanged)
- Q_PROPERTY(QSize size READ size NOTIFY sizeChanged)
Q_PROPERTY(QWaylandSurface *transientParent READ transientParent)
Q_PROPERTY(QPointF transientOffset READ transientOffset)
@@ -121,7 +120,7 @@ public:
Texture
};
- QWaylandSurface(wl_client *client, quint32 id, QWaylandCompositor *compositor);
+ QWaylandSurface(wl_client *client, quint32 id, int version, QWaylandCompositor *compositor);
virtual ~QWaylandSurface();
QWaylandClient *client() const;
@@ -175,7 +174,6 @@ public:
Q_INVOKABLE void destroy();
Q_INVOKABLE void destroySurface();
- Q_INVOKABLE void destroySurfaceByForce();
Q_INVOKABLE void ping();
void ref();
diff --git a/src/compositor/compositor_api/qwaylandsurface_p.h b/src/compositor/compositor_api/qwaylandsurface_p.h
index d6377f21e..2e6f75a64 100644
--- a/src/compositor/compositor_api/qwaylandsurface_p.h
+++ b/src/compositor/compositor_api/qwaylandsurface_p.h
@@ -59,7 +59,7 @@ class Q_COMPOSITOR_EXPORT QWaylandSurfacePrivate : public QObjectPrivate, public
{
Q_DECLARE_PUBLIC(QWaylandSurface)
public:
- QWaylandSurfacePrivate(wl_client *wlClient, quint32 id, QWaylandCompositor *compositor, QWaylandSurface *surface);
+ QWaylandSurfacePrivate(wl_client *wlClient, quint32 id, int version, QWaylandCompositor *compositor, QWaylandSurface *surface);
void setType(QWaylandSurface::WindowType type);
void setTitle(const QString &title);
void setClassName(const QString &className);
diff --git a/src/compositor/hardware_integration/qwlhwintegration.cpp b/src/compositor/hardware_integration/qwlhwintegration.cpp
index 62614c4d4..e71bb652b 100644
--- a/src/compositor/hardware_integration/qwlhwintegration.cpp
+++ b/src/compositor/hardware_integration/qwlhwintegration.cpp
@@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE
namespace QtWayland {
HardwareIntegration::HardwareIntegration(Compositor *compositor)
- : qt_hardware_integration(compositor->wl_display())
+ : qt_hardware_integration(compositor->wl_display(), 1)
{
}
void HardwareIntegration::setClientBufferIntegration(const QString &name)
diff --git a/src/compositor/wayland_wrapper/qwlcompositor.cpp b/src/compositor/wayland_wrapper/qwlcompositor.cpp
index a792d5531..91fd1818a 100644
--- a/src/compositor/wayland_wrapper/qwlcompositor.cpp
+++ b/src/compositor/wayland_wrapper/qwlcompositor.cpp
@@ -140,7 +140,7 @@ void Compositor::init()
if (socketArg != -1 && socketArg + 1 < arguments.size())
m_socket_name = arguments.at(socketArg + 1).toLocal8Bit();
- wl_compositor::init(m_display->handle());
+ wl_compositor::init(m_display->handle(), 3);
m_data_device_manager = new DataDeviceManager(this);
@@ -244,7 +244,7 @@ void Compositor::cleanupGraphicsResources()
void Compositor::compositor_create_surface(Resource *resource, uint32_t id)
{
- QWaylandSurface *surface = new QWaylandSurface(resource->client(), id, m_qt_compositor);
+ QWaylandSurface *surface = new QWaylandSurface(resource->client(), id, resource->version(), m_qt_compositor);
m_surfaces << surface->handle();
//BUG: This may not be an on-screen window surface though
m_qt_compositor->surfaceCreated(surface);
@@ -466,7 +466,7 @@ void Compositor::sendDragEndEvent()
void Compositor::bindGlobal(wl_client *client, void *data, uint32_t version, uint32_t id)
{
QWaylandGlobalInterface *iface = static_cast<QWaylandGlobalInterface *>(data);
- iface->bind(client, version, id);
+ iface->bind(client, qMin(iface->version(), version), id);
};
void Compositor::loadClientBufferIntegration()
diff --git a/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp b/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp
index 2c59f1b52..ab4c3fec0 100644
--- a/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp
+++ b/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp
@@ -60,7 +60,7 @@ namespace QtWayland {
DataDeviceManager::DataDeviceManager(Compositor *compositor)
: QObject(0)
- , wl_data_device_manager(compositor->wl_display())
+ , wl_data_device_manager(compositor->wl_display(), 1)
, m_compositor(compositor)
, m_current_selection_source(0)
, m_retainedReadNotifier(0)
diff --git a/src/compositor/wayland_wrapper/qwldataoffer.cpp b/src/compositor/wayland_wrapper/qwldataoffer.cpp
index 312e53858..02da4ec92 100644
--- a/src/compositor/wayland_wrapper/qwldataoffer.cpp
+++ b/src/compositor/wayland_wrapper/qwldataoffer.cpp
@@ -51,7 +51,7 @@ namespace QtWayland
{
DataOffer::DataOffer(DataSource *dataSource, QtWaylandServer::wl_data_device::Resource *target)
- : QtWaylandServer::wl_data_offer(target->client(), 0)
+ : QtWaylandServer::wl_data_offer(target->client(), 0, 1)
, m_dataSource(dataSource)
{
// FIXME: connect to dataSource and reset m_dataSource on destroy
diff --git a/src/compositor/wayland_wrapper/qwldatasource.cpp b/src/compositor/wayland_wrapper/qwldatasource.cpp
index 679693c32..21e622703 100644
--- a/src/compositor/wayland_wrapper/qwldatasource.cpp
+++ b/src/compositor/wayland_wrapper/qwldatasource.cpp
@@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE
namespace QtWayland {
DataSource::DataSource(struct wl_client *client, uint32_t id, uint32_t time)
- : QtWaylandServer::wl_data_source(client, id)
+ : QtWaylandServer::wl_data_source(client, id, 1)
, m_time(time)
, m_device(0)
, m_manager(0)
diff --git a/src/compositor/wayland_wrapper/qwlextendedoutput.cpp b/src/compositor/wayland_wrapper/qwlextendedoutput.cpp
index 3517a99d3..8bf69ff41 100644
--- a/src/compositor/wayland_wrapper/qwlextendedoutput.cpp
+++ b/src/compositor/wayland_wrapper/qwlextendedoutput.cpp
@@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE
namespace QtWayland {
OutputExtensionGlobal::OutputExtensionGlobal(Compositor *compositor)
- : QtWaylandServer::qt_output_extension(compositor->wl_display())
+ : QtWaylandServer::qt_output_extension(compositor->wl_display(), 1)
, m_compositor(compositor)
{
}
@@ -59,7 +59,7 @@ void OutputExtensionGlobal::output_extension_get_extended_output(qt_output_exten
Output *output = static_cast<Output *>(OutputGlobal::Resource::fromResource(output_resource));
Q_ASSERT(output->extendedOutput == 0);
- ExtendedOutput *extendedOutput = static_cast<ExtendedOutput *>(qt_extended_output::add(resource->client(), id));
+ ExtendedOutput *extendedOutput = static_cast<ExtendedOutput *>(qt_extended_output::add(resource->client(), id, resource->version()));
Q_ASSERT(!output->extendedOutput);
output->extendedOutput = extendedOutput;
diff --git a/src/compositor/wayland_wrapper/qwlextendedsurface.cpp b/src/compositor/wayland_wrapper/qwlextendedsurface.cpp
index a2ee34e36..55878295d 100644
--- a/src/compositor/wayland_wrapper/qwlextendedsurface.cpp
+++ b/src/compositor/wayland_wrapper/qwlextendedsurface.cpp
@@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE
namespace QtWayland {
SurfaceExtensionGlobal::SurfaceExtensionGlobal(Compositor *compositor)
- : QtWaylandServer::qt_surface_extension(compositor->wl_display())
+ : QtWaylandServer::qt_surface_extension(compositor->wl_display(), 1)
{
}
@@ -57,12 +57,12 @@ void SurfaceExtensionGlobal::surface_extension_get_extended_surface(Resource *re
struct wl_resource *surface_resource)
{
Surface *surface = Surface::fromResource(surface_resource);
- new ExtendedSurface(resource->client(),id,surface);
+ new ExtendedSurface(resource->client(),id, wl_resource_get_version(resource->handle), surface);
}
-ExtendedSurface::ExtendedSurface(struct wl_client *client, uint32_t id, Surface *surface)
+ExtendedSurface::ExtendedSurface(struct wl_client *client, uint32_t id, int version, Surface *surface)
: QWaylandSurfaceInterface(surface->waylandSurface())
- , QtWaylandServer::qt_extended_surface(client,id)
+ , QtWaylandServer::qt_extended_surface(client, id, version)
, m_surface(surface)
, m_windowFlags(0)
{
@@ -72,7 +72,8 @@ ExtendedSurface::ExtendedSurface(struct wl_client *client, uint32_t id, Surface
ExtendedSurface::~ExtendedSurface()
{
- m_surface->setExtendedSurface(0);
+ if (m_surface)
+ m_surface->setExtendedSurface(0);
}
void ExtendedSurface::sendGenericProperty(const QString &name, const QVariant &variant)
@@ -91,6 +92,11 @@ void ExtendedSurface::setVisibility(QWindow::Visibility visibility, bool updateC
send_onscreen_visibility(visibility);
}
+void ExtendedSurface::setParentSurface(Surface *surface)
+{
+ m_surface = surface;
+}
+
bool ExtendedSurface::runOperation(QWaylandSurfaceOp *op)
{
switch (op->type()) {
@@ -141,7 +147,7 @@ void ExtendedSurface::extended_surface_set_content_orientation_mask(Resource *re
Qt::ScreenOrientations oldMask = m_contentOrientationMask;
m_contentOrientationMask = mask;
- if (mask != oldMask)
+ if (m_surface && mask != oldMask)
emit m_surface->waylandSurface()->orientationUpdateMaskChanged();
}
@@ -168,7 +174,7 @@ void ExtendedSurface::extended_surface_set_window_flags(Resource *resource, int3
{
Q_UNUSED(resource);
QWaylandSurface::WindowFlags windowFlags(flags);
- if (windowFlags== m_windowFlags)
+ if (m_surface || windowFlags == m_windowFlags)
return;
m_windowFlags = windowFlags;
emit m_surface->waylandSurface()->windowFlagsChanged(windowFlags);
@@ -181,12 +187,14 @@ void ExtendedSurface::extended_surface_destroy_resource(Resource *)
void ExtendedSurface::extended_surface_raise(Resource *)
{
- emit m_surface->waylandSurface()->raiseRequested();
+ if (m_surface)
+ emit m_surface->waylandSurface()->raiseRequested();
}
void ExtendedSurface::extended_surface_lower(Resource *)
{
- emit m_surface->waylandSurface()->lowerRequested();
+ if (m_surface)
+ emit m_surface->waylandSurface()->lowerRequested();
}
}
diff --git a/src/compositor/wayland_wrapper/qwlextendedsurface_p.h b/src/compositor/wayland_wrapper/qwlextendedsurface_p.h
index c22a42832..9bcb28272 100644
--- a/src/compositor/wayland_wrapper/qwlextendedsurface_p.h
+++ b/src/compositor/wayland_wrapper/qwlextendedsurface_p.h
@@ -75,7 +75,7 @@ private:
class ExtendedSurface : public QWaylandSurfaceInterface, public QtWaylandServer::qt_extended_surface
{
public:
- ExtendedSurface(struct wl_client *client, uint32_t id, Surface *surface);
+ ExtendedSurface(struct wl_client *client, uint32_t id, int version, Surface *surface);
~ExtendedSurface();
void sendGenericProperty(const QString &name, const QVariant &variant);
@@ -87,6 +87,7 @@ public:
ExtendedSurface *parent() const;
void setParent(ExtendedSurface *parent);
QLinkedList<QWaylandSurface *> subSurfaces() const;
+ void setParentSurface(Surface *s);
Qt::ScreenOrientations contentOrientationMask() const;
diff --git a/src/compositor/wayland_wrapper/qwlinputdevice.cpp b/src/compositor/wayland_wrapper/qwlinputdevice.cpp
index 8ac629c86..40f21134e 100644
--- a/src/compositor/wayland_wrapper/qwlinputdevice.cpp
+++ b/src/compositor/wayland_wrapper/qwlinputdevice.cpp
@@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE
namespace QtWayland {
InputDevice::InputDevice(QWaylandInputDevice *handle, Compositor *compositor, QWaylandInputDevice::CapabilityFlags caps)
- : QtWaylandServer::wl_seat(compositor->wl_display())
+ : QtWaylandServer::wl_seat(compositor->wl_display(), 2)
, m_handle(handle)
, m_dragHandle(new QWaylandDrag(this))
, m_compositor(compositor)
@@ -151,21 +151,21 @@ void InputDevice::setCapabilities(QWaylandInputDevice::CapabilityFlags caps)
void InputDevice::seat_get_pointer(wl_seat::Resource *resource, uint32_t id)
{
if (!m_pointer.isNull()) {
- m_pointer->add(resource->client(), id);
+ m_pointer->add(resource->client(), id, resource->version());
}
}
void InputDevice::seat_get_keyboard(wl_seat::Resource *resource, uint32_t id)
{
if (!m_keyboard.isNull()) {
- m_keyboard->add(resource->client(), id);
+ m_keyboard->add(resource->client(), id, resource->version());
}
}
void InputDevice::seat_get_touch(wl_seat::Resource *resource, uint32_t id)
{
if (!m_touch.isNull()) {
- m_touch->add(resource->client(), id);
+ m_touch->add(resource->client(), id, resource->version());
}
}
@@ -337,7 +337,7 @@ void InputDevice::clientRequestedDataDevice(DataDeviceManager *, struct wl_clien
{
if (!m_data_device)
m_data_device.reset(new DataDevice(this));
- m_data_device->add(client, id);
+ m_data_device->add(client, id, 1);
}
Compositor *InputDevice::compositor() const
diff --git a/src/compositor/wayland_wrapper/qwlinputmethod.cpp b/src/compositor/wayland_wrapper/qwlinputmethod.cpp
index d1b43992f..ea495b37c 100644
--- a/src/compositor/wayland_wrapper/qwlinputmethod.cpp
+++ b/src/compositor/wayland_wrapper/qwlinputmethod.cpp
@@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE
namespace QtWayland {
InputMethod::InputMethod(Compositor *compositor, InputDevice *seat)
- : QtWaylandServer::wl_input_method(seat->compositor()->wl_display())
+ : QtWaylandServer::wl_input_method(seat->compositor()->wl_display(), 1)
, m_compositor(compositor)
, m_seat(seat)
, m_resource(0)
diff --git a/src/compositor/wayland_wrapper/qwlinputmethodcontext.cpp b/src/compositor/wayland_wrapper/qwlinputmethodcontext.cpp
index b8a7859f5..5b9a24db1 100644
--- a/src/compositor/wayland_wrapper/qwlinputmethodcontext.cpp
+++ b/src/compositor/wayland_wrapper/qwlinputmethodcontext.cpp
@@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE
namespace QtWayland {
InputMethodContext::InputMethodContext(wl_client *client, TextInput *textInput)
- : QtWaylandServer::wl_input_method_context(client, 0)
+ : QtWaylandServer::wl_input_method_context(client, 0, 1)
, m_textInput(textInput)
{
}
diff --git a/src/compositor/wayland_wrapper/qwlinputpanel.cpp b/src/compositor/wayland_wrapper/qwlinputpanel.cpp
index 3848543d7..4dae2749c 100644
--- a/src/compositor/wayland_wrapper/qwlinputpanel.cpp
+++ b/src/compositor/wayland_wrapper/qwlinputpanel.cpp
@@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE
namespace QtWayland {
InputPanel::InputPanel(Compositor *compositor)
- : QtWaylandServer::wl_input_panel(compositor->wl_display())
+ : QtWaylandServer::wl_input_panel(compositor->wl_display(), 1)
, m_compositor(compositor)
, m_handle(new QWaylandInputPanel(this))
, m_focus()
diff --git a/src/compositor/wayland_wrapper/qwlinputpanelsurface.cpp b/src/compositor/wayland_wrapper/qwlinputpanelsurface.cpp
index fd258bcb5..138e57032 100644
--- a/src/compositor/wayland_wrapper/qwlinputpanelsurface.cpp
+++ b/src/compositor/wayland_wrapper/qwlinputpanelsurface.cpp
@@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE
namespace QtWayland {
InputPanelSurface::InputPanelSurface(wl_client *client, int id, Surface *surface)
- : QtWaylandServer::wl_input_panel_surface(client, id)
+ : QtWaylandServer::wl_input_panel_surface(client, id, 1)
, m_surface(surface)
, m_type(Invalid)
, m_output(0)
diff --git a/src/compositor/wayland_wrapper/qwlkeyboard.cpp b/src/compositor/wayland_wrapper/qwlkeyboard.cpp
index 67ad3b727..748639c8d 100644
--- a/src/compositor/wayland_wrapper/qwlkeyboard.cpp
+++ b/src/compositor/wayland_wrapper/qwlkeyboard.cpp
@@ -84,11 +84,13 @@ Keyboard::Keyboard(Compositor *compositor, InputDevice *seat)
Keyboard::~Keyboard()
{
#ifndef QT_NO_WAYLAND_XKB
- if (m_keymap_area)
- munmap(m_keymap_area, m_keymap_size);
- close(m_keymap_fd);
- xkb_context_unref(m_context);
- xkb_state_unref(m_state);
+ if (m_context) {
+ if (m_keymap_area)
+ munmap(m_keymap_area, m_keymap_size);
+ close(m_keymap_fd);
+ xkb_context_unref(m_context);
+ xkb_state_unref(m_state);
+ }
#endif
}
@@ -183,14 +185,16 @@ QtWaylandServer::wl_keyboard::Resource *Keyboard::focusResource() const
void Keyboard::keyboard_bind_resource(wl_keyboard::Resource *resource)
{
#ifndef QT_NO_WAYLAND_XKB
- send_keymap(resource->handle, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
- m_keymap_fd, m_keymap_size);
-#else
+ if (m_context) {
+ send_keymap(resource->handle, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
+ m_keymap_fd, m_keymap_size);
+ return;
+ }
+#endif
int null_fd = open("/dev/null", O_RDONLY);
send_keymap(resource->handle, 0 /* WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP */,
null_fd, 0);
close(null_fd);
-#endif
}
void Keyboard::keyboard_destroy_resource(wl_keyboard::Resource *resource)
@@ -240,6 +244,9 @@ void Keyboard::modifiers(uint32_t serial, uint32_t mods_depressed,
void Keyboard::updateModifierState(uint code, uint32_t state)
{
#ifndef QT_NO_WAYLAND_XKB
+ if (!m_context)
+ return;
+
xkb_state_update_key(m_state, code, state == WL_KEYBOARD_KEY_STATE_PRESSED ? XKB_KEY_DOWN : XKB_KEY_UP);
uint32_t modsDepressed = xkb_state_serialize_mods(m_state, (xkb_state_component)XKB_STATE_DEPRESSED);
@@ -269,6 +276,9 @@ void Keyboard::updateKeymap()
{
m_pendingKeymap = false;
#ifndef QT_NO_WAYLAND_XKB
+ if (!m_context)
+ return;
+
createXKBKeymap();
foreach (Resource *res, resourceMap()) {
send_keymap(res->handle, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, m_keymap_fd, m_keymap_size);
@@ -303,8 +313,10 @@ static int createAnonymousFile(size_t size)
if (fd < 0)
return -1;
- if (ftruncate(fd, size) < 0)
+ if (ftruncate(fd, size) < 0) {
+ close(fd);
return -1;
+ }
return fd;
}
@@ -312,11 +324,19 @@ static int createAnonymousFile(size_t size)
void Keyboard::initXKB()
{
m_context = xkb_context_new(static_cast<xkb_context_flags>(0));
+ if (!m_context) {
+ qWarning("Failed to create a XKB context: keymap will not be supported");
+ return;
+ }
+
createXKBKeymap();
}
void Keyboard::createXKBKeymap()
{
+ if (!m_context)
+ return;
+
if (m_state)
xkb_state_unref(m_state);
diff --git a/src/compositor/wayland_wrapper/qwloutput.cpp b/src/compositor/wayland_wrapper/qwloutput.cpp
index 09e2abc87..7638370bc 100644
--- a/src/compositor/wayland_wrapper/qwloutput.cpp
+++ b/src/compositor/wayland_wrapper/qwloutput.cpp
@@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE
namespace QtWayland {
OutputGlobal::OutputGlobal(struct ::wl_display *display)
- : QtWaylandServer::wl_output(display)
+ : QtWaylandServer::wl_output(display, 2)
, m_displayId(-1)
, m_numQueued(0)
, m_transform(WL_OUTPUT_TRANSFORM_NORMAL)
@@ -70,7 +70,9 @@ void OutputGlobal::output_bind_resource(Resource *resource)
wl_output_send_mode(resource->handle, WL_OUTPUT_MODE_CURRENT|WL_OUTPUT_MODE_PREFERRED,
size().width(), size().height(), refreshRate());
- wl_output_send_done(resource->handle);
+
+ if (resource->version() >= 2)
+ wl_output_send_done(resource->handle);
}
void OutputGlobal::setPhysicalSize(const QSize &size)
@@ -81,7 +83,9 @@ void OutputGlobal::setPhysicalSize(const QSize &size)
foreach (Resource *res, resourceMap()) {
wl_output_send_geometry(res->handle, 0, 0,
m_physicalSize.width(), m_physicalSize.height(), 0, "", "", m_transform);
- wl_output_send_done(res->handle);
+
+ if (res->version() >= 2)
+ wl_output_send_done(res->handle);
}
}
}
@@ -121,7 +125,8 @@ void OutputGlobal::sendOutputOrientation(Qt::ScreenOrientation orientation)
foreach (Resource *res, resourceMap()) {
wl_output_send_geometry(res->handle, 0, 0,
m_physicalSize.width(), m_physicalSize.height(), 0, "", "", m_transform);
- wl_output_send_done(res->handle);
+ if (res->version() >= 2)
+ wl_output_send_done(res->handle);
}
}
diff --git a/src/compositor/wayland_wrapper/qwlqtkey.cpp b/src/compositor/wayland_wrapper/qwlqtkey.cpp
index 74c21b6a8..285709064 100644
--- a/src/compositor/wayland_wrapper/qwlqtkey.cpp
+++ b/src/compositor/wayland_wrapper/qwlqtkey.cpp
@@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE
namespace QtWayland {
QtKeyExtensionGlobal::QtKeyExtensionGlobal(Compositor *compositor)
- : QtWaylandServer::qt_key_extension(compositor->wl_display())
+ : QtWaylandServer::qt_key_extension(compositor->wl_display(), 2)
, m_compositor(compositor)
{
}
diff --git a/src/compositor/wayland_wrapper/qwlqttouch.cpp b/src/compositor/wayland_wrapper/qwlqttouch.cpp
index 335ee1489..0110c433b 100644
--- a/src/compositor/wayland_wrapper/qwlqttouch.cpp
+++ b/src/compositor/wayland_wrapper/qwlqttouch.cpp
@@ -51,7 +51,7 @@ namespace QtWayland {
static const int maxRawPos = 24;
TouchExtensionGlobal::TouchExtensionGlobal(Compositor *compositor)
- : QtWaylandServer::qt_touch_extension(compositor->wl_display())
+ : QtWaylandServer::qt_touch_extension(compositor->wl_display(), 1)
, m_compositor(compositor)
, m_flags(0)
, m_resources()
diff --git a/src/compositor/wayland_wrapper/qwlregion.cpp b/src/compositor/wayland_wrapper/qwlregion.cpp
index fdbc5390d..f9bcde380 100644
--- a/src/compositor/wayland_wrapper/qwlregion.cpp
+++ b/src/compositor/wayland_wrapper/qwlregion.cpp
@@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE
namespace QtWayland {
Region::Region(struct wl_client *client, uint32_t id)
- : QtWaylandServer::wl_region(client, id)
+ : QtWaylandServer::wl_region(client, id, 1)
{
}
diff --git a/src/compositor/wayland_wrapper/qwlshellsurface.cpp b/src/compositor/wayland_wrapper/qwlshellsurface.cpp
index d54a223d6..80304f3cb 100644
--- a/src/compositor/wayland_wrapper/qwlshellsurface.cpp
+++ b/src/compositor/wayland_wrapper/qwlshellsurface.cpp
@@ -67,8 +67,7 @@ const wl_interface *Shell::interface() const
void Shell::bind(struct wl_client *client, uint32_t version, uint32_t id)
{
- Q_UNUSED(version)
- add(client, id);
+ add(client, id, version);
}
ShellSurfacePopupGrabber *Shell::getPopupGrabber(InputDevice *input)
@@ -89,10 +88,9 @@ void Shell::shell_get_shell_surface(Resource *resource, uint32_t id, struct ::wl
ShellSurface::ShellSurface(Shell *shell, wl_client *client, uint32_t id, Surface *surface)
: QWaylandSurfaceInterface(surface->waylandSurface())
- , wl_shell_surface(client, id)
+ , wl_shell_surface(client, id, 1)
, m_shell(shell)
, m_surface(surface)
- , m_deleting(false)
, m_resizeGrabber(0)
, m_moveGrabber(0)
, m_popupGrabber(0)
@@ -105,13 +103,6 @@ ShellSurface::ShellSurface(Shell *shell, wl_client *client, uint32_t id, Surface
ShellSurface::~ShellSurface()
{
- // We must destroy the wl_resource here, but be careful not to do it
- // if we're here from shell_surface_destroy_resource(), i.e. if the
- // wl_resource was destroyed already
- if (!m_deleting) {
- m_deleting = true;
- wl_resource_destroy(resource()->handle);
- }
}
void ShellSurface::sendConfigure(uint32_t edges, int32_t width, int32_t height)
@@ -201,11 +192,7 @@ void ShellSurface::shell_surface_destroy_resource(Resource *)
if (m_popupGrabber)
m_popupGrabber->removePopup(this);
- // If we're here from the destructor don't delete this again
- if (!m_deleting) {
- m_deleting = true;
- delete this;
- }
+ delete this;
}
void ShellSurface::shell_surface_move(Resource *resource,
diff --git a/src/compositor/wayland_wrapper/qwlshellsurface_p.h b/src/compositor/wayland_wrapper/qwlshellsurface_p.h
index f724ef290..92405bbc9 100644
--- a/src/compositor/wayland_wrapper/qwlshellsurface_p.h
+++ b/src/compositor/wayland_wrapper/qwlshellsurface_p.h
@@ -112,7 +112,6 @@ private:
Shell *m_shell;
Surface *m_surface;
QWaylandSurfaceView *m_view;
- bool m_deleting;
ShellSurfaceResizeGrabber *m_resizeGrabber;
ShellSurfaceMoveGrabber *m_moveGrabber;
diff --git a/src/compositor/wayland_wrapper/qwlsurface.cpp b/src/compositor/wayland_wrapper/qwlsurface.cpp
index b494b3e01..ee8197013 100644
--- a/src/compositor/wayland_wrapper/qwlsurface.cpp
+++ b/src/compositor/wayland_wrapper/qwlsurface.cpp
@@ -109,8 +109,8 @@ static QRegion infiniteRegion() {
QPoint(std::numeric_limits<int>::max(), std::numeric_limits<int>::max())));
}
-Surface::Surface(struct wl_client *client, uint32_t id, QWaylandCompositor *compositor, QWaylandSurface *surface)
- : QtWaylandServer::wl_surface(client, id)
+Surface::Surface(struct wl_client *client, uint32_t id, int version, QWaylandCompositor *compositor, QWaylandSurface *surface)
+ : QtWaylandServer::wl_surface(client, id, version)
, m_compositor(compositor->handle())
, m_waylandSurface(surface)
, m_buffer(0)
@@ -340,8 +340,7 @@ Qt::ScreenOrientation Surface::contentOrientation() const
void Surface::surface_destroy_resource(Resource *)
{
if (m_extendedSurface) {
- if (m_extendedSurface->resource())
- wl_resource_destroy(m_extendedSurface->resource()->handle);
+ m_extendedSurface->setParentSurface(Q_NULLPTR);
m_extendedSurface = 0;
}
diff --git a/src/compositor/wayland_wrapper/qwlsurface_p.h b/src/compositor/wayland_wrapper/qwlsurface_p.h
index 70b86aec6..bbab57a4d 100644
--- a/src/compositor/wayland_wrapper/qwlsurface_p.h
+++ b/src/compositor/wayland_wrapper/qwlsurface_p.h
@@ -76,7 +76,7 @@ class FrameCallback;
class Q_COMPOSITOR_EXPORT Surface : public QtWaylandServer::wl_surface
{
public:
- Surface(struct wl_client *client, uint32_t id, QWaylandCompositor *compositor, QWaylandSurface *surface);
+ Surface(struct wl_client *client, uint32_t id, int version, QWaylandCompositor *compositor, QWaylandSurface *surface);
~Surface();
static Surface *fromResource(struct ::wl_resource *resource);
diff --git a/src/compositor/wayland_wrapper/qwltextinput.cpp b/src/compositor/wayland_wrapper/qwltextinput.cpp
index 35bce8327..9aba674f4 100644
--- a/src/compositor/wayland_wrapper/qwltextinput.cpp
+++ b/src/compositor/wayland_wrapper/qwltextinput.cpp
@@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE
namespace QtWayland {
TextInput::TextInput(Compositor *compositor, struct ::wl_client *client, int id)
- : wl_text_input(client, id)
+ : wl_text_input(client, id, 1)
, m_compositor(compositor)
, m_focus()
, m_inputPanelVisible()
diff --git a/src/compositor/wayland_wrapper/qwltextinputmanager.cpp b/src/compositor/wayland_wrapper/qwltextinputmanager.cpp
index 87b6e54e5..92062944b 100644
--- a/src/compositor/wayland_wrapper/qwltextinputmanager.cpp
+++ b/src/compositor/wayland_wrapper/qwltextinputmanager.cpp
@@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE
namespace QtWayland {
TextInputManager::TextInputManager(Compositor *compositor)
- : QtWaylandServer::wl_text_input_manager(compositor->wl_display())
+ : QtWaylandServer::wl_text_input_manager(compositor->wl_display(), 1)
, m_compositor(compositor)
{
}
diff --git a/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.cpp b/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.cpp
index b91d1fb61..150a04e5b 100644
--- a/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.cpp
+++ b/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.cpp
@@ -66,7 +66,7 @@ WindowManagerServerIntegration::~WindowManagerServerIntegration()
void WindowManagerServerIntegration::initialize(QtWayland::Display *waylandDisplay)
{
- init(waylandDisplay->handle());
+ init(waylandDisplay->handle(), 1);
}
void WindowManagerServerIntegration::setShowIsFullScreen(bool value)
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp
index 89ccd9390..99a32018f 100644
--- a/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp
@@ -56,7 +56,7 @@ static const char *qwaylandegl_threadedgl_blacklist_vendor[] = {
};
QWaylandEglClientBufferIntegration::QWaylandEglClientBufferIntegration()
- : m_waylandDisplay(0)
+ : m_display(0)
, m_eglDisplay(EGL_NO_DISPLAY)
, m_supportsThreading(false)
{
@@ -76,10 +76,10 @@ void QWaylandEglClientBufferIntegration::initialize(QWaylandDisplay *display)
setenv("EGL_PLATFORM","wayland",true);
}
- m_waylandDisplay = display->wl_display();
+ m_display = display;
EGLint major,minor;
- m_eglDisplay = eglGetDisplay((EGLNativeDisplayType) m_waylandDisplay);
+ m_eglDisplay = eglGetDisplay((EGLNativeDisplayType) display->wl_display());
if (m_eglDisplay == EGL_NO_DISPLAY) {
qWarning("EGL not available");
return;
@@ -126,7 +126,7 @@ QWaylandWindow *QWaylandEglClientBufferIntegration::createEglWindow(QWindow *win
QPlatformOpenGLContext *QWaylandEglClientBufferIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const
{
- return new QWaylandGLContext(m_eglDisplay, glFormat, share);
+ return new QWaylandGLContext(m_eglDisplay, m_display, glFormat, share);
}
EGLDisplay QWaylandEglClientBufferIntegration::eglDisplay() const
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.h b/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.h
index 9d3d15094..75053190d 100644
--- a/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.h
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.h
@@ -68,7 +68,7 @@ public:
EGLDisplay eglDisplay() const;
private:
- struct wl_display *m_waylandDisplay;
+ QWaylandDisplay *m_display;
EGLDisplay m_eglDisplay;
bool m_supportsThreading;
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
index 5feed543c..9b445e10c 100644
--- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
@@ -104,7 +104,6 @@ void QWaylandEglWindow::setGeometry(const QRect &rect)
void QWaylandEglWindow::updateSurface(bool create)
{
- createDecoration();
QMargins margins = frameMargins();
QRect rect = geometry();
QSize sizeWithMargins = rect.size() + QSize(margins.left() + margins.right(), margins.top() + margins.bottom());
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
index b2db1ad0c..81c74a7d5 100644
--- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
@@ -43,7 +43,7 @@
#include <QtWaylandClient/private/qwaylanddisplay_p.h>
#include <QtWaylandClient/private/qwaylandwindow_p.h>
-#include <QtWaylandClient/private/qwaylanddecoration_p.h>
+#include <QtWaylandClient/private/qwaylandabstractdecoration_p.h>
#include <QtWaylandClient/private/qwaylandintegration_p.h>
#include "qwaylandeglwindow.h"
@@ -56,13 +56,174 @@
#include <qpa/qplatformopenglcontext.h>
#include <QtGui/QSurfaceFormat>
#include <QtGui/QOpenGLShaderProgram>
+#include <QtGui/QOpenGLFunctions>
+
+// Constants from EGL_KHR_create_context
+#ifndef EGL_CONTEXT_MINOR_VERSION_KHR
+#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB
+#endif
+#ifndef EGL_CONTEXT_FLAGS_KHR
+#define EGL_CONTEXT_FLAGS_KHR 0x30FC
+#endif
+#ifndef EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR
+#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD
+#endif
+#ifndef EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR
+#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001
+#endif
+#ifndef EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR
+#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
+#endif
+#ifndef EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR
+#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
+#endif
+#ifndef EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR
+#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002
+#endif
+
+// Constants for OpenGL which are not available in the ES headers.
+#ifndef GL_CONTEXT_FLAGS
+#define GL_CONTEXT_FLAGS 0x821E
+#endif
+#ifndef GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT
+#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001
+#endif
+#ifndef GL_CONTEXT_FLAG_DEBUG_BIT
+#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
+#endif
+#ifndef GL_CONTEXT_PROFILE_MASK
+#define GL_CONTEXT_PROFILE_MASK 0x9126
+#endif
+#ifndef GL_CONTEXT_CORE_PROFILE_BIT
+#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
+#endif
+#ifndef GL_CONTEXT_COMPATIBILITY_PROFILE_BIT
+#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
+#endif
QT_BEGIN_NAMESPACE
-QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat &format, QPlatformOpenGLContext *share)
+class DecorationsBlitter : public QOpenGLFunctions
+{
+public:
+ DecorationsBlitter(QWaylandGLContext *context)
+ : m_context(context)
+ {
+ initializeOpenGLFunctions();
+ m_blitProgram = new QOpenGLShaderProgram();
+ m_blitProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, "attribute vec4 position;\n\
+ attribute vec4 texCoords;\n\
+ varying vec2 outTexCoords;\n\
+ void main()\n\
+ {\n\
+ gl_Position = position;\n\
+ outTexCoords = texCoords.xy;\n\
+ }");
+ m_blitProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, "varying highp vec2 outTexCoords;\n\
+ uniform sampler2D texture;\n\
+ void main()\n\
+ {\n\
+ gl_FragColor = texture2D(texture, outTexCoords);\n\
+ }");
+
+ m_blitProgram->bindAttributeLocation("position", 0);
+ m_blitProgram->bindAttributeLocation("texCoords", 1);
+
+ if (!m_blitProgram->link()) {
+ qDebug() << "Shader Program link failed.";
+ qDebug() << m_blitProgram->log();
+ }
+ }
+ ~DecorationsBlitter()
+ {
+ delete m_blitProgram;
+ }
+ void blit(QWaylandEglWindow *window)
+ {
+ QOpenGLTextureCache *cache = QOpenGLTextureCache::cacheForContext(m_context->context());
+
+ QRect windowRect = window->window()->frameGeometry();
+ glViewport(0, 0, windowRect.width(), windowRect.height());
+
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_BLEND);
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_SCISSOR_TEST);
+ glDepthMask(GL_FALSE);
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+
+ m_context->mUseNativeDefaultFbo = true;
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ m_context->mUseNativeDefaultFbo = false;
+
+ static const GLfloat squareVertices[] = {
+ -1.f, -1.f,
+ 1.0f, -1.f,
+ -1.f, 1.0f,
+ 1.0f, 1.0f
+ };
+
+ static const GLfloat inverseSquareVertices[] = {
+ -1.f, 1.f,
+ 1.f, 1.f,
+ -1.f, -1.f,
+ 1.f, -1.f
+ };
+
+ static const GLfloat textureVertices[] = {
+ 0.0f, 0.0f,
+ 1.0f, 0.0f,
+ 0.0f, 1.0f,
+ 1.0f, 1.0f,
+ };
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ m_blitProgram->bind();
+
+ m_blitProgram->enableAttributeArray(0);
+ m_blitProgram->enableAttributeArray(1);
+ m_blitProgram->setAttributeArray(1, textureVertices, 2);
+
+ glActiveTexture(GL_TEXTURE0);
+
+ //Draw Decoration
+ m_blitProgram->setAttributeArray(0, inverseSquareVertices, 2);
+ QImage decorationImage = window->decoration()->contentImage();
+ cache->bindTexture(m_context->context(), decorationImage);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ if (m_context->context()->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextureRepeat)) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ } else {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ }
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ //Draw Content
+ m_blitProgram->setAttributeArray(0, squareVertices, 2);
+ glBindTexture(GL_TEXTURE_2D, window->contentTexture());
+ QRect r = window->contentsRect();
+ glViewport(r.x(), r.y(), r.width(), r.height());
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ //Cleanup
+ m_blitProgram->disableAttributeArray(0);
+ m_blitProgram->disableAttributeArray(1);
+ }
+
+ QOpenGLShaderProgram *m_blitProgram;
+ QWaylandGLContext *m_context;
+};
+
+
+
+QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, QWaylandDisplay *display, const QSurfaceFormat &format, QPlatformOpenGLContext *share)
: QPlatformOpenGLContext()
, m_eglDisplay(eglDisplay)
- , m_blitProgram(0)
+ , m_display(display)
+ , m_blitter(0)
, mUseNativeDefaultFbo(false)
{
QSurfaceFormat fmt = format;
@@ -72,6 +233,36 @@ QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat
m_format = q_glFormatFromConfig(m_eglDisplay, m_config);
m_shareEGLContext = share ? static_cast<QWaylandGLContext *>(share)->eglContext() : EGL_NO_CONTEXT;
+ QVector<EGLint> eglContextAttrs;
+ eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
+ eglContextAttrs.append(format.majorVersion());
+ const bool hasKHRCreateContext = q_hasEglExtension(m_eglDisplay, "EGL_KHR_create_context");
+ if (hasKHRCreateContext) {
+ eglContextAttrs.append(EGL_CONTEXT_MINOR_VERSION_KHR);
+ eglContextAttrs.append(format.minorVersion());
+ int flags = 0;
+ // The debug bit is supported both for OpenGL and OpenGL ES.
+ if (format.testOption(QSurfaceFormat::DebugContext))
+ flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
+ // The fwdcompat bit is only for OpenGL 3.0+.
+ if (m_format.renderableType() == QSurfaceFormat::OpenGL
+ && format.majorVersion() >= 3
+ && !format.testOption(QSurfaceFormat::DeprecatedFunctions))
+ flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
+ if (flags) {
+ eglContextAttrs.append(EGL_CONTEXT_FLAGS_KHR);
+ eglContextAttrs.append(flags);
+ }
+ // Profiles are OpenGL only and mandatory in 3.2+. The value is silently ignored for < 3.2.
+ if (m_format.renderableType() == QSurfaceFormat::OpenGL) {
+ eglContextAttrs.append(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR);
+ eglContextAttrs.append(format.profile() == QSurfaceFormat::CoreProfile
+ ? EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR
+ : EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR);
+ }
+ }
+ eglContextAttrs.append(EGL_NONE);
+
switch (m_format.renderableType()) {
case QSurfaceFormat::OpenVG:
eglBindAPI(EGL_OPENVG_API);
@@ -90,11 +281,6 @@ QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat
break;
}
- QVector<EGLint> eglContextAttrs;
- eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
- eglContextAttrs.append(format.majorVersion() == 1 ? 1 : 2);
- eglContextAttrs.append(EGL_NONE);
-
m_context = eglCreateContext(m_eglDisplay, m_config, m_shareEGLContext, eglContextAttrs.constData());
if (m_context == EGL_NO_CONTEXT) {
@@ -103,13 +289,75 @@ QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat
}
EGLint error = eglGetError();
- if (error != EGL_SUCCESS)
+ if (error != EGL_SUCCESS) {
qWarning("QWaylandGLContext: failed to create EGLContext, error=%x", error);
+ return;
+ }
+
+ updateGLFormat();
+}
+
+void QWaylandGLContext::updateGLFormat()
+{
+ // Have to save & restore to prevent QOpenGLContext::currentContext() from becoming
+ // inconsistent after QOpenGLContext::create().
+ EGLDisplay prevDisplay = eglGetCurrentDisplay();
+ if (prevDisplay == EGL_NO_DISPLAY) // when no context is current
+ prevDisplay = m_eglDisplay;
+ EGLContext prevContext = eglGetCurrentContext();
+ EGLSurface prevSurfaceDraw = eglGetCurrentSurface(EGL_DRAW);
+ EGLSurface prevSurfaceRead = eglGetCurrentSurface(EGL_READ);
+
+ wl_surface *wlSurface = m_display->createSurface(Q_NULLPTR);
+ wl_egl_window *eglWindow = wl_egl_window_create(wlSurface, 1, 1);
+ EGLSurface eglSurface = eglCreateWindowSurface(m_eglDisplay, m_config, eglWindow, 0);
+
+ if (eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_context)) {
+ if (m_format.renderableType() == QSurfaceFormat::OpenGL
+ || m_format.renderableType() == QSurfaceFormat::OpenGLES) {
+ const GLubyte *s = glGetString(GL_VERSION);
+ if (s) {
+ QByteArray version = QByteArray(reinterpret_cast<const char *>(s));
+ int major, minor;
+ if (QPlatformOpenGLContext::parseOpenGLVersion(version, major, minor)) {
+ m_format.setMajorVersion(major);
+ m_format.setMinorVersion(minor);
+ }
+ }
+ m_format.setProfile(QSurfaceFormat::NoProfile);
+ m_format.setOptions(QSurfaceFormat::FormatOptions());
+ if (m_format.renderableType() == QSurfaceFormat::OpenGL) {
+ // Check profile and options.
+ if (m_format.majorVersion() < 3) {
+ m_format.setOption(QSurfaceFormat::DeprecatedFunctions);
+ } else {
+ GLint value = 0;
+ glGetIntegerv(GL_CONTEXT_FLAGS, &value);
+ if (!(value & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT))
+ m_format.setOption(QSurfaceFormat::DeprecatedFunctions);
+ if (value & GL_CONTEXT_FLAG_DEBUG_BIT)
+ m_format.setOption(QSurfaceFormat::DebugContext);
+ if (m_format.version() >= qMakePair(3, 2)) {
+ value = 0;
+ glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &value);
+ if (value & GL_CONTEXT_CORE_PROFILE_BIT)
+ m_format.setProfile(QSurfaceFormat::CoreProfile);
+ else if (value & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
+ m_format.setProfile(QSurfaceFormat::CompatibilityProfile);
+ }
+ }
+ }
+ }
+ eglMakeCurrent(prevDisplay, prevSurfaceDraw, prevSurfaceRead, prevContext);
+ }
+ eglDestroySurface(m_eglDisplay, eglSurface);
+ wl_egl_window_destroy(eglWindow);
+ wl_surface_destroy(wlSurface);
}
QWaylandGLContext::~QWaylandGLContext()
{
- delete m_blitProgram;
+ delete m_blitter;
eglDestroyContext(m_eglDisplay, m_context);
}
@@ -122,6 +370,13 @@ bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface)
return true;
window->setCanResize(false);
+ // Core profiles mandate the use of VAOs when rendering. We would then need to use one
+ // in DecorationsBlitter, but for that we would need a QOpenGLFunctions_3_2_Core instead
+ // of the QOpenGLFunctions we use, but that would break when using a lower version context.
+ // Instead of going crazy, just disable decorations for core profiles until we use
+ // subsurfaces for them.
+ if (m_format.profile() != QSurfaceFormat::CoreProfile && !window->decoration())
+ window->createDecoration();
if (eglSurface == EGL_NO_SURFACE) {
window->updateSurface(true);
@@ -253,104 +508,9 @@ void QWaylandGLContext::swapBuffers(QPlatformSurface *surface)
// for random context state changes in a swapBuffers() call.
StateGuard stateGuard;
- if (!m_blitProgram) {
- initializeOpenGLFunctions();
- m_blitProgram = new QOpenGLShaderProgram();
- m_blitProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, "attribute vec4 position;\n\
- attribute vec4 texCoords;\n\
- varying vec2 outTexCoords;\n\
- void main()\n\
- {\n\
- gl_Position = position;\n\
- outTexCoords = texCoords.xy;\n\
- }");
- m_blitProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, "varying highp vec2 outTexCoords;\n\
- uniform sampler2D texture;\n\
- void main()\n\
- {\n\
- gl_FragColor = texture2D(texture, outTexCoords);\n\
- }");
-
- m_blitProgram->bindAttributeLocation("position", 0);
- m_blitProgram->bindAttributeLocation("texCoords", 1);
-
- if (!m_blitProgram->link()) {
- qDebug() << "Shader Program link failed.";
- qDebug() << m_blitProgram->log();
- }
- }
-
- QOpenGLTextureCache *cache = QOpenGLTextureCache::cacheForContext(context());
-
- QRect windowRect = window->window()->frameGeometry();
- glViewport(0, 0, windowRect.width(), windowRect.height());
-
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_BLEND);
- glDisable(GL_CULL_FACE);
- glDisable(GL_SCISSOR_TEST);
- glDepthMask(GL_FALSE);
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-
- mUseNativeDefaultFbo = true;
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- mUseNativeDefaultFbo = false;
-
- static const GLfloat squareVertices[] = {
- -1.f, -1.f,
- 1.0f, -1.f,
- -1.f, 1.0f,
- 1.0f, 1.0f
- };
-
- static const GLfloat inverseSquareVertices[] = {
- -1.f, 1.f,
- 1.f, 1.f,
- -1.f, -1.f,
- 1.f, -1.f
- };
-
- static const GLfloat textureVertices[] = {
- 0.0f, 0.0f,
- 1.0f, 0.0f,
- 0.0f, 1.0f,
- 1.0f, 1.0f,
- };
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- m_blitProgram->bind();
-
- m_blitProgram->enableAttributeArray(0);
- m_blitProgram->enableAttributeArray(1);
- m_blitProgram->setAttributeArray(1, textureVertices, 2);
-
- glActiveTexture(GL_TEXTURE0);
-
- //Draw Decoration
- m_blitProgram->setAttributeArray(0, inverseSquareVertices, 2);
- QImage decorationImage = window->decoration()->contentImage();
- cache->bindTexture(context(), decorationImage);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- if (context()->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextureRepeat)) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- } else {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- }
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
- //Draw Content
- m_blitProgram->setAttributeArray(0, squareVertices, 2);
- glBindTexture(GL_TEXTURE_2D, window->contentTexture());
- QRect r = window->contentsRect();
- glViewport(r.x(), r.y(), r.width(), r.height());
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
- //Cleanup
- m_blitProgram->disableAttributeArray(0);
- m_blitProgram->disableAttributeArray(1);
+ if (!m_blitter)
+ m_blitter = new DecorationsBlitter(this);
+ m_blitter->blit(window);
}
eglSwapBuffers(m_eglDisplay, eglSurface);
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h
index 9a1dda014..5528eca7d 100644
--- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h
@@ -45,7 +45,6 @@
#include <QtWaylandClient/private/qwaylanddisplay_p.h>
#include <qpa/qplatformopenglcontext.h>
-#include <QtGui/QOpenGLFunctions>
#include "qwaylandeglinclude.h"
@@ -55,11 +54,12 @@ class QWaylandWindow;
class QWaylandGLWindowSurface;
class QOpenGLShaderProgram;
class QOpenGLTextureCache;
+class DecorationsBlitter;
-class QWaylandGLContext : public QPlatformOpenGLContext, protected QOpenGLFunctions
+class QWaylandGLContext : public QPlatformOpenGLContext
{
public:
- QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat &format, QPlatformOpenGLContext *share);
+ QWaylandGLContext(EGLDisplay eglDisplay, QWaylandDisplay *display, const QSurfaceFormat &format, QPlatformOpenGLContext *share);
~QWaylandGLContext();
void swapBuffers(QPlatformSurface *surface);
@@ -80,14 +80,18 @@ public:
EGLContext eglContext() const { return m_context; }
private:
- EGLDisplay m_eglDisplay;
+ void updateGLFormat();
+ EGLDisplay m_eglDisplay;
+ QWaylandDisplay *m_display;
EGLContext m_context;
EGLContext m_shareEGLContext;
EGLConfig m_config;
QSurfaceFormat m_format;
- QOpenGLShaderProgram *m_blitProgram;
+ DecorationsBlitter *m_blitter;
bool mUseNativeDefaultFbo;
+
+ friend class DecorationsBlitter;
};
QT_END_NAMESPACE
diff --git a/src/hardwareintegration/compositor/brcm-egl/brcmbuffer.cpp b/src/hardwareintegration/compositor/brcm-egl/brcmbuffer.cpp
index e4fbfb553..d480b2dae 100644
--- a/src/hardwareintegration/compositor/brcm-egl/brcmbuffer.cpp
+++ b/src/hardwareintegration/compositor/brcm-egl/brcmbuffer.cpp
@@ -48,7 +48,7 @@
QT_BEGIN_NAMESPACE
BrcmBuffer::BrcmBuffer(struct ::wl_client *client, uint32_t id, const QSize &size, EGLint *data, size_t count)
- : QtWaylandServer::wl_buffer(client, id)
+ : QtWaylandServer::wl_buffer(client, id, 1)
, m_handle(count)
, m_invertedY(false)
, m_size(size)
diff --git a/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.cpp b/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.cpp
index 66533fecb..9fc8badd5 100644
--- a/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.cpp
+++ b/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.cpp
@@ -120,7 +120,7 @@ void BrcmEglIntegration::initializeHardware(QtWayland::Display *waylandDisplay)
return;
}
d->valid = true;
- init(waylandDisplay->handle());
+ init(waylandDisplay->handle(), 1);
}
}
diff --git a/src/hardwareintegration/compositor/drm-egl-server/drmeglserverbufferintegration.cpp b/src/hardwareintegration/compositor/drm-egl-server/drmeglserverbufferintegration.cpp
index 09588f6ff..4e9a04495 100644
--- a/src/hardwareintegration/compositor/drm-egl-server/drmeglserverbufferintegration.cpp
+++ b/src/hardwareintegration/compositor/drm-egl-server/drmeglserverbufferintegration.cpp
@@ -95,7 +95,7 @@ struct ::wl_resource *DrmEglServerBuffer::resourceForClient(struct ::wl_client *
return 0;
}
struct ::wl_resource *drm_egl_resource = (*drm_egl_it)->handle;
- Resource *resource = add(client);
+ Resource *resource = add(client, 1, 1);
m_integration->send_server_buffer_created(drm_egl_resource, resource->handle, m_name, m_size.width(), m_size.height(), m_stride, m_drm_format);
return resource->handle;
}
@@ -166,7 +166,7 @@ void DrmEglServerBufferIntegration::initializeHardware(QWaylandCompositor *compo
return;
}
- QtWaylandServer::qt_drm_egl_server_buffer::init(compositor->waylandDisplay());
+ QtWaylandServer::qt_drm_egl_server_buffer::init(compositor->waylandDisplay(), 1);
}
bool DrmEglServerBufferIntegration::supportsFormat(QtWayland::ServerBuffer::Format format) const
diff --git a/src/hardwareintegration/compositor/libhybris-egl-server/libhybriseglserverbufferintegration.cpp b/src/hardwareintegration/compositor/libhybris-egl-server/libhybriseglserverbufferintegration.cpp
index c15f3d154..7e7a14ab8 100644
--- a/src/hardwareintegration/compositor/libhybris-egl-server/libhybriseglserverbufferintegration.cpp
+++ b/src/hardwareintegration/compositor/libhybris-egl-server/libhybriseglserverbufferintegration.cpp
@@ -89,7 +89,7 @@ struct ::wl_resource *LibHybrisEglServerBuffer::resourceForClient(struct ::wl_cl
return 0;
}
struct ::wl_resource *egl_resource = (*egl_it)->handle;
- Resource *resource = add(client);
+ Resource *resource = add(client, 1, 1);
wl_resource *bufRes = wl_client_new_object(client, &qt_libhybris_buffer_interface, 0, 0);
m_integration->send_server_buffer_created(egl_resource, resource->handle, bufRes, m_fds.size(), QByteArray((char *)m_ints.data(), m_ints.size() * sizeof(int32_t)),
@@ -174,7 +174,7 @@ void LibHybrisEglServerBufferIntegration::initializeHardware(QWaylandCompositor
return;
}
- QtWaylandServer::qt_libhybris_egl_server_buffer::init(compositor->waylandDisplay());
+ QtWaylandServer::qt_libhybris_egl_server_buffer::init(compositor->waylandDisplay(), 1);
}
bool LibHybrisEglServerBufferIntegration::supportsFormat(QtWayland::ServerBuffer::Format format) const
diff --git a/src/hardwareintegration/compositor/xcomposite_share/xcompositebuffer.cpp b/src/hardwareintegration/compositor/xcomposite_share/xcompositebuffer.cpp
index 0457214b4..09789d864 100644
--- a/src/hardwareintegration/compositor/xcomposite_share/xcompositebuffer.cpp
+++ b/src/hardwareintegration/compositor/xcomposite_share/xcompositebuffer.cpp
@@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE
XCompositeBuffer::XCompositeBuffer(Window window, const QSize &size,
struct ::wl_client *client, uint32_t id)
- : QtWaylandServer::wl_buffer(client, id)
+ : QtWaylandServer::wl_buffer(client, id, 1)
, mWindow(window)
, mInvertedY(false)
, mSize(size)
diff --git a/src/hardwareintegration/compositor/xcomposite_share/xcompositehandler.cpp b/src/hardwareintegration/compositor/xcomposite_share/xcompositehandler.cpp
index 0f10d38de..5e002377e 100644
--- a/src/hardwareintegration/compositor/xcomposite_share/xcompositehandler.cpp
+++ b/src/hardwareintegration/compositor/xcomposite_share/xcompositehandler.cpp
@@ -48,7 +48,7 @@
QT_BEGIN_NAMESPACE
XCompositeHandler::XCompositeHandler(QtWayland::Compositor *compositor, Display *display)
- : QtWaylandServer::qt_xcomposite(compositor->wl_display())
+ : QtWaylandServer::qt_xcomposite(compositor->wl_display(), 1)
{
compositor->window()->create();
diff --git a/src/plugins/decorations/bradient/bradient.json b/src/plugins/decorations/bradient/bradient.json
new file mode 100644
index 000000000..e1a5ef24f
--- /dev/null
+++ b/src/plugins/decorations/bradient/bradient.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "bradient" ]
+}
diff --git a/src/plugins/decorations/bradient/bradient.pro b/src/plugins/decorations/bradient/bradient.pro
new file mode 100644
index 000000000..fd376f4a9
--- /dev/null
+++ b/src/plugins/decorations/bradient/bradient.pro
@@ -0,0 +1,17 @@
+PLUGIN_TYPE = wayland-decoration-client
+load(qt_plugin)
+
+QT += waylandclient-private
+
+OTHER_FILES += \
+ bradient.json
+
+SOURCES += main.cpp
+
+contains(QT_CONFIG, no-pkg-config) {
+ LIBS += -lwayland-client
+} else {
+ CONFIG += link_pkgconfig
+ PKGCONFIG += wayland-client
+}
+
diff --git a/src/client/qwaylanddecoration.cpp b/src/plugins/decorations/bradient/main.cpp
index ed4978725..c249248c3 100644
--- a/src/client/qwaylanddecoration.cpp
+++ b/src/plugins/decorations/bradient/main.cpp
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2014 Robin Burchell <robin.burchell@viroteck.net>
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
@@ -39,20 +40,18 @@
**
****************************************************************************/
-#include "qwaylanddecoration_p.h"
-
-#include "qwaylandwindow_p.h"
-#include "qwaylandshellsurface_p.h"
-#include "qwaylandinputdevice_p.h"
-#include "qwaylandscreen_p.h"
-
-#include <QtGui/QGuiApplication>
-#include <QtGui/QImage>
#include <QtGui/QCursor>
#include <QtGui/QPainter>
#include <QtGui/QPalette>
#include <QtGui/QLinearGradient>
+#include <qpa/qwindowsysteminterface.h>
+
+#include <QtWaylandClient/private/qwaylanddecorationplugin_p.h>
+#include <QtWaylandClient/private/qwaylandabstractdecoration_p.h>
+#include <QtWaylandClient/private/qwaylandwindow_p.h>
+#include <QtWaylandClient/private/qwaylandshellsurface_p.h>
+
QT_BEGIN_NAMESPACE
#define BUTTON_SPACING 5
@@ -123,16 +122,35 @@ static const char * const qt_normalizeup_xpm[] = {
# define BUTTON_WIDTH 22
#endif
-QWaylandDecoration::QWaylandDecoration(QWaylandWindow *window)
- : m_window(window->window())
- , m_wayland_window(window)
- , m_isDirty(true)
- , m_decorationContentImage(0)
- , m_margins(3,30,3,3)
- , m_mouseButtons(Qt::NoButton)
+class Q_WAYLAND_CLIENT_EXPORT QWaylandBradientDecoration : public QWaylandAbstractDecoration
+{
+public:
+ QWaylandBradientDecoration();
+protected:
+ QMargins margins() const Q_DECL_OVERRIDE;
+ void paint(QPaintDevice *device) Q_DECL_OVERRIDE;
+ bool handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,Qt::MouseButtons b,Qt::KeyboardModifiers mods) Q_DECL_OVERRIDE;
+ bool handleTouch(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::TouchPointState state, Qt::KeyboardModifiers mods) Q_DECL_OVERRIDE;
+private:
+ void processMouseTop(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods);
+ void processMouseBottom(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods);
+ void processMouseLeft(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods);
+ void processMouseRight(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods);
+
+ QRectF closeButtonRect() const;
+ QRectF maximizeButtonRect() const;
+ QRectF minimizeButtonRect() const;
+
+ QColor m_foregroundColor;
+ QColor m_backgroundColor;
+ QStaticText m_windowTitle;
+};
+
+
+
+QWaylandBradientDecoration::QWaylandBradientDecoration()
+ : QWaylandAbstractDecoration()
{
- m_wayland_window->setDecoration(this);
-
QPalette palette;
m_foregroundColor = palette.color(QPalette::Active, QPalette::HighlightedText);
m_backgroundColor = palette.color(QPalette::Active, QPalette::Highlight);
@@ -142,32 +160,30 @@ QWaylandDecoration::QWaylandDecoration(QWaylandWindow *window)
m_windowTitle.setTextOption(option);
}
-QWaylandDecoration::~QWaylandDecoration()
+QRectF QWaylandBradientDecoration::closeButtonRect() const
{
- m_wayland_window->setDecoration(0);
+ return QRectF(window()->frameGeometry().width() - BUTTON_WIDTH - BUTTON_SPACING * 2,
+ (margins().top() - BUTTON_WIDTH) / 2, BUTTON_WIDTH, BUTTON_WIDTH);
}
-const QImage &QWaylandDecoration::contentImage()
+QRectF QWaylandBradientDecoration::maximizeButtonRect() const
{
- if (m_isDirty) {
- //Update the decoration backingstore
-
- m_decorationContentImage = QImage(window()->frameGeometry().size(), QImage::Format_ARGB32_Premultiplied);
- m_decorationContentImage.fill(Qt::transparent);
- this->paint(&m_decorationContentImage);
-
- m_isDirty = false;
- }
+ return QRectF(window()->frameGeometry().width() - BUTTON_WIDTH * 2 - BUTTON_SPACING * 3,
+ (margins().top() - BUTTON_WIDTH) / 2, BUTTON_WIDTH, BUTTON_WIDTH);
+}
- return m_decorationContentImage;
+QRectF QWaylandBradientDecoration::minimizeButtonRect() const
+{
+ return QRectF(window()->frameGeometry().width() - BUTTON_WIDTH * 3 - BUTTON_SPACING * 4,
+ (margins().top() - BUTTON_WIDTH) / 2, BUTTON_WIDTH, BUTTON_WIDTH);
}
-void QWaylandDecoration::update()
+QMargins QWaylandBradientDecoration::margins() const
{
- m_isDirty = true;
+ return QMargins(3, 30, 3, 3);
}
-void QWaylandDecoration::paint(QPaintDevice *device)
+void QWaylandBradientDecoration::paint(QPaintDevice *device)
{
QRect surfaceRect(QPoint(), window()->frameGeometry().size());
QRect clips[] =
@@ -199,7 +215,7 @@ void QWaylandDecoration::paint(QPaintDevice *device)
}
// Window icon
- QIcon icon = m_wayland_window->windowIcon();
+ QIcon icon = waylandWindow()->windowIcon();
if (!icon.isNull()) {
QPixmap pixmap = icon.pixmap(QSize(128, 128));
QPixmap scaled = pixmap.scaled(22, 22, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
@@ -219,7 +235,7 @@ void QWaylandDecoration::paint(QPaintDevice *device)
}
QRect titleBar = top;
- titleBar.setLeft(m_margins.left() + BUTTON_SPACING +
+ titleBar.setLeft(margins().left() + BUTTON_SPACING +
(icon.isNull() ? 0 : 22 + BUTTON_SPACING));
titleBar.setRight(minimizeButtonRect().left() - BUTTON_SPACING);
@@ -234,7 +250,7 @@ void QWaylandDecoration::paint(QPaintDevice *device)
p.setFont(font);
QPoint windowTitlePoint(top.topLeft().x() + dx,
top.topLeft().y() + dy);
- p.drawStaticText(windowTitlePoint,m_windowTitle);
+ p.drawStaticText(windowTitlePoint, m_windowTitle);
p.restore();
}
@@ -246,7 +262,7 @@ void QWaylandDecoration::paint(QPaintDevice *device)
p.drawPixmap(closeButtonRect(), closePixmap, closePixmap.rect());
// Maximize button
- QPixmap maximizePixmap(m_wayland_window->isMaximized()
+ QPixmap maximizePixmap(waylandWindow()->isMaximized()
? qt_normalizeup_xpm : qt_maximize_xpm);
p.drawPixmap(maximizeButtonRect(), maximizePixmap, maximizePixmap.rect());
@@ -282,7 +298,7 @@ void QWaylandDecoration::paint(QPaintDevice *device)
p.save();
p.drawRect(maximizeButtonRect());
rect = maximizeButtonRect().adjusted(5, 5, -5, -5);
- if (m_wayland_window->isMaximized()) {
+ if (waylandWindow()->isMaximized()) {
QRectF rect1 = rect.adjusted(rect.width() / 3, 0, 0, -rect.height() / 3);
QRectF rect2 = rect.adjusted(0, rect.height() / 4, -rect.width() / 4, 0);
p.drawRect(rect1);
@@ -305,37 +321,37 @@ void QWaylandDecoration::paint(QPaintDevice *device)
#endif
}
-bool QWaylandDecoration::handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
+bool QWaylandBradientDecoration::handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
{
Q_UNUSED(global);
// Figure out what area mouse is in
if (closeButtonRect().contains(local) && isLeftClicked(b)) {
- QWindowSystemInterface::handleCloseEvent(m_window);
+ QWindowSystemInterface::handleCloseEvent(window());
} else if (maximizeButtonRect().contains(local) && isLeftClicked(b)) {
- m_window->setWindowState(m_wayland_window->isMaximized() ? Qt::WindowNoState : Qt::WindowMaximized);
+ window()->setWindowState(waylandWindow()->isMaximized() ? Qt::WindowNoState : Qt::WindowMaximized);
} else if (minimizeButtonRect().contains(local) && isLeftClicked(b)) {
- m_window->setWindowState(Qt::WindowMinimized);
- } else if (local.y() <= m_margins.top()) {
+ window()->setWindowState(Qt::WindowMinimized);
+ } else if (local.y() <= margins().top()) {
processMouseTop(inputDevice,local,b,mods);
- } else if (local.y() > m_window->height() - m_margins.bottom() + m_margins.top()) {
+ } else if (local.y() > window()->height() - margins().bottom() + margins().top()) {
processMouseBottom(inputDevice,local,b,mods);
- } else if (local.x() <= m_margins.left()) {
+ } else if (local.x() <= margins().left()) {
processMouseLeft(inputDevice,local,b,mods);
- } else if (local.x() > m_window->width() - m_margins.right() + m_margins.left()) {
+ } else if (local.x() > window()->width() - margins().right() + margins().left()) {
processMouseRight(inputDevice,local,b,mods);
} else {
- m_wayland_window->restoreMouseCursor(inputDevice);
- m_mouseButtons = b;
+ waylandWindow()->restoreMouseCursor(inputDevice);
+ setMouseButtons(b);
return false;
}
- m_mouseButtons = b;
+ setMouseButtons(b);
return true;
}
-bool QWaylandDecoration::handleTouch(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::TouchPointState state, Qt::KeyboardModifiers mods)
+bool QWaylandBradientDecoration::handleTouch(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::TouchPointState state, Qt::KeyboardModifiers mods)
{
Q_UNUSED(inputDevice);
Q_UNUSED(global);
@@ -343,13 +359,13 @@ bool QWaylandDecoration::handleTouch(QWaylandInputDevice *inputDevice, const QPo
bool handled = state == Qt::TouchPointPressed;
if (handled) {
if (closeButtonRect().contains(local))
- QWindowSystemInterface::handleCloseEvent(m_window);
+ QWindowSystemInterface::handleCloseEvent(window());
else if (maximizeButtonRect().contains(local))
- m_window->setWindowState(m_wayland_window->isMaximized() ? Qt::WindowNoState : Qt::WindowMaximized);
+ window()->setWindowState(waylandWindow()->isMaximized() ? Qt::WindowNoState : Qt::WindowMaximized);
else if (minimizeButtonRect().contains(local))
- m_window->setWindowState(Qt::WindowMinimized);
- else if (local.y() <= m_margins.top())
- m_wayland_window->shellSurface()->move(inputDevice);
+ window()->setWindowState(Qt::WindowMinimized);
+ else if (local.y() <= margins().top())
+ waylandWindow()->shellSurface()->move(inputDevice);
else
handled = false;
}
@@ -357,115 +373,80 @@ bool QWaylandDecoration::handleTouch(QWaylandInputDevice *inputDevice, const QPo
return handled;
}
-bool QWaylandDecoration::inMouseButtonPressedState() const
-{
- return m_mouseButtons & Qt::NoButton;
-}
-
-void QWaylandDecoration::startResize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize resize, Qt::MouseButtons buttons)
-{
- if (isLeftClicked(buttons)) {
- m_wayland_window->shellSurface()->resize(inputDevice, resize);
- inputDevice->removeMouseButtonFromState(Qt::LeftButton);
- }
-}
-
-void QWaylandDecoration::startMove(QWaylandInputDevice *inputDevice, Qt::MouseButtons buttons)
-{
- if (isLeftClicked(buttons)) {
- m_wayland_window->shellSurface()->move(inputDevice);
- inputDevice->removeMouseButtonFromState(Qt::LeftButton);
- }
-}
-
-void QWaylandDecoration::processMouseTop(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
+void QWaylandBradientDecoration::processMouseTop(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
{
Q_UNUSED(mods);
- if (local.y() <= m_margins.bottom()) {
+ if (local.y() <= margins().bottom()) {
if (local.x() <= margins().left()) {
//top left bit
- m_wayland_window->setMouseCursor(inputDevice, Qt::SizeFDiagCursor);
+ waylandWindow()->setMouseCursor(inputDevice, Qt::SizeFDiagCursor);
startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP_LEFT,b);
- } else if (local.x() > m_window->width() - margins().right()) {
+ } else if (local.x() > window()->width() - margins().right()) {
//top right bit
- m_wayland_window->setMouseCursor(inputDevice, Qt::SizeBDiagCursor);
+ waylandWindow()->setMouseCursor(inputDevice, Qt::SizeBDiagCursor);
startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP_RIGHT,b);
} else {
//top reszie bit
- m_wayland_window->setMouseCursor(inputDevice, Qt::SplitVCursor);
+ waylandWindow()->setMouseCursor(inputDevice, Qt::SplitVCursor);
startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP,b);
}
} else {
- m_wayland_window->restoreMouseCursor(inputDevice);
+ waylandWindow()->restoreMouseCursor(inputDevice);
startMove(inputDevice,b);
}
}
-void QWaylandDecoration::processMouseBottom(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
+void QWaylandBradientDecoration::processMouseBottom(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
{
Q_UNUSED(mods);
if (local.x() <= margins().left()) {
//bottom left bit
- m_wayland_window->setMouseCursor(inputDevice, Qt::SizeBDiagCursor);
+ waylandWindow()->setMouseCursor(inputDevice, Qt::SizeBDiagCursor);
startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT,b);
- } else if (local.x() > m_window->width() - margins().right()) {
+ } else if (local.x() > window()->width() - margins().right()) {
//bottom right bit
- m_wayland_window->setMouseCursor(inputDevice, Qt::SizeFDiagCursor);
+ waylandWindow()->setMouseCursor(inputDevice, Qt::SizeFDiagCursor);
startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT,b);
} else {
//bottom bit
- m_wayland_window->setMouseCursor(inputDevice, Qt::SplitVCursor);
+ waylandWindow()->setMouseCursor(inputDevice, Qt::SplitVCursor);
startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_BOTTOM,b);
}
}
-void QWaylandDecoration::processMouseLeft(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
+void QWaylandBradientDecoration::processMouseLeft(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
{
Q_UNUSED(local);
Q_UNUSED(mods);
- m_wayland_window->setMouseCursor(inputDevice, Qt::SplitHCursor);
+ waylandWindow()->setMouseCursor(inputDevice, Qt::SplitHCursor);
startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_LEFT,b);
}
-void QWaylandDecoration::processMouseRight(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
+void QWaylandBradientDecoration::processMouseRight(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
{
Q_UNUSED(local);
Q_UNUSED(mods);
- m_wayland_window->setMouseCursor(inputDevice, Qt::SplitHCursor);
+ waylandWindow()->setMouseCursor(inputDevice, Qt::SplitHCursor);
startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_RIGHT,b);
}
-bool QWaylandDecoration::isLeftClicked(Qt::MouseButtons newMouseButtonState)
+class QWaylandBradientDecorationPlugin : public QWaylandDecorationPlugin
{
- if ((!m_mouseButtons & Qt::LeftButton) && (newMouseButtonState & Qt::LeftButton))
- return true;
- return false;
-}
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID QWaylandDecorationFactoryInterface_iid FILE "bradient.json")
+public:
+ QWaylandAbstractDecoration *create(const QString&, const QStringList&) Q_DECL_OVERRIDE;
+};
-bool QWaylandDecoration::isLeftReleased(Qt::MouseButtons newMouseButtonState)
+QWaylandAbstractDecoration *QWaylandBradientDecorationPlugin::create(const QString& system, const QStringList& paramList)
{
- if ((m_mouseButtons & Qt::LeftButton) && !(newMouseButtonState & Qt::LeftButton))
- return true;
- return false;
+ Q_UNUSED(paramList);
+ Q_UNUSED(system);
+ return new QWaylandBradientDecoration();
}
-QRectF QWaylandDecoration::closeButtonRect() const
-{
- return QRectF(window()->frameGeometry().width() - BUTTON_WIDTH - BUTTON_SPACING * 2,
- (m_margins.top() - BUTTON_WIDTH) / 2, BUTTON_WIDTH, BUTTON_WIDTH);
-}
-
-QRectF QWaylandDecoration::maximizeButtonRect() const
-{
- return QRectF(window()->frameGeometry().width() - BUTTON_WIDTH * 2 - BUTTON_SPACING * 3,
- (m_margins.top() - BUTTON_WIDTH) / 2, BUTTON_WIDTH, BUTTON_WIDTH);
-}
-
-QRectF QWaylandDecoration::minimizeButtonRect() const
-{
- return QRectF(window()->frameGeometry().width() - BUTTON_WIDTH * 3 - BUTTON_SPACING * 4,
- (m_margins.top() - BUTTON_WIDTH) / 2, BUTTON_WIDTH, BUTTON_WIDTH);
-}
QT_END_NAMESPACE
+
+#include "main.moc"
diff --git a/src/plugins/decorations/decorations.pro b/src/plugins/decorations/decorations.pro
new file mode 100644
index 000000000..6d51a450f
--- /dev/null
+++ b/src/plugins/decorations/decorations.pro
@@ -0,0 +1,3 @@
+TEMPLATE = subdirs
+SUBDIRS += \
+ bradient
diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro
index 554dd40cd..a1a8a5b7d 100644
--- a/src/plugins/plugins.pro
+++ b/src/plugins/plugins.pro
@@ -1,2 +1,5 @@
TEMPLATE=subdirs
-SUBDIRS += platforms hardwareintegration
+SUBDIRS += \
+ platforms \
+ hardwareintegration \
+ decorations
diff --git a/src/qtwaylandscanner/qtwaylandscanner.cpp b/src/qtwaylandscanner/qtwaylandscanner.cpp
index c99bf2b48..ae5ec40db 100644
--- a/src/qtwaylandscanner/qtwaylandscanner.cpp
+++ b/src/qtwaylandscanner/qtwaylandscanner.cpp
@@ -416,8 +416,8 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr
printf(" class %s %s\n {\n", serverExport.constData(), interfaceName);
printf(" public:\n");
- printf(" %s(struct ::wl_client *client, int id);\n", interfaceName);
- printf(" %s(struct ::wl_display *display);\n", interfaceName);
+ printf(" %s(struct ::wl_client *client, int id, int version);\n", interfaceName);
+ printf(" %s(struct ::wl_display *display, int version);\n", interfaceName);
printf(" %s();\n", interfaceName);
printf("\n");
printf(" virtual ~%s();\n", interfaceName);
@@ -432,16 +432,17 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr
printf(" struct ::wl_resource *handle;\n");
printf("\n");
printf(" struct ::wl_client *client() const { return handle->client; }\n");
+ printf(" int version() const { return wl_resource_get_version(handle); }\n");
printf("\n");
printf(" static Resource *fromResource(struct ::wl_resource *resource) { return static_cast<Resource *>(resource->data); }\n");
printf(" };\n");
printf("\n");
- printf(" void init(struct ::wl_client *client, int id);\n");
- printf(" void init(struct ::wl_display *display);\n");
+ printf(" void init(struct ::wl_client *client, int id, int version);\n");
+ printf(" void init(struct ::wl_display *display, int version);\n");
printf("\n");
- printf(" Resource *add(struct ::wl_client *client);\n");
- printf(" Resource *add(struct ::wl_client *client, int id);\n");
- printf(" Resource *add(struct wl_list *resource_list, struct ::wl_client *client, int id);\n");
+ printf(" Resource *add(struct ::wl_client *client, int version);\n");
+ printf(" Resource *add(struct ::wl_client *client, int id, int version);\n");
+ printf(" Resource *add(struct wl_list *resource_list, struct ::wl_client *client, int id, int version);\n");
printf("\n");
printf(" Resource *resource() { return m_resource; }\n");
printf(" const Resource *resource() const { return m_resource; }\n");
@@ -491,7 +492,7 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr
printf(" static void bind_func(struct ::wl_client *client, void *data, uint32_t version, uint32_t id);\n");
printf(" static void destroy_func(struct ::wl_resource *client_resource);\n");
printf("\n");
- printf(" Resource *bind(struct ::wl_client *client, uint32_t id);\n");
+ printf(" Resource *bind(struct ::wl_client *client, uint32_t id, int version);\n");
if (hasRequests) {
printf("\n");
@@ -511,6 +512,7 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr
printf(" QMultiMap<struct ::wl_client*, Resource*> m_resource_map;\n");
printf(" Resource *m_resource;\n");
printf(" struct ::wl_global *m_global;\n");
+ printf(" uint32_t m_globalVersion;\n");
printf(" };\n");
if (j < interfaces.size() - 1)
@@ -551,21 +553,21 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr
QByteArray stripped = stripInterfaceName(interface.name, prefix);
const char *interfaceNameStripped = stripped.constData();
- printf(" %s::%s(struct ::wl_client *client, int id)\n", interfaceName, interfaceName);
+ printf(" %s::%s(struct ::wl_client *client, int id, int version)\n", interfaceName, interfaceName);
printf(" : m_resource_map()\n");
printf(" , m_resource(0)\n");
printf(" , m_global(0)\n");
printf(" {\n");
- printf(" init(client, id);\n");
+ printf(" init(client, id, version);\n");
printf(" }\n");
printf("\n");
- printf(" %s::%s(struct ::wl_display *display)\n", interfaceName, interfaceName);
+ printf(" %s::%s(struct ::wl_display *display, int version)\n", interfaceName, interfaceName);
printf(" : m_resource_map()\n");
printf(" , m_resource(0)\n");
printf(" , m_global(0)\n");
printf(" {\n");
- printf(" init(display);\n");
+ printf(" init(display, version);\n");
printf(" }\n");
printf("\n");
@@ -582,31 +584,32 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr
printf(" }\n");
printf("\n");
- printf(" void %s::init(struct ::wl_client *client, int id)\n", interfaceName);
+ printf(" void %s::init(struct ::wl_client *client, int id, int version)\n", interfaceName);
printf(" {\n");
- printf(" m_resource = bind(client, id);\n");
+ printf(" m_resource = bind(client, id, version);\n");
printf(" }\n");
printf("\n");
- printf(" %s::Resource *%s::add(struct ::wl_client *client)\n", interfaceName, interfaceName);
+ printf(" %s::Resource *%s::add(struct ::wl_client *client, int version)\n", interfaceName, interfaceName);
printf(" {\n");
- printf(" Resource *resource = bind(client, 0);\n");
+ printf(" Resource *resource = bind(client, 0, version);\n");
printf(" m_resource_map.insert(client, resource);\n");
printf(" return resource;\n");
printf(" }\n");
printf("\n");
- printf(" %s::Resource *%s::add(struct ::wl_client *client, int id)\n", interfaceName, interfaceName);
+ printf(" %s::Resource *%s::add(struct ::wl_client *client, int id, int version)\n", interfaceName, interfaceName);
printf(" {\n");
- printf(" Resource *resource = bind(client, id);\n");
+ printf(" Resource *resource = bind(client, id, version);\n");
printf(" m_resource_map.insert(client, resource);\n");
printf(" return resource;\n");
printf(" }\n");
printf("\n");
- printf(" void %s::init(struct ::wl_display *display)\n", interfaceName);
+ printf(" void %s::init(struct ::wl_display *display, int version)\n", interfaceName);
printf(" {\n");
- printf(" m_global = wl_global_create(display, &::%s_interface, ::%s_interface.version, this, bind_func);\n", interfaceName, interfaceName);
+ printf(" m_global = wl_global_create(display, &::%s_interface, version, this, bind_func);\n", interfaceName);
+ printf(" m_globalVersion = version;\n");
printf(" }\n");
printf("\n");
@@ -628,8 +631,8 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr
printf(" void %s::bind_func(struct ::wl_client *client, void *data, uint32_t version, uint32_t id)\n", interfaceName);
printf(" {\n");
- printf(" Q_UNUSED(version);\n");
- printf(" static_cast<%s *>(data)->add(client, id);\n", interfaceName);
+ printf(" %s *that = static_cast<%s *>(data);\n", interfaceName, interfaceName);
+ printf(" that->add(client, id, qMin(that->m_globalVersion, version));\n");
printf(" }\n");
printf("\n");
@@ -652,12 +655,12 @@ void process(QXmlStreamReader &xml, const QByteArray &headerPath, const QByteArr
//We should consider changing bind so that it doesn't special case id == 0
//and use function overloading instead. Jan do you have a lot of code dependent on this behavior?
- printf(" %s::Resource *%s::bind(struct ::wl_client *client, uint32_t id)\n", interfaceName, interfaceName);
+ printf(" %s::Resource *%s::bind(struct ::wl_client *client, uint32_t id, int version)\n", interfaceName, interfaceName);
printf(" {\n");
printf(" Resource *resource = %s_allocate();\n", interfaceNameStripped);
printf(" resource->%s_object = this;\n", interfaceNameStripped);
printf("\n");
- printf(" struct ::wl_resource *handle = wl_resource_create(client, &::%s_interface, ::%s_interface.version, id);\n", interfaceName, interfaceName);
+ printf(" struct ::wl_resource *handle = wl_resource_create(client, &::%s_interface, version, id);\n", interfaceName);
printf(" wl_resource_set_implementation(handle, %s, resource, destroy_func);", interfaceMember.constData());
printf("\n");
printf(" resource->handle = handle;\n");