Merge lp:~attente/indicator-keyboard/ibus-panel into lp:indicator-keyboard
- ibus-panel
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Sebastien Bacher |
Approved revision: | 268 |
Merged at revision: | 275 |
Proposed branch: | lp:~attente/indicator-keyboard/ibus-panel |
Merge into: | lp:indicator-keyboard |
Diff against target: |
555 lines (+397/-19) 4 files modified
lib/Makefile.am (+3/-1) lib/ibus-menu.vala (+318/-0) lib/main.vala (+68/-18) lib/source.vala (+8/-0) |
To merge this branch: | bzr merge lp:~attente/indicator-keyboard/ibus-panel |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Sebastien Bacher | user testing | Approve | |
PS Jenkins bot (community) | continuous-integration | Approve | |
Review via email: mp+207240@code.launchpad.net |
Commit message
Implement the IBus panel within the indicator.
Description of the change
Implement the IBus panel within the indicator.
PS Jenkins bot (ps-jenkins) wrote : | # |
Sebastien Bacher (seb128) wrote : | # |
Testing building/running the new version, it seems to work fine. I would welcome testing from somebody who use IMs regularly though since I only use layouts.
I'm going to code review tomorrow (looks fine from a first glance) and try to land that before ff (if somebody else wants to help and do a code review that would be welcome though)
Ted Gould (ted) wrote : | # |
Sad to see that there isn't any tests and not a single comment.
Looking through the code I don't see any specific issues.
I'm curious about the UI thought, I would have expected these options to be radio items: http://
Ted Gould (ted) wrote : | # |
Oh, looks like I lost "Japanese (Anthy)" as a label as well.
- 268. By William Hua
-
Break reference cycle which caused some inconsistent action handling.
Preview Diff
1 | === modified file 'lib/Makefile.am' | |||
2 | --- lib/Makefile.am 2013-11-22 16:44:45 +0000 | |||
3 | +++ lib/Makefile.am 2014-02-20 04:00:27 +0000 | |||
4 | @@ -2,12 +2,14 @@ | |||
5 | 2 | 2 | ||
6 | 3 | AM_CFLAGS = -w -DGNOME_DESKTOP_USE_UNSTABLE_API | 3 | AM_CFLAGS = -w -DGNOME_DESKTOP_USE_UNSTABLE_API |
7 | 4 | AM_LDFLAGS = -lm | 4 | AM_LDFLAGS = -lm |
9 | 5 | AM_VALAFLAGS = --metadatadir $(top_srcdir)/deps \ | 5 | AM_VALAFLAGS = --enable-experimental-non-null \ |
10 | 6 | --metadatadir $(top_srcdir)/deps \ | ||
11 | 6 | --vapidir $(top_srcdir)/deps | 7 | --vapidir $(top_srcdir)/deps |
12 | 7 | 8 | ||
13 | 8 | indicator_keyboard_service_SOURCES = main.vala \ | 9 | indicator_keyboard_service_SOURCES = main.vala \ |
14 | 9 | source.vala \ | 10 | source.vala \ |
15 | 10 | common.vala \ | 11 | common.vala \ |
16 | 12 | ibus-menu.vala \ | ||
17 | 11 | window-stack.vala \ | 13 | window-stack.vala \ |
18 | 12 | unity-greeter.vala | 14 | unity-greeter.vala |
19 | 13 | indicator_keyboard_service_VALAFLAGS = $(AM_VALAFLAGS) \ | 15 | indicator_keyboard_service_VALAFLAGS = $(AM_VALAFLAGS) \ |
20 | 14 | 16 | ||
21 | === added file 'lib/ibus-menu.vala' | |||
22 | --- lib/ibus-menu.vala 1970-01-01 00:00:00 +0000 | |||
23 | +++ lib/ibus-menu.vala 2014-02-20 04:00:27 +0000 | |||
24 | @@ -0,0 +1,318 @@ | |||
25 | 1 | /* | ||
26 | 2 | * Copyright 2014 Canonical Ltd. | ||
27 | 3 | * | ||
28 | 4 | * This program is free software: you can redistribute it and/or modify | ||
29 | 5 | * it under the terms of the GNU General Public License as published by | ||
30 | 6 | * the Free Software Foundation, version 3 of the License. | ||
31 | 7 | * | ||
32 | 8 | * This program is distributed in the hope that it will be useful, | ||
33 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
34 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
35 | 11 | * GNU General Public License for more details. | ||
36 | 12 | * | ||
37 | 13 | * You should have received a copy of the GNU General Public License | ||
38 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
39 | 15 | * | ||
40 | 16 | * Authors: William Hua <william.hua@canonical.com> | ||
41 | 17 | */ | ||
42 | 18 | |||
43 | 19 | public class Indicator.Keyboard.IBusMenu : MenuModel { | ||
44 | 20 | |||
45 | 21 | private static uint radio_counter = 0; | ||
46 | 22 | |||
47 | 23 | private IBus.PropList? properties; | ||
48 | 24 | |||
49 | 25 | private Menu menu; | ||
50 | 26 | private SimpleActionGroup? action_group; | ||
51 | 27 | |||
52 | 28 | private string? radio_name; | ||
53 | 29 | private SimpleAction? radio_action; | ||
54 | 30 | private Gee.HashMap<string, IBus.Property> radio_properties; | ||
55 | 31 | |||
56 | 32 | // A list of the action names this menu registers | ||
57 | 33 | private Gee.LinkedList<string> names; | ||
58 | 34 | |||
59 | 35 | public IBusMenu (SimpleActionGroup? action_group = null, IBus.PropList? properties = null) { | ||
60 | 36 | menu = new Menu (); | ||
61 | 37 | |||
62 | 38 | menu.items_changed.connect ((position, removed, added) => { | ||
63 | 39 | items_changed (position, removed, added); | ||
64 | 40 | }); | ||
65 | 41 | |||
66 | 42 | names = new Gee.LinkedList<string> (); | ||
67 | 43 | set_action_group (action_group); | ||
68 | 44 | set_properties (properties); | ||
69 | 45 | } | ||
70 | 46 | |||
71 | 47 | ~IBusMenu () { | ||
72 | 48 | remove_actions (); | ||
73 | 49 | } | ||
74 | 50 | |||
75 | 51 | public signal void activate (IBus.Property property, IBus.PropState state); | ||
76 | 52 | |||
77 | 53 | private string get_action_name (string key) { | ||
78 | 54 | string name; | ||
79 | 55 | |||
80 | 56 | if (!action_name_is_valid (key)) { | ||
81 | 57 | var builder = new StringBuilder.sized (key.length + 1); | ||
82 | 58 | |||
83 | 59 | unichar letter = 0; | ||
84 | 60 | int index = 0; | ||
85 | 61 | |||
86 | 62 | while (key.get_next_char (ref index, out letter)) { | ||
87 | 63 | if (letter == '-' || letter == '.' || letter.isalnum ()) { | ||
88 | 64 | builder.append_unichar (letter); | ||
89 | 65 | } else { | ||
90 | 66 | builder.append_c ('-'); | ||
91 | 67 | } | ||
92 | 68 | } | ||
93 | 69 | |||
94 | 70 | name = @"ibus-$(builder.str)"; | ||
95 | 71 | } else { | ||
96 | 72 | name = @"ibus-$key"; | ||
97 | 73 | } | ||
98 | 74 | |||
99 | 75 | // Find an unused action name using a counter | ||
100 | 76 | if (action_group != null && (Action?) ((!) action_group).lookup_action (name) != null) { | ||
101 | 77 | var i = 0; | ||
102 | 78 | var unique_name = @"$name-$i"; | ||
103 | 79 | |||
104 | 80 | while ((Action?) ((!) action_group).lookup_action (unique_name) != null) { | ||
105 | 81 | i++; | ||
106 | 82 | unique_name = @"$name-$i"; | ||
107 | 83 | } | ||
108 | 84 | |||
109 | 85 | name = unique_name; | ||
110 | 86 | } | ||
111 | 87 | |||
112 | 88 | return name; | ||
113 | 89 | } | ||
114 | 90 | |||
115 | 91 | private string? get_label (IBus.Property property) { | ||
116 | 92 | string? label = null; | ||
117 | 93 | |||
118 | 94 | if ((IBus.Text?) property.label != null) { | ||
119 | 95 | label = property.label.text; | ||
120 | 96 | } | ||
121 | 97 | |||
122 | 98 | if (label == null && (IBus.Text?) property.symbol != null) { | ||
123 | 99 | label = property.symbol.text; | ||
124 | 100 | } | ||
125 | 101 | |||
126 | 102 | return label; | ||
127 | 103 | } | ||
128 | 104 | |||
129 | 105 | private void append_normal_property (IBus.Property property) { | ||
130 | 106 | if (property.prop_type == IBus.PropType.NORMAL) { | ||
131 | 107 | if ((string?) property.key != null) { | ||
132 | 108 | var name = get_action_name (property.key); | ||
133 | 109 | |||
134 | 110 | if (action_group != null) { | ||
135 | 111 | var action = new SimpleAction (name, null); | ||
136 | 112 | action.activate.connect ((parameter) => { activate (property, property.state); }); | ||
137 | 113 | ((!) action_group).add_action (action); | ||
138 | 114 | names.add (name); | ||
139 | 115 | } | ||
140 | 116 | |||
141 | 117 | menu.append (get_label (property), property.sensitive ? @"indicator.$name" : "-private-disabled"); | ||
142 | 118 | } | ||
143 | 119 | } | ||
144 | 120 | } | ||
145 | 121 | |||
146 | 122 | private void append_toggle_property (IBus.Property property) { | ||
147 | 123 | if (property.prop_type == IBus.PropType.TOGGLE) { | ||
148 | 124 | if ((string?) property.key != null) { | ||
149 | 125 | var name = get_action_name (property.key); | ||
150 | 126 | |||
151 | 127 | if (action_group != null) { | ||
152 | 128 | var state = new Variant.boolean (property.state == IBus.PropState.CHECKED); | ||
153 | 129 | var action = new SimpleAction.stateful (name, null, state); | ||
154 | 130 | |||
155 | 131 | action.activate.connect ((parameter) => { | ||
156 | 132 | action.change_state (new Variant.boolean (!action.get_state ().get_boolean ())); | ||
157 | 133 | }); | ||
158 | 134 | |||
159 | 135 | action.change_state.connect ((value) => { | ||
160 | 136 | if (value != null) { | ||
161 | 137 | action.set_state ((!) value); | ||
162 | 138 | activate (property, ((!) value).get_boolean () ? IBus.PropState.CHECKED : IBus.PropState.UNCHECKED); | ||
163 | 139 | } | ||
164 | 140 | }); | ||
165 | 141 | |||
166 | 142 | ((!) action_group).add_action (action); | ||
167 | 143 | names.add (name); | ||
168 | 144 | } | ||
169 | 145 | |||
170 | 146 | menu.append (get_label (property), property.sensitive ? @"indicator.$name" : "-private-disabled"); | ||
171 | 147 | } | ||
172 | 148 | } | ||
173 | 149 | } | ||
174 | 150 | |||
175 | 151 | private void append_radio_property (IBus.Property property) { | ||
176 | 152 | if (property.prop_type == IBus.PropType.RADIO) { | ||
177 | 153 | if ((string?) property.key != null) { | ||
178 | 154 | // Create a single action for all radio properties. | ||
179 | 155 | if (action_group != null && radio_name == null) { | ||
180 | 156 | radio_counter++; | ||
181 | 157 | radio_name = @"-private-radio-$radio_counter"; | ||
182 | 158 | radio_action = new SimpleAction.stateful ((!) radio_name, VariantType.STRING, new Variant.string ("")); | ||
183 | 159 | |||
184 | 160 | ((!) radio_action).activate.connect ((parameter) => { | ||
185 | 161 | ((!) radio_action).change_state (parameter); | ||
186 | 162 | }); | ||
187 | 163 | |||
188 | 164 | ((!) radio_action).change_state.connect ((value) => { | ||
189 | 165 | if (value != null) { | ||
190 | 166 | var key = ((!) value).get_string (); | ||
191 | 167 | |||
192 | 168 | if (radio_properties.has_key (key)) { | ||
193 | 169 | ((!) radio_action).set_state ((!) value); | ||
194 | 170 | activate (radio_properties[key], IBus.PropState.CHECKED); | ||
195 | 171 | } | ||
196 | 172 | } | ||
197 | 173 | }); | ||
198 | 174 | |||
199 | 175 | ((!) action_group).add_action ((!) radio_action); | ||
200 | 176 | names.add ((!) radio_name); | ||
201 | 177 | } | ||
202 | 178 | |||
203 | 179 | radio_properties[property.key] = property; | ||
204 | 180 | |||
205 | 181 | if (property.state == IBus.PropState.CHECKED) { | ||
206 | 182 | ((!) radio_action).change_state (new Variant.string (property.key)); | ||
207 | 183 | } | ||
208 | 184 | |||
209 | 185 | var item = new MenuItem (get_label (property), "-private-disabled"); | ||
210 | 186 | |||
211 | 187 | if (property.sensitive) { | ||
212 | 188 | item.set_action_and_target_value (@"indicator.$((!) radio_name)", new Variant.string (property.key)); | ||
213 | 189 | } | ||
214 | 190 | |||
215 | 191 | menu.append_item (item); | ||
216 | 192 | } | ||
217 | 193 | } | ||
218 | 194 | } | ||
219 | 195 | |||
220 | 196 | private void append_menu_property (IBus.Property property) { | ||
221 | 197 | if (property.prop_type == IBus.PropType.MENU) { | ||
222 | 198 | var submenu = new IBusMenu (action_group, ((!) property).sub_props); | ||
223 | 199 | submenu.activate.connect ((property, state) => { activate (property, state); }); | ||
224 | 200 | menu.append_submenu (get_label (property), submenu); | ||
225 | 201 | } | ||
226 | 202 | } | ||
227 | 203 | |||
228 | 204 | private void append_property (IBus.Property? property) { | ||
229 | 205 | if (property != null && ((!) property).visible) { | ||
230 | 206 | switch (((!) property).prop_type) { | ||
231 | 207 | case IBus.PropType.NORMAL: | ||
232 | 208 | append_normal_property ((!) property); | ||
233 | 209 | break; | ||
234 | 210 | |||
235 | 211 | case IBus.PropType.TOGGLE: | ||
236 | 212 | append_toggle_property ((!) property); | ||
237 | 213 | break; | ||
238 | 214 | |||
239 | 215 | case IBus.PropType.RADIO: | ||
240 | 216 | append_radio_property ((!) property); | ||
241 | 217 | break; | ||
242 | 218 | |||
243 | 219 | case IBus.PropType.MENU: | ||
244 | 220 | append_menu_property ((!) property); | ||
245 | 221 | break; | ||
246 | 222 | |||
247 | 223 | case IBus.PropType.SEPARATOR: | ||
248 | 224 | break; | ||
249 | 225 | } | ||
250 | 226 | } | ||
251 | 227 | } | ||
252 | 228 | |||
253 | 229 | private void update_menu () { | ||
254 | 230 | // There's a reference cycle between the action group and the submenus. | ||
255 | 231 | // We need to break it here so that those submenus aren't hanging around. | ||
256 | 232 | for (var i = 0; i < menu.get_n_items (); i++) { | ||
257 | 233 | var submenu = menu.get_item_link (i, Menu.LINK_SUBMENU) as IBusMenu; | ||
258 | 234 | |||
259 | 235 | if (submenu != null) { | ||
260 | 236 | ((!) submenu).remove_actions (); | ||
261 | 237 | } | ||
262 | 238 | } | ||
263 | 239 | |||
264 | 240 | menu.remove_all (); | ||
265 | 241 | |||
266 | 242 | if (properties != null) { | ||
267 | 243 | for (var i = 0; i < ((!) properties).properties.length; i++) { | ||
268 | 244 | append_property (((!) properties).get (i)); | ||
269 | 245 | } | ||
270 | 246 | } | ||
271 | 247 | } | ||
272 | 248 | |||
273 | 249 | private void remove_actions () { | ||
274 | 250 | radio_action = null; | ||
275 | 251 | radio_name = null; | ||
276 | 252 | |||
277 | 253 | if (action_group != null) { | ||
278 | 254 | foreach (var name in names) { | ||
279 | 255 | ((!) action_group).remove_action (name); | ||
280 | 256 | } | ||
281 | 257 | } | ||
282 | 258 | |||
283 | 259 | names.clear (); | ||
284 | 260 | } | ||
285 | 261 | |||
286 | 262 | public void set_action_group (SimpleActionGroup? action_group) { | ||
287 | 263 | if (action_group != this.action_group) { | ||
288 | 264 | remove_actions (); | ||
289 | 265 | this.action_group = action_group; | ||
290 | 266 | update_menu (); | ||
291 | 267 | } | ||
292 | 268 | } | ||
293 | 269 | |||
294 | 270 | public void set_properties (IBus.PropList? properties) { | ||
295 | 271 | if (properties != this.properties) { | ||
296 | 272 | remove_actions (); | ||
297 | 273 | radio_properties = new Gee.HashMap<string, IBus.Property> (); | ||
298 | 274 | this.properties = properties; | ||
299 | 275 | update_menu (); | ||
300 | 276 | } | ||
301 | 277 | } | ||
302 | 278 | |||
303 | 279 | public void update_property (IBus.Property property) { | ||
304 | 280 | remove_actions (); | ||
305 | 281 | radio_properties = new Gee.HashMap<string, IBus.Property> (); | ||
306 | 282 | update_menu (); | ||
307 | 283 | } | ||
308 | 284 | |||
309 | 285 | // Forward all menu model calls to our internal menu | ||
310 | 286 | |||
311 | 287 | public override Variant get_item_attribute_value (int item_index, string attribute, VariantType? expected_type) { | ||
312 | 288 | return menu.get_item_attribute_value (item_index, attribute, expected_type); | ||
313 | 289 | } | ||
314 | 290 | |||
315 | 291 | public override void get_item_attributes (int item_index, out HashTable<string, Variant>? attributes) { | ||
316 | 292 | menu.get_item_attributes (item_index, out attributes); | ||
317 | 293 | } | ||
318 | 294 | |||
319 | 295 | public override MenuModel get_item_link (int item_index, string link) { | ||
320 | 296 | return menu.get_item_link (item_index, link); | ||
321 | 297 | } | ||
322 | 298 | |||
323 | 299 | public override void get_item_links (int item_index, out HashTable<string, MenuModel>? links) { | ||
324 | 300 | menu.get_item_links (item_index, out links); | ||
325 | 301 | } | ||
326 | 302 | |||
327 | 303 | public override int get_n_items () { | ||
328 | 304 | return menu.get_n_items (); | ||
329 | 305 | } | ||
330 | 306 | |||
331 | 307 | public override bool is_mutable () { | ||
332 | 308 | return menu.is_mutable (); | ||
333 | 309 | } | ||
334 | 310 | |||
335 | 311 | public override MenuAttributeIter iterate_item_attributes (int item_index) { | ||
336 | 312 | return menu.iterate_item_attributes (item_index); | ||
337 | 313 | } | ||
338 | 314 | |||
339 | 315 | public override MenuLinkIter iterate_item_links (int item_index) { | ||
340 | 316 | return menu.iterate_item_links (item_index); | ||
341 | 317 | } | ||
342 | 318 | } | ||
343 | 0 | 319 | ||
344 | === modified file 'lib/main.vala' | |||
345 | --- lib/main.vala 2014-02-19 15:09:16 +0000 | |||
346 | +++ lib/main.vala 2014-02-20 04:00:27 +0000 | |||
347 | @@ -19,8 +19,9 @@ | |||
348 | 19 | [DBus (name = "com.canonical.indicator.keyboard")] | 19 | [DBus (name = "com.canonical.indicator.keyboard")] |
349 | 20 | public class Indicator.Keyboard.Service : Object { | 20 | public class Indicator.Keyboard.Service : Object { |
350 | 21 | 21 | ||
351 | 22 | private static const uint PROPERTIES_DELAY = 250; | ||
352 | 23 | |||
353 | 22 | private static Service service; | 24 | private static Service service; |
354 | 23 | private static IBus.Bus? ibus; | ||
355 | 24 | 25 | ||
356 | 25 | private bool force; | 26 | private bool force; |
357 | 26 | private bool use_gtk; | 27 | private bool use_gtk; |
358 | @@ -35,12 +36,17 @@ | |||
359 | 35 | private Gee.HashMap<uint, uint>? window_sources; | 36 | private Gee.HashMap<uint, uint>? window_sources; |
360 | 36 | private uint focused_window_id; | 37 | private uint focused_window_id; |
361 | 37 | 38 | ||
362 | 39 | private IBus.Bus? ibus; | ||
363 | 40 | private IBus.PanelService? panel_service; | ||
364 | 41 | private uint panel_timeout; | ||
365 | 42 | |||
366 | 38 | private Source[]? sources; | 43 | private Source[]? sources; |
367 | 39 | 44 | ||
368 | 40 | private SimpleActionGroup? action_group; | 45 | private SimpleActionGroup? action_group; |
369 | 41 | private SimpleAction? indicator_action; | 46 | private SimpleAction? indicator_action; |
370 | 42 | private MenuModel? menu_model; | 47 | private MenuModel? menu_model; |
371 | 43 | private Menu? sources_menu; | 48 | private Menu? sources_menu; |
372 | 49 | private IBusMenu? ibus_menu; | ||
373 | 44 | 50 | ||
374 | 45 | private UnityGreeter? unity_greeter; | 51 | private UnityGreeter? unity_greeter; |
375 | 46 | private string? greeter_user; | 52 | private string? greeter_user; |
376 | @@ -96,7 +102,7 @@ | |||
377 | 96 | } | 102 | } |
378 | 97 | 103 | ||
379 | 98 | [DBus (visible = false)] | 104 | [DBus (visible = false)] |
381 | 99 | private static IBus.Bus get_ibus () { | 105 | private IBus.Bus get_ibus () { |
382 | 100 | if (ibus == null) { | 106 | if (ibus == null) { |
383 | 101 | IBus.init (); | 107 | IBus.init (); |
384 | 102 | ibus = new IBus.Bus (); | 108 | ibus = new IBus.Bus (); |
385 | @@ -210,7 +216,7 @@ | |||
386 | 210 | if (source != null) { | 216 | if (source != null) { |
387 | 211 | var array = source_settings.get_value ("sources"); | 217 | var array = source_settings.get_value ("sources"); |
388 | 212 | 218 | ||
390 | 213 | for (int i = 0; i < array.n_children (); i++) { | 219 | for (var i = 0; i < array.n_children (); i++) { |
391 | 214 | unowned string type; | 220 | unowned string type; |
392 | 215 | unowned string name; | 221 | unowned string name; |
393 | 216 | 222 | ||
394 | @@ -543,6 +549,14 @@ | |||
395 | 543 | break; | 549 | break; |
396 | 544 | } | 550 | } |
397 | 545 | } | 551 | } |
398 | 552 | |||
399 | 553 | if (panel_service == null && sources[i].is_ibus) { | ||
400 | 554 | if (get_ibus ().request_name (IBus.SERVICE_PANEL, IBus.BusNameFlag.REPLACE_EXISTING) > 0) { | ||
401 | 555 | panel_service = new IBus.PanelService (get_ibus ().get_connection ()); | ||
402 | 556 | ((!) panel_service).register_properties.connect (handle_registered_properties); | ||
403 | 557 | ((!) panel_service).update_property.connect (handle_updated_property); | ||
404 | 558 | } | ||
405 | 559 | } | ||
406 | 546 | } | 560 | } |
407 | 547 | } | 561 | } |
408 | 548 | 562 | ||
409 | @@ -550,6 +564,25 @@ | |||
410 | 550 | } | 564 | } |
411 | 551 | 565 | ||
412 | 552 | [DBus (visible = false)] | 566 | [DBus (visible = false)] |
413 | 567 | private void handle_registered_properties (IBus.PropList list) { | ||
414 | 568 | if (panel_timeout > 0) { | ||
415 | 569 | GLib.Source.remove (panel_timeout); | ||
416 | 570 | panel_timeout = 0; | ||
417 | 571 | } | ||
418 | 572 | |||
419 | 573 | panel_timeout = Timeout.add (PROPERTIES_DELAY, () => { | ||
420 | 574 | update_ibus_menu (list); | ||
421 | 575 | panel_timeout = 0; | ||
422 | 576 | return false; | ||
423 | 577 | }); | ||
424 | 578 | } | ||
425 | 579 | |||
426 | 580 | [DBus (visible = false)] | ||
427 | 581 | private void handle_updated_property (IBus.Property property) { | ||
428 | 582 | get_ibus_menu ().update_property (property); | ||
429 | 583 | } | ||
430 | 584 | |||
431 | 585 | [DBus (visible = false)] | ||
432 | 553 | private void update_indicator_action () { | 586 | private void update_indicator_action () { |
433 | 554 | var visible = indicator_settings.get_boolean ("visible"); | 587 | var visible = indicator_settings.get_boolean ("visible"); |
434 | 555 | var current = source_settings.get_uint ("current"); | 588 | var current = source_settings.get_uint ("current"); |
435 | @@ -600,7 +633,7 @@ | |||
436 | 600 | var length = (int) sources.n_children (); | 633 | var length = (int) sources.n_children (); |
437 | 601 | 634 | ||
438 | 602 | if (length > 0) { | 635 | if (length > 0) { |
440 | 603 | var offset = parameter.get_int32 () % length; | 636 | var offset = ((!) parameter).get_int32 () % length; |
441 | 604 | source_settings.set_uint ("current", (current + (length - offset)) % length); | 637 | source_settings.set_uint ("current", (current + (length - offset)) % length); |
442 | 605 | } | 638 | } |
443 | 606 | } | 639 | } |
444 | @@ -610,28 +643,28 @@ | |||
445 | 610 | protected virtual SimpleActionGroup create_action_group (Action root_action) { | 643 | protected virtual SimpleActionGroup create_action_group (Action root_action) { |
446 | 611 | var group = new SimpleActionGroup (); | 644 | var group = new SimpleActionGroup (); |
447 | 612 | 645 | ||
450 | 613 | group.insert (root_action); | 646 | group.add_action (root_action); |
451 | 614 | group.insert (source_settings.create_action ("current")); | 647 | group.add_action (source_settings.create_action ("current")); |
452 | 615 | 648 | ||
453 | 616 | var action = new SimpleAction ("next", null); | 649 | var action = new SimpleAction ("next", null); |
454 | 617 | action.activate.connect (handle_middle_click); | 650 | action.activate.connect (handle_middle_click); |
456 | 618 | group.insert (action); | 651 | group.add_action (action); |
457 | 619 | 652 | ||
458 | 620 | action = new SimpleAction ("scroll", VariantType.INT32); | 653 | action = new SimpleAction ("scroll", VariantType.INT32); |
459 | 621 | action.activate.connect (handle_scroll_wheel); | 654 | action.activate.connect (handle_scroll_wheel); |
461 | 622 | group.insert (action); | 655 | group.add_action (action); |
462 | 623 | 656 | ||
463 | 624 | action = new SimpleAction ("map", null); | 657 | action = new SimpleAction ("map", null); |
464 | 625 | action.activate.connect (handle_activate_map); | 658 | action.activate.connect (handle_activate_map); |
466 | 626 | group.insert (action); | 659 | group.add_action (action); |
467 | 627 | 660 | ||
468 | 628 | action = new SimpleAction ("chart", null); | 661 | action = new SimpleAction ("chart", null); |
469 | 629 | action.activate.connect (handle_activate_chart); | 662 | action.activate.connect (handle_activate_chart); |
471 | 630 | group.insert (action); | 663 | group.add_action (action); |
472 | 631 | 664 | ||
473 | 632 | action = new SimpleAction ("settings", null); | 665 | action = new SimpleAction ("settings", null); |
474 | 633 | action.activate.connect (handle_activate_settings); | 666 | action.activate.connect (handle_activate_settings); |
476 | 634 | group.insert (action); | 667 | group.add_action (action); |
477 | 635 | 668 | ||
478 | 636 | return group; | 669 | return group; |
479 | 637 | } | 670 | } |
480 | @@ -649,12 +682,9 @@ | |||
481 | 649 | private void update_sources_menu () { | 682 | private void update_sources_menu () { |
482 | 650 | if (sources_menu != null) { | 683 | if (sources_menu != null) { |
483 | 651 | var menu = get_sources_menu (); | 684 | var menu = get_sources_menu (); |
487 | 652 | 685 | menu.remove_all (); | |
485 | 653 | while (menu.get_n_items () > 0) | ||
486 | 654 | menu.remove (0); | ||
488 | 655 | 686 | ||
489 | 656 | var sources = get_sources (); | 687 | var sources = get_sources (); |
490 | 657 | |||
491 | 658 | for (var i = 0; i < sources.length; i++) { | 688 | for (var i = 0; i < sources.length; i++) { |
492 | 659 | var item = new MenuItem (sources[i].name, "indicator.current"); | 689 | var item = new MenuItem (sources[i].name, "indicator.current"); |
493 | 660 | item.set_attribute (Menu.ATTRIBUTE_TARGET, "u", i); | 690 | item.set_attribute (Menu.ATTRIBUTE_TARGET, "u", i); |
494 | @@ -682,12 +712,32 @@ | |||
495 | 682 | } | 712 | } |
496 | 683 | 713 | ||
497 | 684 | [DBus (visible = false)] | 714 | [DBus (visible = false)] |
499 | 685 | protected virtual MenuModel create_menu_model (MenuModel section_menu) { | 715 | private void update_ibus_menu (IBus.PropList list) { |
500 | 716 | get_ibus_menu ().set_properties (list); | ||
501 | 717 | } | ||
502 | 718 | |||
503 | 719 | [DBus (visible = false)] | ||
504 | 720 | private IBusMenu get_ibus_menu () { | ||
505 | 721 | if (ibus_menu == null) { | ||
506 | 722 | ibus_menu = new IBusMenu (get_action_group ()); | ||
507 | 723 | ((!) ibus_menu).activate.connect ((property, state) => { | ||
508 | 724 | if (panel_service != null) { | ||
509 | 725 | ((!) panel_service).property_activate (property.key, state); | ||
510 | 726 | } | ||
511 | 727 | }); | ||
512 | 728 | } | ||
513 | 729 | |||
514 | 730 | return (!) ibus_menu; | ||
515 | 731 | } | ||
516 | 732 | |||
517 | 733 | [DBus (visible = false)] | ||
518 | 734 | protected virtual MenuModel create_menu_model (MenuModel sources_menu, MenuModel ibus_menu) { | ||
519 | 686 | var menu = new Menu (); | 735 | var menu = new Menu (); |
520 | 687 | 736 | ||
521 | 688 | var submenu = new Menu (); | 737 | var submenu = new Menu (); |
522 | 689 | 738 | ||
524 | 690 | submenu.append_section (null, section_menu); | 739 | submenu.append_section (null, sources_menu); |
525 | 740 | submenu.append_section (null, ibus_menu); | ||
526 | 691 | 741 | ||
527 | 692 | if (!is_login_user ()) { | 742 | if (!is_login_user ()) { |
528 | 693 | var section = new Menu (); | 743 | var section = new Menu (); |
529 | @@ -710,7 +760,7 @@ | |||
530 | 710 | [DBus (visible = false)] | 760 | [DBus (visible = false)] |
531 | 711 | public MenuModel get_menu_model () { | 761 | public MenuModel get_menu_model () { |
532 | 712 | if (menu_model == null) { | 762 | if (menu_model == null) { |
534 | 713 | menu_model = create_menu_model (get_sources_menu ()); | 763 | menu_model = create_menu_model (get_sources_menu (), get_ibus_menu ()); |
535 | 714 | } | 764 | } |
536 | 715 | 765 | ||
537 | 716 | return (!) menu_model; | 766 | return (!) menu_model; |
538 | 717 | 767 | ||
539 | === modified file 'lib/source.vala' | |||
540 | --- lib/source.vala 2013-08-07 19:11:32 +0000 | |||
541 | +++ lib/source.vala 2014-02-20 04:00:27 +0000 | |||
542 | @@ -69,6 +69,14 @@ | |||
543 | 69 | construct set { _use_gtk = value; icon = null; } | 69 | construct set { _use_gtk = value; icon = null; } |
544 | 70 | } | 70 | } |
545 | 71 | 71 | ||
546 | 72 | public bool is_xkb { | ||
547 | 73 | get { return xkb != null; } | ||
548 | 74 | } | ||
549 | 75 | |||
550 | 76 | public bool is_ibus { | ||
551 | 77 | get { return ibus != null; } | ||
552 | 78 | } | ||
553 | 79 | |||
554 | 72 | public Source (Variant variant, bool use_gtk = false) { | 80 | public Source (Variant variant, bool use_gtk = false) { |
555 | 73 | Object (use_gtk: use_gtk); | 81 | Object (use_gtk: use_gtk); |
556 | 74 | 82 |
PASSED: Continuous integration, rev:267 jenkins. qa.ubuntu. com/job/ indicator- keyboard- ci/45/ jenkins. qa.ubuntu. com/job/ indicator- keyboard- trusty- amd64-ci/ 12 jenkins. qa.ubuntu. com/job/ indicator- keyboard- trusty- armhf-ci/ 12 jenkins. qa.ubuntu. com/job/ indicator- keyboard- trusty- armhf-ci/ 12/artifact/ work/output/ *zip*/output. zip
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/indicator- keyboard- ci/45/rebuild
http://