diff --git a/src/app/mod.rs b/src/app/mod.rs index 59085c58..3fd4ad66 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -745,7 +745,7 @@ impl ApplicationExt for App { // Show any current dialog on top and centered over the view content // We have to use a popover even without a dialog to keep the tree from changing - let mut popover = popover(view_column); + let mut popover = popover(view_column).modal(true); if let Some(dialog) = self.dialog() { popover = popover.popup(dialog.map(Message::App)); } diff --git a/src/widget/popover.rs b/src/widget/popover.rs index 2136ba9a..1d9055ad 100644 --- a/src/widget/popover.rs +++ b/src/widget/popover.rs @@ -34,6 +34,7 @@ pub enum Position { #[must_use] pub struct Popover<'a, Message, Renderer> { content: Element<'a, Message, crate::Theme, Renderer>, + modal: bool, // XXX Avoid refcell; improve iced overlay API? popup: Option>>, position: Position, @@ -43,11 +44,18 @@ impl<'a, Message, Renderer> Popover<'a, Message, Renderer> { pub fn new(content: impl Into>) -> Self { Self { content: content.into(), + modal: false, popup: None, position: Position::Center, } } + /// A modal popup interrupts user inputs and demands action. + pub fn modal(mut self, modal: bool) -> Self { + self.modal = modal; + self + } + pub fn popup(mut self, popup: impl Into>) -> Self { self.popup = Some(RefCell::new(popup.into())); self @@ -127,11 +135,13 @@ where shell: &mut Shell<'_, Message>, viewport: &Rectangle, ) -> event::Status { - if matches!( - event, - Event::Mouse(mouse::Event::ButtonPressed(_)) - | Event::Touch(touch::Event::FingerPressed { .. }) - ) { + if !self.modal + && matches!( + event, + Event::Mouse(mouse::Event::ButtonPressed(_)) + | Event::Touch(touch::Event::FingerPressed { .. }) + ) + { let state = tree.state.downcast_mut::(); state.is_open = cursor_position.is_over(layout.bounds()); }