diff --git a/examples/context-menu/src/main.rs b/examples/context-menu/src/main.rs index e5ca5878..a953c8ed 100644 --- a/examples/context-menu/src/main.rs +++ b/examples/context-menu/src/main.rs @@ -30,6 +30,7 @@ pub enum Message { WindowClose, Surface(cosmic::surface::Action), ToggleHideContent, + ToggleSomeAction, WindowNew, } @@ -82,6 +83,7 @@ impl cosmic::Application for App { /// Handle application events here. fn update(&mut self, message: Self::Message) -> Task { + tracing::error!("Clicked {message:?}"); match message { Message::Clicked => { self.button_label = format!("Clicked {message:?}"); @@ -91,9 +93,10 @@ impl cosmic::Application for App { cosmic::app::Action::Surface(action), )); } - Message::WindowClose => {} - Message::ToggleHideContent => {} - Message::WindowNew => {} + Message::WindowClose | + Message::ToggleHideContent | + Message::ToggleSomeAction | + Message::WindowNew=> {} } Task::none() @@ -102,7 +105,7 @@ impl cosmic::Application for App { /// Creates a view after each update. fn view(&self) -> Element<'_, Self::Message> { let widget = cosmic::widget::context_menu( - cosmic::widget::button::text(self.button_label.to_string()).on_press(Message::Clicked), + cosmic::widget::button::text(self.button_label.clone()).on_press(Message::Clicked), self.context_menu(), ) .on_surface_action(Message::Surface); @@ -131,7 +134,14 @@ impl App { None, self.hide_content, ContextMenuAction::ToggleHideContent, - )], + ), + menu::Item::CheckBox( + "Test content", + None, + self.hide_content, + ContextMenuAction::ToggleSomeAction, + ) + ], ), menu::Item::Divider, menu::Item::Button("Quit", None, ContextMenuAction::WindowClose), @@ -144,6 +154,7 @@ impl App { pub enum ContextMenuAction { WindowClose, ToggleHideContent, + ToggleSomeAction, WindowNew, } @@ -153,6 +164,7 @@ impl menu::Action for ContextMenuAction { match self { ContextMenuAction::WindowClose => Message::WindowClose, ContextMenuAction::ToggleHideContent => Message::ToggleHideContent, + ContextMenuAction::ToggleSomeAction => Message::ToggleSomeAction, ContextMenuAction::WindowNew => Message::WindowNew, } } diff --git a/src/widget/menu/menu_inner.rs b/src/widget/menu/menu_inner.rs index 291d7db0..48b0f4ea 100644 --- a/src/widget/menu/menu_inner.rs +++ b/src/widget/menu/menu_inner.rs @@ -650,7 +650,7 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> { state.pressed = false; // process close condition - if state + if state.open && state .view_cursor .position() .unwrap_or_default() @@ -1428,47 +1428,48 @@ where state.view_cursor = view_cursor; // * remove invalid menus + if state.open { + let mut prev_bounds = std::iter::once(menu.bar_bounds) + .chain( + if menu.is_overlay { + state.menu_states[..state.menu_states.len().saturating_sub(1)].iter() + } else { + state.menu_states[..menu.depth].iter() + } + .map(|s| s.menu_bounds.children_bounds), + ) + .collect::>(); - let mut prev_bounds = std::iter::once(menu.bar_bounds) - .chain( - if menu.is_overlay { - state.menu_states[..state.menu_states.len().saturating_sub(1)].iter() - } else { - state.menu_states[..menu.depth].iter() + if menu.is_overlay && menu.close_condition.leave { + for i in (0..state.menu_states.len()).rev() { + let mb = &state.menu_states[i].menu_bounds; + + if mb.parent_bounds.contains(overlay_cursor) + || menu.is_overlay && mb.children_bounds.contains(overlay_cursor) + || mb.offset_bounds.contains(overlay_cursor) + || (mb.check_bounds.contains(overlay_cursor) + && prev_bounds.iter().all(|pvb| !pvb.contains(overlay_cursor))) + { + break; + } + prev_bounds.pop(); + state.active_root.pop(); + state.menu_states.pop(); } - .map(|s| s.menu_bounds.children_bounds), - ) - .collect::>(); + } else if menu.is_overlay { + for i in (0..state.menu_states.len()).rev() { + let mb = &state.menu_states[i].menu_bounds; - if menu.is_overlay && menu.close_condition.leave { - for i in (0..state.menu_states.len()).rev() { - let mb = &state.menu_states[i].menu_bounds; - - if mb.parent_bounds.contains(overlay_cursor) - || menu.is_overlay && mb.children_bounds.contains(overlay_cursor) - || mb.offset_bounds.contains(overlay_cursor) - || (mb.check_bounds.contains(overlay_cursor) - && prev_bounds.iter().all(|pvb| !pvb.contains(overlay_cursor))) - { - break; + if mb.parent_bounds.contains(overlay_cursor) + || mb.children_bounds.contains(overlay_cursor) + || prev_bounds.iter().all(|pvb| !pvb.contains(overlay_cursor)) + { + break; + } + prev_bounds.pop(); + state.active_root.pop(); + state.menu_states.pop(); } - prev_bounds.pop(); - state.active_root.pop(); - state.menu_states.pop(); - } - } else if menu.is_overlay { - for i in (0..state.menu_states.len()).rev() { - let mb = &state.menu_states[i].menu_bounds; - - if mb.parent_bounds.contains(overlay_cursor) - || mb.children_bounds.contains(overlay_cursor) - || prev_bounds.iter().all(|pvb| !pvb.contains(overlay_cursor)) - { - break; - } - prev_bounds.pop(); - state.active_root.pop(); - state.menu_states.pop(); } }