Can't get nested popupSubMenuMenuItem to open/close

Hi I’m trying to have a nested popupSubMenuMenuItem to expand but once I click on it it closes the parent submenuItem. I tried to override the close() and open() functions but that didn’t help.

Any help is much appreciated.

1 Like

Can you show some code for what you’ve tried? You will have difficulty nesting submenus, since they were not designed for that use case.

Typically each menu item will connect to the activate signal…

        menuItem._activateId = menuItem.connect_after('activate', () => {
            this.emit('activate', menuItem);
            this.itemActivated(BoxPointer.PopupAnimation.FULL);
        });

And call itemActivated() which will close the top menu:

    itemActivated(animate) {
        if (animate == undefined)
            animate = BoxPointer.PopupAnimation.FULL;

        this._getTopMenu().close(animate);
    }

Nested submenus might not be the best method for your use case; menu sections might be a better choice. Otherwise you’ll have to spend some time familiarising yourself with how the signals propagate between menu items and menus to be able to close parent menus if and when you’re ready for that.

1 Like

What I try to do is to include this ContainerSubMenuMenuItem under a PodSubMenuMenuItem which itself extends PopupSubMenuMenuItem.

It’s a work in progress for https://github.com/rgolangh/gnome-shell-extension-containers - here is a gist
https://gist.github.com/rgolangh/fd8cfebc2f87dd39dee8d567742023aa#file-extension-js-L112

I tried adding sections but I didn’t dump the submenu. I’m probably misusing it. Do you have an example extension that does nesting with sections?

p.s @andyholmes thanks a million for the help here and when reviewing the extension!

Sorry I haven’t replied in a few days. PopupMenuSection is sort of an oddity because it behaves as both a menu item and a menu, but for that reason is very straigh-forward to use.

As I recall, it’s as simple as:

const PopupMenu = imports.ui.popupMenu;

// This could be any menu to start, like the PopupMenu of a submenu item
const menu = new PopupMenu.PopupMenuSection();

// Adding a new section to the menu
const section = new PopupMenu.PopupMenuSection();
menu.addMenuItem(section);

// Adding a subsection to the section
const subsection = new PopupMenu.PopupMenuSection();
section.addMenuItem(subsection);

You might want to use a PopupMenu.PopupSeparatorMenuItem as a title for a section:

const PopupMenu = imports.ui.popupMenu;

// Top menu
const menu = new PopupMenu.PopupMenuSection();

// Section
const section = new PopupMenu.PopupMenuSection();
menu.addMenuItem(section);

// Section Title
const sectionTitle = new PopupMenu.PopupSeparatorMenuItem('A Category');
section.addMenuItem(sectionTitle);

// Some items for the section
section.addAction('Item 1' (item) => log(`${item.label.text} Clicked`));
section.addAction('Item 2' (item) => log(`${item.label.text} Clicked`));
section.addAction('Item 3' (item) => log(`${item.label.text} Clicked`));

Does that help?