Defining a menu model with check box items

Hello,

I have a context-menu in my application and am trying to add a few entries with check boxes and radio buttons. I am defining the menu using a .ui file.

The menu is defined using a <menu/> element.

Can this be done? If so how? I was unable to find any information about it online.

Thank you!

EDIT: I should mention that I am using GTK 4.

Hi again,

Is this the wrong place to ask this kind of question?

I still haven’t found a solution for this and would like to avoid re-posting this to multiple places.

Thanks for any insight.

EDIT: Would like to clarify that it’s fine if this can’t be done, I would just like to get a clear answer to this.

You want stateful actions, see the GMenuModel documentation

1 Like

Thanks for the hint.

I did look at the documentation but I can’t figure out how to express stateful actions in a model defined in an .ui XML file.

Is something like that possible?

To help maybe clarify what I would like, this is a shortened version of the .ui file:

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <requires lib="gtk" version="4.0"/>
  <object class="GtkBox">
    <child>
      <object class="GtkPopoverMenu" id="context_menu">
        <property name="menu-model">context_menu_model</property>
      </object>
    </child>
  </object>
  <menu id="context_menu_model">
    <section>
      <item>
        <attribute name="label" translatable="true">Graph _Summary View</attribute>
        <attribute name="action">graph.summary</attribute>
      </item>
      <submenu>
        <attribute name="label" translatable="true">_View</attribute>
        <item>
          <attribute name="label" translatable="true">CP_U</attribute>
          <attribute name="action">graph.cpu</attribute>
        </item>
        <item>
          <attribute name="label" translatable="true">_Memory</attribute>
          <attribute name="action">graph.memory</attribute>
        </item>
        <item>
          <attribute name="label" translatable="true">_Disk</attribute>
          <attribute name="action">graph.disk</attribute>
        </item>
        <item>
          <attribute name="label" translatable="true">_Network</attribute>
          <attribute name="action">graph.network</attribute>
        </item>
        <item>
          <attribute name="label" translatable="true">_GPU</attribute>
          <attribute name="action">graph.gpu</attribute>
        </item>
      </submenu>
    </section>
    <section>
      <item>
        <attribute name="label" translatable="true">_Copy</attribute>
        <attribute name="action">graph.copy</attribute>
      </item>
    </section>
  </menu>
</interface>

I would like, for example, the Graph _Summary View item to be checkable.

Hope this helps, and thank you for your time.

Yes, it’s possible to define menu items bound to stateful and parametrised actions in UI definition files.

Check boxes are represented by stateful actions; you need to create your own stateful action instance and add it to the action map object—typically, the window or the application. You also need to update the action’s state whenever the action is activated. In Rust, this would look like:

self.add_action_entries([gio::ActionEntry::builder("toggle-action")
    .state(initial_state.to_variant())
    .activate(|this: &Application, action, _| {
        let state = action.state().unwrap();
        let action_state: bool = state.get().unwrap();
        let new_state = !action_state; // toggle
        action.set_state(new_state.to_variant());

        // do something with the new state
    })
    .build()]);

In the UI definition file, you can now use the action:

<item>
  <attribute name="label" translatable="yes">Toggle</attribute>
  <attribute name="action">app.toggle-action</attribute>
</item>
1 Like

This looks like what I want, I’ll give it a shot and mark your response as the solution after I’ve tested.

Thank you!

Once you find something that works, it would be helpful if you could suggest some documentation improvements (or as an issue) to GLib to help others in future :slight_smile: :slight_smile:

I would love to, not sure how to go about it though.

In this particular case the issue was that it wasn’t clear to me, even after reading through the page on actions, that they influence how a menu items, defined by a model, are rendered. Ofc this might just be my personal biases at work here, or perhaps I didn’t pay enough attention when reading through the documentation.

Should I just mention all of this in a GLib issue and go from there?

Thanks

Yes please! In particular it would be interesting to know which high level concepts weren’t clear, where you looked for them, and some ideas of what documentation you would have found helpful (and where). :slight_smile:

The actual first place to look at would be the Actions page on the developers documentation website. Adding a proper description of stateful and parametrised actions, as well as code examples, would be great. The page has a link to the Git repository, as well as a “edit in the web browser” link—you’ll need an account on gitlab.gnome.org, and you’ll need to add an SSH key to it before you can edit the content directly from the web UI.

Reading through this documentation it has all the information I would have needed, but I never found it when searching.

Honestly I had no idea this page even existed until now.

Perhaps it would make sense to link from the API documentation, in this case GMenuModel documentation, to these developer tutorials?

The GNOME developer docs are where we put anything that isn’t an API reference.

We probably want to put a link on the docs.gtk.org landing page, so that people are aware. Ideally, using a search engine should lead you in the right place already, but the Google-juice of the whole GNOME docs is kind of low.

I posted an issue on GitLab. Let’s go from there, and if people agree that there is a need for extra clarifications, then I’ll help in any way I can.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.