Hello community,

here is the log from the commit of package kwayland for openSUSE:Factory 
checked in at 2016-10-28 12:24:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/kwayland (Old)
 and      /work/SRC/openSUSE:Factory/.kwayland.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "kwayland"

Changes:
--------
--- /work/SRC/openSUSE:Factory/kwayland/kwayland.changes        2016-09-14 
23:28:58.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.kwayland.new/kwayland.changes   2016-10-28 
12:24:13.000000000 +0200
@@ -1,0 +2,13 @@
+Sun Oct  2 13:00:34 UTC 2016 - [email protected]
+
+- Update to 5.27.0
+  * [server] Don't send key release for not pressed keys and
+    no double key press (kde#366625)
+  * [server] When replacing the clipboard selection previous
+    DataSource needs to be cancelled (kde#368391)
+  * Add support for Surface enter/leave events
+  * [client] Track all created Outputs and add static get method
+  * For more details please see:
+    https://www.kde.org/announcements/kde-frameworks-5.27.0.php
+
+-------------------------------------------------------------------

Old:
----
  kwayland-5.26.0.tar.xz

New:
----
  kwayland-5.27.0.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ kwayland.spec ++++++
--- /var/tmp/diff_new_pack.pZHLJn/_old  2016-10-28 12:24:14.000000000 +0200
+++ /var/tmp/diff_new_pack.pZHLJn/_new  2016-10-28 12:24:14.000000000 +0200
@@ -16,9 +16,9 @@
 #
 
 
-%define _tar_path 5.26
+%define _tar_path 5.27
 Name:           kwayland
-Version:        5.26.0
+Version:        5.27.0
 Release:        0
 Summary:        KDE Wayland library
 License:        LGPL-2.1+

++++++ kwayland-5.26.0.tar.xz -> kwayland-5.27.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kwayland-5.26.0/CMakeLists.txt 
new/kwayland-5.27.0/CMakeLists.txt
--- old/kwayland-5.26.0/CMakeLists.txt  2016-09-06 00:44:32.000000000 +0200
+++ new/kwayland-5.27.0/CMakeLists.txt  2016-10-02 10:13:48.000000000 +0200
@@ -4,7 +4,7 @@
 
 # ECM setup
 include(FeatureSummary)
-find_package(ECM 5.26.0  NO_MODULE)
+find_package(ECM 5.27.0  NO_MODULE)
 set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake 
Modules." URL 
"https://projects.kde.org/projects/kdesupport/extra-cmake-modules";)
 feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND 
FATAL_ON_MISSING_REQUIRED_PACKAGES)
 set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
@@ -18,7 +18,7 @@
 
 include(ECMPoQmTools)
 
-set(KF5_VERSION "5.26.0") # handled by release scripts
+set(KF5_VERSION "5.27.0") # handled by release scripts
 
 ecm_setup_version(${KF5_VERSION} VARIABLE_PREFIX KWAYLAND
                         VERSION_HEADER 
"${CMAKE_CURRENT_BINARY_DIR}/kwayland_version.h"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kwayland-5.26.0/autotests/client/test_datadevice.cpp 
new/kwayland-5.27.0/autotests/client/test_datadevice.cpp
--- old/kwayland-5.26.0/autotests/client/test_datadevice.cpp    2016-09-06 
00:44:32.000000000 +0200
+++ new/kwayland-5.27.0/autotests/client/test_datadevice.cpp    2016-10-02 
10:13:48.000000000 +0200
@@ -53,6 +53,7 @@
     void testDragInternally();
     void testSetSelection();
     void testSendSelectionOnSeat();
+    void testReplaceSource();
     void testDestroy();
 
 private:
@@ -455,6 +456,79 @@
     m_seatInterface->setFocusedKeyboardSurface(serverSurface);
 }
 
+void TestDataDevice::testReplaceSource()
+{
+    // this test verifies that replacing a data source cancels the previous 
source
+    using namespace KWayland::Client;
+    using namespace KWayland::Server;
+    // first add keyboard support to Seat
+    QSignalSpy keyboardChangedSpy(m_seat, &Seat::hasKeyboardChanged);
+    QVERIFY(keyboardChangedSpy.isValid());
+    m_seatInterface->setHasKeyboard(true);
+    QVERIFY(keyboardChangedSpy.wait());
+    // now create DataDevice, Keyboard and a Surface
+    QSignalSpy dataDeviceCreatedSpy(m_dataDeviceManagerInterface, 
&DataDeviceManagerInterface::dataDeviceCreated);
+    QVERIFY(dataDeviceCreatedSpy.isValid());
+    QScopedPointer<DataDevice> 
dataDevice(m_dataDeviceManager->getDataDevice(m_seat));
+    QVERIFY(dataDevice->isValid());
+    QVERIFY(dataDeviceCreatedSpy.wait());
+    auto serverDataDevice = 
dataDeviceCreatedSpy.first().first().value<DataDeviceInterface*>();
+    QVERIFY(serverDataDevice);
+    QScopedPointer<Keyboard> keyboard(m_seat->createKeyboard());
+    QVERIFY(keyboard->isValid());
+    QSignalSpy surfaceCreatedSpy(m_compositorInterface, 
&CompositorInterface::surfaceCreated);
+    QVERIFY(surfaceCreatedSpy.isValid());
+    QScopedPointer<Surface> surface(m_compositor->createSurface());
+    QVERIFY(surface->isValid());
+    QVERIFY(surfaceCreatedSpy.wait());
+
+    auto serverSurface = 
surfaceCreatedSpy.first().first().value<SurfaceInterface*>();
+    QVERIFY(serverSurface);
+    m_seatInterface->setFocusedKeyboardSurface(serverSurface);
+
+    // now set the selection
+    QScopedPointer<DataSource> 
dataSource(m_dataDeviceManager->createDataSource());
+    QVERIFY(dataSource->isValid());
+    dataSource->offer(QStringLiteral("text/plain"));
+    dataDevice->setSelection(1, dataSource.data());
+    QSignalSpy sourceCancelledSpy(dataSource.data(), &DataSource::cancelled);
+    QVERIFY(sourceCancelledSpy.isValid());
+    // we should get a selection offered for that on the data device
+    QSignalSpy selectionOfferedSpy(dataDevice.data(), 
&DataDevice::selectionOffered);
+    QVERIFY(selectionOfferedSpy.isValid());
+    QVERIFY(selectionOfferedSpy.wait());
+    QCOMPARE(selectionOfferedSpy.count(), 1);
+
+    // create a second data source and replace previous one
+    QScopedPointer<DataSource> 
dataSource2(m_dataDeviceManager->createDataSource());
+    QVERIFY(dataSource2->isValid());
+    dataSource2->offer(QStringLiteral("text/plain"));
+    QSignalSpy sourceCancelled2Spy(dataSource2.data(), &DataSource::cancelled);
+    QVERIFY(sourceCancelled2Spy.isValid());
+    dataDevice->setSelection(1, dataSource2.data());
+    QCOMPARE(selectionOfferedSpy.count(), 1);
+    QVERIFY(sourceCancelledSpy.wait());
+    QCOMPARE(selectionOfferedSpy.count(), 2);
+    QVERIFY(sourceCancelled2Spy.isEmpty());
+
+    // create a new DataDevice and replace previous one
+    QScopedPointer<DataDevice> 
dataDevice2(m_dataDeviceManager->getDataDevice(m_seat));
+    QVERIFY(dataDevice2->isValid());
+    QScopedPointer<DataSource> 
dataSource3(m_dataDeviceManager->createDataSource());
+    QVERIFY(dataSource3->isValid());
+    dataSource3->offer(QStringLiteral("text/plain"));
+    dataDevice2->setSelection(1, dataSource3.data());
+    QVERIFY(sourceCancelled2Spy.wait());
+
+    // try to crash by first destroying dataSource3 and setting a new 
DataSource
+    QScopedPointer<DataSource> 
dataSource4(m_dataDeviceManager->createDataSource());
+    QVERIFY(dataSource4->isValid());
+    dataSource4->offer(QStringLiteral("text/plain"));
+    dataSource3.reset();
+    dataDevice2->setSelection(1, dataSource4.data());
+    QVERIFY(selectionOfferedSpy.wait());
+}
+
 void TestDataDevice::testDestroy()
 {
     using namespace KWayland::Client;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/kwayland-5.26.0/autotests/client/test_wayland_output.cpp 
new/kwayland-5.27.0/autotests/client/test_wayland_output.cpp
--- old/kwayland-5.26.0/autotests/client/test_wayland_output.cpp        
2016-09-06 00:44:32.000000000 +0200
+++ new/kwayland-5.27.0/autotests/client/test_wayland_output.cpp        
2016-10-02 10:13:48.000000000 +0200
@@ -185,7 +185,10 @@
     QSignalSpy outputChanged(&output, SIGNAL(changed()));
     QVERIFY(outputChanged.isValid());
 
-    
output.setup(registry.bindOutput(announced.first().first().value<quint32>(), 
announced.first().last().value<quint32>()));
+    auto o = registry.bindOutput(announced.first().first().value<quint32>(), 
announced.first().last().value<quint32>());
+    QVERIFY(!KWayland::Client::Output::get(o));
+    output.setup(o);
+    QCOMPARE(KWayland::Client::Output::get(o), &output);
     wl_display_flush(m_connection->display());
     QVERIFY(outputChanged.wait());
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/kwayland-5.26.0/autotests/client/test_wayland_seat.cpp 
new/kwayland-5.27.0/autotests/client/test_wayland_seat.cpp
--- old/kwayland-5.26.0/autotests/client/test_wayland_seat.cpp  2016-09-06 
00:44:32.000000000 +0200
+++ new/kwayland-5.27.0/autotests/client/test_wayland_seat.cpp  2016-10-02 
10:13:48.000000000 +0200
@@ -1201,6 +1201,21 @@
     QCOMPARE(keyChangedSpy.at(4).at(1).value<Keyboard::KeyState>(), 
Keyboard::KeyState::Released);
     QCOMPARE(keyChangedSpy.at(4).at(2).value<quint32>(), quint32(8));
 
+    // releasing a key which is already released should not set a key changed
+    m_seatInterface->keyReleased(KEY_F1);
+    QVERIFY(!keyChangedSpy.wait(200));
+    // let's press it again
+    m_seatInterface->keyPressed(KEY_F1);
+    QVERIFY(keyChangedSpy.wait());
+    QCOMPARE(keyChangedSpy.count(), 6);
+    // press again should be ignored
+    m_seatInterface->keyPressed(KEY_F1);
+    QVERIFY(!keyChangedSpy.wait(200));
+    // and release
+    m_seatInterface->keyReleased(KEY_F1);
+    QVERIFY(keyChangedSpy.wait());
+    QCOMPARE(keyChangedSpy.count(), 7);
+
     m_seatInterface->updateKeyboardModifiers(1, 2, 3, 4);
     QVERIFY(modifierSpy.wait());
     QCOMPARE(modifierSpy.count(), 2);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/kwayland-5.26.0/autotests/client/test_wayland_surface.cpp 
new/kwayland-5.27.0/autotests/client/test_wayland_surface.cpp
--- old/kwayland-5.26.0/autotests/client/test_wayland_surface.cpp       
2016-09-06 00:44:32.000000000 +0200
+++ new/kwayland-5.27.0/autotests/client/test_wayland_surface.cpp       
2016-10-02 10:13:48.000000000 +0200
@@ -25,6 +25,7 @@
 #include "../../src/client/compositor.h"
 #include "../../src/client/connection_thread.h"
 #include "../../src/client/event_queue.h"
+#include "../../src/client/output.h"
 #include "../../src/client/surface.h"
 #include "../../src/client/region.h"
 #include "../../src/client/registry.h"
@@ -59,6 +60,7 @@
     void testSurfaceAt();
     void testDestroyAttachedBuffer();
     void testDestroyWithPendingCallback();
+    void testOutput();
     void testDisconnect();
 
 private:
@@ -956,5 +958,78 @@
     m_queue->destroy();
 }
 
+void TestWaylandSurface::testOutput()
+{
+    // This test verifies that the enter/leave are sent correctly to the Client
+    using namespace KWayland::Client;
+    using namespace KWayland::Server;
+    qRegisterMetaType<KWayland::Client::Output*>();
+    QScopedPointer<Surface> s(m_compositor->createSurface());
+    QVERIFY(!s.isNull());
+    QVERIFY(s->isValid());
+    QVERIFY(s->outputs().isEmpty());
+    QSignalSpy enteredSpy(s.data(), &Surface::outputEntered);
+    QVERIFY(enteredSpy.isValid());
+    QSignalSpy leftSpy(s.data(), &Surface::outputLeft);
+    QVERIFY(leftSpy.isValid());
+    // wait for the surface on the Server side
+    QSignalSpy surfaceCreatedSpy(m_compositorInterface, 
&CompositorInterface::surfaceCreated);
+    QVERIFY(surfaceCreatedSpy.isValid());
+    QVERIFY(surfaceCreatedSpy.wait());
+    auto serverSurface = 
surfaceCreatedSpy.first().first().value<SurfaceInterface*>();
+    QVERIFY(serverSurface);
+    QCOMPARE(serverSurface->outputs(), QVector<OutputInterface*>());
+
+    // create another registry to get notified about added outputs
+    Registry registry;
+    registry.setEventQueue(m_queue);
+    QSignalSpy allAnnounced(&registry, &Registry::interfacesAnnounced);
+    QVERIFY(allAnnounced.isValid());
+    registry.create(m_connection);
+    QVERIFY(registry.isValid());
+    registry.setup();
+    QVERIFY(allAnnounced.wait());
+    QSignalSpy outputAnnouncedSpy(&registry, &Registry::outputAnnounced);
+    QVERIFY(outputAnnouncedSpy.isValid());
+
+    auto serverOutput = m_display->createOutput(m_display);
+    serverOutput->create();
+    QVERIFY(outputAnnouncedSpy.wait());
+    QScopedPointer<Output> 
clientOutput(registry.createOutput(outputAnnouncedSpy.first().first().value<quint32>(),
 outputAnnouncedSpy.first().last().value<quint32>()));
+    QVERIFY(clientOutput->isValid());
+    m_connection->flush();
+    m_display->dispatchEvents();
+
+    // now enter it
+    serverSurface->setOutputs(QVector<OutputInterface*>{serverOutput});
+    QCOMPARE(serverSurface->outputs(), 
QVector<OutputInterface*>{serverOutput});
+    QVERIFY(enteredSpy.wait());
+    QCOMPARE(enteredSpy.count(), 1);
+    QCOMPARE(enteredSpy.first().first().value<Output*>(), clientOutput.data());
+    QCOMPARE(s->outputs(), QVector<Output*>{clientOutput.data()});
+
+    // adding to same should not trigger
+    serverSurface->setOutputs(QVector<OutputInterface*>{serverOutput});
+
+    // leave again
+    serverSurface->setOutputs(QVector<OutputInterface*>());
+    QCOMPARE(serverSurface->outputs(), QVector<OutputInterface*>());
+    QVERIFY(leftSpy.wait());
+    QCOMPARE(enteredSpy.count(), 1);
+    QCOMPARE(leftSpy.count(), 1);
+    QCOMPARE(leftSpy.first().first().value<Output*>(), clientOutput.data());
+    QCOMPARE(s->outputs(), QVector<Output*>());
+
+    // leave again should not trigger
+    serverSurface->setOutputs(QVector<OutputInterface*>());
+
+    // and enter again, just to verify
+    serverSurface->setOutputs(QVector<OutputInterface*>{serverOutput});
+    QCOMPARE(serverSurface->outputs(), 
QVector<OutputInterface*>{serverOutput});
+    QVERIFY(enteredSpy.wait());
+    QCOMPARE(enteredSpy.count(), 2);
+    QCOMPARE(leftSpy.count(), 1);
+}
+
 QTEST_GUILESS_MAIN(TestWaylandSurface)
 #include "test_wayland_surface.moc"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kwayland-5.26.0/src/client/output.cpp 
new/kwayland-5.27.0/src/client/output.cpp
--- old/kwayland-5.26.0/src/client/output.cpp   2016-09-06 00:44:32.000000000 
+0200
+++ new/kwayland-5.27.0/src/client/output.cpp   2016-10-02 10:13:48.000000000 
+0200
@@ -23,6 +23,7 @@
 #include <QPoint>
 #include <QRect>
 #include <QSize>
+#include <QVector>
 // wayland
 #include <wayland-client-protocol.h>
 
@@ -40,6 +41,7 @@
 {
 public:
     Private(Output *q);
+    ~Private();
     void setup(wl_output *o);
 
     WaylandPointer<wl_output, wl_output_destroy> output;
@@ -54,6 +56,8 @@
     Modes modes;
     Modes::iterator currentMode = modes.end();
 
+    static Output *get(wl_output *o);
+
 private:
     static void geometryCallback(void *data, wl_output *output, int32_t x, 
int32_t y,
                                  int32_t physicalWidth, int32_t 
physicalHeight, int32_t subPixel,
@@ -72,11 +76,35 @@
 
     Output *q;
     static struct wl_output_listener s_outputListener;
+
+    static QVector<Private*> s_allOutputs;
 };
 
+QVector<Output::Private*> Output::Private::s_allOutputs;
+
 Output::Private::Private(Output *q)
     : q(q)
 {
+    s_allOutputs << this;
+}
+
+Output::Private::~Private()
+{
+    s_allOutputs.removeOne(this);
+}
+
+Output *Output::Private::get(wl_output *o)
+{
+    auto it = std::find_if(s_allOutputs.constBegin(), s_allOutputs.constEnd(),
+        [o] (Private *p) {
+            const wl_output *reference = p->output;
+            return reference == o;
+        }
+    );
+    if (it != s_allOutputs.constEnd()) {
+        return (*it)->q;
+    }
+    return nullptr;
 }
 
 void Output::Private::setup(wl_output *o)
@@ -358,5 +386,10 @@
     return d->output;
 }
 
+Output *Output::get(wl_output *o)
+{
+    return Private::get(o);
+}
+
 }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kwayland-5.26.0/src/client/output.h 
new/kwayland-5.27.0/src/client/output.h
--- old/kwayland-5.26.0/src/client/output.h     2016-09-06 00:44:32.000000000 
+0200
+++ new/kwayland-5.27.0/src/client/output.h     2016-10-02 10:13:48.000000000 
+0200
@@ -198,6 +198,12 @@
      **/
     EventQueue *eventQueue() const;
 
+    /**
+     * @returns The Output for the @p native wl_output. @c null if there is no 
Output for it.
+     * @since 5.27
+     **/
+    static Output *get(wl_output *native);
+
 Q_SIGNALS:
     /**
      * Emitted whenever at least one of the data changed.
@@ -236,6 +242,7 @@
 }
 }
 
+Q_DECLARE_METATYPE(KWayland::Client::Output*)
 Q_DECLARE_METATYPE(KWayland::Client::Output::SubPixel)
 Q_DECLARE_METATYPE(KWayland::Client::Output::Transform)
 Q_DECLARE_METATYPE(KWayland::Client::Output::Mode)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kwayland-5.26.0/src/client/surface.cpp 
new/kwayland-5.27.0/src/client/surface.cpp
--- old/kwayland-5.26.0/src/client/surface.cpp  2016-09-06 00:44:32.000000000 
+0200
+++ new/kwayland-5.27.0/src/client/surface.cpp  2016-10-02 10:13:48.000000000 
+0200
@@ -20,6 +20,7 @@
 #include "surface.h"
 #include "buffer.h"
 #include "region.h"
+#include "output.h"
 #include "wayland_pointer_p.h"
 
 #include <QGuiApplication>
@@ -46,14 +47,20 @@
     QSize size;
     bool foreign = false;
     qint32 scale = 1;
+    QVector<Output *> outputs;
+
+    void setup(wl_surface *s);
 
     static QList<Surface*> s_surfaces;
 private:
     void handleFrameCallback();
     static void frameCallback(void *data, wl_callback *callback, uint32_t 
time);
+    static void enterCallback(void *data, wl_surface *wl_surface, wl_output 
*output);
+    static void leaveCallback(void *data, wl_surface *wl_surface, wl_output 
*output);
 
     Surface *q;
     static const wl_callback_listener s_listener;
+    static const wl_surface_listener s_surfaceListener;
 };
 
 QList<Surface*> Surface::Private::s_surfaces = QList<Surface*>();
@@ -130,9 +137,15 @@
 
 void Surface::setup(wl_surface *surface)
 {
-    Q_ASSERT(surface);
-    Q_ASSERT(!d->surface);
-    d->surface.setup(surface);
+    d->setup(surface);
+}
+
+void Surface::Private::setup(wl_surface *s)
+{
+    Q_ASSERT(s);
+    Q_ASSERT(!surface);
+    surface.setup(s);
+    wl_surface_add_listener(s, &s_surfaceListener, this);
 }
 
 void Surface::Private::frameCallback(void *data, wl_callback *callback, 
uint32_t time)
@@ -155,8 +168,37 @@
 const struct wl_callback_listener Surface::Private::s_listener = {
         frameCallback
 };
+
+const struct wl_surface_listener Surface::Private::s_surfaceListener = {
+        enterCallback,
+        leaveCallback
+};
 #endif
 
+void Surface::Private::enterCallback(void *data, wl_surface *surface, 
wl_output *output)
+{
+    Q_UNUSED(surface);
+    auto s = reinterpret_cast<Surface::Private*>(data);
+    Output *o = Output::get(output);
+    if (!o) {
+        return;
+    }
+    s->outputs << o;
+    emit s->q->outputEntered(o);
+}
+
+void Surface::Private::leaveCallback(void *data, wl_surface *surface, 
wl_output *output)
+{
+    Q_UNUSED(surface);
+    auto s = reinterpret_cast<Surface::Private*>(data);
+    Output *o = Output::get(output);
+    if (!o) {
+        return;
+    }
+    s->outputs.removeOne(o);
+    emit s->q->outputLeft(o);
+}
+
 void Surface::Private::setupFrameCallback()
 {
     Q_ASSERT(!frameCallbackInstalled);
@@ -293,5 +335,10 @@
     wl_surface_set_buffer_scale(d->surface, scale);
 }
 
+QVector<Output *> Surface::outputs() const
+{
+    return d->outputs;
+}
+
 }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kwayland-5.26.0/src/client/surface.h 
new/kwayland-5.27.0/src/client/surface.h
--- old/kwayland-5.26.0/src/client/surface.h    2016-09-06 00:44:32.000000000 
+0200
+++ new/kwayland-5.27.0/src/client/surface.h    2016-10-02 10:13:48.000000000 
+0200
@@ -39,6 +39,7 @@
 namespace Client
 {
 
+class Output;
 class Region;
 
 /**
@@ -238,6 +239,14 @@
     quint32 id() const;
 
     /**
+     * @returns All Outputs the Surface is on, may be none.
+     * @see outputEntered
+     * @see outputLeft
+     * @since 5.27
+     **/
+    QVector<Output *> outputs() const;
+
+    /**
      * All Surfaces which are currently created.
      * TODO: KF6 return QList<Surface*> instead of const-ref
      **/
@@ -258,6 +267,28 @@
     void frameRendered();
     void sizeChanged(const QSize&);
 
+    /**
+     * Emitted whenever a change in the Surface (e.g. creation, movement, 
resize) results in
+     * a part of the Surface being within the scanout region of the Output @p 
o.
+     *
+     * @param o The Output the Surface intersects with
+     * @see outputLeft
+     * @see outputs
+     * @since 5.27
+     **/
+    void outputEntered(KWayland::Client::Output *o);
+
+    /**
+     * Emitted whenever a change in the Surface (e.g. creation, movement, 
resize, unmapping)
+     * results in the Surface no longer being within the scanout region of the 
Output @p o.
+     *
+     * @param o The Output the Surface no longer intersects with
+     * @see outputEntered
+     * @see outputs
+     * @since 5.27
+     **/
+    void outputLeft(KWayland::Client::Output *o);
+
 private:
     class Private;
     QScopedPointer<Private> d;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kwayland-5.26.0/src/server/datadevice_interface.cpp 
new/kwayland-5.27.0/src/server/datadevice_interface.cpp
--- old/kwayland-5.26.0/src/server/datadevice_interface.cpp     2016-09-06 
00:44:32.000000000 +0200
+++ new/kwayland-5.27.0/src/server/datadevice_interface.cpp     2016-10-02 
10:13:48.000000000 +0200
@@ -48,6 +48,8 @@
     SurfaceInterface *icon = nullptr;
 
     DataSourceInterface *selection = nullptr;
+    QMetaObject::Connection selectionUnboundConnection;
+    QMetaObject::Connection selectionDestroyedConnection;
 
     struct Drag {
         SurfaceInterface *surface = nullptr;
@@ -120,10 +122,22 @@
 void DataDeviceInterface::Private::setSelection(DataSourceInterface 
*dataSource)
 {
     Q_Q(DataDeviceInterface);
+    QObject::disconnect(selectionUnboundConnection);
+    QObject::disconnect(selectionDestroyedConnection);
+    if (selection) {
+        selection->cancel();
+    }
     selection = dataSource;
     if (selection) {
+        auto clearSelection = [this] {
+            setSelection(nullptr);
+        };
+        selectionUnboundConnection = QObject::connect(selection, 
&Resource::unbound, q, clearSelection);
+        selectionDestroyedConnection = QObject::connect(selection, 
&QObject::destroyed, q, clearSelection);
         emit q->selectionChanged(selection);
     } else {
+        selectionUnboundConnection = QMetaObject::Connection();
+        selectionDestroyedConnection = QMetaObject::Connection();
         emit q->selectionCleared();
     }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kwayland-5.26.0/src/server/datasource_interface.cpp 
new/kwayland-5.27.0/src/server/datasource_interface.cpp
--- old/kwayland-5.26.0/src/server/datasource_interface.cpp     2016-09-06 
00:44:32.000000000 +0200
+++ new/kwayland-5.27.0/src/server/datasource_interface.cpp     2016-10-02 
10:13:48.000000000 +0200
@@ -19,6 +19,7 @@
 *********************************************************************/
 #include "datasource_interface.h"
 #include "datadevicemanager_interface.h"
+#include "clientconnection.h"
 #include "resource_p.h"
 // Qt
 #include <QStringList>
@@ -103,7 +104,11 @@
 void DataSourceInterface::cancel()
 {
     Q_D();
+    if (!d->resource) {
+        return;
+    }
     wl_data_source_send_cancelled(d->resource);
+    client()->flush();
 }
 
 QStringList DataSourceInterface::mimeTypes() const
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kwayland-5.26.0/src/server/output_interface.cpp 
new/kwayland-5.27.0/src/server/output_interface.cpp
--- old/kwayland-5.26.0/src/server/output_interface.cpp 2016-09-06 
00:44:32.000000000 +0200
+++ new/kwayland-5.27.0/src/server/output_interface.cpp 2016-10-02 
10:13:48.000000000 +0200
@@ -506,6 +506,18 @@
     return d->dpms.supported;
 }
 
+QVector<wl_resource *> OutputInterface::clientResources(ClientConnection 
*client) const
+{
+    Q_D();
+    QVector<wl_resource *> ret;
+    for (auto it = d->resources.constBegin(), end = d->resources.constEnd(); 
it != end; ++it) {
+        if (wl_resource_get_client((*it).resource) == client->client()) {
+            ret << (*it).resource;
+        }
+    }
+    return ret;
+}
+
 OutputInterface *OutputInterface::get(wl_resource* native)
 {
     return Private::get(native);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kwayland-5.26.0/src/server/output_interface.h 
new/kwayland-5.27.0/src/server/output_interface.h
--- old/kwayland-5.26.0/src/server/output_interface.h   2016-09-06 
00:44:32.000000000 +0200
+++ new/kwayland-5.27.0/src/server/output_interface.h   2016-10-02 
10:13:48.000000000 +0200
@@ -36,6 +36,7 @@
 namespace Server
 {
 
+class ClientConnection;
 class Display;
 
 /**
@@ -125,6 +126,12 @@
      **/
     void setDpmsMode(DpmsMode mode);
 
+    /**
+     * @returns all wl_resources bound for the @p client
+     * @since 5.27
+     **/
+    QVector<wl_resource *> clientResources(ClientConnection *client) const;
+
     static OutputInterface *get(wl_resource *native);
 
 Q_SIGNALS:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kwayland-5.26.0/src/server/seat_interface.cpp 
new/kwayland-5.27.0/src/server/seat_interface.cpp
--- old/kwayland-5.26.0/src/server/seat_interface.cpp   2016-09-06 
00:44:32.000000000 +0200
+++ new/kwayland-5.27.0/src/server/seat_interface.cpp   2016-10-02 
10:13:48.000000000 +0200
@@ -132,14 +132,18 @@
     it.value() = state;
 }
 
-void SeatInterface::Private::updateKey(quint32 key, Keyboard::State state)
+bool SeatInterface::Private::updateKey(quint32 key, Keyboard::State state)
 {
     auto it = keys.states.find(key);
     if (it == keys.states.end()) {
         keys.states.insert(key, state);
-        return;
+        return true;
+    }
+    if (it.value() == state) {
+        return false;
     }
     it.value() = state;
+    return true;
 }
 
 void SeatInterface::Private::sendName(wl_resource *r)
@@ -321,6 +325,16 @@
 void SeatInterface::Private::updateSelection(DataDeviceInterface *dataDevice, 
bool set)
 {
     if (keys.focus.surface && (keys.focus.surface->client() == 
dataDevice->client())) {
+        if (currentSelection) {
+            // cancel the previous selection
+            if (auto s = currentSelection->selection()) {
+                if (currentSelection != dataDevice) {
+                    // only if current selection is not on the same device
+                    // that would cancel the newly set source
+                    s->cancel();
+                }
+            }
+        }
         // new selection on a data device belonging to current keyboard focus
         currentSelection = dataDevice;
     }
@@ -815,7 +829,9 @@
 {
     Q_D();
     d->keys.lastStateSerial = d->display->nextSerial();
-    d->updateKey(key, Private::Keyboard::State::Pressed);
+    if (!d->updateKey(key, Private::Keyboard::State::Pressed)) {
+        return;
+    }
     if (d->keys.focus.keyboard && d->keys.focus.surface) {
         d->keys.focus.keyboard->keyPressed(key, d->keys.lastStateSerial);
     }
@@ -825,7 +841,9 @@
 {
     Q_D();
     d->keys.lastStateSerial = d->display->nextSerial();
-    d->updateKey(key, Private::Keyboard::State::Released);
+    if (!d->updateKey(key, Private::Keyboard::State::Released)) {
+        return;
+    }
     if (d->keys.focus.keyboard && d->keys.focus.surface) {
         d->keys.focus.keyboard->keyReleased(key, d->keys.lastStateSerial);
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kwayland-5.26.0/src/server/seat_interface_p.h 
new/kwayland-5.27.0/src/server/seat_interface_p.h
--- old/kwayland-5.26.0/src/server/seat_interface_p.h   2016-09-06 
00:44:32.000000000 +0200
+++ new/kwayland-5.27.0/src/server/seat_interface_p.h   2016-10-02 
10:13:48.000000000 +0200
@@ -124,7 +124,7 @@
         } keyRepeat;
     };
     Keyboard keys;
-    void updateKey(quint32 key, Keyboard::State state);
+    bool updateKey(quint32 key, Keyboard::State state);
 
     struct TextInput {
         struct Focus {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kwayland-5.26.0/src/server/surface_interface.cpp 
new/kwayland-5.27.0/src/server/surface_interface.cpp
--- old/kwayland-5.26.0/src/server/surface_interface.cpp        2016-09-06 
00:44:32.000000000 +0200
+++ new/kwayland-5.27.0/src/server/surface_interface.cpp        2016-10-02 
10:13:48.000000000 +0200
@@ -688,6 +688,44 @@
     d->trackedDamage = QRegion();
 }
 
+QVector<OutputInterface *> SurfaceInterface::outputs() const
+{
+    Q_D();
+    return d->outputs;
+}
+
+void SurfaceInterface::setOutputs(const QVector<OutputInterface *> &outputs)
+{
+    Q_D();
+    QVector<OutputInterface *> removedOutputs = d->outputs;
+    for (auto it = outputs.constBegin(), end = outputs.constEnd(); it != end; 
++it) {
+        const auto o = *it;
+        removedOutputs.removeOne(o);
+    }
+    for (auto it = removedOutputs.constBegin(), end = 
removedOutputs.constEnd(); it != end; ++it) {
+        const auto resources = (*it)->clientResources(client());
+        for (wl_resource *r : resources) {
+            wl_surface_send_leave(d->resource, r);
+        }
+    }
+    // TODO: send leave when OutputInterface gets destroyed
+
+    QVector<OutputInterface *> addedOutputsOutputs = outputs;
+    for (auto it = d->outputs.constBegin(), end = d->outputs.constEnd(); it != 
end; ++it) {
+        const auto o = *it;
+        addedOutputsOutputs.removeOne(o);
+    }
+    for (auto it = addedOutputsOutputs.constBegin(), end = 
addedOutputsOutputs.constEnd(); it != end; ++it) {
+        const auto resources = (*it)->clientResources(client());
+        for (wl_resource *r : resources) {
+            wl_surface_send_enter(d->resource, r);
+        }
+    }
+    // TODO: send enter when the client binds the OutputInterface another time
+
+    d->outputs = outputs;
+}
+
 SurfaceInterface *SurfaceInterface::surfaceAt(const QPointF &position)
 {
     if (!isMapped()) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kwayland-5.26.0/src/server/surface_interface.h 
new/kwayland-5.27.0/src/server/surface_interface.h
--- old/kwayland-5.26.0/src/server/surface_interface.h  2016-09-06 
00:44:32.000000000 +0200
+++ new/kwayland-5.27.0/src/server/surface_interface.h  2016-10-02 
10:13:48.000000000 +0200
@@ -206,6 +206,24 @@
     SurfaceInterface *surfaceAt(const QPointF &position);
 
     /**
+     * Sets the @p outputs this SurfaceInterface overlaps with, may be empty.
+     *
+     * The compositor should update whenever the SurfaceInterface becomes 
visible on
+     * an OutputInterface by e.g. getting (un)mapped, resized, moved, etc.
+     *
+     * @see outputs
+     * @since 5.27
+     **/
+    void setOutputs(const QVector<OutputInterface *> &outputs);
+
+    /**
+     * @returns All OutputInterfaces the SurfaceInterface is on.
+     * @see setOutputs
+     * @since 5.27
+     **/
+    QVector<OutputInterface *> outputs() const;
+
+    /**
      * @returns The SurfaceInterface for the @p native resource.
      **/
     static SurfaceInterface *get(wl_resource *native);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kwayland-5.26.0/src/server/surface_interface_p.h 
new/kwayland-5.27.0/src/server/surface_interface_p.h
--- old/kwayland-5.26.0/src/server/surface_interface_p.h        2016-09-06 
00:44:32.000000000 +0200
+++ new/kwayland-5.27.0/src/server/surface_interface_p.h        2016-10-02 
10:13:48.000000000 +0200
@@ -22,6 +22,8 @@
 
 #include "surface_interface.h"
 #include "resource_p.h"
+// Qt
+#include <QVector>
 // Wayland
 #include <wayland-server.h>
 
@@ -89,6 +91,8 @@
     // waiting on the frame callback of the never visible surface
     bool subSurfaceIsMapped = true;
 
+    QVector<OutputInterface *> outputs;
+
 private:
     SurfaceInterface *q_func() {
         return reinterpret_cast<SurfaceInterface *>(q);


Reply via email to