Skip to content

Commit d468825

Browse files
committed
Support tri-state (Mixed) for GTK checkbox menu items
Adds handling for the 'Mixed' state in checkbox menu items by using GTK's inconsistent state. The SetState and GetState methods now properly reflect and retrieve the tri-state visual and logical status.
1 parent c9d5159 commit d468825

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

src/platform/linux/menu_linux.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -344,13 +344,19 @@ void MenuItem::SetState(MenuItemState state) {
344344
pimpl_->state_ = state;
345345
if (pimpl_->gtk_menu_item_) {
346346
if (pimpl_->type_ == MenuItemType::Checkbox) {
347+
// Update checked state
347348
gboolean active = (state == MenuItemState::Checked) ? TRUE : FALSE;
348-
// Block the "toggled" signal to prevent recursive triggering
349-
g_signal_handlers_block_by_func(G_OBJECT(pimpl_->gtk_menu_item_),
349+
// Block the "toggled" signal to prevent recursive triggering when setting active
350+
g_signal_handlers_block_by_func(G_OBJECT(pimpl_->gtk_menu_item_),
350351
(gpointer)OnGtkCheckMenuItemToggled, this);
351352
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(pimpl_->gtk_menu_item_), active);
352-
g_signal_handlers_unblock_by_func(G_OBJECT(pimpl_->gtk_menu_item_),
353+
g_signal_handlers_unblock_by_func(G_OBJECT(pimpl_->gtk_menu_item_),
353354
(gpointer)OnGtkCheckMenuItemToggled, this);
355+
356+
// Reflect tri-state (Mixed) visually using GTK's inconsistent state
357+
gtk_check_menu_item_set_inconsistent(
358+
GTK_CHECK_MENU_ITEM(pimpl_->gtk_menu_item_),
359+
(state == MenuItemState::Mixed) ? TRUE : FALSE);
354360
} else if (pimpl_->type_ == MenuItemType::Radio) {
355361
gboolean active = (state == MenuItemState::Checked) ? TRUE : FALSE;
356362
// Block the "toggled" signal to prevent recursive triggering
@@ -367,6 +373,15 @@ MenuItemState MenuItem::GetState() const {
367373
// For checkbox and radio items, get the actual state from GTK widget
368374
if (pimpl_->gtk_menu_item_ &&
369375
(pimpl_->type_ == MenuItemType::Checkbox || pimpl_->type_ == MenuItemType::Radio)) {
376+
if (pimpl_->type_ == MenuItemType::Checkbox) {
377+
// If inconsistent is set, treat as Mixed regardless of active
378+
gboolean inconsistent = gtk_check_menu_item_get_inconsistent(
379+
GTK_CHECK_MENU_ITEM(pimpl_->gtk_menu_item_));
380+
if (inconsistent) {
381+
return MenuItemState::Mixed;
382+
}
383+
}
384+
370385
gboolean active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(pimpl_->gtk_menu_item_));
371386
return active ? MenuItemState::Checked : MenuItemState::Unchecked;
372387
}

0 commit comments

Comments
 (0)