Merge lp:~townsend/libertine/fix-focus-tracking into lp:libertine

Proposed by Christopher Townsend
Status: Merged
Approved by: Larry Price
Approved revision: 303
Merged at revision: 300
Proposed branch: lp:~townsend/libertine/fix-focus-tracking
Merge into: lp:libertine
Diff against target: 304 lines (+132/-63)
5 files modified
CMakeLists.txt (+0/-1)
debian/control (+0/-1)
pasted/CMakeLists.txt (+1/-1)
pasted/pasted.cpp (+111/-57)
pasted/pasted.h (+20/-3)
To merge this branch: bzr merge lp:~townsend/libertine/fix-focus-tracking
Reviewer Review Type Date Requested Status
Libertine CI Bot continuous-integration Approve
Larry Price Approve
Review via email: mp+305135@code.launchpad.net

Commit message

pasted: Switch to using an X event based model with a worker thread instead of the QTimer polling method. This avoids races and missed focus status.

To post a comment you must log in.
Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :

FAILED: Continuous integration, rev:300
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/120/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/libertine/job/build/332
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=default/265
    FAILURE: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=default/265/console
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=yakkety,testname=default/265
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=vivid+overlay,testname=default/265
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=xenial+overlay,testname=default/265
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=yakkety,testname=default/265
    None: https://jenkins.canonical.com/libertine/job/lp-generic-update-mp/252/console
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-0-fetch/334
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-1-sourcepkg/release=vivid+overlay/317
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-1-sourcepkg/release=xenial+overlay/317
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-1-sourcepkg/release=yakkety/317
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=vivid+overlay/316
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=vivid+overlay/316/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/316
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/316/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=yakkety/316
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=yakkety/316/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=vivid+overlay/316
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=vivid+overlay/316/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/316
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/316/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=yakkety/316
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=yakkety/316/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/120/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :

PASSED: Continuous integration, rev:300
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/121/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/libertine/job/build/333
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=default/266
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=default/266
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=yakkety,testname=default/266
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=vivid+overlay,testname=default/266
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=xenial+overlay,testname=default/266
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=yakkety,testname=default/266
    None: https://jenkins.canonical.com/libertine/job/lp-generic-update-mp/253/console
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-0-fetch/335
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-1-sourcepkg/release=vivid+overlay/318
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-1-sourcepkg/release=xenial+overlay/318
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-1-sourcepkg/release=yakkety/318
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=vivid+overlay/317
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=vivid+overlay/317/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/317
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/317/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=yakkety/317
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=yakkety/317/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=vivid+overlay/317
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=vivid+overlay/317/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/317
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/317/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=yakkety/317
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=yakkety/317/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/121/rebuild

review: Approve (continuous-integration)
Revision history for this message
Larry Price (larryprice) wrote :

few easy inlines - i'll try to verify that it still works in the morning

review: Needs Information
Revision history for this message
Christopher Townsend (townsend) wrote :

Thanks for reviewing. I addressed your question and will make some changes.

Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :

PASSED: Continuous integration, rev:301
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/124/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/libertine/job/build/338
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=default/271
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=default/271
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=yakkety,testname=default/271
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=vivid+overlay,testname=default/271
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=xenial+overlay,testname=default/271
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=yakkety,testname=default/271
    None: https://jenkins.canonical.com/libertine/job/lp-generic-update-mp/256/console
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-0-fetch/340
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-1-sourcepkg/release=vivid+overlay/323
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-1-sourcepkg/release=xenial+overlay/323
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-1-sourcepkg/release=yakkety/323
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=vivid+overlay/322
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=vivid+overlay/322/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/322
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/322/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=yakkety/322
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=yakkety/322/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=vivid+overlay/322
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=vivid+overlay/322/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/322
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/322/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=yakkety/322
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=yakkety/322/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/124/rebuild

review: Approve (continuous-integration)
Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :

PASSED: Continuous integration, rev:302
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/125/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/libertine/job/build/339
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=default/272
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=default/272
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=yakkety,testname=default/272
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=vivid+overlay,testname=default/272
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=xenial+overlay,testname=default/272
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=yakkety,testname=default/272
    None: https://jenkins.canonical.com/libertine/job/lp-generic-update-mp/257/console
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-0-fetch/341
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-1-sourcepkg/release=vivid+overlay/324
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-1-sourcepkg/release=xenial+overlay/324
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-1-sourcepkg/release=yakkety/324
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=vivid+overlay/323
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=vivid+overlay/323/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/323
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/323/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=yakkety/323
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=yakkety/323/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=vivid+overlay/323
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=vivid+overlay/323/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/323
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/323/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=yakkety/323
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=yakkety/323/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/125/rebuild

review: Approve (continuous-integration)
Revision history for this message
Larry Price (larryprice) wrote :

some inline suggestions. wrapping up an sbuild of the arm version now to test on frieza.

review: Needs Information
303. By Christopher Townsend

Changes and fixes based on feedback.

Revision history for this message
Larry Price (larryprice) wrote :

lgtm! very nice updates

review: Approve
Revision history for this message
Libertine CI Bot (libertine-ci-bot) wrote :

PASSED: Continuous integration, rev:303
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/126/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/libertine/job/build/340
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=default/273
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=default/273
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=amd64,release=yakkety,testname=default/273
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=vivid+overlay,testname=default/273
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=xenial+overlay,testname=default/273
    SUCCESS: https://jenkins.canonical.com/libertine/job/test-0-autopkgtest/label=i386,release=yakkety,testname=default/273
    None: https://jenkins.canonical.com/libertine/job/lp-generic-update-mp/258/console
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-0-fetch/342
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-1-sourcepkg/release=vivid+overlay/325
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-1-sourcepkg/release=xenial+overlay/325
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-1-sourcepkg/release=yakkety/325
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=vivid+overlay/324
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=vivid+overlay/324/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/324
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=xenial+overlay/324/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=yakkety/324
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=amd64,release=yakkety/324/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=vivid+overlay/324
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=vivid+overlay/324/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/324
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=xenial+overlay/324/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=yakkety/324
        deb: https://jenkins.canonical.com/libertine/job/build-2-binpkg/arch=i386,release=yakkety/324/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/libertine/job/lp-libertine-ci/126/rebuild

review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2016-09-06 12:36:47 +0000
+++ CMakeLists.txt 2016-09-08 18:47:27 +0000
@@ -20,7 +20,6 @@
20find_package(Qt5Gui REQUIRED)20find_package(Qt5Gui REQUIRED)
21find_package(Qt5Quick REQUIRED)21find_package(Qt5Quick REQUIRED)
22find_package(Qt5Widgets REQUIRED)22find_package(Qt5Widgets REQUIRED)
23find_package(Qt5X11Extras REQUIRED)
24find_package(Gettext REQUIRED)23find_package(Gettext REQUIRED)
25find_package(Intltool REQUIRED)24find_package(Intltool REQUIRED)
26find_package(X11 REQUIRED)25find_package(X11 REQUIRED)
2726
=== modified file 'debian/control'
--- debian/control 2016-09-06 12:36:47 +0000
+++ debian/control 2016-09-08 18:47:27 +0000
@@ -13,7 +13,6 @@
13 libgirepository1.0-dev,13 libgirepository1.0-dev,
14 libglib2.0-dev,14 libglib2.0-dev,
15 libgtest-dev,15 libgtest-dev,
16 libqt5x11extras5-dev,
17 libx11-dev,16 libx11-dev,
18 lsb-release,17 lsb-release,
19 python3-apt,18 python3-apt,
2019
=== modified file 'pasted/CMakeLists.txt'
--- pasted/CMakeLists.txt 2016-08-10 12:23:31 +0000
+++ pasted/CMakeLists.txt 2016-09-08 18:47:27 +0000
@@ -6,5 +6,5 @@
66
7qt5_use_modules(pasted DBus)7qt5_use_modules(pasted DBus)
88
9target_link_libraries(pasted Qt5::Core Qt5::Gui Qt5::Widgets Qt5::X11Extras content-hub X11)9target_link_libraries(pasted Qt5::Core Qt5::Gui Qt5::Widgets content-hub X11)
10install(TARGETS pasted RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})10install(TARGETS pasted RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
1111
=== modified file 'pasted/pasted.cpp'
--- pasted/pasted.cpp 2016-09-01 20:01:52 +0000
+++ pasted/pasted.cpp 2016-09-08 18:47:27 +0000
@@ -19,12 +19,102 @@
1919
20#include "pasted.h"20#include "pasted.h"
2121
22#include <QDBusInterface>
22#include <QDebug>23#include <QDebug>
24#include <QThread>
2325
24#include <QX11Info>
25#include <X11/Xatom.h>26#include <X11/Xatom.h>
2627
2728
29namespace
30{
31
32constexpr auto MIR_WM_PERSISTENT_ID = "_MIR_WM_PERSISTENT_ID";
33constexpr auto UNITY_FOCUSINFO_SERVICE = "com.canonical.Unity.FocusInfo";
34constexpr auto UNITY_FOCUSINFO_PATH = "/com/canonical/Unity/FocusInfo";
35constexpr auto UNITY_FOCUSINFO_INTERFACE = "com.canonical.Unity.FocusInfo";
36constexpr auto UNITY_FOCUSINFO_METHOD = "isSurfaceFocused";
37
38
39static QString getPersistentSurfaceId()
40{
41 Display *dpy = XOpenDisplay(NULL);
42 Atom prop = XInternAtom(dpy, MIR_WM_PERSISTENT_ID, 0),
43 type; // unused
44 int form, // unused
45 status;
46 unsigned long remain, // unused
47 len; // unused
48 unsigned char *data = nullptr;
49 QString persistentSurfaceId;
50
51 status = XGetWindowProperty(dpy, XDefaultRootWindow(dpy), prop, 0, 1024, 0,
52 XA_STRING, &type, &form, &len, &remain, &data);
53
54 if (status)
55 {
56 qDebug() << "Failure retrieving the persistentSurfaceID!";
57 }
58 else
59 {
60 persistentSurfaceId = (const char *)data;
61 }
62
63 XCloseDisplay(dpy);
64 XFree(data);
65
66 return persistentSurfaceId;
67}
68
69} //anonymous namespace
70
71
72void XEventWorker::
73checkForAppFocus()
74{
75 bool hasFocus = false;
76 XEvent event;
77
78 QDBusInterface *unityFocus = new QDBusInterface(UNITY_FOCUSINFO_SERVICE,
79 UNITY_FOCUSINFO_PATH,
80 UNITY_FOCUSINFO_INTERFACE,
81 QDBusConnection::sessionBus(),
82 this);
83
84 QString surfaceId = getPersistentSurfaceId();
85
86 QDBusReply<bool> isFocused = unityFocus->call(UNITY_FOCUSINFO_METHOD, surfaceId);
87
88 if (isFocused == true)
89 {
90 focusChanged();
91 hasFocus = true;
92 }
93
94 Display *dpy = XOpenDisplay(NULL);
95 XSelectInput(dpy, XDefaultRootWindow(dpy), FocusChangeMask);
96
97 while (1)
98 {
99 XNextEvent(dpy, &event);
100
101 isFocused = unityFocus->call(UNITY_FOCUSINFO_METHOD, surfaceId);
102
103 if (hasFocus == false && isFocused == true)
104 {
105 qDebug() << "Surface is focused";
106 focusChanged();
107 hasFocus = true;
108 }
109 else if (hasFocus == true && isFocused == false)
110 {
111 qDebug() << "Surface lost focus";
112 hasFocus = false;
113 }
114 }
115}
116
117
28Pasted::118Pasted::
29Pasted(int argc, char** argv)119Pasted(int argc, char** argv)
30: QApplication(argc, argv)120: QApplication(argc, argv)
@@ -32,15 +122,9 @@
32, content_hub_(cuc::Hub::Client::instance())122, content_hub_(cuc::Hub::Client::instance())
33, mimeDataX_(new QMimeData)123, mimeDataX_(new QMimeData)
34, lastMimeData_()124, lastMimeData_()
35, rootWindowHasFocus_(false)
36, firstSeenWindow_(None)
37{125{
38 setApplicationName("pasted");126 setApplicationName("pasted");
39127
40 QTimer *timer = new QTimer(this);
41 connect(timer, &QTimer::timeout, this, &Pasted::checkForAppFocus);
42 timer->start(400);
43
44 connect(clipboard_, &QClipboard::dataChanged, this, &Pasted::handleXClipboard);128 connect(clipboard_, &QClipboard::dataChanged, this, &Pasted::handleXClipboard);
45}129}
46130
@@ -81,36 +165,6 @@
81}165}
82166
83167
84void Pasted::
85checkForAppFocus()
86{
87 Window w;
88 int revert_to; // unused
89
90 XGetInputFocus(QX11Info::display(), &w, &revert_to);
91
92 if (firstSeenWindow_ == None && w != None)
93 {
94 firstSeenWindow_ = w;
95 }
96
97 if (w == None && rootWindowHasFocus_ == true)
98 {
99 qDebug() << "Xmir lost focus";
100 rootWindowHasFocus_ = false;
101 }
102 else if ((w == PointerRoot ||
103 (w && firstSeenWindow_ == PointerRoot))
104 && rootWindowHasFocus_ == false)
105 {
106 qDebug() << "Xmir gained focus";
107 rootWindowHasFocus_ = true;
108 setPersistentSurfaceId();
109 handleContentHubPasteboard();
110 }
111}
112
113
114bool Pasted::168bool Pasted::
115compareMimeData(const QMimeData *a, const QMimeData *b)169compareMimeData(const QMimeData *a, const QMimeData *b)
116{170{
@@ -180,29 +234,19 @@
180{234{
181 if (persistentSurfaceId_.isEmpty())235 if (persistentSurfaceId_.isEmpty())
182 {236 {
183 Atom prop = XInternAtom(QX11Info::display(), "_MIR_WM_PERSISTENT_ID", 0),237 persistentSurfaceId_ = getPersistentSurfaceId();
184 type; // unused
185 int form, // unused
186 status;
187 unsigned long remain, // unused
188 len; // unused
189 unsigned char *data;
190 status = XGetWindowProperty(QX11Info::display(), XDefaultRootWindow(QX11Info::display()), prop,
191 0, 1024, 0, XA_STRING, &type, &form, &len, &remain, &data);
192
193 if (status)
194 {
195 qDebug() << "Failure retrieving the persistentSurfaceID!";
196 }
197 else
198 {
199 qDebug() << "Setting persistentSurfaceId";
200 persistentSurfaceId_ = (const char *)data;
201 }
202 }238 }
203}239}
204240
205241
242void Pasted::
243appFocused()
244{
245 setPersistentSurfaceId();
246 handleContentHubPasteboard();
247}
248
249
206int250int
207main(int argc, char* argv[])251main(int argc, char* argv[])
208{252{
@@ -210,5 +254,15 @@
210254
211 Pasted pasted(argc, argv);255 Pasted pasted(argc, argv);
212256
213 pasted.exec();257 QThread t;
258 XEventWorker worker;
259
260 worker.moveToThread(&t);
261
262 QObject::connect(&worker, &XEventWorker::focusChanged, &pasted, &Pasted::appFocused);
263 QObject::connect(&t, &QThread::started, &worker, &XEventWorker::checkForAppFocus);
264
265 t.start();
266
267 return pasted.exec();
214}268}
215269
=== modified file 'pasted/pasted.h'
--- pasted/pasted.h 2016-08-29 15:33:05 +0000
+++ pasted/pasted.h 2016-09-08 18:47:27 +0000
@@ -33,6 +33,23 @@
33namespace cuc = com::ubuntu::content;33namespace cuc = com::ubuntu::content;
3434
3535
36class XEventWorker
37: public QObject
38{
39 Q_OBJECT
40
41 public:
42 XEventWorker() = default;
43 virtual ~XEventWorker() = default;
44
45 signals:
46 void focusChanged();
47
48 public slots:
49 void checkForAppFocus();
50};
51
52
36class Pasted53class Pasted
37: public QApplication54: public QApplication
38{55{
@@ -42,6 +59,9 @@
42 Pasted(int argc, char** argv);59 Pasted(int argc, char** argv);
43 virtual ~Pasted() = default;60 virtual ~Pasted() = default;
4461
62 public slots:
63 void appFocused();
64
45 private:65 private:
46 void updateLastMimeData(const QMimeData *source);66 void updateLastMimeData(const QMimeData *source);
47 void updateXMimeData(const QMimeData *source);67 void updateXMimeData(const QMimeData *source);
@@ -53,15 +73,12 @@
5373
54 private slots:74 private slots:
55 void handleXClipboard();75 void handleXClipboard();
56 void checkForAppFocus();
5776
58 private:77 private:
59 QClipboard *clipboard_;78 QClipboard *clipboard_;
60 cuc::Hub *content_hub_;79 cuc::Hub *content_hub_;
61 QMimeData *mimeDataX_;80 QMimeData *mimeDataX_;
62 std::unique_ptr<QMimeData> lastMimeData_;81 std::unique_ptr<QMimeData> lastMimeData_;
63 bool rootWindowHasFocus_;
64 Window firstSeenWindow_;
65 QString persistentSurfaceId_;82 QString persistentSurfaceId_;
66};83};
6784

Subscribers

People subscribed via source and target branches