diff --git a/.changes/fix-top-level-submenu-padding-issue.md b/.changes/fix-top-level-submenu-padding-issue.md new file mode 100644 index 00000000..b043d0b3 --- /dev/null +++ b/.changes/fix-top-level-submenu-padding-issue.md @@ -0,0 +1,5 @@ +--- +"muda": patch +--- + +Fix padding unconditionally added to top-level submenus for icons even when there's no icon on Linux diff --git a/src/platform_impl/gtk/mod.rs b/src/platform_impl/gtk/mod.rs index 18bce50c..1ea730e4 100644 --- a/src/platform_impl/gtk/mod.rs +++ b/src/platform_impl/gtk/mod.rs @@ -761,14 +761,32 @@ impl MenuChild { pub fn set_icon(&mut self, icon: Option) { self.icon.clone_from(&icon); - let pixbuf = icon.map(|i| i.inner.to_pixbuf_scale(16, 16)); + let pixbuf = icon.as_ref().map(|i| i.inner.to_pixbuf_scale(16, 16)); for items in self.gtk_menu_items.borrow().values() { for i in items { let box_container = i.child().unwrap().downcast::().unwrap(); - box_container.children()[0] - .downcast_ref::() - .unwrap() - .set_pixbuf(pixbuf.as_ref()) + let children = box_container.children(); + + // Check if the first child is an image (it might not be if the item + // was created for menu bar without an icon) + if let Some(image) = children + .first() + .and_then(|c| c.downcast_ref::()) + { + if icon.is_some() { + // Image exists and we're setting an icon, update it + image.set_pixbuf(pixbuf.as_ref()); + } else { + // Image exists but we're removing the icon, remove the widget to avoid padding + box_container.remove(image); + } + } else if icon.is_some() { + // No image widget exists yet, but we're setting an icon, so create one + let image = gtk::Image::from_pixbuf(pixbuf.as_ref()); + box_container.pack_start(&image, false, false, 0); + box_container.reorder_child(&image, 0); + image.show(); + } } } } @@ -1027,7 +1045,9 @@ impl MenuChild { let _ = css_provider.load_from_data(theme.as_bytes()); style_context.add_provider(&css_provider, gtk::STYLE_PROVIDER_PRIORITY_APPLICATION); } - box_container.pack_start(&image, false, false, 0); + if !for_menu_bar || self.icon.is_some() { + box_container.pack_start(&image, false, false, 0); + } box_container.pack_start(&label, true, true, 0); box_container.show_all(); @@ -1309,7 +1329,9 @@ impl MenuChild { let _ = css_provider.load_from_data(theme.as_bytes()); style_context.add_provider(&css_provider, gtk::STYLE_PROVIDER_PRIORITY_APPLICATION); } - box_container.pack_start(&image, false, false, 0); + if !for_menu_bar || self.icon.is_some() { + box_container.pack_start(&image, false, false, 0); + } box_container.pack_start(&label, true, true, 0); box_container.show_all(); diff --git a/src/platform_impl/mod.rs b/src/platform_impl/mod.rs index 17018a33..d3908f28 100644 --- a/src/platform_impl/mod.rs +++ b/src/platform_impl/mod.rs @@ -88,7 +88,7 @@ impl MenuItemKind { } } - pub(crate) fn child(&self) -> Ref { + pub(crate) fn child(&self) -> Ref<'_, MenuChild> { match self { MenuItemKind::MenuItem(i) => i.inner.borrow(), MenuItemKind::Submenu(i) => i.inner.borrow(), @@ -98,7 +98,7 @@ impl MenuItemKind { } } - pub(crate) fn child_mut(&self) -> RefMut { + pub(crate) fn child_mut(&self) -> RefMut<'_, MenuChild> { match self { MenuItemKind::MenuItem(i) => i.inner.borrow_mut(), MenuItemKind::Submenu(i) => i.inner.borrow_mut(),