-
-
Notifications
You must be signed in to change notification settings - Fork 95
Description
Have you read through the documentation?
- Astal docs
- Library references
- FAQ this page is 404
Describe what have you tried so far
- used
tray_item.menu_modelwithGtk.PopoverMenudirectly. - built an intermediate
Gio.MenutoGtk.PopoverMenu. - forwarded actions in
tray_item.action_groupand created missing actions.
Describe your question
versions:
Some menu items are unusable in my tray app menu. and they work normally in Waybar.
The "A" submenu is gray
Initially, I built the Menu in the following way:
// in my widget
this.popover = new Gtk.PopoverMenu();
this.popover.set_parent(this);
// menu model
this.tray_item.bind_property("menu-model", this.popover, "menu-model", GObject.BindingFlags.SYNC_CREATE);
// action group
this.popover.insert_action_group("dbusmenu", this.tray_item.action_group);
this.tray_item.connect("notify::action-group", (tray_item) => {
this.popover.insert_action_group("dbusmenu", tray_item.action_group);
});Later, I tried to recursive traversal tray_item.menu_model and build an intermediate Gio.Menu:
function updateMenuFromModel(menu: Gio.Menu, model: Gio.MenuModel) {
// ... recursive traversal `tray_item.menu_model` and update menu
}
// in my widget
const menu = new Gio.Menu();
updateMenuFromModel(menu, this.tray_item.menu_model);
this.tray_item.connect("notify::menu-model", (tray_item) => {
updateMenuFromModel(menu, tray_item.menu_model);
});
this.popover = new Gtk.PopoverMenu({ menu_model: menu });
this.popover.set_parent(this);
// action group
this.popover.insert_action_group("dbusmenu", this.tray_item.action_group);
this.tray_item.connect("notify::action-group", (tray_item) => {
this.popover.insert_action_group("dbusmenu", tray_item.action_group);
});The problem remains, but during my investigation, I discovered:
The menu_model has action dbusmenu.id-305 and dbusmenu.submenu-305, but
action_group only contains dbusmenu.submenu-305.
I am not sure if this is expected, so I tried to create the missing action:
// find all action in model that are missing in action_group and create Gio.Action
function menuMissingActions(action_group: Gio.ActionGroup, model: Gio.MenuModel): Gio.Action[] {
const actions: Gio.Action[] = [];
for (let i = 0, items_count = model.get_n_items(); i < items_count; ++i) {
const action_name = model.get_item_attribute_value(i, Gio.MENU_ATTRIBUTE_ACTION, new GLib.VariantType("s"))?.get_string()[0]?.replace(/^dbusmenu./, "") ?? null;
if (action_name && !action_group.has_action(action_name)) {
const props: Partial<Gio.SimpleAction.ConstructorProps> = {};
const parameter_type = model.get_item_attribute_value(i, Gio.MENU_ATTRIBUTE_TARGET, null)?.get_type() ?? null;
props.name = action_name;
if (parameter_type)
props.parameter_type = parameter_type;
actions.push(new Gio.SimpleAction(props));
}
// recursive
const link = model.get_item_link(i, Gio.MENU_LINK_SUBMENU) ?? model.get_item_link(i, Gio.MENU_LINK_SECTION);
if (link) {
actions.push(...menuMissingActions(action_group, link));
}
}
return actions;
}
function fixedTrayItemActionGroup(tray_item: AstalTray.TrayItem) {
const action_group = new Gio.SimpleActionGroup();
for (const action_name of tray_item.action_group.list_actions()) {
const action_info = tray_item.action_group.query_action(action_name);
const action = new Gio.SimpleAction({ /* ... */ });
action.connect("activate", (action, parameter) => tray_item.action_group.activate_action(action_name, parameter));
action_group.add_action(action);
}
const menu_missing_actions = menuMissingActions(tray_item.action_group, tray_item.menu_model);
for (const action of menu_missing_actions) {
action_group.add_action(action);
}
return action_group;
}
// in my widget
this.popover = new Gtk.PopoverMenu();
this.popover.set_parent(this);
this.tray_item.bind_property("menu-model", this.popover, "menu-model", GObject.BindingFlags.SYNC_CREATE);
this.popover.insert_action_group("dbusmenu", fixedTrayItemActionGroup(this.tray_item));
this.tray_item.connect("notify::action-group", (tray_item) => {
this.popover.insert_action_group("dbusmenu", fixedTrayItemActionGroup(tray_item));
});The menu item became usable after this, but program always crashes shortly after.
Is this a bug in Astal?
What should I do to make it work normally?