FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Fix menu grey-out bug · solvespace/solvespace@390da5b · GitHub

Commit 390da5b

Browse files
authored andcommitted
Fix menu grey-out bug
1 parent f0b95bd commit 390da5b

1 file changed

Lines changed: 28 additions & 21 deletions

File tree

‎src/platform/guigtk4.cpp‎

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,13 @@ class MenuItemImplGtk4 final : public MenuItem {
353353
}
354354
};
355355

356+
// A menu tree (a menu bar or a standalone popup menu, together with all of its
357+
// submenus) shares a single Gio::SimpleActionGroup. That group is inserted into the
358+
// relevant widget exactly once, under the "ss" prefix. Because the group object is
359+
// mutable and stays referenced by the widget after insertion, actions added to (or
360+
// removed from) it later - e.g. when a submenu is repopulated - take effect immediately,
361+
// with no need to re-insert anything into the widget. This avoids stale/missing actions
362+
// (which GTK renders as permanently disabled menu items) after a menu is rebuilt.
356363
class MenuImplGtk4 final : public Menu {
357364
public:
358365
Glib::RefPtr<Gio::Menu> gioMenu;
@@ -361,9 +368,9 @@ class MenuImplGtk4 final : public Menu {
361368
std::vector<std::shared_ptr<MenuImplGtk4>> subMenus;
362369
Glib::RefPtr<Gio::Menu> currentSection;
363370

364-
MenuImplGtk4() {
371+
MenuImplGtk4(Glib::RefPtr<Gio::SimpleActionGroup> sharedActionGroup = {}) {
365372
gioMenu = Gio::Menu::create();
366-
actionGroup = Gio::SimpleActionGroup::create();
373+
actionGroup = sharedActionGroup ? sharedActionGroup : Gio::SimpleActionGroup::create();
367374
currentSection = Gio::Menu::create();
368375
gioMenu->append_section("", currentSection);
369376
}
@@ -384,7 +391,7 @@ class MenuImplGtk4 final : public Menu {
384391
}
385392

386393
MenuRef AddSubMenu(const std::string &label) override {
387-
auto subMenu = std::make_shared<MenuImplGtk4>();
394+
auto subMenu = std::make_shared<MenuImplGtk4>(actionGroup);
388395
subMenus.push_back(subMenu);
389396

390397
currentSection->append_submenu(PrepareMnemonics(label), subMenu->gioMenu);
@@ -427,20 +434,28 @@ class MenuImplGtk4 final : public Menu {
427434
popover->unparent();
428435
}
429436

437+
// All submenus of this menu share the same actionGroup, so it only needs to be
438+
// inserted into the widget once.
430439
void InsertActionsInto(Gtk::Widget *widget) {
431440
widget->insert_action_group("ss", actionGroup);
432-
for(auto &sub : subMenus) {
433-
sub->InsertActionsInto(widget);
434-
}
435441
}
436442

443+
// Remove only the actions owned by this submenu (and its children) from the shared
444+
// group, then reset the menu model. The shared actionGroup itself is preserved (and
445+
// not replaced) since it may already be inserted into a widget; any items added
446+
// after Clear() become visible/enabled immediately.
437447
void Clear() override {
448+
for(auto &item : menuItems) {
449+
actionGroup->remove_action(item->actionName);
450+
}
451+
for(auto &sub : subMenus) {
452+
sub->Clear();
453+
}
438454
gioMenu->remove_all();
439455
currentSection = Gio::Menu::create();
440456
gioMenu->append_section("", currentSection);
441457
menuItems.clear();
442458
subMenus.clear();
443-
actionGroup = Gio::SimpleActionGroup::create();
444459
}
445460
};
446461

@@ -460,7 +475,7 @@ class MenuBarImplGtk4 final : public MenuBar {
460475
}
461476

462477
MenuRef AddSubMenu(const std::string &label) override {
463-
auto subMenu = std::make_shared<MenuImplGtk4>();
478+
auto subMenu = std::make_shared<MenuImplGtk4>(actionGroup);
464479
subMenus.push_back(subMenu);
465480

466481
gioMenu->append_submenu(PrepareMnemonics(label), subMenu->gioMenu);
@@ -469,24 +484,16 @@ class MenuBarImplGtk4 final : public MenuBar {
469484
}
470485

471486
void Clear() override {
487+
for(auto &sub : subMenus) {
488+
sub->Clear();
489+
}
472490
gioMenu->remove_all();
473491
subMenus.clear();
474-
actionGroup = Gio::SimpleActionGroup::create();
475-
}
476-
477-
void CollectActions(const std::shared_ptr<MenuImplGtk4> &menu) {
478-
for(auto &item : menu->menuItems) {
479-
actionGroup->add_action(item->action);
480-
}
481-
for(auto &sub : menu->subMenus) {
482-
CollectActions(sub);
483-
}
484492
}
485493

494+
// All submenus share this menu bar's actionGroup, so it only needs to be inserted
495+
// into the widget once; there is no need to recursively collect actions.
486496
void InsertActionsInto(Gtk::Widget *widget) {
487-
for(auto &sub : subMenus) {
488-
CollectActions(sub);
489-
}
490497
widget->insert_action_group("ss", actionGroup);
491498
}
492499
};

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL