Gerald Zehetner
Gerald Zehetner

Reputation: 606

GLib.Menu Action not working

I'm trying to learn vala at the moment. With my sample app i have a problem with the GLib.Menu actions.

I declared a new action quit_action which should quit the app. The compiler runs without any warnings or errors, but when i run the app i can open the menu, but the item "quit" is greyed-out.

/* main.vala */

using Gtk;

class mainWindow : Gtk.ApplicationWindow {
        public mainWindow (Application app) {

            // Window Properties
            this.set_default_size (800, 600);
            this.window_position = Gtk.WindowPosition.CENTER;
        this.destroy.connect (Gtk.main_quit);

            // HeaderBar
            var headerBar = new Gtk.HeaderBar ();
            headerBar.set_title ("Test Title");
            headerBar.set_subtitle ("Test Subtitle");
            headerBar.set_show_close_button (true);

            // Menu
            var menuButton = new Gtk.Button.from_icon_name ("open-menu-symbolic", Gtk.IconSize.SMALL_TOOLBAR);
            headerBar.pack_end (menuButton);

            var menu = new GLib.Menu ();
        menu.append ("Quit", "app.quit");

            var popover = new Gtk.Popover (menuButton);
            popover.bind_model (menu, "app");

            menuButton.clicked.connect (() =>  {
                popover.popup ();
                popover.show_all ();
            });

            this.set_titlebar (headerBar);

            this.show_all ();
        }
}

public class Application : Gtk.Application {
    public Application () {
        Object (application_id: "org.example.application", flags: 0);
    }

    protected override void activate () {
        // Create a new window for this application.
        mainWindow win = new mainWindow (this);
        win.show_all ();
        Gtk.main ();
    }

    protected override void startup () {
        base.startup ();

        var quit_action = new GLib.SimpleAction ("quit", null);
        quit_action.activate.connect (this.quit);
        this.add_action (quit_action);
    }
}

int main (string[] args) {
    Gtk.init (ref args);
    return new Application ().run (args);
}

Upvotes: 2

Views: 513

Answers (1)

Jens Mühlenhoff
Jens Mühlenhoff

Reputation: 14883

There are two things wrong here:

  1. You have to assign the Application to the ApplicationWindow (this is normally done in the constructor, but since it's a GLib style constructor you can't call the inherited constructor):

    this.application = app;
    
  2. The action names have to match, if you want to use app.quit it has to be called that way in both places.

The fully working code:

/* main.vala */

using Gtk;

class mainWindow : Gtk.ApplicationWindow {
  public mainWindow (Application app) {
    this.application = app;
    // Window Properties
    this.set_default_size (800, 600);
    this.window_position = Gtk.WindowPosition.CENTER;
    this.destroy.connect (Gtk.main_quit);

    // HeaderBar
    var headerBar = new Gtk.HeaderBar ();
    headerBar.set_title ("Test Title");
    headerBar.set_subtitle ("Test Subtitle");
    headerBar.set_show_close_button (true);

    // Menu
    var menuButton = new Gtk.Button.from_icon_name ("open-menu-symbolic", Gtk.IconSize.SMALL_TOOLBAR);
    headerBar.pack_end (menuButton);

    var menu = new GLib.Menu ();
    menu.append ("Quit", "app.quit");

    var popover = new Gtk.Popover (menuButton);
    popover.bind_model (menu, "app");

    menuButton.clicked.connect (() =>  {
      //popover.popdown ();
      popover.show_all ();
    });

    this.set_titlebar (headerBar);

    this.show_all ();
  }
}

public class Application : Gtk.Application {
  public Application () {
    Object (application_id: "org.example.application", flags: 0);
  }

  protected override void activate () {
    // Create a new window for this application.
    mainWindow win = new mainWindow (this);
    win.show_all ();
    Gtk.main ();
  }

  protected override void startup () {
    base.startup ();

    var quit_action = new GLib.SimpleAction ("app.quit", null);
    quit_action.activate.connect (this.quit);
    this.add_action (quit_action);
  }
}

int main (string[] args) {
    Gtk.init (ref args);
    return new Application ().run (args);
}

Upvotes: 1

Related Questions