fix(menu): overlays should be used when multi-window is not active

This commit is contained in:
Ashley Wulber 2025-09-16 22:54:27 -04:00 committed by Michael Murphy
parent 0e797b2440
commit c01254dd18
2 changed files with 53 additions and 12 deletions

View file

@ -9,7 +9,12 @@ use super::{
}, },
menu_tree::MenuTree, menu_tree::MenuTree,
}; };
#[cfg(all(feature = "wayland", feature = "winit", feature = "surface-message"))] #[cfg(all(
feature = "multi-window",
feature = "wayland",
feature = "winit",
feature = "surface-message"
))]
use crate::app::cosmic::{WINDOWING_SYSTEM, WindowingSystem}; use crate::app::cosmic::{WINDOWING_SYSTEM, WindowingSystem};
use crate::{ use crate::{
Renderer, Renderer,
@ -190,7 +195,7 @@ pub struct MenuBar<Message> {
menu_roots: Vec<MenuTree<Message>>, menu_roots: Vec<MenuTree<Message>>,
style: <crate::Theme as StyleSheet>::Style, style: <crate::Theme as StyleSheet>::Style,
window_id: window::Id, window_id: window::Id,
#[cfg(all(feature = "wayland", feature = "winit"))] #[cfg(all(feature = "multi-window", feature = "wayland", feature = "winit"))]
positioner: iced_runtime::platform_specific::wayland::popup::SctkPositioner, positioner: iced_runtime::platform_specific::wayland::popup::SctkPositioner,
pub(crate) on_surface_action: pub(crate) on_surface_action:
Option<Arc<dyn Fn(crate::surface::Action) -> Message + Send + Sync + 'static>>, Option<Arc<dyn Fn(crate::surface::Action) -> Message + Send + Sync + 'static>>,
@ -225,7 +230,7 @@ where
menu_roots, menu_roots,
style: <crate::Theme as StyleSheet>::Style::default(), style: <crate::Theme as StyleSheet>::Style::default(),
window_id: window::Id::NONE, window_id: window::Id::NONE,
#[cfg(all(feature = "wayland", feature = "winit"))] #[cfg(all(feature = "multi-window", feature = "wayland", feature = "winit"))]
positioner: iced_runtime::platform_specific::wayland::popup::SctkPositioner::default(), positioner: iced_runtime::platform_specific::wayland::popup::SctkPositioner::default(),
on_surface_action: None, on_surface_action: None,
} }
@ -319,7 +324,7 @@ where
self self
} }
#[cfg(all(feature = "wayland", feature = "winit"))] #[cfg(all(feature = "multi-window", feature = "wayland", feature = "winit"))]
pub fn with_positioner( pub fn with_positioner(
mut self, mut self,
positioner: iced_runtime::platform_specific::wayland::popup::SctkPositioner, positioner: iced_runtime::platform_specific::wayland::popup::SctkPositioner,
@ -351,7 +356,12 @@ where
self self
} }
#[cfg(all(feature = "wayland", feature = "winit", feature = "surface-message"))] #[cfg(all(
feature = "multi-window",
feature = "wayland",
feature = "winit",
feature = "surface-message"
))]
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
fn create_popup( fn create_popup(
&mut self, &mut self,
@ -630,7 +640,12 @@ where
if !create_popup { if !create_popup {
return event::Status::Ignored; return event::Status::Ignored;
} }
#[cfg(all(feature = "wayland", feature = "winit", feature = "surface-message"))] #[cfg(all(
feature = "multi-window",
feature = "wayland",
feature = "winit",
feature = "surface-message"
))]
if matches!(WINDOWING_SYSTEM.get(), Some(WindowingSystem::Wayland)) { if matches!(WINDOWING_SYSTEM.get(), Some(WindowingSystem::Wayland)) {
self.create_popup(layout, view_cursor, renderer, shell, viewport, my_state); self.create_popup(layout, view_cursor, renderer, shell, viewport, my_state);
} }
@ -638,7 +653,12 @@ where
Mouse(mouse::Event::CursorMoved { .. } | mouse::Event::CursorEntered) Mouse(mouse::Event::CursorMoved { .. } | mouse::Event::CursorEntered)
if open && view_cursor.is_over(layout.bounds()) => if open && view_cursor.is_over(layout.bounds()) =>
{ {
#[cfg(all(feature = "wayland", feature = "winit", feature = "surface-message"))] #[cfg(all(
feature = "multi-window",
feature = "wayland",
feature = "winit",
feature = "surface-message"
))]
if matches!(WINDOWING_SYSTEM.get(), Some(WindowingSystem::Wayland)) { if matches!(WINDOWING_SYSTEM.get(), Some(WindowingSystem::Wayland)) {
self.create_popup(layout, view_cursor, renderer, shell, viewport, my_state); self.create_popup(layout, view_cursor, renderer, shell, viewport, my_state);
} }
@ -715,7 +735,12 @@ where
_renderer: &Renderer, _renderer: &Renderer,
translation: Vector, translation: Vector,
) -> Option<overlay::Element<'b, Message, crate::Theme, Renderer>> { ) -> Option<overlay::Element<'b, Message, crate::Theme, Renderer>> {
#[cfg(all(feature = "wayland", feature = "winit", feature = "surface-message"))] #[cfg(all(
feature = "multi-window",
feature = "wayland",
feature = "winit",
feature = "surface-message"
))]
if matches!(WINDOWING_SYSTEM.get(), Some(WindowingSystem::Wayland)) if matches!(WINDOWING_SYSTEM.get(), Some(WindowingSystem::Wayland))
&& self.on_surface_action.is_some() && self.on_surface_action.is_some()
&& self.window_id != window::Id::NONE && self.window_id != window::Id::NONE

View file

@ -4,7 +4,12 @@
use std::{borrow::Cow, sync::Arc}; use std::{borrow::Cow, sync::Arc};
use super::{menu_bar::MenuBarState, menu_tree::MenuTree}; use super::{menu_bar::MenuBarState, menu_tree::MenuTree};
#[cfg(all(feature = "wayland", feature = "winit", feature = "surface-message"))] #[cfg(all(
feature = "multi-window",
feature = "wayland",
feature = "winit",
feature = "surface-message"
))]
use crate::app::cosmic::{WINDOWING_SYSTEM, WindowingSystem}; use crate::app::cosmic::{WINDOWING_SYSTEM, WindowingSystem};
use crate::style::menu_bar::StyleSheet; use crate::style::menu_bar::StyleSheet;
@ -663,6 +668,7 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
if needs_reset { if needs_reset {
#[cfg(all( #[cfg(all(
feature = "multi-window",
feature = "wayland", feature = "wayland",
feature = "winit", feature = "winit",
feature = "surface-message" feature = "surface-message"
@ -932,7 +938,12 @@ impl<Message: std::clone::Clone + 'static> Widget<Message, crate::Theme, crate::
) -> event::Status { ) -> event::Status {
let (new_root, status) = self.on_event(event, layout, cursor, renderer, clipboard, shell); let (new_root, status) = self.on_event(event, layout, cursor, renderer, clipboard, shell);
#[cfg(all(feature = "wayland", feature = "winit", feature = "surface-message"))] #[cfg(all(
feature = "multi-window",
feature = "wayland",
feature = "winit",
feature = "surface-message"
))]
if matches!(WINDOWING_SYSTEM.get(), Some(WindowingSystem::Wayland)) { if matches!(WINDOWING_SYSTEM.get(), Some(WindowingSystem::Wayland)) {
if let Some((new_root, new_ms)) = new_root { if let Some((new_root, new_ms)) = new_root {
use iced_runtime::platform_specific::wayland::popup::{ use iced_runtime::platform_specific::wayland::popup::{
@ -1177,7 +1188,12 @@ pub(crate) fn init_root_menu<Message: Clone>(
}); });
} }
#[cfg(all(feature = "wayland", feature = "winit", feature = "surface-message"))] #[cfg(all(
feature = "multi-window",
feature = "wayland",
feature = "winit",
feature = "surface-message"
))]
pub(super) fn init_root_popup_menu<Message>( pub(super) fn init_root_popup_menu<Message>(
menu: &mut Menu<'_, Message>, menu: &mut Menu<'_, Message>,
renderer: &crate::Renderer, renderer: &crate::Renderer,
@ -1474,7 +1490,7 @@ where
.as_ref() .as_ref()
.is_some_and(|i| *i != new_index && !active_menu[*i].children.is_empty()); .is_some_and(|i| *i != new_index && !active_menu[*i].children.is_empty());
#[cfg(all(feature = "wayland", feature = "winit", feature = "surface-message"))] #[cfg(all(feature = "multi-window", feature = "wayland", feature = "winit", feature = "surface-message"))]
if matches!(WINDOWING_SYSTEM.get(), Some(WindowingSystem::Wayland)) && remove { if matches!(WINDOWING_SYSTEM.get(), Some(WindowingSystem::Wayland)) && remove {
if let Some(id) = state.popup_id.remove(&menu.window_id) { if let Some(id) = state.popup_id.remove(&menu.window_id) {
state.active_root.truncate(menu.depth + 1); state.active_root.truncate(menu.depth + 1);