diff options
author | Paul Olav Tvete <paul.tvete@qt.io> | 2017-10-25 14:06:54 +0200 |
---|---|---|
committer | Paul Olav Tvete <paul.tvete@qt.io> | 2017-10-25 14:06:54 +0200 |
commit | 523cf490b4c46916c6f5253c666a492f5cce2aad (patch) | |
tree | b4514f338b143ab430fe2b91ec7699cb176a147e | |
parent | 8e3c71b2d1ec37222bf1648aa23eb033062b4ea6 (diff) | |
parent | f1407493d6d25f24a3c71fbcedc00598baa44b56 (diff) | |
download | qtwayland-2af060294a1552b5273899182fa54d40d3285f53.tar.gz |
Merge remote-tracking branch 'qt/5.9' into 5.10v5.10.0-beta3
Change-Id: I6c283081669594b3e8c6b30194bb96e389319cb2
67 files changed, 1340 insertions, 278 deletions
diff --git a/config.tests/drm_egl_server/main.cpp b/config.tests/drm_egl_server/main.cpp index 6552fe74..0dbd42f9 100644 --- a/config.tests/drm_egl_server/main.cpp +++ b/config.tests/drm_egl_server/main.cpp @@ -1,12 +1,22 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Compositor. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are diff --git a/config.tests/glx/main.cpp b/config.tests/glx/main.cpp index 2d413e19..c902c55d 100644 --- a/config.tests/glx/main.cpp +++ b/config.tests/glx/main.cpp @@ -1,12 +1,22 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Compositor. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are diff --git a/config.tests/libhybris_egl_server/main.cpp b/config.tests/libhybris_egl_server/main.cpp index 29488957..368b57a1 100644 --- a/config.tests/libhybris_egl_server/main.cpp +++ b/config.tests/libhybris_egl_server/main.cpp @@ -1,12 +1,22 @@ /**************************************************************************** ** ** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> -** Contact: http://www.qt.io/licensing/ +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Compositor. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are diff --git a/config.tests/wayland/main.cpp b/config.tests/wayland/main.cpp index 1af00ee3..9e0002db 100644 --- a/config.tests/wayland/main.cpp +++ b/config.tests/wayland/main.cpp @@ -1,12 +1,22 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Compositor. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are diff --git a/config.tests/wayland_cursor/main.cpp b/config.tests/wayland_cursor/main.cpp index e1a2bccc..c9cf6619 100644 --- a/config.tests/wayland_cursor/main.cpp +++ b/config.tests/wayland_cursor/main.cpp @@ -1,12 +1,22 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Compositor. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are diff --git a/config.tests/wayland_egl/main.cpp b/config.tests/wayland_egl/main.cpp index f79677cd..c5005646 100644 --- a/config.tests/wayland_egl/main.cpp +++ b/config.tests/wayland_egl/main.cpp @@ -1,12 +1,22 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Compositor. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are diff --git a/config.tests/wayland_scanner/main.cpp b/config.tests/wayland_scanner/main.cpp index 5d20b5bf..dd66f5ff 100644 --- a/config.tests/wayland_scanner/main.cpp +++ b/config.tests/wayland_scanner/main.cpp @@ -1,12 +1,22 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Compositor. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are diff --git a/config.tests/xcomposite/main.cpp b/config.tests/xcomposite/main.cpp index 11ba3b5a..1867b204 100644 --- a/config.tests/xcomposite/main.cpp +++ b/config.tests/xcomposite/main.cpp @@ -1,12 +1,22 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Compositor. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are diff --git a/dist/changes-5.9.2 b/dist/changes-5.9.2 new file mode 100644 index 00000000..23de8dc9 --- /dev/null +++ b/dist/changes-5.9.2 @@ -0,0 +1,62 @@ +Qt 5.9.2 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.9.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.9 series is binary compatible with the 5.8.x series. +Applications compiled for 5.8 will continue to run with 5.9. Exception: +between Qt 5.8.0 and 5.9.0 the QWaylandQuickOutput class was changed +in a binary incompatible way. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Qt Wayland General * +**************************************************************************** + +- Fix detection of wayland-egl on imx6 without pkg-config. + +**************************************************************************** +* Qt Wayland QPA Plugin * +**************************************************************************** + +- Fix crash when window was reset twice (e.g. if both setParent and + setVisible was called together). + +- [QTBUG-61704] Fix crash when focus event arrives after hiding window. + +- Fix crash when window attach was called without waiting for frame + callbacks. + +- [QTBUG-62048] Fix crash with nested menus on Weston. + +- [QTBUG-62044] Fix crash when second monitor is attached. + +- Update QWindow::screen() based on surface enter/leave events. + +- Send pointer event to all bound resources. This fixes the issue where + the breeze Qt style would block mouse events, leading to an unresponsive + client. + +- [QTBUG-60932] Place popup menus correctly even if parent is not set. + +- Make tooltips non-grabbing with XDG shell v6. + +- Make the QT_WAYLAND_SERVER_BUFFER_INTEGRATION environment variable work. + + + +**************************************************************************** +* Qt Wayland Compositor API * +**************************************************************************** + +- Buffer returned by toOpenGLTexture() now has correct size and format. diff --git a/examples/wayland/custom-extension/client-common/customextension.cpp b/examples/wayland/custom-extension/client-common/customextension.cpp index 81f524d9..41b4a30e 100644 --- a/examples/wayland/custom-extension/client-common/customextension.cpp +++ b/examples/wayland/custom-extension/client-common/customextension.cpp @@ -109,6 +109,12 @@ void CustomExtension::registerWindow(QWindow *window) sendWindowRegistration(window); } +CustomExtensionObject *CustomExtension::createCustomObject(const QString &color, const QString &text) +{ + auto *obj = create_local_object(color, text); + return new CustomExtensionObject(obj, text); +} + void CustomExtension::sendBounce(QWindow *window, uint ms) { QtWayland::qt_example_extension::bounce(getWlSurface(window), ms); @@ -152,4 +158,24 @@ void CustomExtension::example_extension_set_window_decoration(uint32_t state) } } +CustomExtensionObject::CustomExtensionObject(struct ::qt_example_local_object *wl_object, const QString &text) + : QWaylandClientExtensionTemplate<CustomExtensionObject>(1) + , QtWayland::qt_example_local_object(wl_object) + , m_text(text) +{ + +} + +void CustomExtensionObject::example_local_object_clicked() +{ + qDebug() << "Object clicked:" << m_text; + emit clicked(); +} + +void CustomExtensionObject::setText(const QString &text) +{ + m_text = text; + set_text(text); +} + QT_END_NAMESPACE diff --git a/examples/wayland/custom-extension/client-common/customextension.h b/examples/wayland/custom-extension/client-common/customextension.h index e76682f6..003a5a00 100644 --- a/examples/wayland/custom-extension/client-common/customextension.h +++ b/examples/wayland/custom-extension/client-common/customextension.h @@ -58,6 +58,8 @@ QT_BEGIN_NAMESPACE +class CustomExtensionObject; + class CustomExtension : public QWaylandClientExtensionTemplate<CustomExtension> , public QtWayland::qt_example_extension { @@ -66,6 +68,8 @@ public: CustomExtension(); Q_INVOKABLE void registerWindow(QWindow *window); + CustomExtensionObject *createCustomObject(const QString &color, const QString &text); + public slots: void sendBounce(QWindow *window, uint ms); void sendSpin(QWindow *window, uint ms); @@ -92,6 +96,36 @@ private: bool m_activated; }; +class CustomExtensionObject : public QWaylandClientExtensionTemplate<CustomExtensionObject> + , public QtWayland::qt_example_local_object +{ + Q_OBJECT + Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) +public: + CustomExtensionObject(struct ::qt_example_local_object *wl_object, const QString &text); + + QString text() const + { + return m_text; + } + +protected: + void example_local_object_clicked() override; + +public slots: + void setText(const QString &text); + + +signals: + void textChanged(const QString &text); + void clicked(); + +private: + QString m_text; +}; + + + QT_END_NAMESPACE #endif // CUSTOMEXTENSION_H diff --git a/examples/wayland/custom-extension/compositor/customextension.cpp b/examples/wayland/custom-extension/compositor/customextension.cpp index 8304e1af..d9f637a1 100644 --- a/examples/wayland/custom-extension/compositor/customextension.cpp +++ b/examples/wayland/custom-extension/compositor/customextension.cpp @@ -123,3 +123,39 @@ void CustomExtension::example_extension_register_surface(QtWaylandServer::qt_exa qDebug() << "server received new surface" << surface; emit surfaceAdded(surface); } + + +void CustomExtension::example_extension_create_local_object(Resource *resource, uint32_t id, const QString &color, const QString &text) +{ + auto *obj = new CustomExtensionObject(color, text, resource->client(), id, 1); + qDebug() << "Object created" << text << color; + emit customObjectCreated(obj); +} + +CustomExtensionObject::CustomExtensionObject(const QString &color, const QString &text, wl_client *client, int id, int version) + : QtWaylandServer::qt_example_local_object(client, id, version) + , m_color(color) + , m_text(text) +{ + +} + +void CustomExtensionObject::sendClicked() +{ + send_clicked(); +} + +void CustomExtensionObject::example_local_object_destroy_resource(QtWaylandServer::qt_example_local_object::Resource *resource) +{ + Q_UNUSED(resource); + qDebug() << "Object destroyed" << m_text << m_color; + emit resourceDestroyed(); +} + + +void CustomExtensionObject::example_local_object_set_text(QtWaylandServer::qt_example_local_object::Resource *resource, const QString &text) +{ + Q_UNUSED(resource); + qDebug() << "Client changed text from" << m_text << "to" << text; + setText(text); +} diff --git a/examples/wayland/custom-extension/compositor/customextension.h b/examples/wayland/custom-extension/compositor/customextension.h index b8f05b17..de7df6ac 100644 --- a/examples/wayland/custom-extension/compositor/customextension.h +++ b/examples/wayland/custom-extension/compositor/customextension.h @@ -58,6 +58,8 @@ #include <QtWaylandCompositor/QWaylandCompositor> #include "qwayland-server-custom.h" +class CustomExtensionObject; + class CustomExtension : public QWaylandCompositorExtensionTemplate<CustomExtension> , public QtWaylandServer::qt_example_extension { @@ -71,6 +73,8 @@ signals: void bounce(QWaylandSurface *surface, uint ms); void spin(QWaylandSurface *surface, uint ms); + void customObjectCreated(CustomExtensionObject *obj); + public slots: void setFontSize(QWaylandSurface *surface, uint pixelSize); void showDecorations(QWaylandClient *client, bool); @@ -80,6 +84,63 @@ protected: void example_extension_bounce(Resource *resource, wl_resource *surface, uint32_t duration) override; void example_extension_spin(Resource *resource, wl_resource *surface, uint32_t duration) override; void example_extension_register_surface(Resource *resource, wl_resource *surface) override; + + void example_extension_create_local_object(Resource *resource, uint32_t id, const QString &color, const QString &text) override; +}; + + +class CustomExtensionObject : public QWaylandCompositorExtensionTemplate<CustomExtensionObject> + , public QtWaylandServer::qt_example_local_object +{ + Q_OBJECT + Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged) + Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) +public: + CustomExtensionObject(const QString &color, const QString &text, struct ::wl_client *client, int id, int version); + + QString color() const + { + return m_color; + } + + QString text() const + { + return m_text; + } + +public slots: + void setColor(const QString &color) + { + if (m_color == color) + return; + + m_color = color; + emit colorChanged(m_color); + } + + void setText(QString text) + { + if (m_text == text) + return; + + m_text = text; + emit textChanged(m_text); + } + void sendClicked(); + +signals: + void colorChanged(const QString &color); + void resourceDestroyed(); + + void textChanged(QString text); + +protected: + void example_local_object_destroy_resource(Resource *resource) override; + void example_local_object_set_text(Resource *resource, const QString &text) override; + +private: + QString m_color; + QString m_text; }; Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(CustomExtension) diff --git a/examples/wayland/custom-extension/compositor/qml/main.qml b/examples/wayland/custom-extension/compositor/qml/main.qml index 6739a5c9..a7d76227 100644 --- a/examples/wayland/custom-extension/compositor/qml/main.qml +++ b/examples/wayland/custom-extension/compositor/qml/main.qml @@ -139,6 +139,40 @@ WaylandCompositor { } } + + Component { + id: customObjectComponent + Rectangle { + id: customItem + property QtObject obj + property alias text: label.text + + width: 100 + height: 100 + radius: width/2 + x: Math.random() * (defaultOutput.surfaceArea.width - 100) + y: Math.random() * (defaultOutput.surfaceArea.height - 100) + + Text { + id: label + anchors.centerIn: parent + text: "?" + } + + MouseArea { + anchors.fill: parent + onClicked: obj.sendClicked() + } + + Connections { + target: obj + onResourceDestroyed: { + customItem.destroy() + } + } + } + } + WlShell { id: defaultShell onWlShellSurfaceCreated: { @@ -168,6 +202,9 @@ WaylandCompositor { var item = itemForSurface(surface) item.doSpin(ms) } + onCustomObjectCreated: { + var item = customObjectComponent.createObject(defaultOutput.surfaceArea, { "color": obj.color, "text": obj.text, "obj": obj } ); + } } function setDecorations(shown) { diff --git a/examples/wayland/custom-extension/cpp-client/main.cpp b/examples/wayland/custom-extension/cpp-client/main.cpp index 54c0bcc0..da6230cc 100644 --- a/examples/wayland/custom-extension/cpp-client/main.cpp +++ b/examples/wayland/custom-extension/cpp-client/main.cpp @@ -70,6 +70,7 @@ public: , rect1(50, 50, 100, 100) , rect2(50, 200, 100, 100) , rect3(50, 350, 100, 100) + , rect4(200,350, 100, 100) { m_extension->registerWindow(this); connect(m_extension, &CustomExtension::fontSize, this, &TestWindow::handleSetFontSize); @@ -101,6 +102,14 @@ public slots: w->show(); } + CustomExtensionObject *newObject() + { + m_objectCount++; + QColor col = QColor::fromHsv(0, 511/(m_objectCount+1), 255); + + return m_extension->createCustomObject(col.name(), QString::number(m_objectCount)); + } + void handleSetFontSize(QWindow *w, uint pixelSize) { if (w == this) { @@ -121,6 +130,9 @@ protected: p.drawText(rect2, Qt::TextWordWrap, "Press here to send bounce request."); p.fillRect(rect3, QColor("#7EA")); p.drawText(rect3, Qt::TextWordWrap, "Create new window."); + p.fillRect(rect4, QColor("#7EABA6")); + p.drawText(rect4, Qt::TextWordWrap, "Create custom object."); + } void mousePressEvent(QMouseEvent *ev) override @@ -131,6 +143,8 @@ protected: doBounce(); else if (rect3.contains(ev->pos())) newWindow(); + else if (rect4.contains(ev->pos())) + newObject(); } private: @@ -138,9 +152,15 @@ private: QRect rect1; QRect rect2; QRect rect3; + QRect rect4; QFont m_font; + static int m_objectCount; + static int m_hue; }; +int TestWindow::m_objectCount = 0; +int TestWindow::m_hue; + int main (int argc, char **argv) { QGuiApplication app(argc, argv); diff --git a/examples/wayland/custom-extension/protocol/custom.xml b/examples/wayland/custom-extension/protocol/custom.xml index 9bbe50d6..2e9a8426 100644 --- a/examples/wayland/custom-extension/protocol/custom.xml +++ b/examples/wayland/custom-extension/protocol/custom.xml @@ -40,9 +40,9 @@ <interface name="qt_example_extension" version="1"> - <description summary="example extension for surfaces"> - This example shows how to add extra functionality to the Wayland - through an extension. + <description summary="Example Wayland extension"> + This example shows how to add extra functionality to Wayland + through an extension. This is the global object of the extension. </description> <request name="register_surface"> @@ -85,23 +85,52 @@ <arg name="pixel_size" type="uint"/> </event> + <enum name="decoration_state"> + <description summary="window decoration state"> + Describes whether window decorations should be shown. + </description> + <entry name="hidden" value="0" summary="Decorations are not shown"/> + <entry name="shown" value="1" summary="Decorations are shown"/> + </enum> + <event name="set_window_decoration"> <description summary="turn window decoration on/off"> Ask the client to turn window decoration on/off on all surfaces. </description> - <enum name="decoration_state"> - <description summary="window decoration state"> - Describes whether window decorations should be shown. - </description> - <entry name="hidden" value="0" summary="Decorations are not shown"/> - <entry name="shown" value="1" summary="Decorations are shown"/> - </enum> - <arg name="state" type="uint"/> </event> + <request name="create_local_object"> + <description summary="Create a sily object"> + Create a new object that should be visualized by the compositor + </description> + <arg name="id" type="new_id" interface="qt_example_local_object"/> + <arg name="color" type = "string"/> + <arg name="text" type = "string"/> + </request> </interface> + <interface name="qt_example_local_object" version="1"> + <description summary="An object created on the client side"> + This object should have a visual representation in the compositor. + </description> + + <request name="set_text"> + <description summary="Change the text"> + Tell the compositor that the object's text is changed + </description> + <arg name="text" type="string"/> + </request> + + <event name="clicked"> + <description summary="The object was clicked"> + Notification to the client that the user clicked the representation of + the object in the compositor. + </description> + + </event> + + </interface> </protocol> diff --git a/examples/wayland/ivi-compositor/doc/src/ivi-compositor.qdoc b/examples/wayland/ivi-compositor/doc/src/ivi-compositor.qdoc index ae37c895..f25eb855 100644 --- a/examples/wayland/ivi-compositor/doc/src/ivi-compositor.qdoc +++ b/examples/wayland/ivi-compositor/doc/src/ivi-compositor.qdoc @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** @@ -11,8 +11,8 @@ ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Free Documentation License Usage ** Alternatively, this file may be used under the terms of the GNU Free @@ -20,7 +20,7 @@ ** Foundation and appearing in the file included in the packaging of ** this file. Please review the following information to ensure ** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/examples/wayland/minimal-qml/doc/src/minimal-qml.qdoc b/examples/wayland/minimal-qml/doc/src/minimal-qml.qdoc index 24a5f652..5a435f3f 100644 --- a/examples/wayland/minimal-qml/doc/src/minimal-qml.qdoc +++ b/examples/wayland/minimal-qml/doc/src/minimal-qml.qdoc @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** @@ -11,8 +11,8 @@ ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Free Documentation License Usage ** Alternatively, this file may be used under the terms of the GNU Free @@ -20,7 +20,7 @@ ** Foundation and appearing in the file included in the packaging of ** this file. Please review the following information to ensure ** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/examples/wayland/minimal-qml/main.cpp b/examples/wayland/minimal-qml/main.cpp index 435b4e3f..60378e86 100644 --- a/examples/wayland/minimal-qml/main.cpp +++ b/examples/wayland/minimal-qml/main.cpp @@ -57,6 +57,9 @@ int main(int argc, char *argv[]) { + // ShareOpenGLContexts is needed for using the threaded renderer + // on Nvidia EGLStreams + QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true); QGuiApplication app(argc, argv); QQmlApplicationEngine appEngine(QUrl("qrc:///main.qml")); diff --git a/examples/wayland/multi-output/doc/src/multi-output.qdoc b/examples/wayland/multi-output/doc/src/multi-output.qdoc index 32b9aa69..233b29ba 100644 --- a/examples/wayland/multi-output/doc/src/multi-output.qdoc +++ b/examples/wayland/multi-output/doc/src/multi-output.qdoc @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** @@ -11,8 +11,8 @@ ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Free Documentation License Usage ** Alternatively, this file may be used under the terms of the GNU Free @@ -20,7 +20,7 @@ ** Foundation and appearing in the file included in the packaging of ** this file. Please review the following information to ensure ** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/examples/wayland/multi-screen/doc/src/multi-screen.qdoc b/examples/wayland/multi-screen/doc/src/multi-screen.qdoc index 20d3912c..cd60213b 100644 --- a/examples/wayland/multi-screen/doc/src/multi-screen.qdoc +++ b/examples/wayland/multi-screen/doc/src/multi-screen.qdoc @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** @@ -11,8 +11,8 @@ ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Free Documentation License Usage ** Alternatively, this file may be used under the terms of the GNU Free @@ -20,7 +20,7 @@ ** Foundation and appearing in the file included in the packaging of ** this file. Please review the following information to ensure ** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/examples/wayland/pure-qml/doc/src/pure-qml.qdoc b/examples/wayland/pure-qml/doc/src/pure-qml.qdoc index 18ca73ec..06a938be 100644 --- a/examples/wayland/pure-qml/doc/src/pure-qml.qdoc +++ b/examples/wayland/pure-qml/doc/src/pure-qml.qdoc @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** @@ -11,8 +11,8 @@ ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Free Documentation License Usage ** Alternatively, this file may be used under the terms of the GNU Free @@ -20,7 +20,7 @@ ** Foundation and appearing in the file included in the packaging of ** this file. Please review the following information to ensure ** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/examples/wayland/pure-qml/main.cpp b/examples/wayland/pure-qml/main.cpp index 304b13c4..38ed5c93 100644 --- a/examples/wayland/pure-qml/main.cpp +++ b/examples/wayland/pure-qml/main.cpp @@ -57,6 +57,9 @@ int main(int argc, char *argv[]) { + // ShareOpenGLContexts is needed for using the threaded renderer + // on Nvidia EGLStreams + QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true); QGuiApplication app(argc, argv); QQmlApplicationEngine appEngine(QUrl("qrc:///qml/main.qml")); diff --git a/examples/wayland/qwindow-compositor/doc/src/qwindow-compositor.qdoc b/examples/wayland/qwindow-compositor/doc/src/qwindow-compositor.qdoc index d268aca4..c4f408c5 100644 --- a/examples/wayland/qwindow-compositor/doc/src/qwindow-compositor.qdoc +++ b/examples/wayland/qwindow-compositor/doc/src/qwindow-compositor.qdoc @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** @@ -11,8 +11,8 @@ ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Free Documentation License Usage ** Alternatively, this file may be used under the terms of the GNU Free @@ -20,7 +20,7 @@ ** Foundation and appearing in the file included in the packaging of ** this file. Please review the following information to ensure ** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/examples/wayland/spanning-screens/doc/src/spanning-screens.qdoc b/examples/wayland/spanning-screens/doc/src/spanning-screens.qdoc index cbb720fa..3ab0b91f 100644 --- a/examples/wayland/spanning-screens/doc/src/spanning-screens.qdoc +++ b/examples/wayland/spanning-screens/doc/src/spanning-screens.qdoc @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2017 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** @@ -11,8 +11,8 @@ ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Free Documentation License Usage ** Alternatively, this file may be used under the terms of the GNU Free @@ -20,7 +20,7 @@ ** Foundation and appearing in the file included in the packaging of ** this file. Please review the following information to ensure ** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/client/qwaylandbuffer.cpp b/src/client/qwaylandbuffer.cpp index a0fcc532..076a0d57 100644 --- a/src/client/qwaylandbuffer.cpp +++ b/src/client/qwaylandbuffer.cpp @@ -66,7 +66,7 @@ void QWaylandBuffer::init(wl_buffer *buf) void QWaylandBuffer::release(void *data, wl_buffer *) { - static_cast<QWaylandBuffer *>(data)->mBusy = false; + static_cast<QWaylandBuffer *>(data)->mBusy--; } const wl_buffer_listener QWaylandBuffer::listener = { diff --git a/src/client/qwaylandbuffer_p.h b/src/client/qwaylandbuffer_p.h index 9e8cba2e..b3513d15 100644 --- a/src/client/qwaylandbuffer_p.h +++ b/src/client/qwaylandbuffer_p.h @@ -73,14 +73,14 @@ public: virtual QSize size() const = 0; virtual int scale() const { return 1; } - void setBusy() { mBusy = true; } - bool busy() const { return mBusy; } + void setBusy() { mBusy++; } + bool busy() const { return mBusy > 0; } protected: struct wl_buffer *mBuffer; private: - bool mBusy; + int mBusy; static void release(void *data, wl_buffer *); static const wl_buffer_listener listener; diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index cac92a7e..cff380e8 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -261,6 +261,8 @@ void QWaylandWindow::reset(bool sendDestroyEvent) wl_callback_destroy(mFrameCallback); mFrameCallback = nullptr; } + + mMask = QRegion(); } QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface) @@ -790,22 +792,27 @@ QWaylandAbstractDecoration *QWaylandWindow::decoration() const return mWindowDecoration; } -static QWindow *topLevelWindow(QWindow *window) +static QWaylandWindow *closestShellSurfaceWindow(QWindow *window) { - while (QWindow *parent = window->parent()) - window = parent; - return window; + while (window) { + auto w = static_cast<QWaylandWindow *>(window->handle()); + if (w->shellSurface()) + return w; + window = window->transientParent() ? window->transientParent() : window->parent(); + } + return nullptr; } QWaylandWindow *QWaylandWindow::transientParent() const { - // Take the top level window here, since the transient parent may be a QWidgetWindow - // or some other window without a shell surface, which is then not able to get mouse - // events. - if (auto transientParent = window()->transientParent()) - return static_cast<QWaylandWindow *>(topLevelWindow(transientParent)->handle()); - else if (QGuiApplication::focusWindow() && (window()->type() == Qt::ToolTip || window()->type() == Qt::Popup)) - return static_cast<QWaylandWindow *>(topLevelWindow(QGuiApplication::focusWindow())->handle()); + // Take the closest window with a shell surface, since the transient parent may be a + // QWidgetWindow or some other window without a shell surface, which is then not able to + // get mouse events. + if (auto transientParent = closestShellSurfaceWindow(window()->transientParent())) + return transientParent; + + if (QGuiApplication::focusWindow() && (window()->type() == Qt::ToolTip || window()->type() == Qt::Popup)) + return closestShellSurfaceWindow(QGuiApplication::focusWindow()); return nullptr; } diff --git a/src/client/qwaylandwlshellsurface.cpp b/src/client/qwaylandwlshellsurface.cpp index 77434e98..92223f45 100644 --- a/src/client/qwaylandwlshellsurface.cpp +++ b/src/client/qwaylandwlshellsurface.cpp @@ -185,6 +185,7 @@ void QWaylandWlShellSurface::updateTransientParent(QWindow *parent) || testShowWithoutActivating(m_window->window())) flags |= WL_SHELL_SURFACE_TRANSIENT_INACTIVE; + Q_ASSERT(parent_wayland_window->object()); set_transient(parent_wayland_window->object(), transientPos.x(), transientPos.y(), @@ -211,15 +212,16 @@ void QWaylandWlShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevic transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top()); } + Q_ASSERT(parent_wayland_window->object()); set_popup(device->wl_seat(), serial, parent_wayland_window->object(), transientPos.x(), transientPos.y(), 0); } void QWaylandWlShellSurface::setType(Qt::WindowType type, QWaylandWindow *transientParent) { - if (type == Qt::Popup && transientParent) + if (type == Qt::Popup && transientParent && transientParent->object()) setPopup(transientParent, m_window->display()->lastInputDevice(), m_window->display()->lastInputSerial()); - else if (transientParent) + else if (transientParent && transientParent->object()) updateTransientParent(transientParent->window()); else setTopLevel(); diff --git a/src/compositor/compositor_api/qwaylandclient.cpp b/src/compositor/compositor_api/qwaylandclient.cpp index 48675c49..f6b5564b 100644 --- a/src/compositor/compositor_api/qwaylandclient.cpp +++ b/src/compositor/compositor_api/qwaylandclient.cpp @@ -167,7 +167,7 @@ QWaylandClient *QWaylandClient::fromWlClient(QWaylandCompositor *compositor, wl_ } /*! - * \qmlproperty object QtWaylandCompositor::WaylandClient::compositor + * \qmlproperty WaylandCompositor QtWaylandCompositor::WaylandClient::compositor * * This property holds the compositor of this WaylandClient. */ diff --git a/src/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp index 522ef041..00f3d83f 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.cpp +++ b/src/compositor/compositor_api/qwaylandcompositor.cpp @@ -660,7 +660,7 @@ QWaylandOutput *QWaylandCompositor::outputFor(QWindow *window) const } /*! - * \qmlproperty object QtWaylandCompositor::WaylandCompositor::defaultOutput + * \qmlproperty WaylandOutput QtWaylandCompositor::WaylandCompositor::defaultOutput * * This property contains the first in the list of outputs added to the * WaylandCompositor, or null if no outputs have been added. @@ -805,7 +805,7 @@ void QWaylandCompositor::overrideSelection(const QMimeData *data) } /*! - * \qmlproperty object QtWaylandCompositor::WaylandCompositor::defaultSeat + * \qmlproperty WaylandSeat QtWaylandCompositor::WaylandCompositor::defaultSeat * * This property contains the default seat for this * WaylandCompositor. diff --git a/src/compositor/compositor_api/qwaylandoutput.cpp b/src/compositor/compositor_api/qwaylandoutput.cpp index cbd7fe77..522de08e 100644 --- a/src/compositor/compositor_api/qwaylandoutput.cpp +++ b/src/compositor/compositor_api/qwaylandoutput.cpp @@ -336,7 +336,7 @@ void QWaylandOutput::update() } /*! - * \qmlproperty object QtWaylandCompositor::WaylandOutput::compositor + * \qmlproperty WaylandCompositor QtWaylandCompositor::WaylandOutput::compositor * * This property holds the compositor displaying content on this WaylandOutput. * @@ -990,6 +990,7 @@ void QWaylandOutput::handleWindowDestroyed() { Q_D(QWaylandOutput); d->window = Q_NULLPTR; + emit windowChanged(); emit windowDestroyed(); } diff --git a/src/compositor/compositor_api/qwaylandpointer.cpp b/src/compositor/compositor_api/qwaylandpointer.cpp index d1ca174d..bf4bf547 100644 --- a/src/compositor/compositor_api/qwaylandpointer.cpp +++ b/src/compositor/compositor_api/qwaylandpointer.cpp @@ -51,31 +51,77 @@ QWaylandPointerPrivate::QWaylandPointerPrivate(QWaylandPointer *pointer, QWaylan , wl_pointer() , seat(seat) , output() - , hasSentEnter(false) , enterSerial(0) , buttonCount() { Q_UNUSED(pointer); } -const QList<QtWaylandServer::wl_pointer::Resource *> QWaylandPointerPrivate::pointerResourcesForFocusedSurface() const -{ - if (!seat->mouseFocus()) - return {}; - - return resourceMap().values(seat->mouseFocus()->surfaceResource()->client); -} - uint QWaylandPointerPrivate::sendButton(Qt::MouseButton button, uint32_t state) { Q_Q(QWaylandPointer); + if (!q->mouseFocus() || !q->mouseFocus()->surface()) + return 0; + + wl_client *client = q->mouseFocus()->surface()->waylandClient(); uint32_t time = compositor()->currentTimeMsecs(); uint32_t serial = compositor()->nextSerial(); - for (auto resource : pointerResourcesForFocusedSurface()) + for (auto resource : resourceMap().values(client)) send_button(resource->handle, serial, time, q->toWaylandButton(button), state); return serial; } +void QWaylandPointerPrivate::sendMotion() +{ + Q_ASSERT(enteredSurface); + uint32_t time = compositor()->currentTimeMsecs(); + wl_fixed_t x = wl_fixed_from_double(localPosition.x()); + wl_fixed_t y = wl_fixed_from_double(localPosition.y()); + for (auto resource : resourceMap().values(enteredSurface->waylandClient())) + wl_pointer_send_motion(resource->handle, time, x, y); +} + +void QWaylandPointerPrivate::sendEnter(QWaylandSurface *surface) +{ + Q_ASSERT(surface && !enteredSurface); + enterSerial = compositor()->nextSerial(); + + QWaylandKeyboard *keyboard = seat->keyboard(); + if (keyboard) + keyboard->sendKeyModifiers(surface->client(), enterSerial); + + wl_fixed_t x = wl_fixed_from_double(localPosition.x()); + wl_fixed_t y = wl_fixed_from_double(localPosition.y()); + for (auto resource : resourceMap().values(surface->waylandClient())) + send_enter(resource->handle, enterSerial, surface->resource(), x, y); + + enteredSurface = surface; + enteredSurfaceDestroyListener.listenForDestruction(surface->resource()); +} + +void QWaylandPointerPrivate::sendLeave() +{ + Q_ASSERT(enteredSurface); + uint32_t serial = compositor()->nextSerial(); + for (auto resource : resourceMap().values(enteredSurface->waylandClient())) + send_leave(resource->handle, serial, enteredSurface->resource()); + enteredSurface = nullptr; + localPosition = QPointF(); + enteredSurfaceDestroyListener.reset(); +} + +void QWaylandPointerPrivate::ensureEntered(QWaylandSurface *surface) +{ + if (enteredSurface == surface) + return; + + if (enteredSurface) + sendLeave(); + + if (surface) + sendEnter(surface); +} + void QWaylandPointerPrivate::pointer_release(wl_pointer::Resource *resource) { wl_resource_destroy(resource->handle); @@ -122,7 +168,7 @@ void QWaylandPointerPrivate::pointer_set_cursor(wl_pointer::Resource *resource, QWaylandPointer::QWaylandPointer(QWaylandSeat *seat, QObject *parent) : QWaylandObject(* new QWaylandPointerPrivate(this, seat), parent) { - connect(&d_func()->focusDestroyListener, &QWaylandDestroyListener::fired, this, &QWaylandPointer::focusDestroyed); + connect(&d_func()->enteredSurfaceDestroyListener, &QWaylandDestroyListener::fired, this, &QWaylandPointer::enteredSurfaceDestroyed); connect(seat, &QWaylandSeat::mouseFocusChanged, this, &QWaylandPointer::pointerFocusChanged); } @@ -173,16 +219,11 @@ uint QWaylandPointer::sendMousePressEvent(Qt::MouseButton button) { Q_D(QWaylandPointer); d->buttonCount++; - uint serial = 0; - - if (d->seat->mouseFocus()) - serial = d->sendButton(button, WL_POINTER_BUTTON_STATE_PRESSED); - if (d->buttonCount == 1) { + if (d->buttonCount == 1) emit buttonPressedChanged(); - } - return serial; + return d->sendButton(button, WL_POINTER_BUTTON_STATE_PRESSED); } /*! @@ -194,15 +235,11 @@ uint QWaylandPointer::sendMouseReleaseEvent(Qt::MouseButton button) { Q_D(QWaylandPointer); d->buttonCount--; - uint serial = 0; - - if (d->seat->mouseFocus()) - serial = d->sendButton(button, WL_POINTER_BUTTON_STATE_RELEASED); if (d->buttonCount == 0) emit buttonPressedChanged(); - return serial; + return d->sendButton(button, WL_POINTER_BUTTON_STATE_RELEASED); } /*! @@ -218,41 +255,20 @@ void QWaylandPointer::sendMouseMoveEvent(QWaylandView *view, const QPointF &loca d->localPosition = localPos; d->spacePosition = outputSpacePos; - //we adjust if the mouse position is on the edge - //to work around Qt's event propagation - if (view && view->surface()) { + if (view) { + // We adjust if the mouse position is on the edge + // to work around Qt's event propagation QSizeF size(view->surface()->size()); - if (d->localPosition.x() == size.width()) + if (d->localPosition.x() == size.width()) d->localPosition.rx() -= 0.01; - if (d->localPosition.y() == size.height()) d->localPosition.ry() -= 0.01; - } - - if (!d->hasSentEnter) { - d->enterSerial = d->compositor()->nextSerial(); - QWaylandKeyboard *keyboard = d->seat->keyboard(); - if (keyboard) - keyboard->sendKeyModifiers(view->surface()->client(), d->enterSerial); - for (auto resource : d->pointerResourcesForFocusedSurface()) { - d->send_enter(resource->handle, d->enterSerial, view->surface()->resource(), - wl_fixed_from_double(d->localPosition.x()), - wl_fixed_from_double(d->localPosition.y())); - } - d->focusDestroyListener.listenForDestruction(view->surface()->resource()); - d->hasSentEnter = true; - } - if (view && view->output()) - setOutput(view->output()); - - uint32_t time = d->compositor()->currentTimeMsecs(); + d->ensureEntered(view->surface()); + d->sendMotion(); - if (d->seat->mouseFocus()) { - wl_fixed_t x = wl_fixed_from_double(currentLocalPosition().x()); - wl_fixed_t y = wl_fixed_from_double(currentLocalPosition().y()); - for (auto resource : d->pointerResourcesForFocusedSurface()) - wl_pointer_send_motion(resource->handle, time, x, y); + if (view->output()) + setOutput(view->output()); } } @@ -262,14 +278,14 @@ void QWaylandPointer::sendMouseMoveEvent(QWaylandView *view, const QPointF &loca void QWaylandPointer::sendMouseWheelEvent(Qt::Orientation orientation, int delta) { Q_D(QWaylandPointer); - if (!d->seat->mouseFocus()) + if (!d->enteredSurface) return; uint32_t time = d->compositor()->currentTimeMsecs(); uint32_t axis = orientation == Qt::Horizontal ? WL_POINTER_AXIS_HORIZONTAL_SCROLL : WL_POINTER_AXIS_VERTICAL_SCROLL; - for (auto resource : d->pointerResourcesForFocusedSurface()) + for (auto resource : d->resourceMap().values(d->enteredSurface->waylandClient())) d->send_axis(resource->handle, time, axis, wl_fixed_from_int(-delta / 12)); } @@ -316,9 +332,8 @@ void QWaylandPointer::addClient(QWaylandClient *client, uint32_t id, uint32_t ve { Q_D(QWaylandPointer); wl_resource *resource = d->add(client->client(), id, qMin<uint32_t>(QtWaylandServer::wl_pointer::interfaceVersion(), version))->handle; - QWaylandView *focus = d->seat->mouseFocus(); - if (focus && client == focus->surface()->client()) { - d->send_enter(resource, d->enterSerial, focus->surfaceResource(), + if (d->enteredSurface && client == d->enteredSurface->client()) { + d->send_enter(resource, d->enterSerial, d->enteredSurface->resource(), wl_fixed_from_double(d->localPosition.x()), wl_fixed_from_double(d->localPosition.y())); } @@ -389,14 +404,19 @@ uint32_t QWaylandPointer::toWaylandButton(Qt::MouseButton button) /*! * \internal */ -void QWaylandPointer::focusDestroyed(void *data) +void QWaylandPointer::enteredSurfaceDestroyed(void *data) { Q_D(QWaylandPointer); Q_UNUSED(data) - d->focusDestroyListener.reset(); + d->enteredSurfaceDestroyListener.reset(); + d->enteredSurface = nullptr; + + d->seat->setMouseFocus(nullptr); - d->seat->setMouseFocus(Q_NULLPTR); - d->buttonCount = 0; + if (d->buttonCount != 0) { + d->buttonCount = 0; + emit buttonPressedChanged(); + } } /*! @@ -404,16 +424,11 @@ void QWaylandPointer::focusDestroyed(void *data) */ void QWaylandPointer::pointerFocusChanged(QWaylandView *newFocus, QWaylandView *oldFocus) { - Q_UNUSED(newFocus); Q_D(QWaylandPointer); - d->localPosition = QPointF(); - d->hasSentEnter = false; - if (oldFocus) { - uint32_t serial = d->compositor()->nextSerial(); - for (auto resource : d->resourceMap().values(oldFocus->surfaceResource()->client)) - d->send_leave(resource->handle, serial, oldFocus->surfaceResource()); - d->focusDestroyListener.reset(); - } + Q_UNUSED(oldFocus); + bool wasSameSurface = newFocus && newFocus->surface() == d->enteredSurface; + if (d->enteredSurface && !wasSameSurface) + d->sendLeave(); } QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandpointer.h b/src/compositor/compositor_api/qwaylandpointer.h index bcba1d6a..409bcc83 100644 --- a/src/compositor/compositor_api/qwaylandpointer.h +++ b/src/compositor/compositor_api/qwaylandpointer.h @@ -89,7 +89,7 @@ Q_SIGNALS: void buttonPressedChanged(); private: - void focusDestroyed(void *data); + void enteredSurfaceDestroyed(void *data); void pointerFocusChanged(QWaylandView *newFocus, QWaylandView *oldFocus); }; diff --git a/src/compositor/compositor_api/qwaylandpointer_p.h b/src/compositor/compositor_api/qwaylandpointer_p.h index 0a9ef232..11076f34 100644 --- a/src/compositor/compositor_api/qwaylandpointer_p.h +++ b/src/compositor/compositor_api/qwaylandpointer_p.h @@ -86,11 +86,15 @@ protected: void pointer_release(Resource *resource) override; private: - const QList<Resource *> pointerResourcesForFocusedSurface() const; uint sendButton(Qt::MouseButton button, uint32_t state); + void sendMotion(); + void sendEnter(QWaylandSurface *surface); + void sendLeave(); + void ensureEntered(QWaylandSurface *surface); QWaylandSeat *seat; QWaylandOutput *output; + QPointer<QWaylandSurface> enteredSurface; QPointF localPosition; QPointF spacePosition; @@ -100,7 +104,7 @@ private: int buttonCount; - QWaylandDestroyListener focusDestroyListener; + QWaylandDestroyListener enteredSurfaceDestroyListener; static QWaylandSurfaceRole s_role; }; diff --git a/src/compositor/compositor_api/qwaylandquickcompositor.cpp b/src/compositor/compositor_api/qwaylandquickcompositor.cpp index dccb8a15..35cd4922 100644 --- a/src/compositor/compositor_api/qwaylandquickcompositor.cpp +++ b/src/compositor/compositor_api/qwaylandquickcompositor.cpp @@ -90,9 +90,9 @@ QWaylandQuickCompositor::QWaylandQuickCompositor(QObject *parent) * import QtWayland.Compositor 1.0 * * WaylandCompositor { - * extensions: [ WlShell { + * WlShell { * // ... - * } ] + * } * } * \endcode */ diff --git a/src/compositor/compositor_api/qwaylandquickitem.cpp b/src/compositor/compositor_api/qwaylandquickitem.cpp index bfd25275..a993467a 100644 --- a/src/compositor/compositor_api/qwaylandquickitem.cpp +++ b/src/compositor/compositor_api/qwaylandquickitem.cpp @@ -371,7 +371,7 @@ QWaylandQuickItem::~QWaylandQuickItem() } /*! - * \qmlproperty object QtWaylandCompositor::WaylandQuickItem::compositor + * \qmlproperty WaylandCompositor QtWaylandCompositor::WaylandQuickItem::compositor * * This property holds the compositor for the surface rendered by this WaylandQuickItem. */ @@ -388,7 +388,7 @@ QWaylandCompositor *QWaylandQuickItem::compositor() const } /*! - * \qmlproperty object QtWaylandCompositor::WaylandQuickItem::view + * \qmlproperty WaylandView QtWaylandCompositor::WaylandQuickItem::view * * This property holds the view rendered by this WaylandQuickItem. */ @@ -405,7 +405,7 @@ QWaylandView *QWaylandQuickItem::view() const } /*! - * \qmlproperty object QtWaylandCompositor::WaylandQuickItem::surface + * \qmlproperty WaylandSurface QtWaylandCompositor::WaylandQuickItem::surface * * This property holds the surface rendered by this WaylandQuickItem. */ diff --git a/src/compositor/compositor_api/qwaylandseat.cpp b/src/compositor/compositor_api/qwaylandseat.cpp index 80b75d61..b4b45392 100644 --- a/src/compositor/compositor_api/qwaylandseat.cpp +++ b/src/compositor/compositor_api/qwaylandseat.cpp @@ -456,6 +456,12 @@ void QWaylandSeat::setMouseFocus(QWaylandView *view) QWaylandView *oldFocus = d->mouseFocus; d->mouseFocus = view; + + if (oldFocus) + disconnect(oldFocus, &QObject::destroyed, this, &QWaylandSeat::handleMouseFocusDestroyed); + if (d->mouseFocus) + connect(d->mouseFocus, &QObject::destroyed, this, &QWaylandSeat::handleMouseFocusDestroyed); + emit mouseFocusChanged(d->mouseFocus, oldFocus); } @@ -512,4 +518,15 @@ QWaylandSeat *QWaylandSeat::fromSeatResource(struct ::wl_resource *resource) * This signal is emitted when the mouse focus has changed from \a oldFocus to \a newFocus. */ +void QWaylandSeat::handleMouseFocusDestroyed() +{ + // This is triggered when the QWaylandView is destroyed, NOT the surface. + // ... so this is for the rare case when the view that currently holds the mouse focus is + // destroyed before its surface + Q_D(QWaylandSeat); + d->mouseFocus = nullptr; + QWaylandView *oldFocus = nullptr; // we have to send nullptr because the old focus is already destroyed at this point + emit mouseFocusChanged(d->mouseFocus, oldFocus); +} + QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandseat.h b/src/compositor/compositor_api/qwaylandseat.h index 86cf250a..e5ef46dc 100644 --- a/src/compositor/compositor_api/qwaylandseat.h +++ b/src/compositor/compositor_api/qwaylandseat.h @@ -133,6 +133,9 @@ Q_SIGNALS: void mouseFocusChanged(QWaylandView *newFocus, QWaylandView *oldFocus); void keyboardFocusChanged(QWaylandSurface *newFocus, QWaylandSurface *oldFocus); void cursorSurfaceRequest(QWaylandSurface *surface, int hotspotX, int hotspotY); + +private: + void handleMouseFocusDestroyed(); }; Q_DECLARE_OPERATORS_FOR_FLAGS(QWaylandSeat::CapabilityFlags) diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp index 6f277dd9..945d6882 100644 --- a/src/compositor/compositor_api/qwaylandsurface.cpp +++ b/src/compositor/compositor_api/qwaylandsurface.cpp @@ -445,7 +445,7 @@ bool QWaylandSurface::isInitialized() const } /*! - * \qmlproperty object QtWaylandCompositor::WaylandSurface::client + * \qmlproperty WaylandClient QtWaylandCompositor::WaylandSurface::client * * This property holds the client using this WaylandSurface. */ diff --git a/src/compositor/compositor_api/qwaylandview.cpp b/src/compositor/compositor_api/qwaylandview.cpp index f56cb0b8..9e829757 100644 --- a/src/compositor/compositor_api/qwaylandview.cpp +++ b/src/compositor/compositor_api/qwaylandview.cpp @@ -99,9 +99,6 @@ QWaylandView::~QWaylandView() if (d->surface) { if (d->output) QWaylandOutputPrivate::get(d->output)->removeView(this, d->surface); - QWaylandSeat *i = d->surface->compositor()->defaultSeat(); - if (i->mouseFocus() == this) - i->setMouseFocus(Q_NULLPTR); QWaylandSurfacePrivate::get(d->surface)->derefView(this); } @@ -117,8 +114,9 @@ QObject *QWaylandView::renderObject() const Q_D(const QWaylandView); return d->renderObject; } + /*! - * \qmlproperty object QtWaylandCompositor::WaylandView::surface + * \qmlproperty WaylandSurface QtWaylandCompositor::WaylandView::surface * * This property holds the surface viewed by this WaylandView. */ @@ -169,7 +167,7 @@ void QWaylandView::setSurface(QWaylandSurface *newSurface) } /*! - * \qmlproperty object QtWaylandCompositor::WaylandView::output + * \qmlproperty WaylandOutput QtWaylandCompositor::WaylandView::output * * This property holds the output on which this view displays its surface. */ diff --git a/src/compositor/doc/src/qtwaylandcompositor-cpp.qdoc b/src/compositor/doc/src/qtwaylandcompositor-cpp.qdoc index 4b38c861..c406b81e 100644 --- a/src/compositor/doc/src/qtwaylandcompositor-cpp.qdoc +++ b/src/compositor/doc/src/qtwaylandcompositor-cpp.qdoc @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** @@ -11,8 +11,8 @@ ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Free Documentation License Usage ** Alternatively, this file may be used under the terms of the GNU Free @@ -20,7 +20,7 @@ ** Foundation and appearing in the file included in the packaging of ** this file. Please review the following information to ensure ** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/compositor/doc/src/qtwaylandcompositor-examples.qdoc b/src/compositor/doc/src/qtwaylandcompositor-examples.qdoc index 2b851128..56084424 100644 --- a/src/compositor/doc/src/qtwaylandcompositor-examples.qdoc +++ b/src/compositor/doc/src/qtwaylandcompositor-examples.qdoc @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** @@ -11,8 +11,8 @@ ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Free Documentation License Usage ** Alternatively, this file may be used under the terms of the GNU Free @@ -20,7 +20,7 @@ ** Foundation and appearing in the file included in the packaging of ** this file. Please review the following information to ensure ** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/compositor/doc/src/qtwaylandcompositor-overview.qdoc b/src/compositor/doc/src/qtwaylandcompositor-overview.qdoc index d2fb6a27..6be6444c 100644 --- a/src/compositor/doc/src/qtwaylandcompositor-overview.qdoc +++ b/src/compositor/doc/src/qtwaylandcompositor-overview.qdoc @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** @@ -11,8 +11,8 @@ ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Free Documentation License Usage ** Alternatively, this file may be used under the terms of the GNU Free @@ -20,7 +20,7 @@ ** Foundation and appearing in the file included in the packaging of ** this file. Please review the following information to ensure ** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/compositor/doc/src/qtwaylandcompositor-qmltypes.qdoc b/src/compositor/doc/src/qtwaylandcompositor-qmltypes.qdoc index 1f1f5828..1dadb710 100644 --- a/src/compositor/doc/src/qtwaylandcompositor-qmltypes.qdoc +++ b/src/compositor/doc/src/qtwaylandcompositor-qmltypes.qdoc @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. ** @@ -11,8 +11,8 @@ ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Free Documentation License Usage ** Alternatively, this file may be used under the terms of the GNU Free @@ -20,7 +20,7 @@ ** Foundation and appearing in the file included in the packaging of ** this file. Please review the following information to ensure ** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/compositor/extensions/qwaylandivisurface.cpp b/src/compositor/extensions/qwaylandivisurface.cpp index 0bb2a615..08b95b3b 100644 --- a/src/compositor/extensions/qwaylandivisurface.cpp +++ b/src/compositor/extensions/qwaylandivisurface.cpp @@ -121,7 +121,7 @@ void QWaylandIviSurface::initialize(QWaylandIviApplication *iviApplication, QWay } /*! - * \qmlproperty object QtWaylandCompositor::IviSurface::surface + * \qmlproperty WaylandSurface QtWaylandCompositor::IviSurface::surface * * This property holds the surface associated with this IviSurface. */ diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp index e52bb485..2b603099 100644 --- a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp +++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp @@ -93,7 +93,7 @@ QWaylandQuickShellSurfaceItem::QWaylandQuickShellSurfaceItem(QWaylandQuickShellS } /*! - * \qmlproperty object QtWaylandCompositor::ShellSurfaceItem::shellSurface + * \qmlproperty ShellSurface QtWaylandCompositor::ShellSurfaceItem::shellSurface * * This property holds the ShellSurface rendered by this ShellSurfaceItem. * It may either be an XdgSurfaceV5, WlShellSurface or IviSurface depending on which shell protocol diff --git a/src/compositor/extensions/qwaylandwlshell.cpp b/src/compositor/extensions/qwaylandwlshell.cpp index 038e41b1..96dbd3dc 100644 --- a/src/compositor/extensions/qwaylandwlshell.cpp +++ b/src/compositor/extensions/qwaylandwlshell.cpp @@ -277,7 +277,7 @@ void QWaylandWlShellSurfacePrivate::shell_surface_set_class(Resource *resource, * import QtWayland.Compositor 1.0 * * WaylandCompositor { - * extensions: WlShell { + * WlShell { * // ... * } * } @@ -384,18 +384,37 @@ const struct wl_interface *QWaylandWlShell::interface() } /*! - * \qmlsignal void QtWaylandCompositor::WlShell::wlShellSurfaceRequested(object surface, object client, int id) + * \qmlsignal void QtWaylandCompositor::WlShell::wlShellSurfaceRequested(WaylandSurface surface, WaylandResource resource) * - * This signal is emitted when the \a client has requested a \c wl_shell_surface to be associated - * with \a surface, which is identified by \a id. The handler for this signal is - * expected to create the shell surface and initialize it within the scope of the - * signal emission. + * This signal is emitted when the client has requested a \c wl_shell_surface to be associated with + * \a surface. The handler for this signal may create a shell surface for \a resource and initialize + * it within the scope of the signal emission. Otherwise a WlShellSurface will be created + * automatically. */ /*! * \fn void QWaylandWlShell::wlShellSurfaceRequested(QWaylandSurface *surface, const QWaylandResource &resource) * - * Constructs a QWaylandSurface, assigns it to \a surface and initializes it with the given \a resource. + * This signal is emitted when the client has requested a \c wl_shell_surface to be associated with + * \a surface. The handler for this signal may create a shell surface for \a resource and initialize + * it within the scope of the signal emission. Otherwise a QWaylandWlShellSurface will be created + * automatically. + */ + +/*! + * \qmlsignal void QtWaylandCompositor::WlShell::wlShellSurfaceCreated(WlShellSurface shellSurface) + * + * This signal is emitted when the client has created a \c wl_shell_surface. + * A common use case is to let the handler of this signal instantiate a ShellSurfaceItem or + * WaylandQuickItem for displaying \a shellSurface in a QtQuick scene. + */ + +/*! + * \fn void QWaylandWlShell::wlShellSurfaceCreated(QWaylandWlShellSurface *shellSurface) + * + * This signal is emitted when the client has created a \c wl_shell_surface. + * A common use case is to let the handler of this signal instantiate a QWaylandShellSurfaceItem or + * QWaylandQuickItem for displaying \a shellSurface in a QtQuick scene. */ /*! @@ -575,7 +594,7 @@ QWaylandQuickShellIntegration *QWaylandWlShellSurface::createIntegration(QWaylan #endif /*! - * \qmlproperty object QtWaylandCompositor::WlShellSurface::surface + * \qmlproperty WaylandSurface QtWaylandCompositor::WlShellSurface::surface * * This property holds the \c wl_surface associated with this WlShellSurface. */ @@ -592,7 +611,7 @@ QWaylandSurface *QWaylandWlShellSurface::surface() const } /*! - * \qmlproperty object QtWaylandCompositor::WlShellSurface::shell + * \qmlproperty WlShell QtWaylandCompositor::WlShellSurface::shell * * This property holds the shell associated with this WlShellSurface. */ diff --git a/src/compositor/extensions/qwaylandxdgshellv5.cpp b/src/compositor/extensions/qwaylandxdgshellv5.cpp index 8f116426..c0cb4f8e 100644 --- a/src/compositor/extensions/qwaylandxdgshellv5.cpp +++ b/src/compositor/extensions/qwaylandxdgshellv5.cpp @@ -646,6 +646,98 @@ void QWaylandXdgShellV5::closeAllPopups() } } +/*! + * \qmlsignal void QtWaylandCompositor::XdgShellV5::xdgSurfaceRequested(WaylandSurface surface, WaylandResource resource) + * + * This signal is emitted when the client has requested an \c xdg_surface to be associated + * with \a surface. The handler for this signal may create the shell surface for \a resource + * and initialize it within the scope of the signal emission. Otherwise an XdgSurfaceV5 will + * be created automatically. + */ + +/*! + * \fn void QWaylandXdgShellV5::xdgSurfaceRequested(QWaylandSurface *surface, const QWaylandResource &resource) + * + * This signal is emitted when the client has requested an \c xdg_surface to be associated + * with \a surface. The handler for this signal may create the shell surface for \a resource + * and initialize it within the scope of the signal emission. Otherwise a QWaylandXdgSurfaceV5 + * will be created automatically. + */ + +/*! + * \qmlsignal void QtWaylandCompositor::XdgShellV5::xdgSurfaceCreated(XdgSurfaceV5 xdgSurface) + * + * This signal is emitted when the client has created an \c xdg_surface. + * A common use case is to let the handler of this signal instantiate a ShellSurfaceItem or + * WaylandQuickItem for displaying \a xdgSurface in a QtQuick scene. + */ + +/*! + * \fn void QWaylandXdgShellV5::xdgSurfaceCreated(QWaylandXdgSurfaceV5 *xdgSurface) + * + * This signal is emitted when the client has created an \c xdg_surface. + * A common use case is to let the handler of this signal instantiate a QWaylandShellSurfaceItem or + * QWaylandQuickItem for displaying \a xdgSurface in a QtQuick scene. + */ + +/*! + * \qmlsignal void QtWaylandCompositor::XdgShellV5::xdgPopupRequested(WaylandSurface surface, WaylandSurface parent, WaylandSeat seat, point position, WaylandResource resource) + * + * This signal is emitted when the client has requested an \c xdg_popup to be associated + * with \a surface. The handler for this signal may create the xdg popup for \a resource and + * initialize it within the scope of the signal emission. Otherwise an XdgPopupV5 will be + * created automatically. + * + * The \a seat is the \c wl_seat that caused the popup to be opened. + * + * \a position is the desired position of the popup, relative to the \a parent. + */ + +/*! + * \fn void QWaylandXdgShellV5::xdgPopupRequested(QWaylandSurface *surface, QWaylandSurface *parent, QWaylandSeat *seat, const QPoint &position, const QWaylandResource &resource) + * + * This signal is emitted when the client has requested an \c xdg_surface to be associated + * with \a surface. The handler for this signal may create the xdg poup for \a resource and + * initialize it within the scope of the signal emission. Otherwise a QWaylandXdgPopupV5 will be + * created automatically. + * + * The \a seat is the \c wl_seat that caused the popup to be opened. + * + * \a position is the desired position of the popup, relative to the \a parent. + */ + +/*! + * \qmlsignal void QtWaylandCompositor::XdgShellV5::xdgPopupCreated(XdgPopupV5 xdgPopup) + * + * This signal is emitted when the client has created an \c xdg_popup. + * A common use case is to let the handler of this signal instantiate a ShellSurfaceItem or + * WaylandQuickItem for displaying \a xdgPopup in a QtQuick scene. + */ + +/*! + * \fn void QWaylandXdgShellV5::xdgPopupCreated(QWaylandXdgPopupV5 *xdgPopup) + * + * This signal is emitted when the client has created an \c xdg_popup. + * A common use case is to let the handler of this signal instantiate a QWaylandShellSurfaceItem or + * QWaylandQuickItem for displaying \a xdgPopup in a QtQuick scene. + */ + +/*! + * \qmlsignal void QtWaylandCompositor::XdgShellV5::pong(int serial) + * + * This signal is emitted when the client has responded to a ping event with serial \a serial. + * + * \sa QtWaylandCompositor::XdgShellV5::ping() + */ + +/*! + * \fn void QWaylandXdgShellV5::pong(uint serial) + * + * This signal is emitted when the client has responded to a ping event with serial \a serial. + * + * \sa QWaylandXdgShellV5::ping() + */ + void QWaylandXdgShellV5::handleSeatChanged(QWaylandSeat *newSeat, QWaylandSeat *oldSeat) { if (oldSeat != nullptr) { @@ -760,6 +852,134 @@ void QWaylandXdgSurfaceV5::initialize(QWaylandXdgShellV5 *xdgShell, QWaylandSurf } /*! + * \qmlsignal void QtWaylandCompositor::XdgSurfaceV5::showWindowMenu(WaylandSeat seat, point localSurfacePosition) + * + * This signal is emitted when the client wants to show a context menu at \a localSurfacePosition, + * using the Wayland seat \a seat. It's typically emitted in response to the user right-clicking + * the window decorations. + */ + +/*! + * \fn void QWaylandXdgSurfaceV5::showWindowMenu(QWaylandSeat *seat, const QPoint &localSurfacePosition) + * + * This signal is emitted when the client wants to show a context menu at \a localSurfacePosition, + * using the Wayland seat \a seat. It's typically emitted in response to the user right-clicking + * the window decorations. + */ + +/*! + * \qmlsignal void QtWaylandCompositor::XdgSurfaceV5::startMove(WaylandSeat seat) + * + * This signal is emitted when the client wants to start an interactive move of the XdgSurfaceV5, + * typically in response to the window decorations being dragged by \a seat. + */ + +/*! + * \fn void QWaylandXdgSurfaceV5::startMove(QWaylandSeat *seat) + * + * This signal is emitted when the client wants to start an interactive move of the + * QWaylandXdgSurfaceV5, typically in response to the window decorations being dragged by \a seat. + */ + +/*! + * \qmlsignal void QtWaylandCompositor::XdgSurfaceV5::startResize(WaylandSeat seat, enumeration edges) + * + * This signal is emitted when the client wants to start an interactive resize of the XdgSurfaceV5, + * typically in response to the window decorations being dragged by \a seat on the window borders + * given by \a edges. + * + * \sa QWaylandXdgSurfaceV5::ResizeEdges + */ + +/*! + * \fn void QWaylandXdgSurfaceV5::startResize(QWaylandSeat *seat, ResizeEdges edges) + * + * This signal is emitted when the client wants to start an interactive resize of the + * QWaylandXdgSurfaceV5, typically in response to the window decorations being dragged by + * \a seat on the window borders given by \a edges. + */ + +/*! + * \qmlsignal void QtWaylandCompositor::XdgSurfaceV5::setMaximized() + * + * This signal is emitted when the client wants the \c xdg_surface to be maximized. + */ + +/*! + * \fn void QWaylandXdgSurfaceV5::setMaximized() + * + * This signal is emitted when the client wants the \c xdg_surface to be maximized. + */ + +/*! + * \qmlsignal void QtWaylandCompositor::XdgSurfaceV5::unsetMaximized() + * + * This signal is emitted when the client doesn't want the \c xdg_surface to be maximized anymore. + */ + +/*! + * \fn void QWaylandXdgSurfaceV5::unsetMaximized() + * + * This signal is emitted when the client doesn't want the \c xdg_surface to be maximized anymore. + */ + +/*! + * \qmlsignal void QtWaylandCompositor::XdgSurfaceV5::setFullscreen(WaylandOutput output) + * + * This signal is emitted when the client wants the \c xdg_surface to be in full screen mode. + * The client may specify an \a output it wishes the \c xdg_surface to be shown on. + */ + +/*! + * \fn void QWaylandXdgSurfaceV5::setFullscreen(QWaylandOutput *output) + * + * This signal is emitted when the client wants the \c xdg_surface to be in full screen mode. + * The client may specify an \a output it wishes the \c xdg_surface to be shown on. + */ + +/*! + * \qmlsignal void QtWaylandCompositor::XdgSurfaceV5::unsetFullscreen() + * + * This signal is emitted when the client doesn't want the \c xdg_surface to be in full screen mode + * anymore. + */ + +/*! + * \fn void QWaylandXdgSurfaceV5::unsetFullscreen() + * + * This signal is emitted when the client doesn't want the \c xdg_surface to be in full screen mode + * anymore. + */ + +/*! + * \qmlsignal void QtWaylandCompositor::XdgSurfaceV5::setMinimized() + * + * This signal is emitted when the client wants the \c xdg_surface to be minimized. + */ + +/*! + * \fn void QWaylandXdgSurfaceV5::setMinimized() + * + * This signal is emitted when the client wants the \c xdg_surface to be minimized. + */ + +/*! + * \qmlsignal void QtWaylandCompositor::XdgSurfaceV5::ackConfigure(int serial) + * + * This signal is emitted when the client has received configure events up to and including the + * configure event with serial \a serial and will draw its surface accordingly in the next committed + * buffer. + */ + +/*! + * \fn void QWaylandXdgSurfaceV5::ackConfigure(uint serial) + * + * This signal is emitted when the client has received configure events up to and including the + * configure event with serial \a serial and will draw its surface accordingly in the next committed + * buffer. + */ + +/*! * \internal */ void QWaylandXdgSurfaceV5::initialize() @@ -789,7 +1009,7 @@ void QWaylandXdgSurfaceV5::handleBufferScaleChanged() } /*! - * \qmlproperty object QtWaylandCompositor::XdgSurfaceV5::shell + * \qmlproperty XdgShellV5 QtWaylandCompositor::XdgSurfaceV5::shell * * This property holds the shell associated with this XdgSurfaceV5. */ @@ -806,7 +1026,7 @@ QWaylandXdgShellV5 *QWaylandXdgSurfaceV5::shell() const } /*! - * \qmlproperty object QtWaylandCompositor::XdgSurfaceV5::surface + * \qmlproperty WaylandSurface QtWaylandCompositor::XdgSurfaceV5::surface * * This property holds the surface associated with this XdgSurfaceV5. */ @@ -823,7 +1043,7 @@ QWaylandSurface *QWaylandXdgSurfaceV5::surface() const } /*! - * \qmlproperty enum QtWaylandCompositor::XdgSurfaceV5::windowType + * \qmlproperty enumeration QtWaylandCompositor::XdgSurfaceV5::windowType * * This property holds the window type of the XdgSurfaceV5. */ @@ -840,7 +1060,7 @@ Qt::WindowType QWaylandXdgSurfaceV5::windowType() const } /*! - * \qmlproperty object QtWaylandCompositor::XdgSurfaceV5::parentSurface + * \qmlproperty XdgSurfaceV5 QtWaylandCompositor::XdgSurfaceV5::parentSurface * * This property holds the XdgSurfaceV5 parent of this XdgSurfaceV5. * When a parent surface is set, the parentSurfaceChanged() signal @@ -1175,7 +1395,7 @@ void QWaylandXdgPopupV5::initialize(QWaylandXdgShellV5 *shell, QWaylandSurface * } /*! - * \qmlproperty object QtWaylandCompositor::XdgPopupV5::shell + * \qmlproperty XdgShellV5 QtWaylandCompositor::XdgPopupV5::shell * * This property holds the shell associated with this XdgPopupV5. */ @@ -1192,7 +1412,7 @@ QWaylandXdgShellV5 *QWaylandXdgPopupV5::shell() const } /*! - * \qmlproperty object QtWaylandCompositor::XdgPopupV5::surface + * \qmlproperty WaylandSurface QtWaylandCompositor::XdgPopupV5::surface * * This property holds the surface associated with this XdgPopupV5. */ @@ -1209,7 +1429,7 @@ QWaylandSurface *QWaylandXdgPopupV5::surface() const } /*! - * \qmlproperty object QtWaylandCompositor::XdgPopupV5::parentSurface + * \qmlproperty WaylandSurface QtWaylandCompositor::XdgPopupV5::parentSurface * * This property holds the surface associated with the parent of this XdgPopupV5. */ @@ -1228,7 +1448,7 @@ QWaylandSurface *QWaylandXdgPopupV5::parentSurface() const /*! - * \qmlproperty object QtWaylandCompositor::XdgPopupV5::position + * \qmlproperty point QtWaylandCompositor::XdgPopupV5::position * * This property holds the location of the upper left corner of the surface * relative to the upper left corner of the parent surface, in surface local diff --git a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp index c9133a22..453800c1 100644 --- a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp +++ b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp @@ -44,6 +44,7 @@ #include <QtGui/QGuiApplication> #include <QtGui/QOpenGLContext> #include <QtGui/QOpenGLTexture> +#include <QtGui/QOffscreenSurface> #include <qpa/qplatformscreen.h> #include <QtGui/QWindow> #include <QtCore/QPointer> @@ -153,14 +154,14 @@ struct BufferState BufferState(); enum EglMode { - ModeNone, + ModeUninitialized, ModeEGLImage, ModeEGLStream }; EGLint egl_format; QVarLengthArray<EGLImageKHR, 3> egl_images; - QOpenGLTexture *textures[3]; + QOpenGLTexture *textures[3] = {}; EGLStreamKHR egl_stream; bool isYInverted; @@ -174,13 +175,17 @@ public: WaylandEglClientBufferIntegrationPrivate(); void initBuffer(WaylandEglClientBuffer *buffer); - void init_egl_texture(WaylandEglClientBuffer *buffer, EGLint format); - void init_egl_fd_texture(WaylandEglClientBuffer *buffer, wl_resource *bufferHandle); - void register_buffer(struct ::wl_resource *buffer, BufferState state); + void initEglTexture(WaylandEglClientBuffer *buffer, EGLint format); + bool ensureContext(); + bool initEglStream(WaylandEglClientBuffer *buffer, struct ::wl_resource *bufferHandle); + void handleEglstreamTexture(WaylandEglClientBuffer *buffer, wl_resource *bufferHandle); + void registerBuffer(struct ::wl_resource *buffer, BufferState state); EGLDisplay egl_display; bool valid; bool display_bound; + QOffscreenSurface *offscreenSurface = nullptr; + QOpenGLContext *localContext = nullptr; PFNEGLBINDWAYLANDDISPLAYWL egl_bind_wayland_display; PFNEGLUNBINDWAYLANDDISPLAYWL egl_unbind_wayland_display; @@ -201,7 +206,7 @@ BufferState::BufferState() : egl_format(EGL_TEXTURE_RGBA) , egl_stream(EGL_NO_STREAM_KHR) , isYInverted(true) - , eglMode(ModeNone) + , eglMode(ModeUninitialized) {} WaylandEglClientBufferIntegrationPrivate::WaylandEglClientBufferIntegrationPrivate() @@ -223,10 +228,10 @@ void WaylandEglClientBufferIntegrationPrivate::initBuffer(WaylandEglClientBuffer EGLint format; if (egl_query_wayland_buffer(egl_display, buffer->waylandBufferHandle(), EGL_TEXTURE_FORMAT, &format)) - init_egl_texture(buffer, format); + initEglTexture(buffer, format); } -void WaylandEglClientBufferIntegrationPrivate::init_egl_texture(WaylandEglClientBuffer *buffer, EGLint format) +void WaylandEglClientBufferIntegrationPrivate::initEglTexture(WaylandEglClientBuffer *buffer, EGLint format) { // Non-streaming case @@ -288,11 +293,31 @@ void WaylandEglClientBufferIntegrationPrivate::init_egl_texture(WaylandEglClient } } -void WaylandEglClientBufferIntegrationPrivate::init_egl_fd_texture(WaylandEglClientBuffer *buffer, struct ::wl_resource *bufferHandle) +bool WaylandEglClientBufferIntegrationPrivate::ensureContext() { -//EglStreams case - BufferState &state = *buffer->d; + bool localContextNeeded = false; + if (!QOpenGLContext::currentContext()) { + if (!localContext && QOpenGLContext::globalShareContext()) { + localContext = new QOpenGLContext; + localContext->setShareContext(QOpenGLContext::globalShareContext()); + localContext->create(); + } + if (localContext) { + if (!offscreenSurface) { + offscreenSurface = new QOffscreenSurface; + offscreenSurface->setFormat(localContext->format()); + offscreenSurface->create(); + } + localContext->makeCurrent(offscreenSurface); + localContextNeeded = true; + } + } + return localContextNeeded; +} +bool WaylandEglClientBufferIntegrationPrivate::initEglStream(WaylandEglClientBuffer *buffer, wl_resource *bufferHandle) +{ + BufferState &state = *buffer->d; state.egl_format = EGL_TEXTURE_EXTERNAL_WL; state.isYInverted = false; @@ -311,39 +336,57 @@ void WaylandEglClientBufferIntegrationPrivate::init_egl_fd_texture(WaylandEglCli if (state.egl_stream == EGL_NO_STREAM_KHR) { qWarning("%s:%d: eglCreateStreamFromFileDescriptorKHR failed: 0x%x", Q_FUNC_INFO, __LINE__, eglGetError()); - return; + return false; } state.eglMode = BufferState::ModeEGLStream; if (!QOpenGLContext::currentContext()) { qWarning("EglClientBufferIntegration: creating texture with no current context"); - return; + return false; } - //TODO This texture might end up in a different context than the quick item which wants to use it, this needs to be fixed somehow. - auto texture = new QOpenGLTexture(static_cast<QOpenGLTexture::Target>(GL_TEXTURE_EXTERNAL_OES)); texture->create(); state.textures[0] = texture; // TODO: support multiple planes for the streaming case - glActiveTexture(GL_TEXTURE0); - texture->create(); texture->bind(); - glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture->textureId()); - - glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR); auto newStream = funcs->stream_consumer_gltexture(egl_display, state.egl_stream); - if (!newStream) { EGLint code = eglGetError(); qWarning() << "Could not initialize EGLStream:" << egl_error_string(code) << hex << (long)code; funcs->destroy_stream(egl_display, state.egl_stream); state.egl_stream = EGL_NO_STREAM_KHR; + return false; + } + return true; +} + +void WaylandEglClientBufferIntegrationPrivate::handleEglstreamTexture(WaylandEglClientBuffer *buffer, struct ::wl_resource *bufferHandle) +{ + bool usingLocalContext = ensureContext(); + + if (buffer->d->eglMode == BufferState::ModeUninitialized) { + bool streamOK = initEglStream(buffer, bufferHandle); + if (!streamOK) + return; } + + BufferState &state = *buffer->d; + auto texture = state.textures[0]; + + // EGLStream requires calling acquire on every frame. + texture->bind(); + EGLint stream_state; + funcs->query_stream(egl_display, state.egl_stream, EGL_STREAM_STATE_KHR, &stream_state); + + if (stream_state == EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR) { + if (funcs->stream_consumer_acquire(egl_display, state.egl_stream) != EGL_TRUE) + qWarning("%s:%d: eglStreamConsumerAcquireKHR failed: 0x%x", Q_FUNC_INFO, __LINE__, eglGetError()); + } + + if (usingLocalContext) + localContext->doneCurrent(); } WaylandEglClientBufferIntegration::WaylandEglClientBufferIntegration() @@ -477,9 +520,12 @@ QOpenGLTexture *WaylandEglClientBuffer::toOpenGlTexture(int plane) if (!m_buffer) return nullptr; - auto *p = WaylandEglClientBufferIntegrationPrivate::get(m_integration); auto texture = d->textures[plane]; - const auto target = static_cast<QOpenGLTexture::Target>((d->eglMode == BufferState::ModeEGLStream || d->egl_format == EGL_TEXTURE_EXTERNAL_WL) ? GL_TEXTURE_EXTERNAL_OES + if (d->eglMode == BufferState::ModeEGLStream) + return texture; // EGLStreams texture is maintained by handle_eglstream_texture() + + auto *p = WaylandEglClientBufferIntegrationPrivate::get(m_integration); + const auto target = static_cast<QOpenGLTexture::Target>(d->egl_format == EGL_TEXTURE_EXTERNAL_WL ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D); if (!texture) { texture = new QOpenGLTexture(target); @@ -489,22 +535,7 @@ QOpenGLTexture *WaylandEglClientBuffer::toOpenGlTexture(int plane) d->textures[plane] = texture; } - - if (d->eglMode == BufferState::ModeEGLStream) { - // EGLStream requires calling acquire on every frame. - if (d->egl_stream != EGL_NO_STREAM_KHR) { - - texture->bind(); - - EGLint stream_state; - p->funcs->query_stream(p->egl_display, d->egl_stream, EGL_STREAM_STATE_KHR, &stream_state); - - if (stream_state == EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR) { - if (p->funcs->stream_consumer_acquire(p->egl_display, d->egl_stream) != EGL_TRUE) - qWarning("%s:%d: eglStreamConsumerAcquireKHR failed: 0x%x", Q_FUNC_INFO, __LINE__, eglGetError()); - } - } - } else if (m_textureDirty) { + if (m_textureDirty) { texture->bind(); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); p->gl_egl_image_target_texture_2d(target, d->egl_images[plane]); @@ -515,9 +546,9 @@ QOpenGLTexture *WaylandEglClientBuffer::toOpenGlTexture(int plane) void WaylandEglClientBuffer::setCommitted(QRegion &damage) { ClientBuffer::setCommitted(damage); - if (d->eglMode == BufferState::ModeNone) { + if (d->eglMode == BufferState::ModeEGLStream || d->eglMode == BufferState::ModeUninitialized) { auto *p = WaylandEglClientBufferIntegrationPrivate::get(m_integration); - p->init_egl_fd_texture(this, waylandBufferHandle()); + p->handleEglstreamTexture(this, waylandBufferHandle()); } } diff --git a/tests/auto/client/client/tst_client.cpp b/tests/auto/client/client/tst_client.cpp index 8acddfbe..1eee90f4 100644 --- a/tests/auto/client/client/tst_client.cpp +++ b/tests/auto/client/client/tst_client.cpp @@ -143,6 +143,8 @@ private slots: void touchDrag(); void mouseDrag(); void dontCrashOnMultipleCommits(); + void hiddenTransientParent(); + void hiddenPopupParent(); private: MockCompositor *compositor; @@ -360,6 +362,48 @@ void tst_WaylandClient::dontCrashOnMultipleCommits() QTRY_VERIFY(!compositor->surface()); } +void tst_WaylandClient::hiddenTransientParent() +{ + QWindow parent; + QWindow transient; + + transient.setTransientParent(&parent); + + parent.show(); + QTRY_VERIFY(compositor->surface()); + + parent.hide(); + QTRY_VERIFY(!compositor->surface()); + + transient.show(); + QTRY_VERIFY(compositor->surface()); +} + +void tst_WaylandClient::hiddenPopupParent() +{ + TestWindow toplevel; + toplevel.show(); + + // wl_shell relies on a mouse event in order to send a serial and seat + // with the set_popup request. + QSharedPointer<MockSurface> surface; + QTRY_VERIFY(surface = compositor->surface()); + QPoint mousePressPos(16, 16); + QCOMPARE(toplevel.mousePressEventCount, 0); + compositor->sendMousePress(surface, mousePressPos); + QTRY_COMPARE(toplevel.mousePressEventCount, 1); + + QWindow popup; + popup.setTransientParent(&toplevel); + popup.setFlag(Qt::Popup, true); + + toplevel.hide(); + QTRY_VERIFY(!compositor->surface()); + + popup.show(); + QTRY_VERIFY(compositor->surface()); +} + int main(int argc, char **argv) { setenv("XDG_RUNTIME_DIR", ".", 1); diff --git a/tests/auto/compositor/compositor/compositor.pro b/tests/auto/compositor/compositor/compositor.pro index f0cdaf32..112e2e74 100644 --- a/tests/auto/compositor/compositor/compositor.pro +++ b/tests/auto/compositor/compositor/compositor.pro @@ -20,11 +20,13 @@ SOURCES += \ testkeyboardgrabber.cpp \ mockclient.cpp \ mockseat.cpp \ - testseat.cpp + testseat.cpp \ + mockpointer.cpp HEADERS += \ testcompositor.h \ testkeyboardgrabber.h \ mockclient.h \ mockseat.h \ - testseat.h + testseat.h \ + mockpointer.h diff --git a/tests/auto/compositor/compositor/mockpointer.cpp b/tests/auto/compositor/compositor/mockpointer.cpp new file mode 100644 index 00000000..6c51d8bd --- /dev/null +++ b/tests/auto/compositor/compositor/mockpointer.cpp @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mockpointer.h" + +static void pointerEnter(void *pointer, struct wl_pointer *wlPointer, uint serial, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y) +{ + Q_UNUSED(wlPointer); + Q_UNUSED(serial); + Q_UNUSED(x); + Q_UNUSED(y); + + static_cast<MockPointer *>(pointer)->m_enteredSurface = surface; +} + +static void pointerLeave(void *pointer, struct wl_pointer *wlPointer, uint32_t serial, struct wl_surface *surface) +{ + Q_UNUSED(pointer); + Q_UNUSED(wlPointer); + Q_UNUSED(serial); + + Q_ASSERT(surface); + + static_cast<MockPointer *>(pointer)->m_enteredSurface = nullptr; +} + +static void pointerMotion(void *pointer, struct wl_pointer *wlPointer, uint32_t time, wl_fixed_t x, wl_fixed_t y) +{ + Q_UNUSED(pointer); + Q_UNUSED(wlPointer); + Q_UNUSED(time); + Q_UNUSED(x); + Q_UNUSED(y); +} + +static void pointerButton(void *pointer, struct wl_pointer *wlPointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state) +{ + Q_UNUSED(pointer); + Q_UNUSED(wlPointer); + Q_UNUSED(serial); + Q_UNUSED(time); + Q_UNUSED(button); + Q_UNUSED(state); +} + +static void pointerAxis(void *pointer, struct wl_pointer *wlPointer, uint32_t time, uint32_t axis, wl_fixed_t value) +{ + Q_UNUSED(pointer); + Q_UNUSED(wlPointer); + Q_UNUSED(time); + Q_UNUSED(axis); + Q_UNUSED(value); +} + +static const struct wl_pointer_listener pointerListener = { + pointerEnter, + pointerLeave, + pointerMotion, + pointerButton, + pointerAxis, +}; + +MockPointer::MockPointer(wl_seat *seat) + : m_pointer(wl_seat_get_pointer(seat)) +{ + wl_pointer_add_listener(m_pointer, &pointerListener, this); +} + +MockPointer::~MockPointer() +{ + wl_pointer_destroy(m_pointer); +} diff --git a/tests/auto/compositor/compositor/mockpointer.h b/tests/auto/compositor/compositor/mockpointer.h new file mode 100644 index 00000000..35386141 --- /dev/null +++ b/tests/auto/compositor/compositor/mockpointer.h @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MOCKPOINTER_H +#define MOCKPOINTER_H + +#include <QObject> +#include <wayland-client.h> + +class MockPointer : public QObject +{ + Q_OBJECT + +public: + MockPointer(wl_seat *seat); + ~MockPointer(); + + wl_pointer *m_pointer = nullptr; + wl_surface *m_enteredSurface = nullptr; +}; + +#endif // MOCKPOINTER_H diff --git a/tests/auto/compositor/compositor/mockseat.cpp b/tests/auto/compositor/compositor/mockseat.cpp index 29c4a4e1..052c2f90 100644 --- a/tests/auto/compositor/compositor/mockseat.cpp +++ b/tests/auto/compositor/compositor/mockseat.cpp @@ -30,6 +30,7 @@ MockSeat::MockSeat(wl_seat *seat) : m_seat(seat) + , m_pointer(new MockPointer(seat)) { // Bind to the keyboard interface so that the compositor has // the right resource associations diff --git a/tests/auto/compositor/compositor/mockseat.h b/tests/auto/compositor/compositor/mockseat.h index 1c6d324c..e6d5e0b1 100644 --- a/tests/auto/compositor/compositor/mockseat.h +++ b/tests/auto/compositor/compositor/mockseat.h @@ -28,6 +28,8 @@ #ifndef MOCKSEAT #define MOCKSEAT +#include "mockpointer.h" + #include <QObject> #include <wayland-client.h> @@ -38,8 +40,13 @@ class MockSeat : public QObject public: MockSeat(wl_seat *seat); ~MockSeat(); + MockPointer *pointer() const { return m_pointer.data(); } wl_seat *m_seat; wl_keyboard *m_keyboard; + +private: + QScopedPointer<MockPointer> m_pointer; }; + #endif diff --git a/tests/auto/compositor/compositor/tst_compositor.cpp b/tests/auto/compositor/compositor/tst_compositor.cpp index 52428eb4..c51c13bd 100644 --- a/tests/auto/compositor/compositor/tst_compositor.cpp +++ b/tests/auto/compositor/compositor/tst_compositor.cpp @@ -27,6 +27,8 @@ ****************************************************************************/ #include "mockclient.h" +#include "mockseat.h" +#include "mockpointer.h" #include "testcompositor.h" #include "testkeyboardgrabber.h" #include "testseat.h" @@ -57,6 +59,7 @@ private slots: void keyboardGrab(); void seatCreation(); void seatKeyboardFocus(); + void seatMouseFocus(); void singleClient(); void multipleClients(); void geometry(); @@ -442,6 +445,59 @@ void tst_WaylandCompositor::seatKeyboardFocus() QTRY_VERIFY(!compositor.defaultSeat()->keyboardFocus()); } +void tst_WaylandCompositor::seatMouseFocus() +{ + TestCompositor compositor(true); + compositor.create(); + + // Create client after all the seats have been set up as the mock client + // does not dynamically listen to new seats + MockClient client; + wl_surface *surface = client.createSurface(); + QTRY_COMPARE(compositor.surfaces.size(), 1); + + QWaylandSurface *waylandSurface = compositor.surfaces.at(0); + auto view = new QWaylandView; + view->setSurface(waylandSurface); + + QWaylandSeat* seat = compositor.defaultSeat(); + seat->setMouseFocus(view); + seat->sendMouseMoveEvent(view, QPointF(10, 10), QPointF(100, 100)); + + compositor.flushClients(); + + QTRY_VERIFY(seat->mouseFocus()); + QTRY_VERIFY(seat->pointer()); + QTRY_COMPARE(seat->mouseFocus()->surface(), waylandSurface); + + QTRY_COMPARE(client.m_seats.size(), 1); + MockPointer *mockPointer = client.m_seats.first()->pointer(); + QVERIFY(mockPointer); + QTRY_COMPARE(mockPointer->m_enteredSurface, surface); + + delete view; + + compositor.flushClients(); + + QTRY_COMPARE(mockPointer->m_enteredSurface, nullptr); + QTRY_VERIFY(!compositor.defaultSeat()->mouseFocus()); + + view = new QWaylandView; + view->setSurface(waylandSurface); + seat->sendMouseMoveEvent(view, QPointF(10, 10), QPointF(100, 100)); + QTRY_COMPARE(compositor.defaultSeat()->mouseFocus(), view); + + compositor.flushClients(); + + QTRY_COMPARE(mockPointer->m_enteredSurface, surface); + + wl_surface_destroy(surface); + QTRY_VERIFY(compositor.surfaces.size() == 0); + QTRY_VERIFY(!compositor.defaultSeat()->mouseFocus()); + + delete view; +} + class XdgTestCompositor: public TestCompositor { Q_OBJECT public: diff --git a/tests/manual/keymap/keymapcompositor.qml b/tests/manual/keymap/keymapcompositor.qml index 7f898263..77111c81 100644 --- a/tests/manual/keymap/keymapcompositor.qml +++ b/tests/manual/keymap/keymapcompositor.qml @@ -1,12 +1,22 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are diff --git a/tests/manual/qmlclient/main.cpp b/tests/manual/qmlclient/main.cpp index cb2044c2..9e0774b1 100644 --- a/tests/manual/qmlclient/main.cpp +++ b/tests/manual/qmlclient/main.cpp @@ -1,12 +1,22 @@ /**************************************************************************** ** ** Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> -** Contact: http://www.qt-project.org/legal +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are diff --git a/tests/manual/qmlclient/main.qml b/tests/manual/qmlclient/main.qml index a1fe241c..5ee63955 100644 --- a/tests/manual/qmlclient/main.qml +++ b/tests/manual/qmlclient/main.qml @@ -1,12 +1,22 @@ /**************************************************************************** ** ** Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> -** Contact: http://www.qt-project.org/legal +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are diff --git a/tests/manual/scaling-compositor/main.cpp b/tests/manual/scaling-compositor/main.cpp index 33ffb038..b5c7dd68 100644 --- a/tests/manual/scaling-compositor/main.cpp +++ b/tests/manual/scaling-compositor/main.cpp @@ -1,12 +1,22 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are diff --git a/tests/manual/scaling-compositor/main.qml b/tests/manual/scaling-compositor/main.qml index e017a44f..056af4e5 100644 --- a/tests/manual/scaling-compositor/main.qml +++ b/tests/manual/scaling-compositor/main.qml @@ -1,12 +1,22 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt-project.org/legal +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are diff --git a/tests/manual/subsurface/child.qml b/tests/manual/subsurface/child.qml index b2e54054..f1bdd66e 100644 --- a/tests/manual/subsurface/child.qml +++ b/tests/manual/subsurface/child.qml @@ -1,12 +1,22 @@ /**************************************************************************** ** ** Copyright (C) 2015 LG Electronics Inc, author: <mikko.levonmaa@lge.com> -** Contact: http://www.qt.io/licensing/ +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are diff --git a/tests/manual/subsurface/main.cpp b/tests/manual/subsurface/main.cpp index c913c32f..375e5d2b 100644 --- a/tests/manual/subsurface/main.cpp +++ b/tests/manual/subsurface/main.cpp @@ -1,12 +1,22 @@ /**************************************************************************** ** ** Copyright (C) 2015 LG Electronics Inc, author: <mikko.levonmaa@lge.com> -** Contact: http://www.qt.io/licensing/ +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are diff --git a/tests/manual/subsurface/main.qml b/tests/manual/subsurface/main.qml index 8d221401..8c27ac78 100644 --- a/tests/manual/subsurface/main.qml +++ b/tests/manual/subsurface/main.qml @@ -1,12 +1,22 @@ /**************************************************************************** ** ** Copyright (C) 2015 LG Electronics Inc, author: <mikko.levonmaa@lge.com> -** Contact: http://www.qt.io/licensing/ +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are diff --git a/tests/manual/subsurface/shmwindow.cpp b/tests/manual/subsurface/shmwindow.cpp index 50452953..32358210 100644 --- a/tests/manual/subsurface/shmwindow.cpp +++ b/tests/manual/subsurface/shmwindow.cpp @@ -1,12 +1,22 @@ /**************************************************************************** ** ** Copyright (C) 2015 LG Electronics Ltd, author: <mikko.levonmaa@lge.com> -** Contact: http://www.qt.io/licensing/ +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are diff --git a/tests/manual/subsurface/shmwindow.h b/tests/manual/subsurface/shmwindow.h index 44d111e7..10041eea 100644 --- a/tests/manual/subsurface/shmwindow.h +++ b/tests/manual/subsurface/shmwindow.h @@ -1,12 +1,22 @@ /**************************************************************************** ** ** Copyright (C) 2015 LG Electronics Ltd, author: <mikko.levonmaa@lge.com> -** Contact: http://www.qt.io/licensing/ +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are |