Merge lp:~townsend/libertine/fix-pasted-xmir-rootless into lp:libertine
- fix-pasted-xmir-rootless
- Merge into devel
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Larry Price | ||||
Approved revision: | 441 | ||||
Merged at revision: | 444 | ||||
Proposed branch: | lp:~townsend/libertine/fix-pasted-xmir-rootless | ||||
Merge into: | lp:libertine | ||||
Diff against target: |
248 lines (+90/-53) 2 files modified
pasted/pasted.cpp (+77/-48) pasted/pasted.h (+13/-5) |
||||
To merge this branch: | bzr merge lp:~townsend/libertine/fix-pasted-xmir-rootless | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Libertine CI Bot | continuous-integration | Approve | |
Larry Price | Approve | ||
Review via email:
|
Commit message
Fix pasted to work with rootless Xmir.
Description of the change
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Libertine CI Bot (libertine-ci-bot) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:434
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Larry Price (larryprice) wrote : | # |
left some inline presents for you
- 435. By Christopher Townsend
-
Some cleanup based on review.
- 436. By Christopher Townsend
-
Merge lp:libertine.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:436
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
- 437. By Christopher Townsend
-
Another bit of cleanup.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:437
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Larry Price (larryprice) wrote : | # |
Whoops, guess I'm going to leave this open until ChrisTownsend returns...
This works for internal copy/paste, but does not work between apps. Is that expected for now and can you link the relevant bugs to this one when you get back?
- 438. By Christopher Townsend
-
Merge lp:libertine.
- 439. By Christopher Townsend
-
Merge lp:libertine.
- 440. By Christopher Townsend
-
Revert libertine.pot.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Libertine CI Bot (libertine-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:439
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:440
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:439
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
- 441. By Christopher Townsend
-
Add closing the disaply in the XEventWorker dtor.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:441
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Preview Diff
1 | === modified file 'pasted/pasted.cpp' |
2 | --- pasted/pasted.cpp 2017-03-20 19:22:25 +0000 |
3 | +++ pasted/pasted.cpp 2017-03-20 20:42:05 +0000 |
4 | @@ -36,9 +36,8 @@ |
5 | constexpr auto UNITY_FOCUSINFO_METHOD = "isSurfaceFocused"; |
6 | |
7 | |
8 | -static QString getPersistentSurfaceId() |
9 | +static QString getPersistentSurfaceId(Display *dpy, const Window& id) |
10 | { |
11 | - Display *dpy = XOpenDisplay(NULL); |
12 | Atom prop = XInternAtom(dpy, MIR_WM_PERSISTENT_ID, 0), |
13 | type; // unused |
14 | int form, // unused |
15 | @@ -48,7 +47,7 @@ |
16 | unsigned char *data = nullptr; |
17 | QString persistentSurfaceId; |
18 | |
19 | - status = XGetWindowProperty(dpy, XDefaultRootWindow(dpy), prop, 0, 1024, 0, |
20 | + status = XGetWindowProperty(dpy, id, prop, 0, 1024, 0, |
21 | XA_STRING, &type, &form, &len, &remain, &data); |
22 | |
23 | if (status) |
24 | @@ -60,14 +59,13 @@ |
25 | persistentSurfaceId = (const char *)data; |
26 | } |
27 | |
28 | - XCloseDisplay(dpy); |
29 | XFree(data); |
30 | |
31 | return persistentSurfaceId; |
32 | } |
33 | |
34 | |
35 | -void checkXServer() |
36 | +Display *checkXServer() |
37 | { |
38 | char *display = getenv("DISPLAY"); |
39 | |
40 | @@ -84,55 +82,86 @@ |
41 | exit(-1); |
42 | } |
43 | |
44 | - XCloseDisplay(dpy); |
45 | - |
46 | - return; |
47 | + return dpy; |
48 | } |
49 | |
50 | } //anonymous namespace |
51 | |
52 | |
53 | +XEventWorker:: |
54 | +XEventWorker(Display *dpy) |
55 | +: dpy_(dpy) |
56 | +{ |
57 | + unityFocus_ = new QDBusInterface(UNITY_FOCUSINFO_SERVICE, |
58 | + UNITY_FOCUSINFO_PATH, |
59 | + UNITY_FOCUSINFO_INTERFACE, |
60 | + QDBusConnection::sessionBus(), |
61 | + this); |
62 | +} |
63 | + |
64 | + |
65 | +XEventWorker:: |
66 | +~XEventWorker() |
67 | +{ |
68 | + XCloseDisplay(dpy_); |
69 | +} |
70 | + |
71 | + |
72 | +bool XEventWorker:: |
73 | +isSurfaceFocused(const Window& focus_window) |
74 | +{ |
75 | + surfaceId_ = getPersistentSurfaceId(dpy_, focus_window); |
76 | + |
77 | + QDBusReply<bool> isFocused = unityFocus_->call(UNITY_FOCUSINFO_METHOD, surfaceId_); |
78 | + |
79 | + return isFocused; |
80 | +} |
81 | + |
82 | + |
83 | void XEventWorker:: |
84 | checkForAppFocus() |
85 | { |
86 | bool hasFocus = false; |
87 | + int focus_state; |
88 | + Window focus_window; |
89 | + |
90 | + XGetInputFocus(dpy_, &focus_window, &focus_state); |
91 | + |
92 | + if (focus_window > PointerRoot) |
93 | + { |
94 | + if (isSurfaceFocused(focus_window)) |
95 | + { |
96 | + focusChanged(surfaceId_); |
97 | + hasFocus = true; |
98 | + } |
99 | + } |
100 | + |
101 | + XSelectInput(dpy_, XDefaultRootWindow(dpy_), FocusChangeMask); |
102 | + |
103 | + bool focused = false; |
104 | XEvent event; |
105 | |
106 | - QDBusInterface *unityFocus = new QDBusInterface(UNITY_FOCUSINFO_SERVICE, |
107 | - UNITY_FOCUSINFO_PATH, |
108 | - UNITY_FOCUSINFO_INTERFACE, |
109 | - QDBusConnection::sessionBus(), |
110 | - this); |
111 | - |
112 | - QString surfaceId = getPersistentSurfaceId(); |
113 | - |
114 | - QDBusReply<bool> isFocused = unityFocus->call(UNITY_FOCUSINFO_METHOD, surfaceId); |
115 | - |
116 | - if (isFocused == true) |
117 | - { |
118 | - focusChanged(); |
119 | - hasFocus = true; |
120 | - } |
121 | - |
122 | - Display *dpy = XOpenDisplay(NULL); |
123 | - XSelectInput(dpy, XDefaultRootWindow(dpy), FocusChangeMask); |
124 | - |
125 | while (1) |
126 | { |
127 | - XNextEvent(dpy, &event); |
128 | - |
129 | - isFocused = unityFocus->call(UNITY_FOCUSINFO_METHOD, surfaceId); |
130 | - |
131 | - if (hasFocus == false && isFocused == true) |
132 | - { |
133 | - qDebug() << "Surface is focused"; |
134 | - focusChanged(); |
135 | - hasFocus = true; |
136 | - } |
137 | - else if (hasFocus == true && isFocused == false) |
138 | - { |
139 | - qDebug() << "Surface lost focus"; |
140 | - hasFocus = false; |
141 | + XNextEvent(dpy_, &event); |
142 | + |
143 | + XGetInputFocus(dpy_, &focus_window, &focus_state); |
144 | + |
145 | + if (focus_window > PointerRoot) |
146 | + { |
147 | + focused = isSurfaceFocused(focus_window); |
148 | + |
149 | + if (hasFocus == false && focused == true) |
150 | + { |
151 | + qDebug() << "Surface is focused"; |
152 | + focusChanged(surfaceId_); |
153 | + hasFocus = true; |
154 | + } |
155 | + else if (hasFocus == true && focused == false) |
156 | + { |
157 | + qDebug() << "Surface lost focus"; |
158 | + hasFocus = false; |
159 | + } |
160 | } |
161 | } |
162 | } |
163 | @@ -253,19 +282,19 @@ |
164 | |
165 | |
166 | void Pasted:: |
167 | -setPersistentSurfaceId() |
168 | +setPersistentSurfaceId(const QString& surfaceId) |
169 | { |
170 | - if (persistentSurfaceId_.isEmpty()) |
171 | + if (persistentSurfaceId_ != surfaceId) |
172 | { |
173 | - persistentSurfaceId_ = getPersistentSurfaceId(); |
174 | + persistentSurfaceId_ = surfaceId; |
175 | } |
176 | } |
177 | |
178 | |
179 | void Pasted:: |
180 | -appFocused() |
181 | +appFocused(const QString& surfaceId) |
182 | { |
183 | - setPersistentSurfaceId(); |
184 | + setPersistentSurfaceId(surfaceId); |
185 | handleContentHubPasteboard(); |
186 | } |
187 | |
188 | @@ -275,12 +304,12 @@ |
189 | { |
190 | qSetMessagePattern(QString("%{appname}: %{message}")); |
191 | |
192 | - checkXServer(); |
193 | + Display *dpy = checkXServer(); |
194 | |
195 | Pasted pasted(argc, argv); |
196 | |
197 | QThread t; |
198 | - XEventWorker worker; |
199 | + XEventWorker worker(dpy); |
200 | |
201 | worker.moveToThread(&t); |
202 | |
203 | |
204 | === modified file 'pasted/pasted.h' |
205 | --- pasted/pasted.h 2016-09-12 17:59:56 +0000 |
206 | +++ pasted/pasted.h 2017-03-20 20:42:05 +0000 |
207 | @@ -39,14 +39,22 @@ |
208 | Q_OBJECT |
209 | |
210 | public: |
211 | - XEventWorker() = default; |
212 | - virtual ~XEventWorker() = default; |
213 | + XEventWorker(Display *dpy); |
214 | + virtual ~XEventWorker(); |
215 | + |
216 | + private: |
217 | + bool isSurfaceFocused(const Window& focus_window); |
218 | |
219 | signals: |
220 | - void focusChanged(); |
221 | + void focusChanged(const QString& surfaceId); |
222 | |
223 | public slots: |
224 | void checkForAppFocus(); |
225 | + |
226 | + private: |
227 | + Display *dpy_; |
228 | + QDBusInterface *unityFocus_; |
229 | + QString surfaceId_; |
230 | }; |
231 | |
232 | |
233 | @@ -60,13 +68,13 @@ |
234 | virtual ~Pasted() = default; |
235 | |
236 | public slots: |
237 | - void appFocused(); |
238 | + void appFocused(const QString& surfaceId); |
239 | |
240 | private: |
241 | void updateLastMimeData(const QMimeData *source); |
242 | void updateXMimeData(const QMimeData *source); |
243 | void handleContentHubPasteboard(); |
244 | - void setPersistentSurfaceId(); |
245 | + void setPersistentSurfaceId(const QString& surfaceId); |
246 | |
247 | static bool compareMimeData(const QMimeData *a, const QMimeData *b); |
248 | static void copyMimeData(QMimeData& target, const QMimeData *source); |
FAILED: Continuous integration, rev:434 /jenkins. canonical. com/libertine/ job/lp- libertine- ci/458/ /jenkins. canonical. com/libertine/ job/build/ 845/console /jenkins. canonical. com/libertine/ job/build- 0-fetch/ 855 /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=amd64, release= xenial+ overlay/ 847 /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=amd64, release= xenial+ overlay/ 847/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=amd64, release= zesty/847 /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=amd64, release= zesty/847/ artifact/ output/ *zip*/output. zip /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=i386, release= xenial+ overlay/ 847/console /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=i386, release= zesty/847 /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=i386, release= zesty/847/ artifact/ output/ *zip*/output. zip
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild: /jenkins. canonical. com/libertine/ job/lp- libertine- ci/458/ rebuild
https:/