Merge lp:~dandrader/qtubuntu/dbusClipboard into lp:qtubuntu

Proposed by Daniel d'Andrada
Status: Merged
Approved by: Robert Carr
Approved revision: 244
Merged at revision: 247
Proposed branch: lp:~dandrader/qtubuntu/dbusClipboard
Merge into: lp:qtubuntu
Diff against target: 580 lines (+282/-84)
8 files modified
src/ubuntumirclient/clipboard.cpp (+219/-73)
src/ubuntumirclient/clipboard.h (+31/-2)
src/ubuntumirclient/input.cpp (+3/-1)
src/ubuntumirclient/integration.cpp (+6/-2)
src/ubuntumirclient/integration.h (+4/-2)
src/ubuntumirclient/ubuntumirclient.pro (+1/-1)
src/ubuntumirclient/window.cpp (+15/-2)
src/ubuntumirclient/window.h (+3/-1)
To merge this branch: bzr merge lp:~dandrader/qtubuntu/dbusClipboard
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Robert Carr (community) Approve
Review via email: mp+235502@code.launchpad.net

Commit message

Use the global clipboard from D-Bus

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Robert Carr (robertcarr) wrote :

Why the commenting of debug statements at 412? Beyond that seems ok. The assert in serialization is less concerning on the client side than the server side.

review: Approve
Revision history for this message
Daniel d'Andrada (dandrader) wrote :

> Why the commenting of debug statements at 412?

Because they're ridiculously verbose. A simple swipe produces dozens of lines. So I think it's better for them to be an opt-in thing that you manually enable when you're debugging events. But yeah, not directly related to the objective of that MP.

lp:~dandrader/qtubuntu/dbusClipboard updated
244. By Daniel d'Andrada

Implement contents size limitation on the global clipboard

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Robert Carr (robertcarr) wrote :

thanks for applying fixes from other branch!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/ubuntumirclient/clipboard.cpp'
2--- src/ubuntumirclient/clipboard.cpp 2014-06-18 23:10:00 +0000
3+++ src/ubuntumirclient/clipboard.cpp 2014-09-23 11:49:39 +0000
4@@ -18,9 +18,9 @@
5
6 #include <QtCore/QMimeData>
7 #include <QtCore/QStringList>
8-
9-// Platform API
10-#include <ubuntu/application/ui/clipboard.h>
11+#include <QDBusInterface>
12+#include <QDBusPendingCallWatcher>
13+#include <QDBusPendingReply>
14
15 // FIXME(loicm) The clipboard data format is not defined by Ubuntu Platform API
16 // which makes it impossible to have non-Qt applications communicate with Qt
17@@ -29,19 +29,26 @@
18 // embedding different mime types in the clipboard.
19
20 // Data format:
21-// number of mime types (4 bytes)
22-// data layout (16 bytes * number of mime types)
23-// mime type string offset (4 bytes)
24-// mime type string size (4 bytes)
25-// data offset (4 bytes)
26-// data size (4 bytes)
27+// number of mime types (sizeof(int))
28+// data layout ((4 * sizeof(int)) * number of mime types)
29+// mime type string offset (sizeof(int))
30+// mime type string size (sizeof(int))
31+// data offset (sizeof(int))
32+// data size (sizeof(int))
33 // data (n bytes)
34
35+namespace {
36+
37 const int maxFormatsCount = 16;
38 const int maxBufferSize = 4 * 1024 * 1024; // 4 Mb
39
40+}
41+
42 UbuntuClipboard::UbuntuClipboard()
43 : mMimeData(new QMimeData)
44+ , mIsOutdated(true)
45+ , mUpdatesDisabled(false)
46+ , mDBusSetupDone(false)
47 {
48 }
49
50@@ -50,80 +57,200 @@
51 delete mMimeData;
52 }
53
54+void UbuntuClipboard::requestDBusClipboardContents()
55+{
56+ if (!mDBusSetupDone) {
57+ setupDBus();
58+ }
59+
60+ if (!mPendingGetContentsCall.isNull())
61+ return;
62+
63+ QDBusPendingCall pendingCall = mDBusClipboard->asyncCall("GetContents");
64+
65+ mPendingGetContentsCall = new QDBusPendingCallWatcher(pendingCall, this);
66+
67+ QObject::connect(mPendingGetContentsCall.data(), SIGNAL(finished(QDBusPendingCallWatcher*)),
68+ this, SLOT(onDBusClipboardGetContentsFinished(QDBusPendingCallWatcher*)));
69+}
70+
71+void UbuntuClipboard::onDBusClipboardGetContentsFinished(QDBusPendingCallWatcher* call)
72+{
73+ Q_ASSERT(call == mPendingGetContentsCall.data());
74+
75+ QDBusPendingReply<QByteArray> reply = *call;
76+ if (reply.isError()) {
77+ qCritical("UbuntuClipboard - Failed to get system clipboard contents via D-Bus. %s, %s",
78+ qPrintable(reply.error().name()), qPrintable(reply.error().message()));
79+ // TODO: Might try again later a number of times...
80+ } else {
81+ QByteArray serializedMimeData = reply.argumentAt<0>();
82+ updateMimeData(serializedMimeData);
83+ }
84+ call->deleteLater();
85+}
86+
87+void UbuntuClipboard::onDBusClipboardSetContentsFinished(QDBusPendingCallWatcher *call)
88+{
89+ QDBusPendingReply<void> reply = *call;
90+ if (reply.isError()) {
91+ qCritical("UbuntuClipboard - Failed to set the system clipboard contents via D-Bus. %s, %s",
92+ qPrintable(reply.error().name()), qPrintable(reply.error().message()));
93+ // TODO: Might try again later a number of times...
94+ }
95+ call->deleteLater();
96+}
97+
98+void UbuntuClipboard::updateMimeData(const QByteArray &serializedMimeData)
99+{
100+ if (mUpdatesDisabled)
101+ return;
102+
103+ QMimeData *newMimeData = deserializeMimeData(serializedMimeData);
104+ if (newMimeData) {
105+ delete mMimeData;
106+ mMimeData = newMimeData;
107+ mIsOutdated = false;
108+ emitChanged(QClipboard::Clipboard);
109+ } else {
110+ qWarning("UbuntuClipboard - Got invalid serialized mime data. Ignoring it.");
111+ }
112+}
113+
114+void UbuntuClipboard::setupDBus()
115+{
116+ QDBusConnection dbusConnection = QDBusConnection::sessionBus();
117+
118+ bool ok = dbusConnection.connect(
119+ "com.canonical.QtMir",
120+ "/com/canonical/QtMir/Clipboard",
121+ "com.canonical.QtMir.Clipboard",
122+ "ContentsChanged",
123+ this, SLOT(updateMimeData(QByteArray)));
124+ if (!ok) {
125+ qCritical("UbuntuClipboard - Failed to connect to ContentsChanged signal form the D-Bus system clipboard.");
126+ }
127+
128+ mDBusClipboard = new QDBusInterface("com.canonical.QtMir",
129+ "/com/canonical/QtMir/Clipboard",
130+ "com.canonical.QtMir.Clipboard",
131+ dbusConnection);
132+
133+ mDBusSetupDone = true;
134+}
135+
136+QByteArray UbuntuClipboard::serializeMimeData(QMimeData *mimeData) const
137+{
138+ const QStringList formats = mimeData->formats();
139+ const int formatCount = qMin(formats.size(), maxFormatsCount);
140+ const int headerSize = sizeof(int) + (formatCount * 4 * sizeof(int));
141+ int bufferSize = headerSize;
142+
143+ for (int i = 0; i < formatCount; i++)
144+ bufferSize += formats[i].size() + mimeData->data(formats[i]).size();
145+
146+ QByteArray serializedMimeData;
147+ if (bufferSize <= maxBufferSize) {
148+ // Serialize data.
149+ serializedMimeData.resize(bufferSize);
150+ {
151+ char *buffer = serializedMimeData.data();
152+ int* header = reinterpret_cast<int*>(serializedMimeData.data());
153+ int offset = headerSize;
154+ header[0] = formatCount;
155+ for (int i = 0; i < formatCount; i++) {
156+ const int formatOffset = offset;
157+ const int formatSize = formats[i].size();
158+ const int dataOffset = offset + formatSize;
159+ const int dataSize = mimeData->data(formats[i]).size();
160+ memcpy(&buffer[formatOffset], formats[i].toLatin1().data(), formatSize);
161+ memcpy(&buffer[dataOffset], mimeData->data(formats[i]).data(), dataSize);
162+ header[i*4+1] = formatOffset;
163+ header[i*4+2] = formatSize;
164+ header[i*4+3] = dataOffset;
165+ header[i*4+4] = dataSize;
166+ offset += formatSize + dataSize;
167+ }
168+ }
169+ } else {
170+ qWarning("UbuntuClipboard: Not sending contents (%d bytes) to the global clipboard as it's"
171+ " bigger than the maximum allowed size of %d bytes", bufferSize, maxBufferSize);
172+ }
173+
174+ return serializedMimeData;
175+}
176+
177+QMimeData *UbuntuClipboard::deserializeMimeData(const QByteArray &serializedMimeData) const
178+{
179+ if (static_cast<std::size_t>(serializedMimeData.size()) < sizeof(int)) {
180+ // Data is invalid
181+ return nullptr;
182+ }
183+
184+ QMimeData *mimeData = new QMimeData;
185+
186+ const char* const buffer = serializedMimeData.constData();
187+ const int* const header = reinterpret_cast<const int*>(serializedMimeData.constData());
188+
189+ const int count = qMin(header[0], maxFormatsCount);
190+
191+ for (int i = 0; i < count; i++) {
192+ const int formatOffset = header[i*4+1];
193+ const int formatSize = header[i*4+2];
194+ const int dataOffset = header[i*4+3];
195+ const int dataSize = header[i*4+4];
196+
197+ if (formatOffset + formatSize <= serializedMimeData.size()
198+ && dataOffset + dataSize <= serializedMimeData.size()) {
199+
200+ QString mimeType = QString::fromLatin1(&buffer[formatOffset], formatSize);
201+ QByteArray mimeDataBytes(&buffer[dataOffset], dataSize);
202+
203+ mimeData->setData(mimeType, mimeDataBytes);
204+ }
205+ }
206+
207+ return mimeData;
208+}
209+
210 QMimeData* UbuntuClipboard::mimeData(QClipboard::Mode mode)
211 {
212- Q_UNUSED(mode);
213- // Get clipboard data.
214- void* data = NULL;
215- size_t size = 0;
216- ua_ui_get_clipboard_content(&data, &size);
217+ if (mode != QClipboard::Clipboard)
218+ return nullptr;
219
220- // Deserialize, update and return mime data taking care of incorrectly
221- // formatted input.
222- mMimeData->clear();
223- if (static_cast<size_t>(size) > sizeof(int) // Should be at least that big to read the count.
224- && data != NULL) {
225- const char* const buffer = reinterpret_cast<char*>(data);
226- const int* const header = reinterpret_cast<int*>(data);
227- const int count = qMin(header[0], maxFormatsCount);
228- for (int i = 0; i < count; i++) {
229- const unsigned int formatOffset = header[i*4+1];
230- const unsigned int formatSize = header[i*4+2];
231- const unsigned int dataOffset = header[i*4+3];
232- const unsigned int dataSize = header[i*4+4];
233- if (formatOffset + formatSize <= size && dataOffset + dataSize <= size) {
234- mMimeData->setData(QString(&buffer[formatOffset]),
235- QByteArray(&buffer[dataOffset], dataSize));
236- }
237- }
238+ if (mIsOutdated && mPendingGetContentsCall.isNull()) {
239+ requestDBusClipboardContents();
240 }
241+
242+ // Return whatever we have at the moment instead of blocking until we have something.
243+ //
244+ // This might be called during app startup just for the sake of checking if some
245+ // "Paste" UI control should be enabled or not.
246+ // We will emit QClipboard::changed() once we finally have something.
247 return mMimeData;
248 }
249
250 void UbuntuClipboard::setMimeData(QMimeData* mimeData, QClipboard::Mode mode)
251 {
252- Q_UNUSED(mode);
253- if (mimeData == NULL) {
254- ua_ui_set_clipboard_content(NULL, 0);
255+ if (mode != QClipboard::Clipboard)
256 return;
257- }
258-
259- const QStringList formats = mimeData->formats();
260- const int count = qMin(formats.size(), maxFormatsCount);
261- const int headerSize = sizeof(int) + count * 4 * sizeof(int);
262- int bufferSize = headerSize;
263- char* buffer;
264-
265- // Get the buffer size considering the header size, the NULL-terminated
266- // formats and the non NULL-terminated data.
267- for (int i = 0; i < count; i++)
268- bufferSize += formats[i].size() + 1 + mimeData->data(formats[i]).size();
269- // FIXME(loicm) Implement max buffer size limitation.
270- // FIXME(loicm) Remove ASSERT before release.
271- Q_ASSERT(bufferSize <= maxBufferSize);
272-
273- // Serialize data.
274- buffer = new char[bufferSize];
275- int* header = reinterpret_cast<int*>(buffer);
276- int offset = headerSize;
277- header[0] = count;
278- for (int i = 0; i < count; i++) {
279- const int formatOffset = offset;
280- const int formatSize = formats[i].size() + 1;
281- const int dataOffset = offset + formatSize;
282- const int dataSize = mimeData->data(formats[i]).size();
283- memcpy(&buffer[formatOffset], formats[i].toLatin1().data(), formatSize);
284- memcpy(&buffer[dataOffset], mimeData->data(formats[i]).data(), dataSize);
285- header[i*4+1] = formatOffset;
286- header[i*4+2] = formatSize;
287- header[i*4+3] = dataOffset;
288- header[i*4+4] = dataSize;
289- offset += formatSize + dataSize;
290- }
291-
292- // Set clipboard content.
293- ua_ui_set_clipboard_content(reinterpret_cast<void*>(buffer), bufferSize);
294- delete [] buffer;
295+
296+ if (!mPendingGetContentsCall.isNull()) {
297+ // Ignore whatever comes from the system clipboard as we are going to change it anyway
298+ QObject::disconnect(mPendingGetContentsCall.data(), 0, this, 0);
299+ mUpdatesDisabled = true;
300+ mPendingGetContentsCall->waitForFinished();
301+ mUpdatesDisabled = false;
302+ delete mPendingGetContentsCall.data();
303+ }
304+
305+ QByteArray serializedMimeData = serializeMimeData(mimeData);
306+ if (!serializedMimeData.isEmpty()) {
307+ setDBusClipboardContents(serializedMimeData);
308+ }
309+
310+ mMimeData = mimeData;
311+ emitChanged(QClipboard::Clipboard);
312 }
313
314 bool UbuntuClipboard::supportsMode(QClipboard::Mode mode) const
315@@ -136,3 +263,22 @@
316 Q_UNUSED(mode);
317 return false;
318 }
319+
320+void UbuntuClipboard::setDBusClipboardContents(const QByteArray &clipboardContents)
321+{
322+ if (!mPendingSetContentsCall.isNull()) {
323+ // Ignore any previous set call as we are going to overwrite it anyway
324+ QObject::disconnect(mPendingSetContentsCall.data(), 0, this, 0);
325+ mUpdatesDisabled = true;
326+ mPendingSetContentsCall->waitForFinished();
327+ mUpdatesDisabled = false;
328+ delete mPendingSetContentsCall.data();
329+ }
330+
331+ QDBusPendingCall pendingCall = mDBusClipboard->asyncCall("SetContents", clipboardContents);
332+
333+ mPendingSetContentsCall = new QDBusPendingCallWatcher(pendingCall, this);
334+
335+ QObject::connect(mPendingSetContentsCall.data(), SIGNAL(finished(QDBusPendingCallWatcher*)),
336+ this, SLOT(onDBusClipboardSetContentsFinished(QDBusPendingCallWatcher*)));
337+}
338
339=== modified file 'src/ubuntumirclient/clipboard.h'
340--- src/ubuntumirclient/clipboard.h 2014-06-18 23:10:00 +0000
341+++ src/ubuntumirclient/clipboard.h 2014-09-23 11:49:39 +0000
342@@ -19,8 +19,14 @@
343
344 #include <qpa/qplatformclipboard.h>
345
346-class UbuntuClipboard : public QPlatformClipboard
347+#include <QMimeData>
348+#include <QPointer>
349+class QDBusInterface;
350+class QDBusPendingCallWatcher;
351+
352+class UbuntuClipboard : public QObject, public QPlatformClipboard
353 {
354+ Q_OBJECT
355 public:
356 UbuntuClipboard();
357 virtual ~UbuntuClipboard();
358@@ -31,8 +37,31 @@
359 bool supportsMode(QClipboard::Mode mode) const override;
360 bool ownsMode(QClipboard::Mode mode) const override;
361
362+ void requestDBusClipboardContents();
363+
364+private Q_SLOTS:
365+ void onDBusClipboardGetContentsFinished(QDBusPendingCallWatcher*);
366+ void onDBusClipboardSetContentsFinished(QDBusPendingCallWatcher*);
367+ void updateMimeData(const QByteArray &serializedMimeData);
368+
369 private:
370- QMimeData* mMimeData;
371+ void setupDBus();
372+
373+ QByteArray serializeMimeData(QMimeData *mimeData) const;
374+ QMimeData *deserializeMimeData(const QByteArray &serializedMimeData) const;
375+
376+ void setDBusClipboardContents(const QByteArray &clipboardContents);
377+
378+ QMimeData *mMimeData;
379+ bool mIsOutdated;
380+
381+ QPointer<QDBusInterface> mDBusClipboard;
382+
383+ QPointer<QDBusPendingCallWatcher> mPendingGetContentsCall;
384+ QPointer<QDBusPendingCallWatcher> mPendingSetContentsCall;
385+
386+ bool mUpdatesDisabled;
387+ bool mDBusSetupDone;
388 };
389
390 #endif // UBUNTU_CLIPBOARD_H
391
392=== modified file 'src/ubuntumirclient/input.cpp'
393--- src/ubuntumirclient/input.cpp 2014-08-14 09:45:04 +0000
394+++ src/ubuntumirclient/input.cpp 2014-09-23 11:49:39 +0000
395@@ -160,6 +160,7 @@
396 }
397
398 #ifndef QT_NO_DEBUG
399+/*
400 static const char* nativeEventTypeToStr(int eventType)
401 {
402 switch (eventType) {
403@@ -178,6 +179,7 @@
404 return "INVALID!";
405 }
406 }
407+*/
408 #endif
409
410 void UbuntuInput::customEvent(QEvent* event)
411@@ -199,7 +201,7 @@
412 return;
413 }
414
415- DLOG("UbuntuInput::customEvent(type=%s)", nativeEventTypeToStr(nativeEvent->type));
416+ //DLOG("UbuntuInput::customEvent(type=%s)", nativeEventTypeToStr(nativeEvent->type));
417
418 // Event dispatching.
419 switch (nativeEvent->type) {
420
421=== modified file 'src/ubuntumirclient/integration.cpp'
422--- src/ubuntumirclient/integration.cpp 2014-08-05 16:02:48 +0000
423+++ src/ubuntumirclient/integration.cpp 2014-09-23 11:49:39 +0000
424@@ -108,7 +108,6 @@
425
426 UbuntuClientIntegration::~UbuntuClientIntegration()
427 {
428- delete mClipboard;
429 delete mInput;
430 delete mInputContext;
431 delete mScreen;
432@@ -157,7 +156,7 @@
433 QPlatformWindow* UbuntuClientIntegration::createPlatformWindow(QWindow* window)
434 {
435 QPlatformWindow* platformWindow = new UbuntuWindow(
436- window, static_cast<UbuntuScreen*>(mScreen), mInput, mInstance);
437+ window, mClipboard, static_cast<UbuntuScreen*>(mScreen), mInput, mInstance);
438 platformWindow->requestActivateWindow();
439 return platformWindow;
440 }
441@@ -233,3 +232,8 @@
442 }
443 return QPlatformIntegration::styleHint(hint);
444 }
445+
446+QPlatformClipboard* UbuntuClientIntegration::clipboard() const
447+{
448+ return mClipboard.data();
449+}
450
451=== modified file 'src/ubuntumirclient/integration.h'
452--- src/ubuntumirclient/integration.h 2014-08-05 16:02:48 +0000
453+++ src/ubuntumirclient/integration.h 2014-09-23 11:49:39 +0000
454@@ -18,6 +18,7 @@
455 #define UBUNTU_CLIENT_INTEGRATION_H
456
457 #include <qpa/qplatformintegration.h>
458+#include <QSharedPointer>
459
460 #include "platformservices.h"
461
462@@ -27,6 +28,7 @@
463 #include <ubuntu/application/ui/options.h>
464 #include <ubuntu/application/ui/session.h>
465
466+class UbuntuClipboard;
467 class UbuntuInput;
468 class UbuntuScreen;
469
470@@ -48,7 +50,7 @@
471 QPlatformServices *services() const override;
472 QPlatformWindow* createPlatformWindow(QWindow* window) const override;
473 QPlatformInputContext* inputContext() const override { return mInputContext; }
474- QPlatformClipboard* clipboard() const override { return mClipboard; }
475+ QPlatformClipboard* clipboard() const override;
476
477 QPlatformOpenGLContext* createPlatformOpenGLContext(QOpenGLContext* context);
478 QPlatformWindow* createPlatformWindow(QWindow* window);
479@@ -66,7 +68,7 @@
480 UbuntuScreen* mScreen;
481 UbuntuInput* mInput;
482 QPlatformInputContext* mInputContext;
483- QPlatformClipboard* mClipboard;
484+ QSharedPointer<UbuntuClipboard> mClipboard;
485 qreal mScaleFactor;
486
487 // Platform API stuff
488
489=== modified file 'src/ubuntumirclient/ubuntumirclient.pro'
490--- src/ubuntumirclient/ubuntumirclient.pro 2014-08-14 13:18:24 +0000
491+++ src/ubuntumirclient/ubuntumirclient.pro 2014-09-23 11:49:39 +0000
492@@ -2,7 +2,7 @@
493 TEMPLATE = lib
494
495 QT -= gui
496-QT += core-private gui-private platformsupport-private sensors
497+QT += core-private gui-private platformsupport-private sensors dbus
498
499 CONFIG += plugin no_keywords qpa/genericunixfontdatabase
500
501
502=== modified file 'src/ubuntumirclient/window.cpp'
503--- src/ubuntumirclient/window.cpp 2014-08-08 14:04:13 +0000
504+++ src/ubuntumirclient/window.cpp 2014-09-23 11:49:39 +0000
505@@ -15,6 +15,7 @@
506 */
507
508 // Local
509+#include "clipboard.h"
510 #include "input.h"
511 #include "window.h"
512 #include "screen.h"
513@@ -55,17 +56,17 @@
514 QSize bufferSize;
515 QSize targetBufferSize;
516 QMutex mutex;
517+ QSharedPointer<UbuntuClipboard> clipboard;
518 };
519
520 static void eventCallback(void* context, const WindowEvent* event)
521 {
522- DLOG("eventCallback (context=%p, event=%p)", context, event);
523 DASSERT(context != NULL);
524 UbuntuWindow* platformWindow = static_cast<UbuntuWindow*>(context);
525 platformWindow->priv()->input->postEvent(platformWindow, event);
526 }
527
528-UbuntuWindow::UbuntuWindow(QWindow* w, UbuntuScreen* screen,
529+UbuntuWindow::UbuntuWindow(QWindow* w, QSharedPointer<UbuntuClipboard> clipboard, UbuntuScreen* screen,
530 UbuntuInput* input, UApplicationInstance* instance)
531 : QObject(nullptr), QPlatformWindow(w)
532 {
533@@ -77,6 +78,7 @@
534 d->input = input;
535 d->state = window()->windowState();
536 d->uaInstance = instance;
537+ d->clipboard = clipboard;
538
539 static int id = 1;
540 d->id = id++;
541@@ -265,6 +267,17 @@
542 {
543 LOG("UbuntuWindow::handleSurfaceFocusChange(focused=%s)", focused ? "true" : "false");
544 QWindow *activatedWindow = focused ? window() : nullptr;
545+
546+ // System clipboard contents might have changed while this window was unfocused and wihtout
547+ // this process getting notified about it because it might have been suspended (due to
548+ // application lifecycle policies), thus unable to listen to any changes notified through
549+ // D-Bus.
550+ // Therefore let's ensure we are up to date with the system clipboard now that we are getting
551+ // focused again.
552+ if (focused) {
553+ d->clipboard->requestDBusClipboardContents();
554+ }
555+
556 QWindowSystemInterface::handleWindowActivated(activatedWindow, Qt::ActiveWindowFocusReason);
557 }
558
559
560=== modified file 'src/ubuntumirclient/window.h'
561--- src/ubuntumirclient/window.h 2014-08-08 12:05:21 +0000
562+++ src/ubuntumirclient/window.h 2014-09-23 11:49:39 +0000
563@@ -18,7 +18,9 @@
564 #define UBUNTU_WINDOW_H
565
566 #include <qpa/qplatformwindow.h>
567+#include <QSharedPointer>
568
569+class UbuntuClipboard;
570 class UbuntuInput;
571 class UbuntuScreen;
572 class UbuntuWindowPrivate;
573@@ -27,7 +29,7 @@
574 {
575 Q_OBJECT
576 public:
577- UbuntuWindow(QWindow* w, UbuntuScreen* screen,
578+ UbuntuWindow(QWindow* w, QSharedPointer<UbuntuClipboard> clipboard, UbuntuScreen* screen,
579 UbuntuInput* input, void* instance);
580 virtual ~UbuntuWindow();
581

Subscribers

People subscribed via source and target branches