I need to make an application in Vala, using Gtk, that supports keyboard accelerators that can be changed by the user.

First, I add an entry to the global Gtk.AccelMap and then set the accel_path for the Gtk.MenuItems. But, it doesn't work. The accels don't appear in the items of the menubar. To clear what I'm trying to do, here is a sample code:

// main.vala
public class MyWindow: Gtk.Window {
    public MyWindow() {
    this.set_default_size(500, 500);

    var main_box = new Gtk.VBox(false, 0);

    // Menubar
    var menubar = new Gtk.MenuBar();
    main_box.pack_start(menubar, false, false, 0);

    var file = new Gtk.MenuItem.with_label("File");

    var file_menu = new Gtk.Menu();

    var quit_mi = new Gtk.MenuItem.with_label("Quit");

    // Register a new accelerator with the global accelerator map
    Gtk.AccelMap.add_entry("<MyWindow>/File/Quit", 'Q', Gdk.ModifierType.CONTROL_MASK);

    // Connect signals

    // Label
    var label = new Gtk.Label("My Window");
    main_box.pack_start(label, true, true, 0);


int main(string[] args) {
    Gtk.init(ref args);

    var win = new MyWindow();

    return 0;

I use:

valac main.vala -o main --pkg gtk+-3.0

to compile the source code.

So, the question is: what's missing in the code? I think I need to do something else, but I don't know what.


Could you please clarify whether you want mnemonics (keyboard shortcuts for gui widgets i.e. ctrl-q) or accelerators (keyboard shortcuts for activating menu items i.e. alt-f q). As far as I understand these are two different things, so setting a mnemonic for a menu item will not also form a accelerator for it.

In any case, for the accelerators you can form them by simply creating your menu items with a different function: Gtk.MenuItem.with_mnemonic("_File"); in stead of Gtk.MenuItem.with_label("File"). It is then re-definable with e.g. the file.set_label('Fil_e') function

For the mnemonics, I'm not exactly sure why it doesn't work, as I'm totally new to vala. But I was able to piggy bag of of this c-example and get it to work using accelerator groups in stead of the accelerator map. So I replaced

// Register a new accelerator with the global accelerator map
Gtk.AccelMap.add_entry("<MyWindow>/File/Quit", 'Q', Gdk.ModifierType.CONTROL_MASK);
quit_mi.set_accel_path("<MyWindow>/File/Quit");enter code here


var accel_group = new Gtk.AccelGroup();
quit_mi.add_accelerator("activate", accel_group, 'R', Gdk.ModifierType.CONTROL_MASK, Gtk.AccelFlags.VISIBLE);

and that seems to do the trick.

I hope it helps. Regards TLE

|improve this answer|||||
  • 1
    You inverted the meaning of the words: what you said to be an accelerator is, actually, a mnemonic, and vice-versa. – LuisABOL May 18 '12 at 12:07
  • I already tried to do what you suggested, but I wanna know how to use an AccelMap to load the ACCELERATORS. – LuisABOL May 18 '12 at 12:13
  • Ahh I followed the wording on this page. In any case I think there is still some confusion. You want accelerators (cleared up to be a general shortcut to activate a widget), but at the same time you ask why it does not show a mnemonic. I don't think those are linked, after all what would happen then if you make an accelerator for a menuitem using a key (letter) that is not in the label? In any case, I regret not being able to help you as I don't know much about the accelerator maps. Good luck. – TLE May 19 '12 at 13:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.