Re: [Gtk-osx-users] accelerator problem with GtkOSXApplication

On 15/02/2011, at 8:15 AM, Olivier Sessink wrote:
> [...]

> In the old ige-mac-integration code all entries were 
> automatically converted from <control> to <command>. With the new 
> GtkOSXApplication code it seems I need something like 600 lines of extra 
> code to replace all accelerators, and I should try to keep these in 
> sync. Or is this again a misunderstanding and can I get the 'magic' 
> behavior with a few lines of code?

Just to jump in here: /if/ you're using the gtk AccelMap for keybindings, 
which is a 1:1 mapping from application-specific binding names to key binding 
definitions that can be altered at run-time, then you can achieve the 
ige-mac-integration effect of converting all <ctrl> to <command> via 
(in python; should be straightforward to transliterate into C): 

        am = gtk.accel_map_get()

        def translate_control_key_to_meta(accel_path, accel_key, accel_mods, changed):
            if accel_mods & gtk.gdk.CONTROL_MASK:
                accel_mods &= ~gtk.gdk.CONTROL_MASK
                accel_mods |= gtk.gdk.META_MASK

                if not gtk.accel_map_change_entry(accel_path,
                                                  accel_key, accel_mods, replace=False):
                    assert False # as binding conflicts with existing, say


If you're /not/ using the AccelMap, then, AFAIK, 
such run-time conversion is not possible.

warm regards,

PS. For what it's worth, here're my notes on the GTK keybinding system  
(which from where I'm standing strikes me as unnecessarily confusing):

*** AccelGroups 

Accelerators must work, even if the widget with which they are
associated is not focused. However, it increases coupling if top-level
widgets in the hierarchy are responsible for the accelerators of their

Therefore, we have the AccelGroup object, which fills this role of 
  - Listening for keyboard shortcuts and 
  - Dispatching them to the right handler. 

The gist is: 
  Get an AccelGroup, a container of accelerators mapping key-press -> callback 
  Associate it with a top-level widget, eg, gtk.Window.add_accel_group() 
gtk.Widgets.add_accelerator is /almost/ a convenience function which
lets us add an accelerator to an AccelGroup that emits a signal on the
widget when the key combination occurs. However, for menuitems it
provides a hook to setup the accelerator label appropriately. 

Now, changing key bindings at run time is cumbersome for the user
because there is in general no user-visible name for the action a
key-press is associated with. Therefore the singleton accelerator map
provides a user-visible directory of named key bindings in the system.
see gtk.accel_map_change_entry(). These are "accel paths", which the
gtk.AccelGroup understands.

**** How do I retrieve the AccelGroups? 

**** How can I retrieve bindings from an AccelGroup? 
There doesn't seem to be a way? 

**** How do AccelGroups receive key press events? 
Via their TopLevel window key-press handler, see

**** Can AccelGroup handlers decline to be activated? 

 -> gtk_window_activate_key 
   -> gtk_accel_groups_activate
     -> gtk_accel_group_activate 
       -> emits 'accel_activate' on the accel group.	 
          If this returns 'True', the key-press is considered handled. 
	  Each callback registered with a binding  
          observes the accel_activate signal. 

	  I can't see how the appropriate callback is invoked --- it 
	  seems as if they all are?! 

*** gtk.Actions and keyboard accelerators 

We can bind a gtk.Action to a system accel path via

gtk.ActionGroup.add_action_with_accel is a convenience method which
1) creates an accel path, rooted in the ActionGroup name 
2) adds a mapping from accel_path -> the keybinding spec, if any, 
   via gtk_accel_map_add_entry
3) Calls gtk.Action.set_accel_path. 
4) Adds the action to the action group 

*** How do AccelGroup and AccelPaths interact? 
AccelPaths are just a mapping from string -> keybinding 
AccelGroups map keybinding -> callback 
They don't interact. 

We may assign an AccelPath to an Action, which will then use the 
keybinding when it sets up a callback with the AccelGroup when 
gtk.Action.set_accel_group() is called. 

> forgive me for my ignorance on this subject, I'm not a fulltime gtk 
> programmer and it's sometimes hard to keep track of all the 
> possibilities in gtk.
> Olivier
> ------------------------------------------------------------------------------
> The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio XE:
> Pinpoint memory and threading errors before they happen.
> Find and fix more than 250 security defects in the development cycle.
> Locate bottlenecks in serial and parallel code that limit performance.
> _______________________________________________
> Gtk-osx-users mailing list
> Gtk-osx-users lists sourceforge net

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]