Pop open a - Glade-defined - menu

Hi !

I’m trying to understand how popup menus work in Gtk nowadays ; I used to be able to do it before with uibuilder’s menu.popup() but now it’s deprecated, I also see in Glade that the “tearoff” attribute for menus is deprecated too (and indeed just checking it in breaks everything) so I’m a bit confused about what the good practice is.

I have my menu defined in Glade, it shows and works, I have an Eventbox around the zone I want to cover, I’m passing the “file” submenu though the “user_data” param of the “button-pressed” event of the Eventbox in Glade, and I do get the event.button == 3 back alright, but when I menu.show() nothing happens, not even a warning…?

I tried passing the whole menu but then I got errors, so it seems like I got the right object, I just don’t know how to show it / pop it open :confused:

Maybe I’m missing some Gtk.FLAG in the main window, but I can’t find where, in Glade, would I set such flags…?

These days you use:

  • actions, to define what each menu item does; actions are also used by other widgets, like GtkButton, or by shortcuts
  • menus, to define the structure of a menu

After you described your menu—either programmatically or, preferably, using XML—you assign it to a widget like GtkMenuButton, GtkPopoverMenu, or GtkPopoverMenuBar.

It seems you’re using GTK3, though, so you’ll have to use GtkPopover and GtkMenuBar. The behaviour is exactly the same.

1 Like

Hi, thanks for your quick answer!

1-It is my understanding that in order to use Gio actions one must adopt the Application framework and I’d love to; The thing is, I’m using Glade to define my window, so the whole


   def do_activate(self):
        # We only allow a single window and raise any existing ones
        if not self.window:
            # Windows are associated with the application
            # when the last one is closed the application shuts down
            self.window = AppWindow(application=self, title="Main Window")

        self.window.present()

Breaks my subsequently (the sequence is startup -activate - window) defined window (in AppWindow) ; At this point I obviously have two windows, and the app quits gracefully. I could not overcome this in a whole day of trying, if you know how to do that I would be eternally grateful for your enlightenment :pray: it would make my code so much cleaner.

2-Sooo the option of just poping up the menu in the old fashion way (like not in a popover, that BTW has compositing / transparency problems on other WMs, notably i3 here, I’m just saying, I like the popover don’t get me wrong) by just building a temporary structure containing the existing menu items that I want to show is… Out now ?

  1. You don’t need to have a single window with a GtkApplication; the application singleton can track have as many windows as your application has. For instance:
def do_activate(self):
    win = AppWindow(application=self, title="Some Window")
    win.present()

will create a new window every time the application gets activated. The important part is setting the application property when creating the new window. Once every window tracked by the application gets closed, the application will automatically terminate.

  1. with GTK3 you can create a Gtk.Menu instance from a Gio.Menu model, and then pop up the menu widget; in GTK4, menus-as-widgets have been removed, which means you cannot construct a menu out of widgets, but you can only use the Gio.Menu model to describe its contents.

If your window manager does not support compositing on X11, please: fix the window manager, or require a compositor. It’s 2022, not 1997, and the only way app developers and toolkit developers test their project is under a compositing window manager—either X11 or, more likely, Wayland. Uncomposited X11 is broken by design.

1 Like

As a side note: using Glade is not recommended, even with GTK3. Glade is not currently maintained, either, and it does not/will not support GTK4.

Handwriting a small XML fragment to describe a menu is perfectly doable.

1 Like

You don’t need to have a single window with a GtkApplication; the application singleton can track have as many windows as your application has.

But I do have a single window in my app, and it seem like this activate function is doing the right thing in ensuring that the last window closes the whole app

The important part is setting the application property when creating the new window. Once every window tracked by the application gets closed, the application will automatically terminate.

See that’s what I can’t find how to do. My app window is defined like so:

class MyApp:
    def __init__(self):

        # (...)

        self.window = self.builder.get_object('main_app_window')

And I don’t know how to instruct do_activate that somehow the window will be realized later.

I tried getting taking the builder / window logic out of the main class, but no matter what I do, the main window spawns and immediately closes.

As a side note: using Glade is not recommended, even with GTK3.

I’ll keep that in mind ; My app is pretty small, also Glade is great to learn about Gtk as everything is exposed :slightly_smiling_face:

and it does not/will not support GTK4.

Wow. That I didn’t know either, thanks.

I’d recommend you look at the code repository for the “Getting Started” tutorial: Teams / Documentation / Getting Started Tutorial · GitLab

There’s also a description of how GtkApplication works.

You can set the application property after creating the window:

class MyApp (Gtk.Application):
    def __init__(self):
        super().__init__()
        self._window = self.builder.get_object("main_app_window")

    def do_activate(self):
        self._window.application = self
        self._window.present()

That didn’t work, and I understand, you can’t have two main windows definitions ; I found a workaround by just getting the main box from the Glade file, on which I used “remove parent” I mean you gotta love Glade. I’m gonna use it for just what you said: Fragments of xml, and it’s going to work great. And when I’m done with Glade I can write my own definitions, but for now I’m learning.

Seriously, there will be no official Gtk4 interface designer? That’s a sad thing to hear.

There is no “official” UI designer for GTK3 either: Glade is just a project, written by people who were not working on the toolkit.

For GTK4 there currently is Cambalache, a UI design tool written by the (former) Glade maintainer; and there is going to be a component in GNOME Builder, currently under development.

There’s also a tool called Blueprint, which uses a different, more human friendly syntax that “compiles” to XML.

In any case, writing UI files by hand is not that complicated: people write entire websites without a visual tool. What you need is:

  • smaller UI files, using composite widget templates
  • the GTK inspector for quick tweaks and experiments at run time
  • a good text editor or IDE
2 Likes

Wow, a lot of information, thank you very much.

smaller UI files, using composite widget templates

Yes. I have to look into that ; But please note that Glade told me about it first :slight_smile:

the GTK inspector for quick tweaks and experiments at run time

That sounds really good, where is it? when I type gtk/TAB, here is what I get:

gtk3-demo                 gtk3-demo-application     gtk3-icon-browser       
gtk3-widget-factory       gtk4-builder-tool         gtk4-demo               
gtk4-demo-application     gtk4-encode-symbolic-svg  gtk4-icon-browser       
gtk4-launch               gtk4-print-editor         gtk4-query-settings     
gtk4-update-icon-cache    gtk4-widget-factory       gtk-builder-tool        
gtk-encode-symbolic-svg   GTK_IM_MODULE             gtk-launch              
GTK_MODULES               gtk-query-settings        gtk-redshift            
gtk-update-icon-cache

What do I need to install to get this inspector? I love inspectors :wink:

a good text editor or IDE

Out of curiosity what do you use? Also from what I understand you run the Gimp Discourse channel (correct me if I’m wrong) a piece of software that I use everyday basically, so thank you.

GNOME Builder, mainly.

I am one of the admins of the GNOME Discourse and one of the people working on GTK (and a bunch of other GNOME projects), but I have never contributed to GIMP, so I can’t take the credit for anything done by the GIMP developers. :slight_smile:

1 Like