Do

Merge lp:~cszikszoy/do/kb-service into lp:do

Proposed by Chris S.
Status: Merged
Merged at revision: not available
Proposed branch: lp:~cszikszoy/do/kb-service
Merge into: lp:do
Diff against target: None lines
To merge this branch: bzr merge lp:~cszikszoy/do/kb-service
Reviewer Review Type Date Requested Status
Robert Dyer (community) Needs Fixing
Review via email: mp+9308@code.launchpad.net

This proposal supersedes a proposal from 2009-07-23.

To post a comment you must log in.
Revision history for this message
Chris S. (cszikszoy) wrote : Posted in a previous version of this proposal

This adds a Keybinding service to Do.Platform.

This service is what all other assemblies will interact with to register keys (both internal and with the host OS) to perform specific actions. Keys can now be bound from any other assmebly that references Do.Platform. Also, multiple key combinations can now be registered with the host OS. For example, I've added a new global hotkey, "<Super>period", this will summon do directly in text mode. Using the keybinding service, this can all be done in one line.

The keybinding service consists of an interface in Do.Platform, IKeyBindingService. Next, in Do.Platform.Common an AbstractKeyBindingService is defined. This class implements all of the platform independant code relating to mapping and keeping track of hotkeys. For example, all internal events (anything other than the summon key, basically) get handled by this class. This class defines two abstract methods, RegisterOSKey, and UnRegisterOSKey. These methods should be defined in the platform specific implementation of the Keybinding service which gets placed in Do.Platform.*

Along with creating the keybinging service, I've also edited libdo to return gbooleans when it tries to register or unregister keys. This feedback helpful in determining if we were successful in attempting to register a particular keystring with the host OS. Should the binding of a keystring, the KeybindingService will attempt to use the DefaultKeystring, instead of what's in the preferences.

Finally, I've removed unnecessary files (XKeyBinder.cs & CoreKeyBindings.cs, both in Do) and fixed the KeyBindingTreeview in the preferences widget. Thanks to a tip I saw on a bug report, setting the CellRendererAccelMode to "Other" allows many more keys to be grabbed.

I originally wrote this service as a part of the Windows port, and I've already written the windows specific implementation of KeyBindingService there.

Revision history for this message
Chris S. (cszikszoy) wrote : Posted in a previous version of this proposal

Also, please ignore the Console.WriteLine () on line 1038 of the diff. I removed that in rev 1285, but LP currently doesn't update the merge diff when I add revisions after I proposed the merge.

(Here's to hoping they fix that! https://bugs.launchpad.net/launchpad-code/+bug/392343)

Revision history for this message
David Siegel (djsiegel-deactivatedaccount) wrote : Posted in a previous version of this proposal

Awesome.

Revision history for this message
Alex Launi (alexlauni) wrote : Posted in a previous version of this proposal

Please remove the <Super>period global keybinding, and then we'll be merge
ready!

--
--Alex Launi

Revision history for this message
Chris S. (cszikszoy) wrote : Posted in a previous version of this proposal

I can do that, but I thought it was pretty neat and useful for plugins that primarily use text mode, like Microblogging or Translate. It was also something that I put in there to highlight the capabilities of the new keybinding service, but if you think it should go, I can take it out.

Revision history for this message
Alex Launi (alexlauni) wrote : Posted in a previous version of this proposal

On Sat, Jul 25, 2009 at 12:28 AM, Chris S. <email address hidden> wrote:

> I can do that, but I thought it was pretty neat and useful for plugins that
> primarily use text mode, like Microblogging or Translate. It was also
> something that I put in there to highlight the capabilities of the new
> keybinding service, but if you think it should go, I can take it out.
> --
> https://code.edge.launchpad.net/~cszikszoy/do/kb-service/+merge/9183<https://code.edge.launchpad.net/%7Ecszikszoy/do/kb-service/+merge/9183>
> Your team GNOME Do Core Team is subscribed to branch lp:do.
>

I can see why it'd be neat but I don't think it's useful enough to warrant a
second keybinding to summon Do, and has the potential to be more confusing
than useful. I wouldn't be opposed to leaving it in the keybindings UI but
unbound by default, so that power users can bind it if they want. How do you
feel about that?

--
--Alex Launi

Revision history for this message
Robert Dyer (psybers) wrote :

Notes: I can only review the diff on the merge proposal as I have no way at the moment to check out the code. Thus, if the diff is outdated so is this review. I don't know if the code compiles. I have not *tested* the code. :-)

All line numbers refer to the diff.

1) On line 1045, you do a hack to stop from binding to 'only' the super key. The hack checks for Gdk.Key.Super_L, should it also check for Super_R (for keyboards w/ 2 windows keys I'm guessing... I have no way to test this myself).

2) In RegisterOSKey, add a check to see if the binding is emptyornull, if so return false
This way, you don't have to check it every time you call it (make the method enforce its pre-condition). Thus you can remove those checks on lines 253, 256, 286, 289. Might make sense to also check if the callback is null.

3) Clean this code:
253 + if (!string.IsNullOrEmpty (binding.KeyString))
254 + success = RegisterOSKey (binding.KeyString, binding.Callback);
255 + //if we fail to register the summon key, try again with the default binding
256 + if (!success && !string.IsNullOrEmpty (binding.DefaultKeyString)) {
257 + success = RegisterOSKey (binding.DefaultKeyString, binding.Callback);
258 + //if we succeeded now, change the event's keystring
259 + if (success)
260 + binding.KeyString = binding.DefaultKeyString;
261 + }
262 + }
263 +
264 + if (success) {
265 + //add the event to the list of bindings
266 + Bindings.Add (binding);
267 + //set the bound keystring in the prefs
268 + prefs.Set (binding.Description.Replace (' ', '_'), binding.KeyString);
269 + }

Can turn this into:

<<<
254 + success = RegisterOSKey (binding.KeyString, binding.Callback);
255 + //if we fail to register the summon key, try again with the default binding
>>> + if (!success) {
257 + success = RegisterOSKey (binding.DefaultKeyString, binding.Callback);
258 + //if we succeeded now, change the event's keystring
>>> + if (success)
>>> + binding.KeyString = binding.DefaultKeyString;
>>> + }
>>> + if (!success)
>>> return false;
262 + }
263 +
<<<
265 + //add the event to the list of bindings
266 + Bindings.Add (binding);
267 + //set the bound keystring in the prefs
268 + prefs.Set (binding.Description.Replace (' ', '_'), binding.KeyString);

See the change? You don't need to put that last block in a test for success. Basically when the OS binding fails, you don't want to do anything else (hence, just return false). If it passes, you want to do everything else. This is slightly clearer, as if it is not an OS binding, you skip the block that potentially sets success = false. So reasoning for that case is much clearer and reasoning in the other case is the same.

4) Similar thing for SetKeyString on line 274.

5) What is the commented block on lines 294-301? If it isn't needed remove it.

That is all I see. Nice work. :-)

review: Needs Fixing
lp:~cszikszoy/do/kb-service updated
1287. By Chris S.

merge trunk

1288. By Chris S.

fixes as per Roberts review

1289. By Chris S.

it helps when I save the file _before_ pushing...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'Do.Platform.Linux/Do.Platform.Linux.dll.config.in'
2--- Do.Platform.Linux/Do.Platform.Linux.dll.config.in 1970-01-01 00:00:00 +0000
3+++ Do.Platform.Linux/Do.Platform.Linux.dll.config.in 2009-07-23 07:17:00 +0000
4@@ -0,0 +1,3 @@
5+<configuration>
6+ <dllmap dll="libdo" target="@expanded_libdir@/@PACKAGE@/libdo.so"/>
7+</configuration>
8
9=== modified file 'Do.Platform.Linux/Do.Platform.Linux.mdp'
10--- Do.Platform.Linux/Do.Platform.Linux.mdp 2009-06-26 11:01:40 +0000
11+++ Do.Platform.Linux/Do.Platform.Linux.mdp 2009-07-22 01:12:59 +0000
12@@ -52,6 +52,7 @@
13 <File name="src/Do.Platform/Do.Platform.Linux/NetworkService.cs" subtype="Code" buildaction="Compile" />
14 <File name="src/Do.Widgets/PluginAvailableDialog.cs" subtype="Code" buildaction="Compile" />
15 <File name="gtk-gui/Do.Platform.Linux.PluginAvailableDialog.cs" subtype="Code" buildaction="Compile" />
16+ <File name="src/Do.Platform/Do.Platform.Linux/KeyBindingService.cs" subtype="Code" buildaction="Compile" />
17 </Contents>
18 <References>
19 <ProjectReference type="Gac" localcopy="True" refto="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
20@@ -71,7 +72,7 @@
21 <ProjectReference type="Project" localcopy="True" refto="Do.Interface.Linux" />
22 <ProjectReference type="Gac" localcopy="True" refto="gnome-vfs-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
23 <ProjectReference type="Gac" localcopy="True" refto="gnome-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
24+ <ProjectReference type="Gac" localcopy="True" refto="Mono.Addins, Version=0.4.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />
25 <ProjectReference type="Gac" localcopy="True" refto="nunit.framework, Version=2.2.0.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77" />
26- <ProjectReference type="Gac" localcopy="True" refto="Mono.Addins, Version=0.4.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />
27 </References>
28 </Project>
29\ No newline at end of file
30
31=== modified file 'Do.Platform.Linux/Makefile.am'
32--- Do.Platform.Linux/Makefile.am 2009-06-26 11:01:40 +0000
33+++ Do.Platform.Linux/Makefile.am 2009-07-23 07:17:00 +0000
34@@ -7,7 +7,7 @@
35 FILES = \
36 gtk-gui/Do.Platform.Linux.AbstractLoginWidget.cs \
37 gtk-gui/Do.Platform.Linux.PluginAvailableDialog.cs \
38- gtk-gui/generated.cs \
39+ gtk-gui/generated.cs \
40 src/AssemblyInfo.cs \
41 src/Do.Platform/ConsoleCrayon.cs \
42 src/Do.Platform/Do.Platform.Linux/Do.Platform.Linux.DBus/IController.cs \
43@@ -23,6 +23,7 @@
44 src/Do.Platform/Do.Platform.Linux/TrayIconService.cs \
45 src/Do.Platform/Do.Platform.Linux/UniverseFactoryService.cs \
46 src/Do.Platform/Do.Platform.Linux/NetworkService.cs \
47+ src/Do.Platform/Do.Platform.Linux/KeyBindingService.cs \
48 src/Do.Universe/ApplicationItem.cs \
49 src/Do.Universe/CategoryItem.cs \
50 src/Do.Universe/NullApplicationItem.cs \
51@@ -63,3 +64,8 @@
52 Do.Universe \
53 Do.Platform \
54 Do.Interface.Linux
55+
56+CLEANFILES += Do.Platform.Linux.dll.config
57+EXTRA_DIST += Do.Platform.Linux.dll.config.in
58+
59+module_DATA += Do.Platform.Linux.dll.config
60
61=== modified file 'Do.Platform.Linux/Resources/Do.Platform.Linux.addin.xml'
62--- Do.Platform.Linux/Resources/Do.Platform.Linux.addin.xml 2009-06-26 09:44:33 +0000
63+++ Do.Platform.Linux/Resources/Do.Platform.Linux.addin.xml 2009-07-22 01:12:59 +0000
64@@ -22,6 +22,7 @@
65 <Service type="Do.Platform.Linux.NetworkService" />
66 <Service type="Do.Platform.Linux.TrayIconService" />
67 <Service type="Do.Platform.Linux.ConsoleLogService" />
68+ <Service type="Do.Platform.Linux.KeyBindingService" />
69 <Service type="Do.Platform.Linux.EnvironmentService" />
70 <Service type="Do.Platform.Linux.UniverseFactoryService" />
71 <Service type="Do.Platform.Linux.GConfPreferencesService" />
72
73=== added file 'Do.Platform.Linux/src/Do.Platform/Do.Platform.Linux/KeyBindingService.cs'
74--- Do.Platform.Linux/src/Do.Platform/Do.Platform.Linux/KeyBindingService.cs 1970-01-01 00:00:00 +0000
75+++ Do.Platform.Linux/src/Do.Platform/Do.Platform.Linux/KeyBindingService.cs 2009-07-27 01:25:19 +0000
76@@ -0,0 +1,57 @@
77+using System;
78+using System.Linq;
79+using System.Collections.Generic;
80+using System.Runtime.InteropServices;
81+
82+using Mono.Unix;
83+using Gdk;
84+using Do.Platform.Common;
85+
86+namespace Do.Platform.Linux
87+{
88+ class KeyBindingService : AbstractKeyBindingService
89+ {
90+
91+ [DllImport("libdo")]
92+ static extern void gnomedo_keybinder_init ();
93+
94+ [DllImport("libdo")]
95+ static extern bool gnomedo_keybinder_bind (string keystring, BindkeyHandler handler);
96+
97+ [DllImport("libdo")]
98+ static extern bool gnomedo_keybinder_unbind (string keystring, BindkeyHandler handler);
99+
100+ public delegate void BindkeyHandler (string key, IntPtr user_data);
101+
102+ BindkeyHandler key_handler;
103+
104+ public KeyBindingService () : base ()
105+ {
106+ key_handler = new BindkeyHandler (KeybindingPressed);
107+
108+ try {
109+ gnomedo_keybinder_init ();
110+ } catch (DllNotFoundException) {
111+ Log.Error ("libdo not found - keybindings will not work.");
112+ }
113+ }
114+
115+ void KeybindingPressed (string keystring, IntPtr user_data) {
116+ if (Bindings.Any (k => k.KeyString == keystring)) {
117+ Bindings.First (k => k.KeyString == keystring).Callback (null);
118+ }
119+ }
120+
121+ public override bool RegisterOSKey (string keyString, EventCallback cb) {
122+ return gnomedo_keybinder_bind (keyString, key_handler);
123+ }
124+
125+ public override bool UnRegisterOSKey (string keyString) {
126+
127+ if (Bindings.Any (k => k.KeyString == keyString)) {
128+ return gnomedo_keybinder_unbind (keyString, key_handler);
129+ }
130+ return false;
131+ }
132+ }
133+}
134\ No newline at end of file
135
136=== modified file 'Do.Platform/Do.Platform.mdp'
137--- Do.Platform/Do.Platform.mdp 2009-06-26 11:01:40 +0000
138+++ Do.Platform/Do.Platform.mdp 2009-07-23 07:17:00 +0000
139@@ -86,6 +86,10 @@
140 <File name="src/Do.Platform/Do.Platform.Default/PluginManagerService.cs" subtype="Code" buildaction="Compile" />
141 <File name="src/Do.Platform/Do.Platform.ServiceStack/IStrictService.cs" subtype="Code" buildaction="Compile" />
142 <File name="src/Do.Universe/Do.Universe.Common/CopyToClipboardAction.cs" subtype="Code" buildaction="Compile" />
143+ <File name="src/Do.Platform/Do.Platform.Common/AbstractKeyBindingService.cs" subtype="Code" buildaction="Compile" />
144+ <File name="src/Do.Platform/IKeyBindingService.cs" subtype="Code" buildaction="Compile" />
145+ <File name="src/Do.Platform/KeyBinding.cs" subtype="Code" buildaction="Compile" />
146+ <File name="src/Do.Platform/Do.Platform.Default/KeyBindingService.cs" subtype="Code" buildaction="Compile" />
147 </Contents>
148 <References>
149 <ProjectReference type="Gac" localcopy="True" refto="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
150@@ -95,7 +99,7 @@
151 <ProjectReference type="Gac" localcopy="True" refto="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
152 <ProjectReference type="Gac" localcopy="True" refto="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
153 <ProjectReference type="Gac" localcopy="True" refto="gnome-vfs-sharp, Version=2.24.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
154+ <ProjectReference type="Gac" localcopy="True" refto="Mono.Addins, Version=0.4.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />
155 <ProjectReference type="Gac" localcopy="True" refto="nunit.framework, Version=2.2.0.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77" />
156- <ProjectReference type="Gac" localcopy="True" refto="Mono.Addins, Version=0.4.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />
157 </References>
158-</Project>
159+</Project>
160\ No newline at end of file
161
162=== modified file 'Do.Platform/Makefile.am'
163--- Do.Platform/Makefile.am 2009-06-26 11:01:40 +0000
164+++ Do.Platform/Makefile.am 2009-07-23 07:17:00 +0000
165@@ -14,6 +14,7 @@
166 src/Do.Platform/Do.Platform.Common/DictionaryPreferencesService.cs \
167 src/Do.Platform/Do.Platform.Common/EventsOnlyNotificationsService.cs \
168 src/Do.Platform/Do.Platform.Common/FileLogService.cs \
169+ src/Do.Platform/Do.Platform.Common/AbstractKeyBindingService.cs \
170 src/Do.Platform/Do.Platform.Default/CoreService.cs \
171 src/Do.Platform/Do.Platform.Default/DefaultApplicationService.cs \
172 src/Do.Platform/Do.Platform.Default/DefaultSystemService.cs \
173@@ -28,6 +29,7 @@
174 src/Do.Platform/Do.Platform.Default/UniverseFactoryService.cs \
175 src/Do.Platform/Do.Platform.Default/WindowingService.cs \
176 src/Do.Platform/Do.Platform.Default/NetworkService.cs \
177+ src/Do.Platform/Do.Platform.Default/KeyBindingService.cs \
178 src/Do.Platform/Do.Platform.Preferences/PreferencesFactory.cs \
179 src/Do.Platform/Do.Platform.Preferences/PreferencesImplementation.cs \
180 src/Do.Platform/Do.Platform.ServiceStack/IInitializedService.cs \
181@@ -57,6 +59,8 @@
182 src/Do.Platform/Services.cs \
183 src/Do.Platform/INetworkService.cs \
184 src/Do.Platform/NetworkStateChangedEventArgs.cs \
185+ src/Do.Platform/IKeyBindingService.cs \
186+ src/Do.Platform/KeyBinding.cs \
187 src/Do.Universe/Do.Universe.Common/EmailAction.cs \
188 src/Do.Universe/Do.Universe.Common/OpenAction.cs \
189 src/Do.Universe/Do.Universe.Common/OpenUrlAction.cs \
190@@ -89,5 +93,6 @@
191 System \
192 System.Core \
193 Mono.Posix \
194+ $(GTK_SHARP_20_LIBS) \
195 $(MONO_ADDINS_LIBS) \
196 $(NUNIT_LIBS)
197
198=== added file 'Do.Platform/src/Do.Platform/Do.Platform.Common/AbstractKeyBindingService.cs'
199--- Do.Platform/src/Do.Platform/Do.Platform.Common/AbstractKeyBindingService.cs 1970-01-01 00:00:00 +0000
200+++ Do.Platform/src/Do.Platform/Do.Platform.Common/AbstractKeyBindingService.cs 2009-07-27 01:25:19 +0000
201@@ -0,0 +1,115 @@
202+using System;
203+using System.Collections.Generic;
204+using System.Linq;
205+using System.Text;
206+
207+using Do.Platform.Common;
208+
209+namespace Do.Platform.Common
210+{
211+ public abstract class AbstractKeyBindingService : IKeyBindingService
212+ {
213+
214+ public abstract bool RegisterOSKey (string keyString, EventCallback cb);
215+ public abstract bool UnRegisterOSKey (string keyString);
216+
217+ IPreferences prefs;
218+
219+ #region IInitializedService
220+
221+ public void Initialize () {
222+ Bindings = new List<KeyBinding> ();
223+
224+ prefs = Services.Preferences.Get<AbstractKeyBindingService> ();
225+ }
226+
227+ #endregion
228+
229+ #region IKeyBindingService
230+
231+ public List<KeyBinding> Bindings { get; private set; }
232+
233+ public bool RegisterKeyBinding (KeyBinding binding) {
234+ bool success = true;
235+
236+ //first check if this keystring is already used
237+ if (Bindings.Any (k => k.KeyString == binding.KeyString)) {
238+ Log<AbstractKeyBindingService>.Error ("Key '{0}' is already mapped.", binding.KeyString);
239+ return false;
240+ }
241+
242+ //try to get the keystring from the prefs. We default to the KeyBinding.KeyString, so we can later check
243+ //if the prefs value matches that, we're using the default, otherwise we're using a user specified value
244+ string prefsKeyString = prefs.Get (binding.Description.Replace (' ', '_'), binding.KeyString);
245+ //if these values don't match then the user has specified a new keystring
246+ //update the KeyEvent then continue
247+ if (prefsKeyString != binding.KeyString)
248+ binding.KeyString = prefsKeyString;
249+
250+ //if we are registering a key with the OS, do something special
251+ if (binding.IsOSKey) {
252+ //try to register the key from the prefs with the OS
253+ if (!string.IsNullOrEmpty (binding.KeyString))
254+ success = RegisterOSKey (binding.KeyString, binding.Callback);
255+ //if we fail to register the summon key, try again with the default binding
256+ if (!success && !string.IsNullOrEmpty (binding.DefaultKeyString)) {
257+ success = RegisterOSKey (binding.DefaultKeyString, binding.Callback);
258+ //if we succeeded now, change the event's keystring
259+ if (success)
260+ binding.KeyString = binding.DefaultKeyString;
261+ }
262+ }
263+
264+ if (success) {
265+ //add the event to the list of bindings
266+ Bindings.Add (binding);
267+ //set the bound keystring in the prefs
268+ prefs.Set (binding.Description.Replace (' ', '_'), binding.KeyString);
269+ }
270+
271+ return success;
272+ }
273+
274+ public bool SetKeyString (KeyBinding binding, string newKeyString) {
275+ bool success = true;
276+
277+ //first check if this keystring exists
278+ if (!Bindings.Any (k => k.KeyString == binding.KeyString)) {
279+ Log<AbstractKeyBindingService>.Error ("Key '{0}' is not mapped.", binding.KeyString);
280+ return false;
281+ }
282+
283+ //if this key should be registered with the OS
284+ if (binding.IsOSKey) {
285+ //remove the old keystring from the OS
286+ if (!string.IsNullOrEmpty (binding.KeyString))
287+ UnRegisterOSKey (binding.KeyString);
288+ //register again with the new keystring
289+ if (!string.IsNullOrEmpty (newKeyString))
290+ success = RegisterOSKey (newKeyString, binding.Callback);
291+ }
292+
293+ if (success) {
294+ /*
295+ //first remove the old binding
296+ Bindings.Remove (binding.KeyString);
297+ //next set the new keystring
298+ binding.KeyString = newKeyString;
299+ //now add it back to the dict of bindings
300+ Bindings.Add (binding.KeyString, binding);
301+ */
302+ //set the new keystring
303+ Bindings.First (k => k.KeyString == binding.KeyString).KeyString = newKeyString;
304+
305+ //save the new value in the prefs
306+ prefs.Set (binding.Description.Replace (' ', '_'), binding.KeyString);
307+
308+ Log<AbstractKeyBindingService>.Debug ("\"{0}\" now mapped to '{1}'", binding.Description, binding.KeyString);
309+ }
310+
311+ return success;
312+ }
313+
314+ #endregion
315+ }
316+}
317\ No newline at end of file
318
319=== added file 'Do.Platform/src/Do.Platform/Do.Platform.Default/KeyBindingService.cs'
320--- Do.Platform/src/Do.Platform/Do.Platform.Default/KeyBindingService.cs 1970-01-01 00:00:00 +0000
321+++ Do.Platform/src/Do.Platform/Do.Platform.Default/KeyBindingService.cs 2009-07-27 01:25:19 +0000
322@@ -0,0 +1,23 @@
323+using System;
324+using System.Collections.Generic;
325+using System.Linq;
326+using System.Text;
327+
328+using Do.Platform.Common;
329+
330+namespace Do.Platform.Default
331+{
332+ class KeyBindingService : IKeyBindingService
333+ {
334+ public bool RegisterKeyBinding (KeyBinding evnt) {
335+ Log.Error ("Default keybinding service cannot register key events. {0}", evnt.KeyString);
336+ return false;
337+ }
338+ public bool SetKeyString (KeyBinding binding, string keyString) {
339+ return false;
340+ }
341+ public List<KeyBinding> Bindings { get { return new List<KeyBinding> (); } }
342+ public void Initialize () {
343+ }
344+ }
345+}
346
347=== added file 'Do.Platform/src/Do.Platform/IKeyBindingService.cs'
348--- Do.Platform/src/Do.Platform/IKeyBindingService.cs 1970-01-01 00:00:00 +0000
349+++ Do.Platform/src/Do.Platform/IKeyBindingService.cs 2009-07-27 01:25:19 +0000
350@@ -0,0 +1,19 @@
351+using System;
352+using System.Collections.Generic;
353+
354+using Do.Platform.Common;
355+using Do.Platform.ServiceStack;
356+
357+using Gdk;
358+
359+namespace Do.Platform
360+{
361+ public delegate void EventCallback (EventKey evtky);
362+
363+ public interface IKeyBindingService : IInitializedService
364+ {
365+ bool RegisterKeyBinding (KeyBinding evnt);
366+ bool SetKeyString (KeyBinding binding, string keyString);
367+ List<KeyBinding> Bindings { get; }
368+ }
369+}
370
371=== added file 'Do.Platform/src/Do.Platform/KeyBinding.cs'
372--- Do.Platform/src/Do.Platform/KeyBinding.cs 1970-01-01 00:00:00 +0000
373+++ Do.Platform/src/Do.Platform/KeyBinding.cs 2009-07-27 01:25:19 +0000
374@@ -0,0 +1,33 @@
375+using System;
376+using System.Collections.Generic;
377+using System.Linq;
378+using System.Text;
379+
380+using Do.Platform.Common;
381+
382+using Gdk;
383+
384+namespace Do.Platform
385+{
386+ public class KeyBinding
387+ {
388+ public string Description { get; private set; }
389+ public EventCallback Callback { get; private set; }
390+ public string KeyString { get; set; }
391+ public string DefaultKeyString { get; private set; }
392+ public bool IsOSKey { get; private set; }
393+
394+ public KeyBinding (string description, string keyString, EventCallback eventFunc) : this (description, keyString, eventFunc, false)
395+ {
396+ }
397+
398+ public KeyBinding (string description, string keyString, EventCallback eventFunc, bool isoskey)
399+ {
400+ this.Description = description;
401+ this.KeyString = keyString;
402+ this.DefaultKeyString = keyString;
403+ this.Callback = eventFunc;
404+ this.IsOSKey = isoskey;
405+ }
406+ }
407+}
408\ No newline at end of file
409
410=== modified file 'Do.Platform/src/Do.Platform/Services.cs'
411--- Do.Platform/src/Do.Platform/Services.cs 2009-06-26 11:01:40 +0000
412+++ Do.Platform/src/Do.Platform/Services.cs 2009-07-22 01:12:59 +0000
413@@ -38,6 +38,7 @@
414 static INetworkService network;
415 static IWindowingService windowing;
416 static AbstractSystemService system;
417+ static IKeyBindingService keybinder;
418 static IEnumerable<ILogService> logs;
419 static PreferencesFactory preferences;
420 static IEnvironmentService environment;
421@@ -198,6 +199,7 @@
422 return package_manager;
423 }
424 }
425+
426 public static IPluginManagerService PluginManager {
427 get {
428 if (plugin_manager == null)
429@@ -205,6 +207,14 @@
430 return plugin_manager;
431 }
432 }
433+
434+ public static IKeyBindingService Keybinder {
435+ get {
436+ if (keybinder == null)
437+ keybinder = LocateService<IKeyBindingService, Default.KeyBindingService> ();
438+ return keybinder;
439+ }
440+ }
441
442 public static PreferencesFactory Preferences {
443
444
445=== removed file 'Do/Do.exe.config.in'
446--- Do/Do.exe.config.in 2008-04-27 01:12:26 +0000
447+++ Do/Do.exe.config.in 1970-01-01 00:00:00 +0000
448@@ -1,4 +0,0 @@
449-<configuration>
450- <dllmap dll="libc" target="libc.so.6"/>
451- <dllmap dll="libdo" target="@expanded_libdir@/@PACKAGE@/libdo.so"/>
452-</configuration>
453
454=== modified file 'Do/Makefile.am'
455--- Do/Makefile.am 2009-06-26 11:01:40 +0000
456+++ Do/Makefile.am 2009-07-23 09:29:41 +0000
457@@ -16,7 +16,6 @@
458 gtk-gui/generated.cs \
459 src/AssemblyInfo.cs \
460 src/CorePreferences.cs \
461- src/CoreKeybindings.cs \
462 src/Do.Core/Do.Core.Addins/AddinClassifier.cs \
463 src/Do.Core/Do.Core.Addins/CommunityAddinClassifier.cs \
464 src/Do.Core/Do.Core.Addins/GreedyAddinClassifier.cs \
465@@ -73,8 +72,7 @@
466 src/Mono.Addins/AddinExtensions.cs \
467 src/Mono.Addins/Mono.Addins.Setup/AddinRepositoryEntryExtensions.cs \
468 src/PathExtensions.cs \
469- src/Util.cs \
470- src/XKeybinder.cs
471+ src/Util.cs
472
473 RESOURCES = \
474 gtk-gui/gui.stetic \
475@@ -103,10 +101,10 @@
476 # Extra rules for our binary, not worth factoring out
477 #
478
479-CLEANFILES += Do.exe.config gnome-do
480-EXTRA_DIST += Do.exe.config.in gnome-do.in Do.addins
481+CLEANFILES += gnome-do
482+EXTRA_DIST += gnome-do.in Do.addins
483
484-module_DATA += Do.exe.config Do.addins
485+module_DATA += Do.addins
486 bin_SCRIPTS = gnome-do
487
488 MCS_FLAGS += -unsafe
489
490=== modified file 'Do/gtk-gui/gui.stetic'
491--- Do/gtk-gui/gui.stetic 2009-06-26 11:01:40 +0000
492+++ Do/gtk-gui/gui.stetic 2009-07-23 07:17:00 +0000
493@@ -5,9 +5,6 @@
494 <target-gtk-version>2.12</target-gtk-version>
495 </configuration>
496 <import>
497- <widget-library name="../../Do.Platform.Linux/bin/Debug/Do.Platform.Linux.dll" />
498- <widget-library name="../../Do.Interface.Linux/bin/Debug/Do.Interface.Linux.dll" />
499- <widget-library name="../../Do.Interface.Linux.AnimationBase/bin/Debug/Do.Interface.Linux.AnimationBase.dll" />
500 <widget-library name="Mono.Addins.Gui, Version=0.4.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" />
501 <widget-library name="../bin/Debug/Do.exe" internal="true" />
502 </import>
503@@ -136,6 +133,7 @@
504 <property name="Position">0</property>
505 <property name="AutoSize">False</property>
506 <property name="Expand">False</property>
507+ <property name="Fill">False</property>
508 </packing>
509 </child>
510 <child>
511@@ -143,7 +141,8 @@
512 <property name="MemberName" />
513 <property name="Ypad">1</property>
514 <property name="Xalign">0</property>
515- <property name="LabelProp" translatable="yes">To edit a shortcut, double-click it and type a new one.</property>
516+ <property name="LabelProp" translatable="yes">To edit a shortcut, double-click it and type a new one.
517+To restore a shortcut to the default, double click and press Backspace.</property>
518 <property name="Wrap">True</property>
519 </widget>
520 <packing>
521
522=== removed file 'Do/src/CoreKeybindings.cs'
523--- Do/src/CoreKeybindings.cs 2009-03-28 23:09:02 +0000
524+++ Do/src/CoreKeybindings.cs 1970-01-01 00:00:00 +0000
525@@ -1,230 +0,0 @@
526-
527-/* Keybindings.cs
528- *
529- * GNOME Do is the legal property of its developers. Please refer to the
530- * COPYRIGHT file distributed with this
531- * source distribution.
532- *
533- * This program is free software: you can redistribute it and/or modify
534- * it under the terms of the GNU General Public License as published by
535- * the Free Software Foundation, either version 3 of the License, or
536- * (at your option) any later version.
537- *
538- * This program is distributed in the hope that it will be useful,
539- * but WITHOUT ANY WARRANTY; without even the implied warranty of
540- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
541- * GNU General Public License for more details.
542- *
543- * You should have received a copy of the GNU General Public License
544- * along with this program. If not, see <http://www.gnu.org/licenses/>.
545- */
546-
547-using System;
548-using System.Linq;
549-using System.Collections;
550-using System.Collections.Generic;
551-using Env = System.Environment;
552-
553-using Do.Platform;
554-
555-namespace Do
556-{
557-
558- class CoreKeybindings
559- {
560- Dictionary<string, string> KeycodeMap ; // keybinding -> shortcut name
561- Dictionary<string, Shortcut> ShortcutMap ; // shortcut name -> shortcut
562- Dictionary<string, string> DefaultShortcutMap ; // default keybinding -> shortcut name
563-
564- IPreferences Preferences { get; set; }
565-
566- public ArrayList Shortcuts ;
567- public Dictionary<string, List<KeyChangedCb>> PreferencesCbs;
568- public delegate void KeyChangedCb (object sender, PreferencesChangedEventArgs e);
569-
570- public CoreKeybindings ()
571- {
572-
573- Preferences = Services.Preferences.Get<CoreKeybindings> ();
574- Preferences.PreferencesChanged += PreferencesChanged;
575-
576- Shortcuts = new ArrayList ();
577- KeycodeMap = new Dictionary<string, string> (); // keybinding -> shortcut name
578- ShortcutMap = new Dictionary<string, Shortcut> (); // shortcut name -> shortcut
579- DefaultShortcutMap = new Dictionary<string, string> (); // default keybinding -> shortcut name
580- PreferencesCbs = new Dictionary<string, List<KeyChangedCb>> ();
581-
582- Initialize ();
583- }
584-
585- public void Initialize ()
586- {
587- // Read all values out of preferences and populate the KeybindingMap
588- ReadShortcuts ();
589- }
590-
591- public bool RegisterShortcut (Shortcut sc, string defaultBinding)
592- {
593- if (!RegisterShortcut (sc))
594- return false;
595- if (!BindDefault (sc, defaultBinding))
596- return false;
597- return true;
598- }
599-
600- public bool RegisterShortcut (Shortcut sc)
601- {
602- if (Shortcuts.Contains (sc) || ShortcutMap.ContainsKey (sc.ShortcutName))
603- return false;
604-
605- Shortcuts.Add (sc);
606- ShortcutMap [sc.ShortcutName] = sc;
607- PreferencesCbs [sc.ShortcutName] = new List<KeyChangedCb> ();
608- SaveShortcuts ();
609- return true;
610- }
611-
612- public Shortcut GetShortcutByKeycode (string keycode)
613- {
614- if (!KeycodeMap.ContainsKey (keycode))
615- return null;
616-
617- string scname = KeycodeMap [keycode];
618-
619- if (!ShortcutMap.ContainsKey (scname))
620- return null;
621-
622- return ShortcutMap [scname];
623-
624- }
625-
626- public string GetKeybinding (Shortcut sc)
627- {
628- return GetKeybinding (sc.ShortcutName);
629- }
630-
631- public string GetKeybinding (string sc)
632- {
633-
634- foreach (KeyValuePair<string, string> entry in KeycodeMap) {
635- if (entry.Value == sc)
636- return entry.Key;
637- }
638- return null;
639- }
640-
641- public string GetDefaultKeybinding (Shortcut sc)
642- {
643- return GetDefaultKeybinding (sc.ShortcutName);
644- }
645-
646- public string GetDefaultKeybinding (string sc)
647- {
648- foreach (KeyValuePair<string, string> entry in DefaultShortcutMap) {
649- if (entry.Value == sc)
650- return entry.Key;
651- }
652- return null;
653- }
654-
655-
656- public bool BindShortcut (Shortcut sc, string keycode)
657- {
658- // Add this function to our keybinding map
659- return BindShortcut (sc.ShortcutName, keycode);
660-
661- }
662-
663- public bool BindShortcut (string sc, string keycode)
664- {
665- string oldcode = GetKeybinding (sc);
666- if (oldcode != null)
667- KeycodeMap.Remove (oldcode); // remove the old keybinding from the map
668-
669- KeycodeMap [keycode] = sc;
670- Preferences.Set (sc, keycode);
671-
672- return true;
673- }
674-
675- // Add Default Keycode mapping - used for resetting to default or not overwriting read values
676- public bool BindDefault (Shortcut sc, string keycode)
677- {
678- return BindDefault (sc.ShortcutName, keycode);
679-
680- }
681-
682- public bool BindDefault (string sc, string keycode)
683- {
684-
685- string assigned_keycode = GetKeybinding (sc);
686- if (assigned_keycode == null) {
687- // Put this shortcut in the mapping
688- BindShortcut (sc, keycode);
689- }
690-
691- DefaultShortcutMap [keycode] = sc;
692- return true;
693-
694- }
695-
696- public bool UnregisterShortcut (Shortcut sc)
697- {
698- if (!Shortcuts.Contains (sc))
699- return false;
700-
701- Shortcuts.Remove (sc);
702- ShortcutMap.Remove (sc.ShortcutName);
703- SaveShortcuts ();
704- return true;
705- }
706-
707- public bool RegisterNotification (Shortcut sc, KeyChangedCb cb)
708- {
709- return RegisterNotification (sc.ShortcutName, cb);
710- }
711-
712- public bool RegisterNotification (string scname, KeyChangedCb cb)
713- {
714- PreferencesCbs [scname].Add (cb);
715- return true;
716- }
717-
718- void SaveShortcuts ()
719- {
720- string scstring = "";
721- foreach (Shortcut sc in Shortcuts) {
722- scstring += sc.ShortcutName.Trim () + ",";
723- }
724- Preferences.Set ("RegisteredShortcuts", scstring);
725- }
726-
727- void ReadShortcuts ()
728- {
729- string scstring = Preferences.Get ("RegisteredShortcuts", "").Trim ();
730- if (scstring == "")
731- return;
732-
733- foreach (string sc in scstring.Split (',')) {
734- if (sc.Trim () == "")
735- continue;
736-
737- string keycode = Preferences.Get (sc, "");
738- if (keycode != "")
739- BindShortcut (sc, keycode);
740- }
741- }
742-
743- void PreferencesChanged (object sender, PreferencesChangedEventArgs e)
744- {
745-
746- if (PreferencesCbs.ContainsKey (e.Key)) {
747- foreach (KeyChangedCb cb in PreferencesCbs [e.Key]) {
748- cb (this, e);
749- }
750- }
751- }
752-
753- }
754-
755-}
756
757=== modified file 'Do/src/Do.Core/Controller.cs'
758--- Do/src/Do.Core/Controller.cs 2009-06-24 01:42:21 +0000
759+++ Do/src/Do.Core/Controller.cs 2009-07-27 01:25:19 +0000
760@@ -30,6 +30,7 @@
761 using Do.UI;
762 using Do.Universe;
763 using Do.Platform;
764+using Do.Platform.Common;
765 using Do.Interface;
766
767 namespace Do.Core
768@@ -108,96 +109,37 @@
769 Screen.Default.CompositedChanged += OnCompositingChanged;
770
771 // Register Shortcuts
772- // TODO: Localize the text here.
773- // Previous shortcuts
774- Do.Keybindings.RegisterShortcut (
775- new Shortcut ("SummonKey",
776- Catalog.GetString ("Summon GNOME Do"),
777- OnSummonKeyPressEvent),
778- "<Super>space");
779- Do.Keybindings.RegisterShortcut (
780- new Shortcut ("TextModeKey",
781- Catalog.GetString ("Enter text mode"),
782- OnTextModePressEvent),
783- "period");
784- // New shortcuts
785- Do.Keybindings.RegisterShortcut (
786- new Shortcut ("CopyKey",
787- Catalog.GetString ("Copy Text"),
788- OnCopyEvent),
789- "<Control>c");
790- Do.Keybindings.RegisterShortcut (
791- new Shortcut ("PasteKey",
792- Catalog.GetString ("Paste Text"),
793- OnPasteEvent),
794- "<Control>v");
795- Do.Keybindings.RegisterShortcut (
796- new Shortcut ("AlternateEscapeKey",
797- Catalog.GetString ("Alternate Escape"),
798- OnEscapeKeyPressEvent));
799- Do.Keybindings.RegisterShortcut (
800- new Shortcut ("AlternateActivateKey",
801- Catalog.GetString ("Alternate Activate"),
802- OnActivateKeyPressEvent));
803- Do.Keybindings.RegisterShortcut (
804- new Shortcut ("AlternateDeleteKey",
805- Catalog.GetString ("Alternate Delete"),
806- OnDeleteKeyPressEvent));
807- Do.Keybindings.RegisterShortcut (
808- new Shortcut ("ShiftTabKey",
809- Catalog.GetString ("Previous Pane"),
810- OnShiftTabKeyPressEvent),
811- "ISO_Left_Tab");
812- Do.Keybindings.RegisterShortcut (
813- new Shortcut ("TabKey",
814- Catalog.GetString ("Next Pane"),
815- OnTabKeyPressEvent),
816- "Tab");
817- Do.Keybindings.RegisterShortcut (
818- new Shortcut ("UpKey",
819- Catalog.GetString ("Previous Result"),
820- OnUpKeyPressEvent),
821- "Up");
822- Do.Keybindings.RegisterShortcut (
823- new Shortcut ("DownKey",
824- Catalog.GetString ("Next Result"),
825- OnDownKeyPressEvent),
826- "Down");
827- Do.Keybindings.RegisterShortcut (
828- new Shortcut ("HomeKey",
829- Catalog.GetString ("First Result"),
830- OnHomeKeyPressEvent),
831- "Home");
832- Do.Keybindings.RegisterShortcut (
833- new Shortcut ("EndKey",
834- Catalog.GetString ("Last Result"),
835- OnEndKeyPressEvent),
836- "End");
837- Do.Keybindings.RegisterShortcut (
838- new Shortcut ("PageUpKey",
839- Catalog.GetString ("Previous 5 Results"),
840- OnPageUpKeyPressEvent),
841- "Page_Up");
842- Do.Keybindings.RegisterShortcut (
843- new Shortcut ("PageDownKey",
844- Catalog.GetString ("Next 5 Results"),
845- OnPageDownKeyPressEvent),
846- "Page_Down");
847- Do.Keybindings.RegisterShortcut (
848- new Shortcut ("LeftKey",
849- Catalog.GetString ("Step out of Item"),
850- OnLeftKeyPressEvent),
851- "Left");
852- Do.Keybindings.RegisterShortcut (
853- new Shortcut ("RightKey",
854- Catalog.GetString ("Browse Into Item"),
855- OnRightKeyPressEvent),
856- "Right");
857- Do.Keybindings.RegisterShortcut (
858- new Shortcut ("CommaKey",
859- Catalog.GetString ("Multiple selection"),
860- OnSelectionKeyPressEvent),
861- "comma");
862+ Services.Keybinder.RegisterKeyBinding (new KeyBinding (Catalog.GetString ("Enter Text Mode"), "period",
863+ OnTextModePressEvent));
864+ Services.Keybinder.RegisterKeyBinding (new KeyBinding (Catalog.GetString ("Copy to Clipboard"), "<Control>c",
865+ OnCopyEvent));
866+ Services.Keybinder.RegisterKeyBinding (new KeyBinding (Catalog.GetString ("Paste Current Text"), "<Control>v",
867+ OnPasteEvent));
868+ Services.Keybinder.RegisterKeyBinding (new KeyBinding (Catalog.GetString ("Previous Pane"), "<Shift>Tab",
869+ OnPreviousPanePressEvent));
870+ Services.Keybinder.RegisterKeyBinding (new KeyBinding (Catalog.GetString ("Next Pane"), "Tab",
871+ OnNextPanePressEvent));
872+ Services.Keybinder.RegisterKeyBinding (new KeyBinding (Catalog.GetString ("Previous Item"), "Up",
873+ OnUpKeyPressEvent));
874+ Services.Keybinder.RegisterKeyBinding (new KeyBinding (Catalog.GetString ("Next Item"), "Down",
875+ OnDownKeyPressEvent));
876+ Services.Keybinder.RegisterKeyBinding (new KeyBinding (Catalog.GetString ("First Item"), "Home",
877+ OnHomeKeyPressEvent));
878+ Services.Keybinder.RegisterKeyBinding (new KeyBinding (Catalog.GetString ("Last Item"), "End",
879+ OnEndKeyPressEvent));
880+ Services.Keybinder.RegisterKeyBinding (new KeyBinding (Catalog.GetString ("Previous 5 Results"), "Page_Up",
881+ OnPageUpKeyPressEvent));
882+ Services.Keybinder.RegisterKeyBinding (new KeyBinding (Catalog.GetString ("Next 5 Results"), "Page_Down",
883+ OnPageDownKeyPressEvent));
884+ Services.Keybinder.RegisterKeyBinding (new KeyBinding (Catalog.GetString ("Step Out of Item"), "Left",
885+ OnLeftKeyPressEvent));
886+ Services.Keybinder.RegisterKeyBinding (new KeyBinding (Catalog.GetString ("Browse Into Item"), "Right",
887+ OnRightKeyPressEvent));
888+ Services.Keybinder.RegisterKeyBinding (new KeyBinding (Catalog.GetString ("Select Multiple Items"), "comma",
889+ OnSelectionKeyPressEvent));
890+ //summon in text mode
891+ Services.Keybinder.RegisterKeyBinding (new KeyBinding (Catalog.GetString ("Summon in Text Mode"), "",
892+ delegate { this.Summon (); SearchController.TextMode = true; UpdatePane (CurrentPane); } , true));
893 }
894
895 void OnSummoned ()
896@@ -507,13 +449,10 @@
897 } else if (key == Key.Delete ||
898 key == Key.BackSpace) {
899 OnDeleteKeyPressEvent (evnt);
900- } else {
901+ } else if (Services.Keybinder.Bindings.Any (k => k.KeyString == KeyEventToString (evnt))) {
902 // User set keybindings
903- Shortcut sc = Do.Keybindings.GetShortcutByKeycode (KeyEventToString (evnt));
904- if (sc != null) {
905- sc.Callback (evnt);
906- return;
907- }
908+ Services.Keybinder.Bindings.First (k => k.KeyString == KeyEventToString (evnt)).Callback (evnt);
909+ } else {
910 OnInputKeyPressEvent (evnt);
911 }
912 }
913@@ -648,7 +587,7 @@
914 if (SearchController.ItemChildSearch ()) GrowResults ();
915 }
916
917- void OnTabKeyPressEvent (EventKey evnt)
918+ void OnNextPanePressEvent (EventKey evnt)
919 {
920 im_context.Reset ();
921 ShrinkResults ();
922@@ -661,7 +600,7 @@
923 UpdatePane (CurrentPane);
924 }
925
926- void OnShiftTabKeyPressEvent (EventKey evnt)
927+ void OnPreviousPanePressEvent (EventKey evnt)
928 {
929 im_context.Reset ();
930 ShrinkResults ();
931@@ -760,7 +699,14 @@
932 if ((evnt.State & ModifierType.Mod1Mask) != 0) {
933 modifier += "<Alt>";
934 }
935- return modifier + evnt.Key.ToString ();
936+ if ((evnt.State & ModifierType.ShiftMask) != 0) {
937+ modifier += "<Shift>";
938+ //if we're pressing shift, and the key is ISO_Left_Tab,
939+ //just make it Tab
940+ if (evnt.Key == Key.ISO_Left_Tab)
941+ return string.Format ("{0}{1}", modifier, Key.Tab);
942+ }
943+ return string.Format ("{0}{1}", modifier, evnt.Key.ToString ());
944 }
945 #endregion
946
947
948=== modified file 'Do/src/Do.UI/KeybindingTreeView.cs'
949--- Do/src/Do.UI/KeybindingTreeView.cs 2009-06-20 04:30:05 +0000
950+++ Do/src/Do.UI/KeybindingTreeView.cs 2009-07-27 01:25:19 +0000
951@@ -20,40 +20,41 @@
952
953
954 using System;
955+using System.Linq;
956+
957 using Gtk;
958 using Mono.Unix;
959
960+using Do.Platform;
961+using Do.Platform.Common;
962+
963 namespace Do.UI
964 {
965 public class KeybindingTreeView : TreeView
966 {
967 enum Column {
968 Action = 0,
969+ BoundKeyString,
970+ DefaultKeybinding,
971 Binding,
972- DefaultKeybinding,
973- ShortcutName,
974 NumColumns
975 }
976
977 public KeybindingTreeView ()
978 {
979- Model = new ListStore (typeof (string), typeof (string), typeof (string), typeof (string));
980+ Model = new ListStore (typeof (string), typeof (string), typeof (string), typeof (KeyBinding));
981
982 CellRendererText actionCell = new CellRendererText ();
983 actionCell.Width = 150;
984 InsertColumn (-1, Catalog.GetString ("Action"), actionCell, "text", (int)Column.Action);
985
986 CellRendererAccel bindingCell = new CellRendererAccel ();
987- bindingCell.AccelMode = CellRendererAccelMode.Gtk;
988+ bindingCell.AccelMode = CellRendererAccelMode.Other;
989 bindingCell.Editable = true;
990 bindingCell.AccelEdited += new AccelEditedHandler (OnAccelEdited);
991 bindingCell.AccelCleared += new AccelClearedHandler (OnAccelCleared);
992- InsertColumn (-1, Catalog.GetString ("Shortcut"), bindingCell, "text", (int)Column.Binding);
993-
994- CellRendererText defaultbindingCell = new CellRendererText ();
995- actionCell.Width = 150;
996-// InsertColumn (-1, Catalog.GetString ("Default Shortcut"), defaultbindingCell, "text", (int)Column.DefaultKeybinding);
997-
998+ InsertColumn (-1, Catalog.GetString ("Shortcut"), bindingCell, "text", (int)Column.BoundKeyString);
999+
1000 RowActivated += new RowActivatedHandler (OnRowActivated);
1001 ButtonPressEvent += new ButtonPressEventHandler (OnButtonPress);
1002
1003@@ -66,9 +67,8 @@
1004 ListStore store = Model as ListStore;
1005 store.Clear ();
1006
1007- foreach (Shortcut sc in Do.Keybindings.Shortcuts) {
1008- store.AppendValues (sc.FriendlyName, Do.Keybindings.GetKeybinding (sc),
1009- Do.Keybindings.GetDefaultKeybinding (sc), sc.ShortcutName);
1010+ foreach (KeyBinding binding in Services.Keybinder.Bindings.OrderBy (k => k.Description)) {
1011+ store.AppendValues (binding.Description, binding.KeyString, binding.DefaultKeyString, binding);
1012 }
1013 }
1014
1015@@ -81,21 +81,21 @@
1016
1017 if (GetPathAtPos ((int) args.Event.X, (int) args.Event.Y,out path)) {
1018 GrabFocus ();
1019- SetCursor (path, GetColumn ((int) Column.Binding), true);
1020+ SetCursor (path, GetColumn ((int) Column.BoundKeyString), true);
1021 }
1022 }
1023
1024 private void OnRowActivated (object o, RowActivatedArgs args)
1025 {
1026 GrabFocus ();
1027- SetCursor (args.Path, GetColumn ((int) Column.Binding), true);
1028+ SetCursor (args.Path, GetColumn ((int) Column.BoundKeyString), true);
1029 }
1030
1031 private bool ClearPreviousBinding (TreeModel model, TreePath path, TreeIter treeiter, string keyBinding)
1032 {
1033- string binding = model.GetValue (treeiter, (int) Column.Binding) as string;
1034+ string binding = model.GetValue (treeiter, (int) Column.BoundKeyString) as string;
1035 if (binding == keyBinding) {
1036- model.SetValue (treeiter, (int) Column.Binding, "");
1037+ model.SetValue (treeiter, (int) Column.BoundKeyString, "");
1038 }
1039 return false;
1040 }
1041@@ -110,10 +110,16 @@
1042
1043 string realKey = Gtk.Accelerator.Name (args.AccelKey, args.AccelMods);
1044
1045+ if (args.AccelKey == (uint) Gdk.Key.Super_L) {
1046+ //setting CellRenderAccelMode to "Other" ignores the Super key as a modifier
1047+ //this prevents us from grabbing _only_ the Super key.
1048+ return;
1049+ }
1050+
1051 // Look for any other rows that have the same binding and then zero that binding out
1052 Model.Foreach ((model, path, treeiter) => ClearPreviousBinding (model, path, treeiter, realKey));
1053
1054- store.SetValue (iter, (int) Column.Binding, realKey);
1055+ store.SetValue (iter, (int) Column.BoundKeyString, realKey);
1056
1057 SaveBindings ();
1058 }
1059@@ -127,9 +133,9 @@
1060 store.GetIter (out iter, new TreePath (args.PathString));
1061 try {
1062 string defaultVal = store.GetValue (iter, (int) Column.DefaultKeybinding).ToString ();
1063- store.SetValue (iter, (int) Column.Binding, defaultVal);
1064+ store.SetValue (iter, (int) Column.BoundKeyString, defaultVal);
1065 } catch (Exception e) {
1066- store.SetValue (iter, (int) Column.Binding, "");
1067+ store.SetValue (iter, (int) Column.BoundKeyString, "");
1068 }
1069
1070 SaveBindings ();
1071@@ -142,12 +148,18 @@
1072
1073 private bool SaveBindingsForeachFunc (TreeModel model, TreePath path, TreeIter iter)
1074 {
1075- string binding, shortcutname;
1076- binding = model.GetValue (iter, (int) Column.Binding) as string;
1077- shortcutname = model.GetValue (iter, (int) Column.ShortcutName) as string;
1078+ string newKeyString = model.GetValue (iter, (int) Column.BoundKeyString) as string;
1079+ KeyBinding binding = model.GetValue (iter, (int) Column.Binding) as KeyBinding;
1080
1081- if (binding != null && binding != "DISABLED" && binding != Do.Keybindings.GetKeybinding (shortcutname))
1082- Do.Keybindings.BindShortcut (shortcutname, binding);
1083+ //only save if the keystring changed
1084+ if (newKeyString != null && binding.KeyString != newKeyString) {
1085+ //try to save
1086+ if (!Services.Keybinder.SetKeyString (binding, newKeyString)) {
1087+ //if we fail reset to the default value
1088+ model.SetValue (iter, (int) Column.BoundKeyString, binding.DefaultKeyString);
1089+ Services.Keybinder.SetKeyString (binding, binding.DefaultKeyString);
1090+ }
1091+ }
1092 return false;
1093 }
1094
1095
1096=== modified file 'Do/src/Do.cs'
1097--- Do/src/Do.cs 2009-06-21 02:20:30 +0000
1098+++ Do/src/Do.cs 2009-07-23 09:29:41 +0000
1099@@ -27,18 +27,17 @@
1100 using Do.UI;
1101 using Do.Core;
1102 using Do.Platform;
1103+using Do.Platform.Common;
1104
1105 namespace Do {
1106
1107 static class Do {
1108
1109- static XKeybinder keybinder;
1110 static Controller controller;
1111 static UniverseManager universe_manager;
1112
1113- public static CorePreferences Preferences { get; private set; }
1114- public static CoreKeybindings Keybindings { get; private set; }
1115-
1116+ public static CorePreferences Preferences { get; private set; }
1117+
1118 internal static void Main (string [] args)
1119 {
1120 Catalog.Init ("gnome-do", AssemblyInfo.LocaleDirectory);
1121@@ -55,8 +54,6 @@
1122
1123 Preferences = new CorePreferences ();
1124
1125- Keybindings = new CoreKeybindings ();
1126-
1127 // Now we can set the preferred log level.
1128 if (Preferences.QuietStart)
1129 Log.DisplayLevel = LogLevel.Error;
1130@@ -73,12 +70,11 @@
1131 Controller.Initialize ();
1132 UniverseManager.Initialize ();
1133
1134- keybinder = new XKeybinder ();
1135 SetupKeybindings ();
1136
1137 if (!Preferences.QuietStart)
1138 Controller.Summon ();
1139-
1140+
1141 Gtk.Application.Run ();
1142
1143 RelevanceProvider.Serialize (RelevanceProvider.DefaultProvider);
1144@@ -100,37 +96,17 @@
1145 return universe_manager;
1146 }
1147 }
1148-
1149- static void SummonKeyCb (object sender, PreferencesChangedEventArgs e)
1150- {
1151- try {
1152- if (e.OldValue != null)
1153- keybinder.Unbind (e.OldValue as string);
1154- keybinder.Bind (Keybindings.GetKeybinding ("SummonKey"), OnActivate);
1155- } catch (Exception ex) {
1156- Log.Error ("Could not bind summon key: {0}", ex.Message);
1157- Log.Debug (ex.StackTrace);
1158- }
1159-
1160- }
1161
1162 static void SetupKeybindings ()
1163 {
1164 try {
1165- keybinder.Bind (Keybindings.GetKeybinding ("SummonKey"), OnActivate);
1166+ if (!Services.Keybinder.RegisterKeyBinding (new KeyBinding (Catalog.GetString ("Summon Do"),
1167+ "<Super>space", delegate { controller.Summon (); }, true)))
1168+ throw new Exception ();
1169 } catch (Exception e) {
1170- Log.Error ("Could not bind summon key: {0}", e.Message);
1171+ Log.Fatal ("Could not bind summon key!");
1172 Log.Debug (e.StackTrace);
1173 }
1174-
1175- // Watch preferences for changes to the keybinding so we
1176- // can change the binding when the user reassigns it.
1177- Keybindings.RegisterNotification ("SummonKey", SummonKeyCb);
1178- }
1179-
1180- static void OnActivate (object sender, EventArgs e)
1181- {
1182- controller.Summon ();
1183 }
1184 }
1185 }
1186
1187=== removed file 'Do/src/XKeybinder.cs'
1188--- Do/src/XKeybinder.cs 2008-12-18 18:39:06 +0000
1189+++ Do/src/XKeybinder.cs 1970-01-01 00:00:00 +0000
1190@@ -1,103 +0,0 @@
1191-/*****************************************************************************/
1192-/* XKeybinder.cs - Keybinding code taken from Tomboy */
1193-/* Copyright (C) 2004-2007 Alex Graveley <alex@beatniksoftware.com> */
1194-/* */
1195-/* This library is free software; you can redistribute it and/or */
1196-/* modify it under the terms of the GNU Lesser General Public */
1197-/* License as published by the Free Software Foundation; either */
1198-/* version 2.1 of the License, or (at your option) any later version. */
1199-/* */
1200-/* This library is distributed in the hope that it will be useful, */
1201-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
1202-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
1203-/* Lesser General Public License for more details. */
1204-/* */
1205-/* You should have received a copy of the GNU Lesser General Public */
1206-/* License along with this library; if not, write to the Free Software */
1207-/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
1208-/*****************************************************************************/
1209-
1210-using System;
1211-using System.Collections;
1212-using System.Runtime.InteropServices;
1213-using Mono.Unix;
1214-
1215-using Do.Platform;
1216-
1217-namespace Do
1218-{
1219- public class XKeybinder
1220- {
1221- [DllImport("libdo")]
1222- static extern void gnomedo_keybinder_init ();
1223-
1224- [DllImport("libdo")]
1225- static extern void gnomedo_keybinder_bind (string keystring, BindkeyHandler handler);
1226-
1227- [DllImport("libdo")]
1228- static extern void gnomedo_keybinder_unbind (string keystring, BindkeyHandler handler);
1229-
1230- public delegate void BindkeyHandler (string key, IntPtr user_data);
1231-
1232- ArrayList bindings;
1233- BindkeyHandler key_handler;
1234-
1235- struct Binding {
1236- internal string keystring;
1237- internal EventHandler handler;
1238- }
1239-
1240- public XKeybinder ()
1241- : base ()
1242- {
1243- bindings = new ArrayList ();
1244- key_handler = new BindkeyHandler (KeybindingPressed);
1245-
1246- try {
1247- gnomedo_keybinder_init ();
1248- } catch (DllNotFoundException) {
1249- Log.Error ("libdo not found - keybindings will not work.");
1250- }
1251- }
1252-
1253- void KeybindingPressed (string keystring, IntPtr user_data)
1254- {
1255- foreach (Binding bind in bindings) {
1256- if (bind.keystring == keystring) {
1257- bind.handler (this, new EventArgs ());
1258- }
1259- }
1260- }
1261-
1262- public void Bind (string keystring, EventHandler handler)
1263- {
1264- Binding bind = new Binding ();
1265- bind.keystring = keystring;
1266- bind.handler = handler;
1267- bindings.Add (bind);
1268-
1269- gnomedo_keybinder_bind (bind.keystring, key_handler);
1270- }
1271-
1272- public void Unbind (string keystring)
1273- {
1274- foreach (Binding bind in bindings) {
1275- if (bind.keystring == keystring) {
1276- gnomedo_keybinder_unbind (bind.keystring, key_handler);
1277-
1278- bindings.Remove (bind);
1279- break;
1280- }
1281- }
1282- }
1283-
1284- public virtual void UnbindAll ()
1285- {
1286- foreach (Binding bind in bindings) {
1287- gnomedo_keybinder_unbind (bind.keystring, key_handler);
1288- }
1289-
1290- bindings.Clear ();
1291- }
1292- }
1293-}
1294
1295=== modified file 'configure.ac'
1296--- configure.ac 2009-07-08 09:33:18 +0000
1297+++ configure.ac 2009-07-23 09:14:01 +0000
1298@@ -134,7 +134,6 @@
1299
1300 AC_CONFIG_FILES([
1301 BundledLibraries/Makefile
1302-Do/Do.exe.config
1303 Do/Makefile
1304 Do/gnome-do
1305 Do/src/AssemblyInfo.cs
1306@@ -152,6 +151,7 @@
1307 Do.Platform/Makefile
1308 Do.Platform/src/AssemblyInfo.cs
1309 Do.Platform.Linux/Makefile
1310+Do.Platform.Linux/Do.Platform.Linux.dll.config
1311 Do.Platform.Linux/src/AssemblyInfo.cs
1312 Do.Platform.Linux.JoliCloud/Makefile
1313 Do.Platform.Linux.JoliCloud/src/AssemblyInfo.cs
1314@@ -201,4 +201,4 @@
1315 Release Build: ${enable_release}
1316 NUnit: ${have_nunit}
1317
1318-EOF
1319\ No newline at end of file
1320+EOF
1321
1322=== modified file 'libdo/keybinder.c'
1323--- libdo/keybinder.c 2008-02-18 14:40:44 +0000
1324+++ libdo/keybinder.c 2009-07-23 07:17:00 +0000
1325@@ -257,7 +257,7 @@
1326 NULL);
1327 }
1328
1329-void
1330+gboolean
1331 gnomedo_keybinder_bind (const char *keystring,
1332 GnomeDoBindkeyHandler handler,
1333 gpointer user_data)
1334@@ -279,9 +279,11 @@
1335 g_free (binding->keystring);
1336 g_free (binding);
1337 }
1338+
1339+ return success;
1340 }
1341
1342-void
1343+gboolean
1344 gnomedo_keybinder_unbind (const char *keystring,
1345 GnomeDoBindkeyHandler handler)
1346 {
1347@@ -302,6 +304,8 @@
1348 g_free (binding);
1349 break;
1350 }
1351+
1352+ return TRUE;
1353 }
1354
1355 /*
1356
1357=== modified file 'libdo/keybinder.h'
1358--- libdo/keybinder.h 2008-02-18 14:40:44 +0000
1359+++ libdo/keybinder.h 2009-07-23 07:17:00 +0000
1360@@ -32,11 +32,11 @@
1361
1362 void gnomedo_keybinder_init (void);
1363
1364-void gnomedo_keybinder_bind (const char *keystring,
1365+gboolean gnomedo_keybinder_bind (const char *keystring,
1366 GnomeDoBindkeyHandler handler,
1367 gpointer user_data);
1368
1369-void gnomedo_keybinder_unbind (const char *keystring,
1370+gboolean gnomedo_keybinder_unbind (const char *keystring,
1371 GnomeDoBindkeyHandler handler);
1372
1373 gboolean gnomedo_keybinder_is_modifier (guint keycode);