Merge lp:~dandrader/qtubuntu/content-hub-clipboard into lp:qtubuntu

Proposed by Daniel d'Andrada on 2016-07-27
Status: Merged
Approved by: Ken VanDine on 2016-08-29
Approved revision: 339
Merged at revision: 341
Proposed branch: lp:~dandrader/qtubuntu/content-hub-clipboard
Merge into: lp:qtubuntu
Diff against target: 655 lines (+149/-277)
9 files modified
debian/control (+1/-0)
src/ubuntumirclient/clipboard.cpp (+96/-233)
src/ubuntumirclient/clipboard.h (+23/-22)
src/ubuntumirclient/input.cpp (+0/-1)
src/ubuntumirclient/integration.cpp (+6/-3)
src/ubuntumirclient/integration.h (+0/-2)
src/ubuntumirclient/ubuntumirclient.pro (+1/-1)
src/ubuntumirclient/window.cpp (+20/-11)
src/ubuntumirclient/window.h (+2/-4)
To merge this branch: bzr merge lp:~dandrader/qtubuntu/content-hub-clipboard
Reviewer Review Type Date Requested Status
Unity8 CI Bot continuous-integration Needs Fixing on 2016-08-24
Ken VanDine 2016-07-27 Approve on 2016-08-03
Review via email: mp+301272@code.launchpad.net

Commit Message

Use content-hub for clipboard services

To post a comment you must log in.
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:334
https://unity8-jenkins.ubuntu.com/job/lp-qtubuntu-ci/99/
Executed test runs:
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build/2412/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/2440
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/2327
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/2327
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/2327
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/2320/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/2320/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/2320/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/2320/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/2320/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/2320/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/2320/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/2320/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/2320/console

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-qtubuntu-ci/99/rebuild

review: Needs Fixing (continuous-integration)
Ken VanDine (ken-vandine) wrote :

Looks good and works great!

review: Approve
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
339. By Daniel d'Andrada on 2016-08-24

Use content-hub for clipboard services

Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:339
https://unity8-jenkins.ubuntu.com/job/lp-qtubuntu-ci/110/
Executed test runs:
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build/2651/console
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/2679
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/2552
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/2552
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/2552
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/2546/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/2546/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=yakkety/2546/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/2546/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/2546/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=yakkety/2546/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/2546/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/2546/console
    FAILURE: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=yakkety/2546/console

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-qtubuntu-ci/110/rebuild

review: Needs Fixing (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/control'
2--- debian/control 2016-06-03 09:38:55 +0000
3+++ debian/control 2016-08-24 12:43:18 +0000
4@@ -3,6 +3,7 @@
5 Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
6 Build-Depends: debhelper (>= 9),
7 libatspi2.0-dev,
8+ libcontent-hub-dev (>= 0.2),
9 libegl1-mesa-dev,
10 libfontconfig1-dev,
11 libfreetype6-dev,
12
13=== modified file 'src/ubuntumirclient/clipboard.cpp'
14--- src/ubuntumirclient/clipboard.cpp 2015-12-04 16:19:33 +0000
15+++ src/ubuntumirclient/clipboard.cpp 2016-08-24 12:43:18 +0000
16@@ -1,5 +1,5 @@
17 /*
18- * Copyright (C) 2014 Canonical, Ltd.
19+ * Copyright (C) 2014,2016 Canonical, Ltd.
20 *
21 * This program is free software: you can redistribute it and/or modify it under
22 * the terms of the GNU Lesser General Public License version 3, as published by
23@@ -16,41 +16,35 @@
24
25 #include "clipboard.h"
26 #include "logging.h"
27+#include "window.h"
28
29+#include <QDBusPendingCallWatcher>
30+#include <QGuiApplication>
31+#include <QSignalBlocker>
32 #include <QtCore/QMimeData>
33 #include <QtCore/QStringList>
34-#include <QDBusInterface>
35-#include <QDBusPendingCallWatcher>
36-#include <QDBusPendingReply>
37-
38-// FIXME(loicm) The clipboard data format is not defined by Ubuntu Platform API
39-// which makes it impossible to have non-Qt applications communicate with Qt
40-// applications through the clipboard API. The solution would be to have
41-// Ubuntu Platform define the data format or propose an API that supports
42-// embedding different mime types in the clipboard.
43-
44-// Data format:
45-// number of mime types (sizeof(int))
46-// data layout ((4 * sizeof(int)) * number of mime types)
47-// mime type string offset (sizeof(int))
48-// mime type string size (sizeof(int))
49-// data offset (sizeof(int))
50-// data size (sizeof(int))
51-// data (n bytes)
52-
53-namespace {
54-
55-const int maxFormatsCount = 16;
56-const int maxBufferSize = 4 * 1024 * 1024; // 4 Mb
57-
58-}
59+
60+// content-hub
61+#include <com/ubuntu/content/hub.h>
62+
63+// get this cumbersome nested namespace out of the way
64+using namespace com::ubuntu::content;
65
66 UbuntuClipboard::UbuntuClipboard()
67 : mMimeData(new QMimeData)
68- , mIsOutdated(true)
69- , mUpdatesDisabled(false)
70- , mDBusSetupDone(false)
71+ , mContentHub(Hub::Client::instance())
72 {
73+ connect(mContentHub, &Hub::pasteboardChanged, this, [this]() {
74+ if (mClipboardState == UbuntuClipboard::SyncedClipboard) {
75+ mClipboardState = UbuntuClipboard::OutdatedClipboard;
76+ emitChanged(QClipboard::Clipboard);
77+ }
78+ });
79+
80+ connect(qGuiApp, &QGuiApplication::applicationStateChanged,
81+ this, &UbuntuClipboard::onApplicationStateChanged);
82+
83+ requestMimeData();
84 }
85
86 UbuntuClipboard::~UbuntuClipboard()
87@@ -58,203 +52,39 @@
88 delete mMimeData;
89 }
90
91-void UbuntuClipboard::requestDBusClipboardContents()
92-{
93- if (!mDBusSetupDone) {
94- setupDBus();
95- }
96-
97- if (!mPendingGetContentsCall.isNull())
98- return;
99-
100- QDBusPendingCall pendingCall = mDBusClipboard->asyncCall(QStringLiteral("GetContents"));
101-
102- mPendingGetContentsCall = new QDBusPendingCallWatcher(pendingCall, this);
103-
104- QObject::connect(mPendingGetContentsCall.data(), &QDBusPendingCallWatcher::finished,
105- this, &UbuntuClipboard::onDBusClipboardGetContentsFinished);
106-}
107-
108-void UbuntuClipboard::onDBusClipboardGetContentsFinished(QDBusPendingCallWatcher* call)
109-{
110- Q_ASSERT(call == mPendingGetContentsCall.data());
111-
112- QDBusPendingReply<QByteArray> reply = *call;
113- if (reply.isError()) {
114- qCCritical(ubuntumirclient, "Failed to get system clipboard contents via D-Bus. %s, %s",
115- qPrintable(reply.error().name()), qPrintable(reply.error().message()));
116- // TODO: Might try again later a number of times...
117- } else {
118- QByteArray serializedMimeData = reply.argumentAt<0>();
119- updateMimeData(serializedMimeData);
120- }
121- call->deleteLater();
122-}
123-
124-void UbuntuClipboard::onDBusClipboardSetContentsFinished(QDBusPendingCallWatcher *call)
125-{
126- QDBusPendingReply<void> reply = *call;
127- if (reply.isError()) {
128- qCCritical(ubuntumirclient, "Failed to set the system clipboard contents via D-Bus. %s, %s",
129- qPrintable(reply.error().name()), qPrintable(reply.error().message()));
130- // TODO: Might try again later a number of times...
131- }
132- call->deleteLater();
133-}
134-
135-void UbuntuClipboard::updateMimeData(const QByteArray &serializedMimeData)
136-{
137- if (mUpdatesDisabled)
138- return;
139-
140- QMimeData *newMimeData = deserializeMimeData(serializedMimeData);
141- if (newMimeData) {
142- delete mMimeData;
143- mMimeData = newMimeData;
144- mIsOutdated = false;
145- emitChanged(QClipboard::Clipboard);
146- } else {
147- qCWarning(ubuntumirclient) << "Got invalid serialized mime data. Ignoring it.";
148- }
149-}
150-
151-void UbuntuClipboard::setupDBus()
152-{
153- QDBusConnection dbusConnection = QDBusConnection::sessionBus();
154-
155- bool ok = dbusConnection.connect(
156- QStringLiteral("com.canonical.QtMir"),
157- QStringLiteral("/com/canonical/QtMir/Clipboard"),
158- QStringLiteral("com.canonical.QtMir.Clipboard"),
159- QStringLiteral("ContentsChanged"),
160- this, SLOT(updateMimeData(QByteArray)));
161- if (!ok) {
162- qCCritical(ubuntumirclient) << "Failed to connect to ContentsChanged signal form the D-Bus system clipboard.";
163- }
164-
165- mDBusClipboard = new QDBusInterface(QStringLiteral("com.canonical.QtMir"),
166- QStringLiteral("/com/canonical/QtMir/Clipboard"),
167- QStringLiteral("com.canonical.QtMir.Clipboard"),
168- dbusConnection);
169-
170- mDBusSetupDone = true;
171-}
172-
173-QByteArray UbuntuClipboard::serializeMimeData(QMimeData *mimeData) const
174-{
175- Q_ASSERT(mimeData != nullptr);
176-
177- const QStringList formats = mimeData->formats();
178- const int formatCount = qMin(formats.size(), maxFormatsCount);
179- const int headerSize = sizeof(int) + (formatCount * 4 * sizeof(int));
180- int bufferSize = headerSize;
181-
182- for (int i = 0; i < formatCount; i++)
183- bufferSize += formats[i].size() + mimeData->data(formats[i]).size();
184-
185- QByteArray serializedMimeData;
186- if (bufferSize <= maxBufferSize) {
187- // Serialize data.
188- serializedMimeData.resize(bufferSize);
189- {
190- char *buffer = serializedMimeData.data();
191- int* header = reinterpret_cast<int*>(serializedMimeData.data());
192- int offset = headerSize;
193- header[0] = formatCount;
194- for (int i = 0; i < formatCount; i++) {
195- const QByteArray data = mimeData->data(formats[i]);
196- const int formatOffset = offset;
197- const int formatSize = formats[i].size();
198- const int dataOffset = offset + formatSize;
199- const int dataSize = data.size();
200- memcpy(&buffer[formatOffset], formats[i].toLatin1().data(), formatSize);
201- memcpy(&buffer[dataOffset], data.data(), dataSize);
202- header[i*4+1] = formatOffset;
203- header[i*4+2] = formatSize;
204- header[i*4+3] = dataOffset;
205- header[i*4+4] = dataSize;
206- offset += formatSize + dataSize;
207- }
208- }
209- } else {
210- qCWarning(ubuntumirclient, "Not sending contents (%d bytes) to the global clipboard as it's"
211- " bigger than the maximum allowed size of %d bytes", bufferSize, maxBufferSize);
212- }
213-
214- return serializedMimeData;
215-}
216-
217-QMimeData *UbuntuClipboard::deserializeMimeData(const QByteArray &serializedMimeData) const
218-{
219- if (static_cast<std::size_t>(serializedMimeData.size()) < sizeof(int)) {
220- // Data is invalid
221- return nullptr;
222- }
223-
224- QMimeData *mimeData = new QMimeData;
225-
226- const char* const buffer = serializedMimeData.constData();
227- const int* const header = reinterpret_cast<const int*>(serializedMimeData.constData());
228-
229- const int count = qMin(header[0], maxFormatsCount);
230-
231- for (int i = 0; i < count; i++) {
232- const int formatOffset = header[i*4+1];
233- const int formatSize = header[i*4+2];
234- const int dataOffset = header[i*4+3];
235- const int dataSize = header[i*4+4];
236-
237- if (formatOffset + formatSize <= serializedMimeData.size()
238- && dataOffset + dataSize <= serializedMimeData.size()) {
239-
240- QString mimeType = QString::fromLatin1(&buffer[formatOffset], formatSize);
241- QByteArray mimeDataBytes(&buffer[dataOffset], dataSize);
242-
243- mimeData->setData(mimeType, mimeDataBytes);
244- }
245- }
246-
247- return mimeData;
248-}
249-
250 QMimeData* UbuntuClipboard::mimeData(QClipboard::Mode mode)
251 {
252 if (mode != QClipboard::Clipboard)
253 return nullptr;
254
255- if (mIsOutdated && mPendingGetContentsCall.isNull()) {
256- requestDBusClipboardContents();
257+ // Blocks dataChanged() signal from being emitted. Makes no sense to emit it from
258+ // inside the data getter.
259+ const QSignalBlocker blocker(this);
260+
261+ if (mClipboardState == OutdatedClipboard) {
262+ updateMimeData();
263+ } else if (mClipboardState == SyncingClipboard) {
264+ mPasteReply->waitForFinished();
265 }
266
267- // Return whatever we have at the moment instead of blocking until we have something.
268- //
269- // This might be called during app startup just for the sake of checking if some
270- // "Paste" UI control should be enabled or not.
271- // We will emit QClipboard::changed() once we finally have something.
272 return mMimeData;
273 }
274
275 void UbuntuClipboard::setMimeData(QMimeData* mimeData, QClipboard::Mode mode)
276 {
277- if (mode != QClipboard::Clipboard)
278- return;
279-
280- if (!mPendingGetContentsCall.isNull()) {
281- // Ignore whatever comes from the system clipboard as we are going to change it anyway
282- QObject::disconnect(mPendingGetContentsCall.data(), 0, this, 0);
283- mUpdatesDisabled = true;
284- mPendingGetContentsCall->waitForFinished();
285- mUpdatesDisabled = false;
286- delete mPendingGetContentsCall.data();
287- }
288-
289- if (mimeData != nullptr) {
290- QByteArray serializedMimeData = serializeMimeData(mimeData);
291- if (!serializedMimeData.isEmpty()) {
292- setDBusClipboardContents(serializedMimeData);
293- }
294+ QWindow *focusWindow = QGuiApplication::focusWindow();
295+ if (focusWindow && mode == QClipboard::Clipboard && mimeData != nullptr) {
296+ QString surfaceId = static_cast<UbuntuWindow*>(focusWindow->handle())->persistentSurfaceId();
297+
298+ QDBusPendingCall reply = mContentHub->createPaste(surfaceId, *mimeData);
299+
300+ // Don't care whether it succeeded
301+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
302+ connect(watcher, &QDBusPendingCallWatcher::finished,
303+ watcher, &QObject::deleteLater);
304
305 mMimeData = mimeData;
306+ mClipboardState = SyncedClipboard;
307 emitChanged(QClipboard::Clipboard);
308 }
309 }
310@@ -270,25 +100,58 @@
311 return false;
312 }
313
314-void UbuntuClipboard::setDBusClipboardContents(const QByteArray &clipboardContents)
315-{
316- if (!mDBusSetupDone) {
317- setupDBus();
318- }
319-
320- if (!mPendingSetContentsCall.isNull()) {
321- // Ignore any previous set call as we are going to overwrite it anyway
322- QObject::disconnect(mPendingSetContentsCall.data(), 0, this, 0);
323- mUpdatesDisabled = true;
324- mPendingSetContentsCall->waitForFinished();
325- mUpdatesDisabled = false;
326- delete mPendingSetContentsCall.data();
327- }
328-
329- QDBusPendingCall pendingCall = mDBusClipboard->asyncCall(QStringLiteral("SetContents"), clipboardContents);
330-
331- mPendingSetContentsCall = new QDBusPendingCallWatcher(pendingCall, this);
332-
333- QObject::connect(mPendingSetContentsCall.data(), &QDBusPendingCallWatcher::finished,
334- this, &UbuntuClipboard::onDBusClipboardSetContentsFinished);
335+void UbuntuClipboard::onApplicationStateChanged(Qt::ApplicationState state)
336+{
337+ if (state == Qt::ApplicationActive) {
338+ // Only focused or active applications might be allowed to paste, so we probably
339+ // missed changes in the clipboard while we were hidden, inactive or, more importantly,
340+ // suspended.
341+ requestMimeData();
342+ }
343+}
344+
345+void UbuntuClipboard::updateMimeData()
346+{
347+ if (qGuiApp->applicationState() != Qt::ApplicationActive) {
348+ // Don't even bother asking as content-hub would probably ignore our request (and should).
349+ return;
350+ }
351+
352+ delete mMimeData;
353+
354+ QWindow *focusWindow = QGuiApplication::focusWindow();
355+ if (focusWindow) {
356+ QString surfaceId = static_cast<UbuntuWindow*>(focusWindow->handle())->persistentSurfaceId();
357+ mMimeData = mContentHub->latestPaste(surfaceId);
358+ mClipboardState = SyncedClipboard;
359+ emitChanged(QClipboard::Clipboard);
360+ }
361+}
362+
363+void UbuntuClipboard::requestMimeData()
364+{
365+ if (qGuiApp->applicationState() != Qt::ApplicationActive) {
366+ // Don't even bother asking as content-hub would probably ignore our request (and should).
367+ return;
368+ }
369+
370+ QWindow *focusWindow = QGuiApplication::focusWindow();
371+ if (!focusWindow) {
372+ return;
373+ }
374+
375+ QString surfaceId = static_cast<UbuntuWindow*>(focusWindow->handle())->persistentSurfaceId();
376+ QDBusPendingCall reply = mContentHub->requestLatestPaste(surfaceId);
377+ mClipboardState = SyncingClipboard;
378+
379+ mPasteReply = new QDBusPendingCallWatcher(reply, this);
380+ connect(mPasteReply, &QDBusPendingCallWatcher::finished,
381+ this, [this]() {
382+ delete mMimeData;
383+ mMimeData = mContentHub->paste(*mPasteReply);
384+ mClipboardState = SyncedClipboard;
385+ mPasteReply->deleteLater();
386+ mPasteReply = nullptr;
387+ emitChanged(QClipboard::Clipboard);
388+ });
389 }
390
391=== modified file 'src/ubuntumirclient/clipboard.h'
392--- src/ubuntumirclient/clipboard.h 2014-09-22 17:29:40 +0000
393+++ src/ubuntumirclient/clipboard.h 2016-08-24 12:43:18 +0000
394@@ -1,5 +1,5 @@
395 /*
396- * Copyright (C) 2014 Canonical, Ltd.
397+ * Copyright (C) 2014,2016 Canonical, Ltd.
398 *
399 * This program is free software: you can redistribute it and/or modify it under
400 * the terms of the GNU Lesser General Public License version 3, as published by
401@@ -21,7 +21,15 @@
402
403 #include <QMimeData>
404 #include <QPointer>
405-class QDBusInterface;
406+
407+namespace com {
408+ namespace ubuntu {
409+ namespace content {
410+ class Hub;
411+ }
412+ }
413+}
414+
415 class QDBusPendingCallWatcher;
416
417 class UbuntuClipboard : public QObject, public QPlatformClipboard
418@@ -37,31 +45,24 @@
419 bool supportsMode(QClipboard::Mode mode) const override;
420 bool ownsMode(QClipboard::Mode mode) const override;
421
422- void requestDBusClipboardContents();
423-
424 private Q_SLOTS:
425- void onDBusClipboardGetContentsFinished(QDBusPendingCallWatcher*);
426- void onDBusClipboardSetContentsFinished(QDBusPendingCallWatcher*);
427- void updateMimeData(const QByteArray &serializedMimeData);
428+ void onApplicationStateChanged(Qt::ApplicationState state);
429
430 private:
431- void setupDBus();
432-
433- QByteArray serializeMimeData(QMimeData *mimeData) const;
434- QMimeData *deserializeMimeData(const QByteArray &serializedMimeData) const;
435-
436- void setDBusClipboardContents(const QByteArray &clipboardContents);
437+ void updateMimeData();
438+ void requestMimeData();
439
440 QMimeData *mMimeData;
441- bool mIsOutdated;
442-
443- QPointer<QDBusInterface> mDBusClipboard;
444-
445- QPointer<QDBusPendingCallWatcher> mPendingGetContentsCall;
446- QPointer<QDBusPendingCallWatcher> mPendingSetContentsCall;
447-
448- bool mUpdatesDisabled;
449- bool mDBusSetupDone;
450+
451+ enum {
452+ OutdatedClipboard, // Our mimeData is outdated, need to fetch latest from ContentHub
453+ SyncingClipboard, // Our mimeData is outdated and we are waiting for ContentHub to reply with the latest paste
454+ SyncedClipboard // Our mimeData is in sync with what ContentHub has
455+ } mClipboardState{OutdatedClipboard};
456+
457+ com::ubuntu::content::Hub *mContentHub;
458+
459+ QDBusPendingCallWatcher *mPasteReply{nullptr};
460 };
461
462 #endif // UBUNTU_CLIPBOARD_H
463
464=== modified file 'src/ubuntumirclient/input.cpp'
465--- src/ubuntumirclient/input.cpp 2016-08-09 23:00:49 +0000
466+++ src/ubuntumirclient/input.cpp 2016-08-24 12:43:18 +0000
467@@ -610,7 +610,6 @@
468 // so that we don't deactivate windows prematurely.
469 if (focused) {
470 mPendingFocusGainedEvents--;
471- window->handleSurfaceFocused();
472 QWindowSystemInterface::handleWindowActivated(window->window(), Qt::ActiveWindowFocusReason);
473
474 // NB: Since processing of system events is queued, never check qGuiApp->applicationState()
475
476=== modified file 'src/ubuntumirclient/integration.cpp'
477--- src/ubuntumirclient/integration.cpp 2016-06-22 17:07:57 +0000
478+++ src/ubuntumirclient/integration.cpp 2016-08-24 12:43:18 +0000
479@@ -74,7 +74,6 @@
480 , mNativeInterface(new UbuntuNativeInterface(this))
481 , mFontDb(new QGenericUnixFontDatabase)
482 , mServices(new UbuntuPlatformServices)
483- , mClipboard(new UbuntuClipboard)
484 , mScaleFactor(1.0)
485 {
486 {
487@@ -211,7 +210,7 @@
488
489 QPlatformWindow* UbuntuClientIntegration::createPlatformWindow(QWindow* window) const
490 {
491- return new UbuntuWindow(window, mClipboard, mInput, mNativeInterface, mEglDisplay, mMirConnection);
492+ return new UbuntuWindow(window, mInput, mNativeInterface, mEglDisplay, mMirConnection);
493 }
494
495 bool UbuntuClientIntegration::hasCapability(QPlatformIntegration::Capability cap) const
496@@ -305,7 +304,11 @@
497
498 QPlatformClipboard* UbuntuClientIntegration::clipboard() const
499 {
500- return mClipboard.data();
501+ static QPlatformClipboard *clipboard = nullptr;
502+ if (!clipboard) {
503+ clipboard = new UbuntuClipboard;
504+ }
505+ return clipboard;
506 }
507
508 QPlatformNativeInterface* UbuntuClientIntegration::nativeInterface() const
509
510=== modified file 'src/ubuntumirclient/integration.h'
511--- src/ubuntumirclient/integration.h 2016-06-22 12:30:09 +0000
512+++ src/ubuntumirclient/integration.h 2016-08-24 12:43:18 +0000
513@@ -29,7 +29,6 @@
514
515 #include <EGL/egl.h>
516
517-class UbuntuClipboard;
518 class UbuntuInput;
519 class UbuntuNativeInterface;
520 class UbuntuScreen;
521@@ -82,7 +81,6 @@
522
523 UbuntuInput* mInput;
524 QPlatformInputContext* mInputContext;
525- QSharedPointer<UbuntuClipboard> mClipboard;
526 QScopedPointer<UbuntuScreenObserver> mScreenObserver;
527 qreal mScaleFactor;
528
529
530=== modified file 'src/ubuntumirclient/ubuntumirclient.pro'
531--- src/ubuntumirclient/ubuntumirclient.pro 2016-05-30 17:14:14 +0000
532+++ src/ubuntumirclient/ubuntumirclient.pro 2016-08-24 12:43:18 +0000
533@@ -12,7 +12,7 @@
534 QMAKE_LFLAGS += -std=c++11 -Wl,-no-undefined
535
536 CONFIG += link_pkgconfig
537-PKGCONFIG += egl mirclient ubuntu-platform-api xkbcommon
538+PKGCONFIG += egl mirclient ubuntu-platform-api xkbcommon libcontent-hub
539
540 SOURCES = \
541 backingstore.cpp \
542
543=== modified file 'src/ubuntumirclient/window.cpp'
544--- src/ubuntumirclient/window.cpp 2016-08-09 23:00:32 +0000
545+++ src/ubuntumirclient/window.cpp 2016-08-24 12:43:18 +0000
546@@ -16,7 +16,6 @@
547
548 // Local
549 #include "window.h"
550-#include "clipboard.h"
551 #include "nativeinterface.h"
552 #include "input.h"
553 #include "screen.h"
554@@ -401,6 +400,8 @@
555
556 bool mNeedsExposeCatchup;
557
558+ QString persistentSurfaceId();
559+
560 private:
561 static void surfaceEventCallback(MirSurface* surface, const MirEvent *event, void* context);
562 void postEvent(const MirEvent *event);
563@@ -422,6 +423,7 @@
564 QMutex mTargetSizeMutex;
565 QSize mTargetSize;
566 MirShellChrome mShellChrome;
567+ QString mPersistentIdStr;
568 };
569
570 void UbuntuSurface::resize(const QSize& size)
571@@ -575,12 +577,21 @@
572 mir_surface_apply_spec(mMirSurface, spec.get());
573 }
574
575-UbuntuWindow::UbuntuWindow(QWindow *w, const QSharedPointer<UbuntuClipboard> &clipboard,
576- UbuntuInput *input, UbuntuNativeInterface *native, EGLDisplay eglDisplay, MirConnection *mirConnection)
577+QString UbuntuSurface::persistentSurfaceId()
578+{
579+ if (mPersistentIdStr.isEmpty()) {
580+ MirPersistentId* mirPermaId = mir_surface_request_persistent_id_sync(mMirSurface);
581+ mPersistentIdStr = mir_persistent_id_as_string(mirPermaId);
582+ mir_persistent_id_release(mirPermaId);
583+ }
584+ return mPersistentIdStr;
585+}
586+
587+UbuntuWindow::UbuntuWindow(QWindow *w, UbuntuInput *input, UbuntuNativeInterface *native,
588+ EGLDisplay eglDisplay, MirConnection *mirConnection)
589 : QObject(nullptr)
590 , QPlatformWindow(w)
591 , mId(makeId())
592- , mClipboard(clipboard)
593 , mWindowState(w->windowState())
594 , mWindowFlags(w->flags())
595 , mWindowVisible(false)
596@@ -639,13 +650,6 @@
597 {
598 qCDebug(ubuntumirclient, "handleSurfaceFocused(window=%p)", window());
599
600- // System clipboard contents might have changed while this window was unfocused and without
601- // this process getting notified about it because it might have been suspended (due to
602- // application lifecycle policies), thus unable to listen to any changes notified through
603- // D-Bus.
604- // Therefore let's ensure we are up to date with the system clipboard now that we are getting
605- // focused again.
606- mClipboard->requestDBusClipboardContents();
607 }
608
609 void UbuntuWindow::handleSurfaceVisibilityChanged(bool visible)
610@@ -840,3 +844,8 @@
611 updatePanelHeightHack(newState != mir_surface_state_fullscreen);
612 }
613 }
614+
615+QString UbuntuWindow::persistentSurfaceId()
616+{
617+ return mSurface->persistentSurfaceId();
618+}
619
620=== modified file 'src/ubuntumirclient/window.h'
621--- src/ubuntumirclient/window.h 2016-06-22 12:30:09 +0000
622+++ src/ubuntumirclient/window.h 2016-08-24 12:43:18 +0000
623@@ -27,7 +27,6 @@
624
625 #include <EGL/egl.h>
626
627-class UbuntuClipboard;
628 class UbuntuNativeInterface;
629 class UbuntuInput;
630 class UbuntuScreen;
631@@ -39,8 +38,7 @@
632 {
633 Q_OBJECT
634 public:
635- UbuntuWindow(QWindow *w, const QSharedPointer<UbuntuClipboard> &clipboard,
636- UbuntuInput *input, UbuntuNativeInterface* native, EGLDisplay eglDisplay,
637+ UbuntuWindow(QWindow *w, UbuntuInput *input, UbuntuNativeInterface* native, EGLDisplay eglDisplay,
638 MirConnection *mirConnection);
639 virtual ~UbuntuWindow();
640
641@@ -70,13 +68,13 @@
642 void handleSurfaceStateChanged(Qt::WindowState state);
643 void onSwapBuffersDone();
644 void handleScreenPropertiesChange(MirFormFactor formFactor, float scale);
645+ QString persistentSurfaceId();
646
647 private:
648 void updatePanelHeightHack(bool enable);
649 void updateSurfaceState();
650 mutable QMutex mMutex;
651 const WId mId;
652- const QSharedPointer<UbuntuClipboard> mClipboard;
653 Qt::WindowState mWindowState;
654 Qt::WindowFlags mWindowFlags;
655 bool mWindowVisible;

Subscribers

People subscribed via source and target branches