Merge ~3v1n0/ubuntu/+source/gnome-calculator:ubuntu/bionic-xubuntu-cancel-search into ~ubuntu-desktop/ubuntu/+source/gnome-calculator:ubuntu/bionic
- Git
- lp:~3v1n0/ubuntu/+source/gnome-calculator
- ubuntu/bionic-xubuntu-cancel-search
- Merge into ubuntu/bionic
Proposed by
Marco Trevisan (Treviño)
Status: | Merged |
---|---|
Merged at revision: | 3b2a861e9c0ef946f7bbc64ead0e6411cd665e5a |
Proposed branch: | ~3v1n0/ubuntu/+source/gnome-calculator:ubuntu/bionic-xubuntu-cancel-search |
Merge into: | ~ubuntu-desktop/ubuntu/+source/gnome-calculator:ubuntu/bionic |
Prerequisite: | ~3v1n0/ubuntu/+source/gnome-calculator:ubuntu/bionic |
Diff against target: |
1129 lines (+1026/-2) 15 files modified
debian/changelog (+28/-0) debian/control (+2/-1) debian/control.in (+2/-1) debian/patches/Use-GLib.List.deep_copy-to-fix-type-argument-mismatch.patch (+25/-0) debian/patches/search-provider-Handle-errors-gracefully.patch (+108/-0) debian/patches/search-provider-Use-async-calls-cancel-search-on-inactivi.patch (+233/-0) debian/patches/search-provider-Use-lower-inactivity-timeout.patch (+30/-0) debian/patches/search-provider-cache-equations-avoiding-spawning-calcula.patch (+171/-0) debian/patches/search-provider-cache-only-a-limited-number-of-equations.patch (+45/-0) debian/patches/search-provider-cancel-the-current-process-on-new-calcula.patch (+30/-0) debian/patches/search-provider-renew-inactivity-timeout-at-each-calculat.patch (+61/-0) debian/patches/search-provider-simplify-solve_subprocess.patch (+114/-0) debian/patches/search-provider-stop-normalizing-the-equation-twice.patch (+48/-0) debian/patches/series (+11/-0) debian/patches/ubuntu/search-provider-Cancel-operations-on-XUbuntuCancel.patch (+118/-0) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Desktop | Pending | ||
Review via email: mp+354335@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/debian/changelog b/debian/changelog | |||
2 | index 44dd584..9da064b 100644 | |||
3 | --- a/debian/changelog | |||
4 | +++ b/debian/changelog | |||
5 | @@ -1,3 +1,31 @@ | |||
6 | 1 | gnome-calculator (1:3.28.2-1~ubuntu18.04.3) UNRELEASED; urgency=medium | ||
7 | 2 | |||
8 | 3 | * d/p/search-provider-stop-normalizing-the-equation-twice.patch: | ||
9 | 4 | - Don't normalize multiple times an equation, fixing issues with decimal | ||
10 | 5 | numbers computations (fixes a regression introduced with previous | ||
11 | 6 | patch set in order to fix LP: #1756826) | ||
12 | 7 | * d/p/Use-GLib.List.deep_copy-to-fix-type-argument-mismatch.patch: | ||
13 | 8 | - Fix a build issue when compiling with vala 0.40.17 (LP: #1857005) | ||
14 | 9 | |||
15 | 10 | -- Marco Trevisan (Treviño) <marco@ubuntu.com> Wed, 18 Dec 2019 21:10:54 +0100 | ||
16 | 11 | |||
17 | 12 | gnome-calculator (1:3.28.2-1~ubuntu18.04.2) bionic; urgency=medium | ||
18 | 13 | |||
19 | 14 | * d/p/search-provider-Use-async-calls-cancel-search-on-inactivi.patch, | ||
20 | 15 | d/p/search-provider-renew-inactivity-timeout-at-each-calculat.patch, | ||
21 | 16 | d/p/search-provider-Use-lower-inactivity-timeout.patch, | ||
22 | 17 | d/p/search-provider-simplify-solve_subprocess.patch, | ||
23 | 18 | d/p/search-provider-cache-equations-avoiding-spawning-calcula.patch, | ||
24 | 19 | d/p/search-provider-cancel-the-current-process-on-new-calcula.patch, | ||
25 | 20 | d/p/search-provider-cache-only-a-limited-number-of-equations.patch, | ||
26 | 21 | d/p/search-provider-Handle-errors-gracefully.patch, | ||
27 | 22 | d/p/ubuntu/search-provider-Cancel-operations-on-XUbuntuCancel.patch: | ||
28 | 23 | - Make search provider async and support XUbuntuCancel method to | ||
29 | 24 | stop expensive operations that might lead to an unresponsive | ||
30 | 25 | process (LP: #1756826) | ||
31 | 26 | |||
32 | 27 | -- Marco Trevisan (Treviño) <marco@ubuntu.com> Thu, 08 Nov 2018 01:34:07 -0500 | ||
33 | 28 | |||
34 | 1 | gnome-calculator (1:3.28.2-1~ubuntu18.04.1) bionic; urgency=medium | 29 | gnome-calculator (1:3.28.2-1~ubuntu18.04.1) bionic; urgency=medium |
35 | 2 | 30 | ||
36 | 3 | * New upstream stable release (LP: #1790876) | 31 | * New upstream stable release (LP: #1790876) |
37 | diff --git a/debian/control b/debian/control | |||
38 | index cd4706c..0782192 100644 | |||
39 | --- a/debian/control | |||
40 | +++ b/debian/control | |||
41 | @@ -5,7 +5,8 @@ | |||
42 | 5 | Source: gnome-calculator | 5 | Source: gnome-calculator |
43 | 6 | Section: math | 6 | Section: math |
44 | 7 | Priority: optional | 7 | Priority: optional |
46 | 8 | Maintainer: Debian GNOME Maintainers <pkg-gnome-maintainers@lists.alioth.debian.org> | 8 | Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com> |
47 | 9 | XSBC-Original-Maintainer: Debian GNOME Maintainers <pkg-gnome-maintainers@lists.alioth.debian.org> | ||
48 | 9 | Uploaders: Jeremy Bicha <jbicha@debian.org>, Laurent Bigonville <bigon@debian.org>, Michael Biebl <biebl@debian.org> | 10 | Uploaders: Jeremy Bicha <jbicha@debian.org>, Laurent Bigonville <bigon@debian.org>, Michael Biebl <biebl@debian.org> |
49 | 10 | Build-Depends: appstream-util, | 11 | Build-Depends: appstream-util, |
50 | 11 | debhelper (>= 11.1.3), | 12 | debhelper (>= 11.1.3), |
51 | diff --git a/debian/control.in b/debian/control.in | |||
52 | index b5194ee..d9e0327 100644 | |||
53 | --- a/debian/control.in | |||
54 | +++ b/debian/control.in | |||
55 | @@ -1,7 +1,8 @@ | |||
56 | 1 | Source: gnome-calculator | 1 | Source: gnome-calculator |
57 | 2 | Section: math | 2 | Section: math |
58 | 3 | Priority: optional | 3 | Priority: optional |
60 | 4 | Maintainer: Debian GNOME Maintainers <pkg-gnome-maintainers@lists.alioth.debian.org> | 4 | Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com> |
61 | 5 | XSBC-Original-Maintainer: Debian GNOME Maintainers <pkg-gnome-maintainers@lists.alioth.debian.org> | ||
62 | 5 | Uploaders: @GNOME_TEAM@ | 6 | Uploaders: @GNOME_TEAM@ |
63 | 6 | Build-Depends: appstream-util, | 7 | Build-Depends: appstream-util, |
64 | 7 | debhelper (>= 11.1.3), | 8 | debhelper (>= 11.1.3), |
65 | diff --git a/debian/patches/Use-GLib.List.deep_copy-to-fix-type-argument-mismatch.patch b/debian/patches/Use-GLib.List.deep_copy-to-fix-type-argument-mismatch.patch | |||
66 | 8 | new file mode 100644 | 9 | new file mode 100644 |
67 | index 0000000..0810e88 | |||
68 | --- /dev/null | |||
69 | +++ b/debian/patches/Use-GLib.List.deep_copy-to-fix-type-argument-mismatch.patch | |||
70 | @@ -0,0 +1,25 @@ | |||
71 | 1 | From: Rico Tzschichholz <ricotz@ubuntu.com> | ||
72 | 2 | Date: Sun, 4 Nov 2018 19:41:23 +0100 | ||
73 | 3 | Subject: Use GLib.List.deep_copy() to fix type-argument mismatch | ||
74 | 4 | |||
75 | 5 | Origin: https://gitlab.gnome.org/GNOME/gnome-calculator/commit/d89466a7 | ||
76 | 6 | Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/gnome-calculator/+bug/1857005 | ||
77 | 7 | Applied-Upstream: 3.31.2 | ||
78 | 8 | |||
79 | 9 | --- | ||
80 | 10 | lib/equation-parser.vala | 2 +- | ||
81 | 11 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
82 | 12 | |||
83 | 13 | diff --git a/lib/equation-parser.vala b/lib/equation-parser.vala | ||
84 | 14 | index 668e1cd..d16e5b1 100644 | ||
85 | 15 | --- a/lib/equation-parser.vala | ||
86 | 16 | +++ b/lib/equation-parser.vala | ||
87 | 17 | @@ -76,7 +76,7 @@ public class ParseNode : Object | ||
88 | 18 | public ParseNode.WithList (Parser parser, List<LexerToken> token_list, uint precedence, Associativity associativity, string? value = null) | ||
89 | 19 | { | ||
90 | 20 | this.parser = parser; | ||
91 | 21 | - this.token_list = token_list.copy(); | ||
92 | 22 | + this.token_list = token_list.copy_deep((CopyFunc) Object.ref); | ||
93 | 23 | this.precedence = precedence; | ||
94 | 24 | this.associativity = associativity; | ||
95 | 25 | this.value = value; | ||
96 | diff --git a/debian/patches/search-provider-Handle-errors-gracefully.patch b/debian/patches/search-provider-Handle-errors-gracefully.patch | |||
97 | 0 | new file mode 100644 | 26 | new file mode 100644 |
98 | index 0000000..f78c54b | |||
99 | --- /dev/null | |||
100 | +++ b/debian/patches/search-provider-Handle-errors-gracefully.patch | |||
101 | @@ -0,0 +1,108 @@ | |||
102 | 1 | From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> | ||
103 | 2 | Date: Wed, 5 Sep 2018 17:11:27 +0200 | ||
104 | 3 | Subject: search-provider: Handle errors gracefully | ||
105 | 4 | |||
106 | 5 | Instead of exiting immediately if a spawn error occurred, inform our dbus | ||
107 | 6 | client about it with a proper spawn error. | ||
108 | 7 | |||
109 | 8 | As bonus, get rid of the compile warning. | ||
110 | 9 | |||
111 | 10 | Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/gnome-calculator/+bug/1795399 | ||
112 | 11 | Forwarded: https://gitlab.gnome.org/GNOME/gnome-calculator/merge_requests/10 | ||
113 | 12 | Applied-Upstream: yes, 3.31.1 | ||
114 | 13 | --- | ||
115 | 14 | search-provider/search-provider.vala | 24 +++++++++++++----------- | ||
116 | 15 | 1 file changed, 13 insertions(+), 11 deletions(-) | ||
117 | 16 | |||
118 | 17 | diff --git a/search-provider/search-provider.vala b/search-provider/search-provider.vala | ||
119 | 18 | index fc72128..a48c440 100644 | ||
120 | 19 | --- a/search-provider/search-provider.vala | ||
121 | 20 | +++ b/search-provider/search-provider.vala | ||
122 | 21 | @@ -63,7 +63,7 @@ public class SearchProvider : Object | ||
123 | 22 | } | ||
124 | 23 | catch (Error e) | ||
125 | 24 | { | ||
126 | 25 | - error ("Failed to spawn Calculator: %s", e.message); | ||
127 | 26 | + throw e; | ||
128 | 27 | } | ||
129 | 28 | |||
130 | 29 | if (cancellable == null) | ||
131 | 30 | @@ -79,7 +79,7 @@ public class SearchProvider : Object | ||
132 | 31 | return subprocess; | ||
133 | 32 | } | ||
134 | 33 | |||
135 | 34 | - private async bool solve_equation (string equation) | ||
136 | 35 | + private async bool solve_equation (string equation) throws DBusError | ||
137 | 36 | { | ||
138 | 37 | string? result; | ||
139 | 38 | |||
140 | 39 | @@ -112,7 +112,8 @@ public class SearchProvider : Object | ||
141 | 40 | } | ||
142 | 41 | catch (SpawnError e) | ||
143 | 42 | { | ||
144 | 43 | - error ("Failed to spawn Calculator: %s", e.message); | ||
145 | 44 | + critical ("Failed to spawn Calculator: %s", e.message); | ||
146 | 45 | + throw new DBusError.SPAWN_FAILED (e.message); | ||
147 | 46 | } | ||
148 | 47 | catch (Error e) | ||
149 | 48 | { | ||
150 | 49 | @@ -128,7 +129,7 @@ public class SearchProvider : Object | ||
151 | 50 | return true; | ||
152 | 51 | } | ||
153 | 52 | |||
154 | 53 | - private async string[] get_result_identifier (string[] terms) | ||
155 | 54 | + private async string[] get_result_identifier (string[] terms) throws Error | ||
156 | 55 | { | ||
157 | 56 | /* We have at most one result: the search terms as one string */ | ||
158 | 57 | var equation = terms_to_equation (terms); | ||
159 | 58 | @@ -138,17 +139,17 @@ public class SearchProvider : Object | ||
160 | 59 | return new string[0]; | ||
161 | 60 | } | ||
162 | 61 | |||
163 | 62 | - public async string[] get_initial_result_set (string[] terms) | ||
164 | 63 | + public async string[] get_initial_result_set (string[] terms) throws Error | ||
165 | 64 | { | ||
166 | 65 | return yield get_result_identifier (terms); | ||
167 | 66 | } | ||
168 | 67 | |||
169 | 68 | - public async string[] get_subsearch_result_set (string[] previous_results, string[] terms) | ||
170 | 69 | + public async string[] get_subsearch_result_set (string[] previous_results, string[] terms) throws Error | ||
171 | 70 | { | ||
172 | 71 | return yield get_result_identifier (terms); | ||
173 | 72 | } | ||
174 | 73 | |||
175 | 74 | - public async HashTable<string, Variant>[] get_result_metas (string[] results, GLib.BusName sender) | ||
176 | 75 | + public async HashTable<string, Variant>[] get_result_metas (string[] results, GLib.BusName sender) throws Error | ||
177 | 76 | requires (results.length == 1) | ||
178 | 77 | { | ||
179 | 78 | string equation; | ||
180 | 79 | @@ -171,7 +172,7 @@ public class SearchProvider : Object | ||
181 | 80 | return metadata; | ||
182 | 81 | } | ||
183 | 82 | |||
184 | 83 | - private static void spawn_and_display_equation (string[] terms) | ||
185 | 84 | + private static void spawn_and_display_equation (string[] terms) throws Error | ||
186 | 85 | { | ||
187 | 86 | try | ||
188 | 87 | { | ||
189 | 88 | @@ -180,16 +181,17 @@ public class SearchProvider : Object | ||
190 | 89 | } | ||
191 | 90 | catch (SpawnError e) | ||
192 | 91 | { | ||
193 | 92 | - error ("Failed to spawn Calculator: %s", e.message); | ||
194 | 93 | + critical ("Failed to spawn Calculator: %s", e.message); | ||
195 | 94 | + throw new DBusError.SPAWN_FAILED (e.message); | ||
196 | 95 | } | ||
197 | 96 | } | ||
198 | 97 | |||
199 | 98 | - public void activate_result (string result, string[] terms, uint32 timestamp) | ||
200 | 99 | + public void activate_result (string result, string[] terms, uint32 timestamp) throws Error | ||
201 | 100 | { | ||
202 | 101 | spawn_and_display_equation (terms); | ||
203 | 102 | } | ||
204 | 103 | |||
205 | 104 | - public void launch_search (string[] terms, uint32 timestamp) | ||
206 | 105 | + public void launch_search (string[] terms, uint32 timestamp) throws Error | ||
207 | 106 | { | ||
208 | 107 | spawn_and_display_equation (terms); | ||
209 | 108 | } | ||
210 | diff --git a/debian/patches/search-provider-Use-async-calls-cancel-search-on-inactivi.patch b/debian/patches/search-provider-Use-async-calls-cancel-search-on-inactivi.patch | |||
211 | 0 | new file mode 100644 | 109 | new file mode 100644 |
212 | index 0000000..d8e38be | |||
213 | --- /dev/null | |||
214 | +++ b/debian/patches/search-provider-Use-async-calls-cancel-search-on-inactivi.patch | |||
215 | @@ -0,0 +1,233 @@ | |||
216 | 1 | From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> | ||
217 | 2 | Date: Fri, 24 Aug 2018 06:57:03 +0200 | ||
218 | 3 | Subject: search-provider: Use async calls, cancel search on inactivity | ||
219 | 4 | |||
220 | 5 | Move to async methods everywhere and factorize the `solve` calls to a single | ||
221 | 6 | method that only uses Subprocess and that can be cancelled. | ||
222 | 7 | |||
223 | 8 | As per this, if the the search-provider is trying to compute some complex | ||
224 | 9 | operation, the daemon won't hang and once the applications' inactivity | ||
225 | 10 | timeout is hit, any running instance of gnome-calculator will be killed and | ||
226 | 11 | the daemon will return accordingly. | ||
227 | 12 | |||
228 | 13 | This reduces the impact of an issue that can cause gnome-calculator to keep | ||
229 | 14 | running forever if a complex computation is required (10!!!) from the shell, | ||
230 | 15 | and won't ever be killed (see GNOME/gnome-shell#183). | ||
231 | 16 | |||
232 | 17 | This is also a prerequisite for supporting the search Cancellation that is | ||
233 | 18 | going to be available on next version of the Search provider protocol | ||
234 | 19 | (as per GNOME/gnome-shell#436) | ||
235 | 20 | |||
236 | 21 | Bug-Ubuntu: https://launchpad.net/bugs/1756826 | ||
237 | 22 | Bug-GNOME: https://gitlab.gnome.org/GNOME/gnome-shell/issues/183 | ||
238 | 23 | Forwarded: https://gitlab.gnome.org/GNOME/gnome-calculator/merge_requests/10 | ||
239 | 24 | Applied-Upstream: yes, 3.31.1 | ||
240 | 25 | --- | ||
241 | 26 | search-provider/search-provider.vala | 126 +++++++++++++++++++++++++---------- | ||
242 | 27 | 1 file changed, 89 insertions(+), 37 deletions(-) | ||
243 | 28 | |||
244 | 29 | diff --git a/search-provider/search-provider.vala b/search-provider/search-provider.vala | ||
245 | 30 | index 26c72af..659f73d 100644 | ||
246 | 31 | --- a/search-provider/search-provider.vala | ||
247 | 32 | +++ b/search-provider/search-provider.vala | ||
248 | 33 | @@ -1,6 +1,7 @@ | ||
249 | 34 | /* -*- Mode: vala; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- | ||
250 | 35 | * | ||
251 | 36 | * Copyright (C) 2014 Michael Catanzaro | ||
252 | 37 | + * Copyright (C) 2018 Marco Trevisan | ||
253 | 38 | * | ||
254 | 39 | * This program is free software: you can redistribute it and/or modify it under | ||
255 | 40 | * the terms of the GNU General Public License as published by the Free Software | ||
256 | 41 | @@ -12,17 +13,85 @@ | ||
257 | 42 | [DBus (name = "org.gnome.Shell.SearchProvider2")] | ||
258 | 43 | public class SearchProvider : Object | ||
259 | 44 | { | ||
260 | 45 | + private Cancellable cancellable = new Cancellable (); | ||
261 | 46 | + | ||
262 | 47 | + ~SearchProvider () | ||
263 | 48 | + { | ||
264 | 49 | + cancel (); | ||
265 | 50 | + } | ||
266 | 51 | + | ||
267 | 52 | + [DBus (visible = false)] | ||
268 | 53 | + public void cancel () | ||
269 | 54 | + { | ||
270 | 55 | + if (cancellable != null) | ||
271 | 56 | + { | ||
272 | 57 | + cancellable.cancel (); | ||
273 | 58 | + } | ||
274 | 59 | + } | ||
275 | 60 | + | ||
276 | 61 | private static string terms_to_equation (string[] terms) | ||
277 | 62 | { | ||
278 | 63 | return string.joinv (" ", terms); | ||
279 | 64 | } | ||
280 | 65 | |||
281 | 66 | - private static bool can_parse (string[] terms) | ||
282 | 67 | + private async Subprocess solve_subprocess (string equation, bool return_solution = false, out string? solution_buf = null) throws Error | ||
283 | 68 | { | ||
284 | 69 | + Subprocess subprocess; | ||
285 | 70 | + string[] argv = {"gnome-calculator", "--solve"}; | ||
286 | 71 | + argv += equation; | ||
287 | 72 | + argv += null; | ||
288 | 73 | + | ||
289 | 74 | + debug (@"Trying to solve $(equation)"); | ||
290 | 75 | + | ||
291 | 76 | try | ||
292 | 77 | { | ||
293 | 78 | - int exit_status; | ||
294 | 79 | + // Eat output so that it doesn't wind up in the journal. It's | ||
295 | 80 | + // expected that most searches are not valid calculator input. | ||
296 | 81 | + var flags = SubprocessFlags.STDERR_PIPE; | ||
297 | 82 | + | ||
298 | 83 | + if (return_solution) | ||
299 | 84 | + { | ||
300 | 85 | + flags |= SubprocessFlags.STDOUT_PIPE; | ||
301 | 86 | + } | ||
302 | 87 | + | ||
303 | 88 | + subprocess = new Subprocess.newv (argv, flags); | ||
304 | 89 | + } | ||
305 | 90 | + catch (Error e) | ||
306 | 91 | + { | ||
307 | 92 | + error ("Failed to spawn Calculator: %s", e.message); | ||
308 | 93 | + } | ||
309 | 94 | + | ||
310 | 95 | + try | ||
311 | 96 | + { | ||
312 | 97 | + string stderr_buf; | ||
313 | 98 | + | ||
314 | 99 | + cancellable = new Cancellable (); | ||
315 | 100 | + cancellable.cancelled.connect (() => { | ||
316 | 101 | + subprocess.force_exit (); | ||
317 | 102 | + cancellable = null; | ||
318 | 103 | + }); | ||
319 | 104 | + | ||
320 | 105 | + yield subprocess.communicate_utf8_async (null, cancellable, out solution_buf, out stderr_buf); | ||
321 | 106 | + } | ||
322 | 107 | + catch (Error e) | ||
323 | 108 | + { | ||
324 | 109 | + if (e is IOError.CANCELLED) | ||
325 | 110 | + { | ||
326 | 111 | + throw e; | ||
327 | 112 | + } | ||
328 | 113 | + else | ||
329 | 114 | + { | ||
330 | 115 | + error ("Failed reading result: %s", e.message); | ||
331 | 116 | + } | ||
332 | 117 | + } | ||
333 | 118 | |||
334 | 119 | + return subprocess; | ||
335 | 120 | + } | ||
336 | 121 | + | ||
337 | 122 | + private async bool can_parse (string[] terms) | ||
338 | 123 | + { | ||
339 | 124 | + try | ||
340 | 125 | + { | ||
341 | 126 | var tsep_string = Posix.nl_langinfo (Posix.NLItem.THOUSEP); | ||
342 | 127 | if (tsep_string == null || tsep_string == "") | ||
343 | 128 | tsep_string = " "; | ||
344 | 129 | @@ -39,14 +108,8 @@ public class SearchProvider : Object | ||
345 | 130 | return false; | ||
346 | 131 | } | ||
347 | 132 | |||
348 | 133 | - // Eat output so that it doesn't wind up in the journal. It's | ||
349 | 134 | - // expected that most searches are not valid calculator input. | ||
350 | 135 | - string stdout_buf; | ||
351 | 136 | - string stderr_buf; | ||
352 | 137 | - Process.spawn_command_line_sync ( | ||
353 | 138 | - "gnome-calculator --solve " + Shell.quote (equation), | ||
354 | 139 | - out stdout_buf, out stderr_buf, out exit_status); | ||
355 | 140 | - Process.check_exit_status (exit_status); | ||
356 | 141 | + var subprocess = yield solve_subprocess (equation); | ||
357 | 142 | + yield subprocess.wait_check_async (); | ||
358 | 143 | } | ||
359 | 144 | catch (SpawnError e) | ||
360 | 145 | { | ||
361 | 146 | @@ -60,54 +123,37 @@ public class SearchProvider : Object | ||
362 | 147 | return true; | ||
363 | 148 | } | ||
364 | 149 | |||
365 | 150 | - private static string[] get_result_identifier (string[] terms) | ||
366 | 151 | - ensures (result.length == 0 || result.length == 1) | ||
367 | 152 | + private async string[] get_result_identifier (string[] terms) | ||
368 | 153 | { | ||
369 | 154 | /* We have at most one result: the search terms as one string */ | ||
370 | 155 | - if (can_parse (terms)) | ||
371 | 156 | + if (yield can_parse (terms)) | ||
372 | 157 | return { terms_to_equation (terms) }; | ||
373 | 158 | else | ||
374 | 159 | return new string[0]; | ||
375 | 160 | } | ||
376 | 161 | |||
377 | 162 | - public string[] get_initial_result_set (string[] terms) | ||
378 | 163 | + public async string[] get_initial_result_set (string[] terms) | ||
379 | 164 | { | ||
380 | 165 | - return get_result_identifier (terms); | ||
381 | 166 | + return yield get_result_identifier (terms); | ||
382 | 167 | } | ||
383 | 168 | |||
384 | 169 | - public string[] get_subsearch_result_set (string[] previous_results, string[] terms) | ||
385 | 170 | + public async string[] get_subsearch_result_set (string[] previous_results, string[] terms) | ||
386 | 171 | { | ||
387 | 172 | - return get_result_identifier (terms); | ||
388 | 173 | + return yield get_result_identifier (terms); | ||
389 | 174 | } | ||
390 | 175 | |||
391 | 176 | - public HashTable<string, Variant>[] get_result_metas (string[] results) | ||
392 | 177 | + public async HashTable<string, Variant>[] get_result_metas (string[] results, GLib.BusName sender) | ||
393 | 178 | requires (results.length == 1) | ||
394 | 179 | - ensures (result.length == 1) | ||
395 | 180 | { | ||
396 | 181 | - Subprocess subprocess; | ||
397 | 182 | string stdout_buf; | ||
398 | 183 | - string stderr_buf; | ||
399 | 184 | - | ||
400 | 185 | - string[] argv = {"gnome-calculator", "--solve"}; | ||
401 | 186 | - argv += results[0]; | ||
402 | 187 | - argv += null; | ||
403 | 188 | - | ||
404 | 189 | - try | ||
405 | 190 | - { | ||
406 | 191 | - subprocess = new Subprocess.newv (argv, SubprocessFlags.STDOUT_PIPE | SubprocessFlags.STDERR_PIPE); | ||
407 | 192 | - } | ||
408 | 193 | - catch (Error e) | ||
409 | 194 | - { | ||
410 | 195 | - error ("Failed to spawn Calculator: %s", e.message); | ||
411 | 196 | - } | ||
412 | 197 | |||
413 | 198 | try | ||
414 | 199 | { | ||
415 | 200 | - subprocess.communicate_utf8 (null, null, out stdout_buf, out stderr_buf); | ||
416 | 201 | + yield solve_subprocess (results[0], true, out stdout_buf); | ||
417 | 202 | } | ||
418 | 203 | catch (Error e) | ||
419 | 204 | { | ||
420 | 205 | - error ("Failed reading result: %s", e.message); | ||
421 | 206 | + return new HashTable<string, Variant>[0]; | ||
422 | 207 | } | ||
423 | 208 | |||
424 | 209 | var metadata = new HashTable<string, Variant>[1]; | ||
425 | 210 | @@ -155,9 +201,11 @@ public class SearchProviderApp : Application | ||
426 | 211 | |||
427 | 212 | public override bool dbus_register (DBusConnection connection, string object_path) | ||
428 | 213 | { | ||
429 | 214 | + SearchProvider search_provider = new SearchProvider (); | ||
430 | 215 | + | ||
431 | 216 | try | ||
432 | 217 | { | ||
433 | 218 | - connection.register_object (object_path, new SearchProvider ()); | ||
434 | 219 | + connection.register_object (object_path, search_provider); | ||
435 | 220 | } | ||
436 | 221 | catch (IOError error) | ||
437 | 222 | { | ||
438 | 223 | @@ -165,6 +213,10 @@ public class SearchProviderApp : Application | ||
439 | 224 | quit (); | ||
440 | 225 | } | ||
441 | 226 | |||
442 | 227 | + shutdown.connect (() => { | ||
443 | 228 | + search_provider.cancel (); | ||
444 | 229 | + }); | ||
445 | 230 | + | ||
446 | 231 | return true; | ||
447 | 232 | } | ||
448 | 233 | } | ||
449 | diff --git a/debian/patches/search-provider-Use-lower-inactivity-timeout.patch b/debian/patches/search-provider-Use-lower-inactivity-timeout.patch | |||
450 | 0 | new file mode 100644 | 234 | new file mode 100644 |
451 | index 0000000..5008fe5 | |||
452 | --- /dev/null | |||
453 | +++ b/debian/patches/search-provider-Use-lower-inactivity-timeout.patch | |||
454 | @@ -0,0 +1,30 @@ | |||
455 | 1 | From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> | ||
456 | 2 | Date: Fri, 24 Aug 2018 07:12:12 +0200 | ||
457 | 3 | Subject: search-provider: Use lower inactivity timeout | ||
458 | 4 | |||
459 | 5 | Since we're renewing it at every call involving a process call, we can just | ||
460 | 6 | set it to a lower value than the default dbus proxy timeout, so that the provider | ||
461 | 7 | will return invalid values before that the timeout has been hit. | ||
462 | 8 | |||
463 | 9 | Bug-Ubuntu: https://launchpad.net/bugs/1756826 | ||
464 | 10 | Bug-GNOME: https://gitlab.gnome.org/GNOME/gnome-shell/issues/183 | ||
465 | 11 | Forwarded: https://gitlab.gnome.org/GNOME/gnome-calculator/merge_requests/10 | ||
466 | 12 | Applied-Upstream: yes, 3.31.1 | ||
467 | 13 | --- | ||
468 | 14 | search-provider/search-provider.vala | 3 ++- | ||
469 | 15 | 1 file changed, 2 insertions(+), 1 deletion(-) | ||
470 | 16 | |||
471 | 17 | diff --git a/search-provider/search-provider.vala b/search-provider/search-provider.vala | ||
472 | 18 | index 7e54fa6..9035c58 100644 | ||
473 | 19 | --- a/search-provider/search-provider.vala | ||
474 | 20 | +++ b/search-provider/search-provider.vala | ||
475 | 21 | @@ -203,7 +203,8 @@ public class SearchProviderApp : Application | ||
476 | 22 | { | ||
477 | 23 | Object (application_id: "org.gnome.Calculator.SearchProvider", | ||
478 | 24 | flags: ApplicationFlags.IS_SERVICE, | ||
479 | 25 | - inactivity_timeout: 60000); | ||
480 | 26 | + inactivity_timeout: 20000); | ||
481 | 27 | + } | ||
482 | 28 | |||
483 | 29 | public void renew_inactivity_timeout () | ||
484 | 30 | { | ||
485 | diff --git a/debian/patches/search-provider-cache-equations-avoiding-spawning-calcula.patch b/debian/patches/search-provider-cache-equations-avoiding-spawning-calcula.patch | |||
486 | 0 | new file mode 100644 | 31 | new file mode 100644 |
487 | index 0000000..85d83ce | |||
488 | --- /dev/null | |||
489 | +++ b/debian/patches/search-provider-cache-equations-avoiding-spawning-calcula.patch | |||
490 | @@ -0,0 +1,171 @@ | |||
491 | 1 | From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> | ||
492 | 2 | Date: Mon, 27 Aug 2018 18:45:34 +0200 | ||
493 | 3 | Subject: search-provider: cache equations avoiding spawning calculator twice | ||
494 | 4 | |||
495 | 5 | Currently we spawn the calculator two times for each operation, one to check | ||
496 | 6 | if the search provider is valid for such syntax, the other time to actually | ||
497 | 7 | present the results. But since these results are just available at first | ||
498 | 8 | call, we can just keep them around and return them if the shell requires them. | ||
499 | 9 | |||
500 | 10 | Since the search provider deamon is kept alive for just few moments, there's | ||
501 | 11 | no real need to cleanup the cache using a queue. | ||
502 | 12 | |||
503 | 13 | In case of multiple async calls, reuse cancellable instead so that we can | ||
504 | 14 | just kill all the related processes one time at once. | ||
505 | 15 | |||
506 | 16 | Bug-Ubuntu: https://launchpad.net/bugs/1756826 | ||
507 | 17 | Bug-GNOME: https://gitlab.gnome.org/GNOME/gnome-shell/issues/183 | ||
508 | 18 | Forwarded: https://gitlab.gnome.org/GNOME/gnome-calculator/merge_requests/10 | ||
509 | 19 | Applied-Upstream: yes, 3.31.1 | ||
510 | 20 | --- | ||
511 | 21 | search-provider/search-provider.vala | 79 ++++++++++++++++++++---------------- | ||
512 | 22 | 1 file changed, 45 insertions(+), 34 deletions(-) | ||
513 | 23 | |||
514 | 24 | diff --git a/search-provider/search-provider.vala b/search-provider/search-provider.vala | ||
515 | 25 | index a3c57f7..af2779e 100644 | ||
516 | 26 | --- a/search-provider/search-provider.vala | ||
517 | 27 | +++ b/search-provider/search-provider.vala | ||
518 | 28 | @@ -14,10 +14,13 @@ | ||
519 | 29 | public class SearchProvider : Object | ||
520 | 30 | { | ||
521 | 31 | private unowned SearchProviderApp application; | ||
522 | 32 | - private Cancellable cancellable = new Cancellable (); | ||
523 | 33 | + private Cancellable cancellable; | ||
524 | 34 | + | ||
525 | 35 | + private HashTable<string, string> cached_equations; | ||
526 | 36 | public SearchProvider (SearchProviderApp app) | ||
527 | 37 | { | ||
528 | 38 | application = app; | ||
529 | 39 | + cached_equations = new HashTable<string, string> (str_hash, str_equal); | ||
530 | 40 | } | ||
531 | 41 | |||
532 | 42 | ~SearchProvider () | ||
533 | 43 | @@ -29,9 +32,7 @@ public class SearchProvider : Object | ||
534 | 44 | public void cancel () | ||
535 | 45 | { | ||
536 | 46 | if (cancellable != null) | ||
537 | 47 | - { | ||
538 | 48 | cancellable.cancel (); | ||
539 | 49 | - } | ||
540 | 50 | } | ||
541 | 51 | |||
542 | 52 | private static string terms_to_equation (string[] terms) | ||
543 | 53 | @@ -60,7 +61,9 @@ public class SearchProvider : Object | ||
544 | 54 | error ("Failed to spawn Calculator: %s", e.message); | ||
545 | 55 | } | ||
546 | 56 | |||
547 | 57 | - cancellable = new Cancellable (); | ||
548 | 58 | + if (cancellable == null) | ||
549 | 59 | + cancellable = new Cancellable (); | ||
550 | 60 | + | ||
551 | 61 | cancellable.cancelled.connect (() => { | ||
552 | 62 | subprocess.force_exit (); | ||
553 | 63 | cancellable = null; | ||
554 | 64 | @@ -71,29 +74,36 @@ public class SearchProvider : Object | ||
555 | 65 | return subprocess; | ||
556 | 66 | } | ||
557 | 67 | |||
558 | 68 | - private async bool can_parse (string[] terms) | ||
559 | 69 | + private async bool solve_equation (string equation) | ||
560 | 70 | { | ||
561 | 71 | - try | ||
562 | 72 | - { | ||
563 | 73 | - var tsep_string = Posix.nl_langinfo (Posix.NLItem.THOUSEP); | ||
564 | 74 | - if (tsep_string == null || tsep_string == "") | ||
565 | 75 | - tsep_string = " "; | ||
566 | 76 | + string? result; | ||
567 | 77 | |||
568 | 78 | - var decimal = Posix.nl_langinfo (Posix.NLItem.RADIXCHAR); | ||
569 | 79 | - if (decimal == null) | ||
570 | 80 | - decimal = ""; | ||
571 | 81 | + cancel(); | ||
572 | 82 | |||
573 | 83 | - // "normalize" input to a format known to double.try_parse | ||
574 | 84 | - var equation = terms_to_equation (terms).replace (tsep_string, "").replace (decimal, "."); | ||
575 | 85 | + var tsep_string = Posix.nl_langinfo (Posix.NLItem.THOUSEP); | ||
576 | 86 | + if (tsep_string == null || tsep_string == "") | ||
577 | 87 | + tsep_string = " "; | ||
578 | 88 | |||
579 | 89 | - cancel(); | ||
580 | 90 | + var decimal = Posix.nl_langinfo (Posix.NLItem.RADIXCHAR); | ||
581 | 91 | + if (decimal == null) | ||
582 | 92 | + decimal = ""; | ||
583 | 93 | |||
584 | 94 | - // if the search is a plain number, don't process it | ||
585 | 95 | - if (double.try_parse (equation)) { | ||
586 | 96 | - return false; | ||
587 | 97 | - } | ||
588 | 98 | + // "normalize" input to a format known to double.try_parse | ||
589 | 99 | + var normalized_equation = equation.replace (tsep_string, "").replace (decimal, "."); | ||
590 | 100 | |||
591 | 101 | - (yield solve_subprocess (equation)).wait_check (cancellable); | ||
592 | 102 | + // if the search is a plain number, don't process it | ||
593 | 103 | + if (double.try_parse (normalized_equation)) { | ||
594 | 104 | + return false; | ||
595 | 105 | + } | ||
596 | 106 | + | ||
597 | 107 | + if (cached_equations.lookup (equation) != null) | ||
598 | 108 | + return true; | ||
599 | 109 | + | ||
600 | 110 | + try | ||
601 | 111 | + { | ||
602 | 112 | + var subprocess = yield solve_subprocess (normalized_equation); | ||
603 | 113 | + yield subprocess.communicate_utf8_async (null, cancellable, out result, null); | ||
604 | 114 | + subprocess.wait_check (cancellable); | ||
605 | 115 | } | ||
606 | 116 | catch (SpawnError e) | ||
607 | 117 | { | ||
608 | 118 | @@ -104,14 +114,17 @@ public class SearchProvider : Object | ||
609 | 119 | return false; | ||
610 | 120 | } | ||
611 | 121 | |||
612 | 122 | + cached_equations.insert (equation, result.strip ()); | ||
613 | 123 | + | ||
614 | 124 | return true; | ||
615 | 125 | } | ||
616 | 126 | |||
617 | 127 | private async string[] get_result_identifier (string[] terms) | ||
618 | 128 | { | ||
619 | 129 | /* We have at most one result: the search terms as one string */ | ||
620 | 130 | - if (yield can_parse (terms)) | ||
621 | 131 | - return { terms_to_equation (terms) }; | ||
622 | 132 | + var equation = terms_to_equation (terms); | ||
623 | 133 | + if (yield solve_equation (equation)) | ||
624 | 134 | + return { equation }; | ||
625 | 135 | else | ||
626 | 136 | return new string[0]; | ||
627 | 137 | } | ||
628 | 138 | @@ -129,24 +142,22 @@ public class SearchProvider : Object | ||
629 | 139 | public async HashTable<string, Variant>[] get_result_metas (string[] results, GLib.BusName sender) | ||
630 | 140 | requires (results.length == 1) | ||
631 | 141 | { | ||
632 | 142 | - string stdout_buf; | ||
633 | 143 | - string stderr_buf; | ||
634 | 144 | + string equation; | ||
635 | 145 | + string result; | ||
636 | 146 | |||
637 | 147 | - try | ||
638 | 148 | - { | ||
639 | 149 | - var subprocess = yield solve_subprocess (results[0]); | ||
640 | 150 | - yield subprocess.communicate_utf8_async (null, cancellable, out stdout_buf, out stderr_buf); | ||
641 | 151 | - } | ||
642 | 152 | - catch (Error e) | ||
643 | 153 | - { | ||
644 | 154 | + equation = terms_to_equation (results); | ||
645 | 155 | + | ||
646 | 156 | + if (!yield solve_equation (equation)) | ||
647 | 157 | return new HashTable<string, Variant>[0]; | ||
648 | 158 | - } | ||
649 | 159 | + | ||
650 | 160 | + result = cached_equations.lookup (equation); | ||
651 | 161 | + assert (result != null); | ||
652 | 162 | |||
653 | 163 | var metadata = new HashTable<string, Variant>[1]; | ||
654 | 164 | metadata[0] = new HashTable<string, Variant>(str_hash, str_equal); | ||
655 | 165 | metadata[0].insert ("id", results[0]); | ||
656 | 166 | metadata[0].insert ("name", results[0] ); | ||
657 | 167 | - metadata[0].insert ("description", " = " + stdout_buf.strip ()); | ||
658 | 168 | + metadata[0].insert ("description", @" = $result"); | ||
659 | 169 | |||
660 | 170 | return metadata; | ||
661 | 171 | } | ||
662 | diff --git a/debian/patches/search-provider-cache-only-a-limited-number-of-equations.patch b/debian/patches/search-provider-cache-only-a-limited-number-of-equations.patch | |||
663 | 0 | new file mode 100644 | 172 | new file mode 100644 |
664 | index 0000000..651aa28 | |||
665 | --- /dev/null | |||
666 | +++ b/debian/patches/search-provider-cache-only-a-limited-number-of-equations.patch | |||
667 | @@ -0,0 +1,45 @@ | |||
668 | 1 | From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> | ||
669 | 2 | Date: Mon, 27 Aug 2018 18:56:09 +0200 | ||
670 | 3 | Subject: search-provider: cache only a limited number of equations | ||
671 | 4 | |||
672 | 5 | Bug-Ubuntu: https://launchpad.net/bugs/1756826 | ||
673 | 6 | Bug-GNOME: https://gitlab.gnome.org/GNOME/gnome-shell/issues/183 | ||
674 | 7 | Forwarded: https://gitlab.gnome.org/GNOME/gnome-calculator/merge_requests/10 | ||
675 | 8 | Applied-Upstream: yes, 3.31.1 | ||
676 | 9 | --- | ||
677 | 10 | search-provider/search-provider.vala | 9 +++++++++ | ||
678 | 11 | 1 file changed, 9 insertions(+) | ||
679 | 12 | |||
680 | 13 | diff --git a/search-provider/search-provider.vala b/search-provider/search-provider.vala | ||
681 | 14 | index af2779e..fc72128 100644 | ||
682 | 15 | --- a/search-provider/search-provider.vala | ||
683 | 16 | +++ b/search-provider/search-provider.vala | ||
684 | 17 | @@ -16,10 +16,15 @@ public class SearchProvider : Object | ||
685 | 18 | private unowned SearchProviderApp application; | ||
686 | 19 | private Cancellable cancellable; | ||
687 | 20 | |||
688 | 21 | + private const int MAX_CACHED_OPERATIONS = 10; | ||
689 | 22 | + private Queue<string> queued_equations; | ||
690 | 23 | private HashTable<string, string> cached_equations; | ||
691 | 24 | + | ||
692 | 25 | public SearchProvider (SearchProviderApp app) | ||
693 | 26 | { | ||
694 | 27 | application = app; | ||
695 | 28 | + | ||
696 | 29 | + queued_equations = new Queue<string> (); | ||
697 | 30 | cached_equations = new HashTable<string, string> (str_hash, str_equal); | ||
698 | 31 | } | ||
699 | 32 | |||
700 | 33 | @@ -114,8 +119,12 @@ public class SearchProvider : Object | ||
701 | 34 | return false; | ||
702 | 35 | } | ||
703 | 36 | |||
704 | 37 | + queued_equations.push_tail (equation); | ||
705 | 38 | cached_equations.insert (equation, result.strip ()); | ||
706 | 39 | |||
707 | 40 | + if (queued_equations.length > MAX_CACHED_OPERATIONS) | ||
708 | 41 | + cached_equations.remove (queued_equations.pop_head ()); | ||
709 | 42 | + | ||
710 | 43 | return true; | ||
711 | 44 | } | ||
712 | 45 | |||
713 | diff --git a/debian/patches/search-provider-cancel-the-current-process-on-new-calcula.patch b/debian/patches/search-provider-cancel-the-current-process-on-new-calcula.patch | |||
714 | 0 | new file mode 100644 | 46 | new file mode 100644 |
715 | index 0000000..26435e2 | |||
716 | --- /dev/null | |||
717 | +++ b/debian/patches/search-provider-cancel-the-current-process-on-new-calcula.patch | |||
718 | @@ -0,0 +1,30 @@ | |||
719 | 1 | From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> | ||
720 | 2 | Date: Thu, 30 Aug 2018 18:47:16 +0200 | ||
721 | 3 | Subject: search-provider: cancel the current process on new calculation | ||
722 | 4 | request | ||
723 | 5 | |||
724 | 6 | As there's just one shell running at time, there's no point of supporting | ||
725 | 7 | parallel calls, we can just safely refer to the last equation as the only one | ||
726 | 8 | we need to compute. | ||
727 | 9 | |||
728 | 10 | Bug-Ubuntu: https://launchpad.net/bugs/1756826 | ||
729 | 11 | Bug-GNOME: https://gitlab.gnome.org/GNOME/gnome-shell/issues/183 | ||
730 | 12 | Forwarded: https://gitlab.gnome.org/GNOME/gnome-calculator/merge_requests/10 | ||
731 | 13 | Applied-Upstream: yes, 3.31.1 | ||
732 | 14 | --- | ||
733 | 15 | search-provider/search-provider.vala | 2 ++ | ||
734 | 16 | 1 file changed, 2 insertions(+) | ||
735 | 17 | |||
736 | 18 | diff --git a/search-provider/search-provider.vala b/search-provider/search-provider.vala | ||
737 | 19 | index df37b86..a3c57f7 100644 | ||
738 | 20 | --- a/search-provider/search-provider.vala | ||
739 | 21 | +++ b/search-provider/search-provider.vala | ||
740 | 22 | @@ -86,6 +86,8 @@ public class SearchProvider : Object | ||
741 | 23 | // "normalize" input to a format known to double.try_parse | ||
742 | 24 | var equation = terms_to_equation (terms).replace (tsep_string, "").replace (decimal, "."); | ||
743 | 25 | |||
744 | 26 | + cancel(); | ||
745 | 27 | + | ||
746 | 28 | // if the search is a plain number, don't process it | ||
747 | 29 | if (double.try_parse (equation)) { | ||
748 | 30 | return false; | ||
749 | diff --git a/debian/patches/search-provider-renew-inactivity-timeout-at-each-calculat.patch b/debian/patches/search-provider-renew-inactivity-timeout-at-each-calculat.patch | |||
750 | 0 | new file mode 100644 | 31 | new file mode 100644 |
751 | index 0000000..274aae1 | |||
752 | --- /dev/null | |||
753 | +++ b/debian/patches/search-provider-renew-inactivity-timeout-at-each-calculat.patch | |||
754 | @@ -0,0 +1,61 @@ | |||
755 | 1 | From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> | ||
756 | 2 | Date: Fri, 24 Aug 2018 07:10:17 +0200 | ||
757 | 3 | Subject: search-provider: renew inactivity timeout at each calculator run | ||
758 | 4 | |||
759 | 5 | As per the async rewrite, now the daemon inactivity timeout might happen | ||
760 | 6 | when another call has just been done, while we don't want this to be the case. | ||
761 | 7 | |||
762 | 8 | So, everytime we do a subprocess call, let's renew the application timeout. | ||
763 | 9 | |||
764 | 10 | Bug-Ubuntu: https://launchpad.net/bugs/1756826 | ||
765 | 11 | Bug-GNOME: https://gitlab.gnome.org/GNOME/gnome-shell/issues/183 | ||
766 | 12 | Forwarded: https://gitlab.gnome.org/GNOME/gnome-calculator/merge_requests/100 | ||
767 | 13 | Applied-Upstream: yes, 3.31.1 | ||
768 | 14 | --- | ||
769 | 15 | search-provider/search-provider.vala | 14 +++++++++++++- | ||
770 | 16 | 1 file changed, 13 insertions(+), 1 deletion(-) | ||
771 | 17 | |||
772 | 18 | diff --git a/search-provider/search-provider.vala b/search-provider/search-provider.vala | ||
773 | 19 | index 659f73d..7e54fa6 100644 | ||
774 | 20 | --- a/search-provider/search-provider.vala | ||
775 | 21 | +++ b/search-provider/search-provider.vala | ||
776 | 22 | @@ -13,7 +13,12 @@ | ||
777 | 23 | [DBus (name = "org.gnome.Shell.SearchProvider2")] | ||
778 | 24 | public class SearchProvider : Object | ||
779 | 25 | { | ||
780 | 26 | + private unowned SearchProviderApp application; | ||
781 | 27 | private Cancellable cancellable = new Cancellable (); | ||
782 | 28 | + public SearchProvider (SearchProviderApp app) | ||
783 | 29 | + { | ||
784 | 30 | + application = app; | ||
785 | 31 | + } | ||
786 | 32 | |||
787 | 33 | ~SearchProvider () | ||
788 | 34 | { | ||
789 | 35 | @@ -71,6 +76,8 @@ public class SearchProvider : Object | ||
790 | 36 | cancellable = null; | ||
791 | 37 | }); | ||
792 | 38 | |||
793 | 39 | + application.renew_inactivity_timeout (); | ||
794 | 40 | + | ||
795 | 41 | yield subprocess.communicate_utf8_async (null, cancellable, out solution_buf, out stderr_buf); | ||
796 | 42 | } | ||
797 | 43 | catch (Error e) | ||
798 | 44 | @@ -197,11 +204,16 @@ public class SearchProviderApp : Application | ||
799 | 45 | Object (application_id: "org.gnome.Calculator.SearchProvider", | ||
800 | 46 | flags: ApplicationFlags.IS_SERVICE, | ||
801 | 47 | inactivity_timeout: 60000); | ||
802 | 48 | + | ||
803 | 49 | + public void renew_inactivity_timeout () | ||
804 | 50 | + { | ||
805 | 51 | + this.hold (); | ||
806 | 52 | + this.release (); | ||
807 | 53 | } | ||
808 | 54 | |||
809 | 55 | public override bool dbus_register (DBusConnection connection, string object_path) | ||
810 | 56 | { | ||
811 | 57 | - SearchProvider search_provider = new SearchProvider (); | ||
812 | 58 | + SearchProvider search_provider = new SearchProvider (this); | ||
813 | 59 | |||
814 | 60 | try | ||
815 | 61 | { | ||
816 | diff --git a/debian/patches/search-provider-simplify-solve_subprocess.patch b/debian/patches/search-provider-simplify-solve_subprocess.patch | |||
817 | 0 | new file mode 100644 | 62 | new file mode 100644 |
818 | index 0000000..4f9cde8 | |||
819 | --- /dev/null | |||
820 | +++ b/debian/patches/search-provider-simplify-solve_subprocess.patch | |||
821 | @@ -0,0 +1,114 @@ | |||
822 | 1 | From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> | ||
823 | 2 | Date: Fri, 24 Aug 2018 07:31:37 +0200 | ||
824 | 3 | Subject: search-provider: simplify solve_subprocess | ||
825 | 4 | |||
826 | 5 | Only return a subprocess in solve_subprocess and make the callers deal with | ||
827 | 6 | the actual operation to perform. | ||
828 | 7 | |||
829 | 8 | Bug-Ubuntu: https://launchpad.net/bugs/1756826 | ||
830 | 9 | Bug-GNOME: https://gitlab.gnome.org/GNOME/gnome-shell/issues/183 | ||
831 | 10 | Forwarded: https://gitlab.gnome.org/GNOME/gnome-calculator/merge_requests/10 | ||
832 | 11 | Applied-Upstream: yes, 3.31.1 | ||
833 | 12 | --- | ||
834 | 13 | search-provider/search-provider.vala | 49 ++++++++++-------------------------- | ||
835 | 14 | 1 file changed, 13 insertions(+), 36 deletions(-) | ||
836 | 15 | |||
837 | 16 | diff --git a/search-provider/search-provider.vala b/search-provider/search-provider.vala | ||
838 | 17 | index 9035c58..df37b86 100644 | ||
839 | 18 | --- a/search-provider/search-provider.vala | ||
840 | 19 | +++ b/search-provider/search-provider.vala | ||
841 | 20 | @@ -39,7 +39,7 @@ public class SearchProvider : Object | ||
842 | 21 | return string.joinv (" ", terms); | ||
843 | 22 | } | ||
844 | 23 | |||
845 | 24 | - private async Subprocess solve_subprocess (string equation, bool return_solution = false, out string? solution_buf = null) throws Error | ||
846 | 25 | + private async Subprocess solve_subprocess (string equation) throws Error | ||
847 | 26 | { | ||
848 | 27 | Subprocess subprocess; | ||
849 | 28 | string[] argv = {"gnome-calculator", "--solve"}; | ||
850 | 29 | @@ -52,13 +52,7 @@ public class SearchProvider : Object | ||
851 | 30 | { | ||
852 | 31 | // Eat output so that it doesn't wind up in the journal. It's | ||
853 | 32 | // expected that most searches are not valid calculator input. | ||
854 | 33 | - var flags = SubprocessFlags.STDERR_PIPE; | ||
855 | 34 | - | ||
856 | 35 | - if (return_solution) | ||
857 | 36 | - { | ||
858 | 37 | - flags |= SubprocessFlags.STDOUT_PIPE; | ||
859 | 38 | - } | ||
860 | 39 | - | ||
861 | 40 | + var flags = SubprocessFlags.STDOUT_PIPE | SubprocessFlags.STDERR_PIPE; | ||
862 | 41 | subprocess = new Subprocess.newv (argv, flags); | ||
863 | 42 | } | ||
864 | 43 | catch (Error e) | ||
865 | 44 | @@ -66,31 +60,13 @@ public class SearchProvider : Object | ||
866 | 45 | error ("Failed to spawn Calculator: %s", e.message); | ||
867 | 46 | } | ||
868 | 47 | |||
869 | 48 | - try | ||
870 | 49 | - { | ||
871 | 50 | - string stderr_buf; | ||
872 | 51 | - | ||
873 | 52 | - cancellable = new Cancellable (); | ||
874 | 53 | - cancellable.cancelled.connect (() => { | ||
875 | 54 | - subprocess.force_exit (); | ||
876 | 55 | - cancellable = null; | ||
877 | 56 | - }); | ||
878 | 57 | - | ||
879 | 58 | - application.renew_inactivity_timeout (); | ||
880 | 59 | + cancellable = new Cancellable (); | ||
881 | 60 | + cancellable.cancelled.connect (() => { | ||
882 | 61 | + subprocess.force_exit (); | ||
883 | 62 | + cancellable = null; | ||
884 | 63 | + }); | ||
885 | 64 | |||
886 | 65 | - yield subprocess.communicate_utf8_async (null, cancellable, out solution_buf, out stderr_buf); | ||
887 | 66 | - } | ||
888 | 67 | - catch (Error e) | ||
889 | 68 | - { | ||
890 | 69 | - if (e is IOError.CANCELLED) | ||
891 | 70 | - { | ||
892 | 71 | - throw e; | ||
893 | 72 | - } | ||
894 | 73 | - else | ||
895 | 74 | - { | ||
896 | 75 | - error ("Failed reading result: %s", e.message); | ||
897 | 76 | - } | ||
898 | 77 | - } | ||
899 | 78 | + application.renew_inactivity_timeout (); | ||
900 | 79 | |||
901 | 80 | return subprocess; | ||
902 | 81 | } | ||
903 | 82 | @@ -115,8 +91,7 @@ public class SearchProvider : Object | ||
904 | 83 | return false; | ||
905 | 84 | } | ||
906 | 85 | |||
907 | 86 | - var subprocess = yield solve_subprocess (equation); | ||
908 | 87 | - yield subprocess.wait_check_async (); | ||
909 | 88 | + (yield solve_subprocess (equation)).wait_check (cancellable); | ||
910 | 89 | } | ||
911 | 90 | catch (SpawnError e) | ||
912 | 91 | { | ||
913 | 92 | @@ -153,10 +128,12 @@ public class SearchProvider : Object | ||
914 | 93 | requires (results.length == 1) | ||
915 | 94 | { | ||
916 | 95 | string stdout_buf; | ||
917 | 96 | + string stderr_buf; | ||
918 | 97 | |||
919 | 98 | try | ||
920 | 99 | { | ||
921 | 100 | - yield solve_subprocess (results[0], true, out stdout_buf); | ||
922 | 101 | + var subprocess = yield solve_subprocess (results[0]); | ||
923 | 102 | + yield subprocess.communicate_utf8_async (null, cancellable, out stdout_buf, out stderr_buf); | ||
924 | 103 | } | ||
925 | 104 | catch (Error e) | ||
926 | 105 | { | ||
927 | 106 | @@ -167,7 +144,7 @@ public class SearchProvider : Object | ||
928 | 107 | metadata[0] = new HashTable<string, Variant>(str_hash, str_equal); | ||
929 | 108 | metadata[0].insert ("id", results[0]); | ||
930 | 109 | metadata[0].insert ("name", results[0] ); | ||
931 | 110 | - metadata[0].insert ("description", " = " + stdout_buf.strip() ); | ||
932 | 111 | + metadata[0].insert ("description", " = " + stdout_buf.strip ()); | ||
933 | 112 | |||
934 | 113 | return metadata; | ||
935 | 114 | } | ||
936 | diff --git a/debian/patches/search-provider-stop-normalizing-the-equation-twice.patch b/debian/patches/search-provider-stop-normalizing-the-equation-twice.patch | |||
937 | 0 | new file mode 100644 | 115 | new file mode 100644 |
938 | index 0000000..6882583 | |||
939 | --- /dev/null | |||
940 | +++ b/debian/patches/search-provider-stop-normalizing-the-equation-twice.patch | |||
941 | @@ -0,0 +1,48 @@ | |||
942 | 1 | From: Pascal Nowack <Pascal.Nowack@gmx.de> | ||
943 | 2 | Date: Sun, 31 Mar 2019 14:11:16 +0200 | ||
944 | 3 | Subject: search-provider: stop normalizing the equation twice | ||
945 | 4 | |||
946 | 5 | When an equation is given by the g-s overview, g-c | ||
947 | 6 | will solve this equation, where it will be first | ||
948 | 7 | normalized and then solved. | ||
949 | 8 | This is done by running a subprocess, where g-c | ||
950 | 9 | will call g-c in this subprocess with the | ||
951 | 10 | "--solve" argument. | ||
952 | 11 | With this "--solve" argument, the equation will | ||
953 | 12 | also be normalized. | ||
954 | 13 | However, when an equation is given by the g-s | ||
955 | 14 | overview, it will also be normalized in a check, | ||
956 | 15 | that happens before the solve process, to not to | ||
957 | 16 | process single numbers given by the g-s overview. | ||
958 | 17 | This normalized equation will then be used to | ||
959 | 18 | invoke the subprocess to solve the equation, | ||
960 | 19 | leading into normalizing the already normalized | ||
961 | 20 | equation and therefore resulting into wrong | ||
962 | 21 | results when the equation itself contains | ||
963 | 22 | decimal numbers. | ||
964 | 23 | |||
965 | 24 | Solve this issue, by invoking the subprocess with | ||
966 | 25 | the unnormalized equation, instead of the | ||
967 | 26 | normalized one, to not to normalize the | ||
968 | 27 | equation twice. | ||
969 | 28 | |||
970 | 29 | Closes: https://gitlab.gnome.org/GNOME/gnome-calculator/issues/104 | ||
971 | 30 | |||
972 | 31 | Bug-GNOME: https://gitlab.gnome.org/GNOME/gnome-shell/issues/104 | ||
973 | 32 | --- | ||
974 | 33 | search-provider/search-provider.vala | 2 +- | ||
975 | 34 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
976 | 35 | |||
977 | 36 | diff --git a/search-provider/search-provider.vala b/search-provider/search-provider.vala | ||
978 | 37 | index 9823ef7..7f9f51e 100644 | ||
979 | 38 | --- a/search-provider/search-provider.vala | ||
980 | 39 | +++ b/search-provider/search-provider.vala | ||
981 | 40 | @@ -129,7 +129,7 @@ public class SearchProvider : Object | ||
982 | 41 | |||
983 | 42 | try | ||
984 | 43 | { | ||
985 | 44 | - var subprocess = yield solve_subprocess (normalized_equation); | ||
986 | 45 | + var subprocess = yield solve_subprocess (equation); | ||
987 | 46 | yield subprocess.communicate_utf8_async (null, cancellable, out result, null); | ||
988 | 47 | subprocess.wait_check (cancellable); | ||
989 | 48 | } | ||
990 | diff --git a/debian/patches/series b/debian/patches/series | |||
991 | index e69de29..f088177 100644 | |||
992 | --- a/debian/patches/series | |||
993 | +++ b/debian/patches/series | |||
994 | @@ -0,0 +1,11 @@ | |||
995 | 1 | search-provider-Use-async-calls-cancel-search-on-inactivi.patch | ||
996 | 2 | search-provider-renew-inactivity-timeout-at-each-calculat.patch | ||
997 | 3 | search-provider-Use-lower-inactivity-timeout.patch | ||
998 | 4 | search-provider-simplify-solve_subprocess.patch | ||
999 | 5 | search-provider-cancel-the-current-process-on-new-calcula.patch | ||
1000 | 6 | search-provider-cache-equations-avoiding-spawning-calcula.patch | ||
1001 | 7 | search-provider-cache-only-a-limited-number-of-equations.patch | ||
1002 | 8 | search-provider-Handle-errors-gracefully.patch | ||
1003 | 9 | ubuntu/search-provider-Cancel-operations-on-XUbuntuCancel.patch | ||
1004 | 10 | search-provider-stop-normalizing-the-equation-twice.patch | ||
1005 | 11 | Use-GLib.List.deep_copy-to-fix-type-argument-mismatch.patch | ||
1006 | diff --git a/debian/patches/ubuntu/search-provider-Cancel-operations-on-XUbuntuCancel.patch b/debian/patches/ubuntu/search-provider-Cancel-operations-on-XUbuntuCancel.patch | |||
1007 | 0 | new file mode 100644 | 12 | new file mode 100644 |
1008 | index 0000000..edc9419 | |||
1009 | --- /dev/null | |||
1010 | +++ b/debian/patches/ubuntu/search-provider-Cancel-operations-on-XUbuntuCancel.patch | |||
1011 | @@ -0,0 +1,118 @@ | |||
1012 | 1 | From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net> | ||
1013 | 2 | Date: Tue, 28 Aug 2018 04:12:20 +0200 | ||
1014 | 3 | Subject: search-provider: Cancel operations on XUbuntuCancel | ||
1015 | 4 | |||
1016 | 5 | Stop process and any computation on XUbuntuCancel method, if the caller | ||
1017 | 6 | was the same triggering the last operation. | ||
1018 | 7 | |||
1019 | 8 | Fixes LP: #1756826 | ||
1020 | 9 | |||
1021 | 10 | Bug-Ubuntu: https://launchpad.net/bugs/1756826 | ||
1022 | 11 | Bug-GNOME: https://gitlab.gnome.org/GNOME/gnome-shell/issues/183 | ||
1023 | 12 | Forwarded: not-needed | ||
1024 | 13 | --- | ||
1025 | 14 | search-provider/search-provider.vala | 46 ++++++++++++++++++++++++++++++++---- | ||
1026 | 15 | 1 file changed, 41 insertions(+), 5 deletions(-) | ||
1027 | 16 | |||
1028 | 17 | diff --git a/search-provider/search-provider.vala b/search-provider/search-provider.vala | ||
1029 | 18 | index a48c440..9823ef7 100644 | ||
1030 | 19 | --- a/search-provider/search-provider.vala | ||
1031 | 20 | +++ b/search-provider/search-provider.vala | ||
1032 | 21 | @@ -10,11 +10,33 @@ | ||
1033 | 22 | * license. | ||
1034 | 23 | */ | ||
1035 | 24 | |||
1036 | 25 | +public class CallerTracker : Object | ||
1037 | 26 | +{ | ||
1038 | 27 | + public BusName? bus { get; set; } | ||
1039 | 28 | +} | ||
1040 | 29 | + | ||
1041 | 30 | +public class Caller | ||
1042 | 31 | +{ | ||
1043 | 32 | + private CallerTracker caller_tracker; | ||
1044 | 33 | + | ||
1045 | 34 | + public Caller (CallerTracker c, BusName sender) | ||
1046 | 35 | + { | ||
1047 | 36 | + caller_tracker = c; | ||
1048 | 37 | + caller_tracker.bus = sender; | ||
1049 | 38 | + } | ||
1050 | 39 | + | ||
1051 | 40 | + ~Caller () | ||
1052 | 41 | + { | ||
1053 | 42 | + caller_tracker.bus = null; | ||
1054 | 43 | + } | ||
1055 | 44 | +} | ||
1056 | 45 | + | ||
1057 | 46 | [DBus (name = "org.gnome.Shell.SearchProvider2")] | ||
1058 | 47 | public class SearchProvider : Object | ||
1059 | 48 | { | ||
1060 | 49 | private unowned SearchProviderApp application; | ||
1061 | 50 | private Cancellable cancellable; | ||
1062 | 51 | + private CallerTracker caller_tracker; | ||
1063 | 52 | |||
1064 | 53 | private const int MAX_CACHED_OPERATIONS = 10; | ||
1065 | 54 | private Queue<string> queued_equations; | ||
1066 | 55 | @@ -24,6 +46,7 @@ public class SearchProvider : Object | ||
1067 | 56 | { | ||
1068 | 57 | application = app; | ||
1069 | 58 | |||
1070 | 59 | + caller_tracker = new CallerTracker (); | ||
1071 | 60 | queued_equations = new Queue<string> (); | ||
1072 | 61 | cached_equations = new HashTable<string, string> (str_hash, str_equal); | ||
1073 | 62 | } | ||
1074 | 63 | @@ -129,8 +152,10 @@ public class SearchProvider : Object | ||
1075 | 64 | return true; | ||
1076 | 65 | } | ||
1077 | 66 | |||
1078 | 67 | - private async string[] get_result_identifier (string[] terms) throws Error | ||
1079 | 68 | + private async string[] get_result_identifier (string[] terms, GLib.BusName sender) throws Error | ||
1080 | 69 | { | ||
1081 | 70 | + var owner = new Caller (caller_tracker, sender); (void) owner; | ||
1082 | 71 | + | ||
1083 | 72 | /* We have at most one result: the search terms as one string */ | ||
1084 | 73 | var equation = terms_to_equation (terms); | ||
1085 | 74 | if (yield solve_equation (equation)) | ||
1086 | 75 | @@ -139,14 +164,14 @@ public class SearchProvider : Object | ||
1087 | 76 | return new string[0]; | ||
1088 | 77 | } | ||
1089 | 78 | |||
1090 | 79 | - public async string[] get_initial_result_set (string[] terms) throws Error | ||
1091 | 80 | + public async string[] get_initial_result_set (string[] terms, GLib.BusName sender) throws Error | ||
1092 | 81 | { | ||
1093 | 82 | - return yield get_result_identifier (terms); | ||
1094 | 83 | + return yield get_result_identifier (terms, sender); | ||
1095 | 84 | } | ||
1096 | 85 | |||
1097 | 86 | - public async string[] get_subsearch_result_set (string[] previous_results, string[] terms) throws Error | ||
1098 | 87 | + public async string[] get_subsearch_result_set (string[] previous_results, string[] terms, GLib.BusName sender) throws Error | ||
1099 | 88 | { | ||
1100 | 89 | - return yield get_result_identifier (terms); | ||
1101 | 90 | + return yield get_result_identifier (terms, sender); | ||
1102 | 91 | } | ||
1103 | 92 | |||
1104 | 93 | public async HashTable<string, Variant>[] get_result_metas (string[] results, GLib.BusName sender) throws Error | ||
1105 | 94 | @@ -155,6 +180,8 @@ public class SearchProvider : Object | ||
1106 | 95 | string equation; | ||
1107 | 96 | string result; | ||
1108 | 97 | |||
1109 | 98 | + var owner = new Caller (caller_tracker, sender); (void) owner; | ||
1110 | 99 | + | ||
1111 | 100 | equation = terms_to_equation (results); | ||
1112 | 101 | |||
1113 | 102 | if (!yield solve_equation (equation)) | ||
1114 | 103 | @@ -172,6 +199,15 @@ public class SearchProvider : Object | ||
1115 | 104 | return metadata; | ||
1116 | 105 | } | ||
1117 | 106 | |||
1118 | 107 | + public async void x_ubuntu_cancel (BusName sender) | ||
1119 | 108 | + { | ||
1120 | 109 | + if (caller_tracker.bus == sender) | ||
1121 | 110 | + { | ||
1122 | 111 | + debug ("Cancelling Request"); | ||
1123 | 112 | + cancel (); | ||
1124 | 113 | + } | ||
1125 | 114 | + } | ||
1126 | 115 | + | ||
1127 | 116 | private static void spawn_and_display_equation (string[] terms) throws Error | ||
1128 | 117 | { | ||
1129 | 118 | try |