fix(menu): panic when right-clicking a submenu
This commit is contained in:
parent
a5267e623f
commit
3a8ebf9197
2 changed files with 56 additions and 43 deletions
|
|
@ -30,6 +30,7 @@ pub enum Message {
|
||||||
WindowClose,
|
WindowClose,
|
||||||
Surface(cosmic::surface::Action),
|
Surface(cosmic::surface::Action),
|
||||||
ToggleHideContent,
|
ToggleHideContent,
|
||||||
|
ToggleSomeAction,
|
||||||
WindowNew,
|
WindowNew,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -82,6 +83,7 @@ impl cosmic::Application for App {
|
||||||
|
|
||||||
/// Handle application events here.
|
/// Handle application events here.
|
||||||
fn update(&mut self, message: Self::Message) -> Task<Self::Message> {
|
fn update(&mut self, message: Self::Message) -> Task<Self::Message> {
|
||||||
|
tracing::error!("Clicked {message:?}");
|
||||||
match message {
|
match message {
|
||||||
Message::Clicked => {
|
Message::Clicked => {
|
||||||
self.button_label = format!("Clicked {message:?}");
|
self.button_label = format!("Clicked {message:?}");
|
||||||
|
|
@ -91,9 +93,10 @@ impl cosmic::Application for App {
|
||||||
cosmic::app::Action::Surface(action),
|
cosmic::app::Action::Surface(action),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Message::WindowClose => {}
|
Message::WindowClose |
|
||||||
Message::ToggleHideContent => {}
|
Message::ToggleHideContent |
|
||||||
Message::WindowNew => {}
|
Message::ToggleSomeAction |
|
||||||
|
Message::WindowNew=> {}
|
||||||
}
|
}
|
||||||
|
|
||||||
Task::none()
|
Task::none()
|
||||||
|
|
@ -102,7 +105,7 @@ impl cosmic::Application for App {
|
||||||
/// Creates a view after each update.
|
/// Creates a view after each update.
|
||||||
fn view(&self) -> Element<'_, Self::Message> {
|
fn view(&self) -> Element<'_, Self::Message> {
|
||||||
let widget = cosmic::widget::context_menu(
|
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(),
|
self.context_menu(),
|
||||||
)
|
)
|
||||||
.on_surface_action(Message::Surface);
|
.on_surface_action(Message::Surface);
|
||||||
|
|
@ -131,7 +134,14 @@ impl App {
|
||||||
None,
|
None,
|
||||||
self.hide_content,
|
self.hide_content,
|
||||||
ContextMenuAction::ToggleHideContent,
|
ContextMenuAction::ToggleHideContent,
|
||||||
)],
|
),
|
||||||
|
menu::Item::CheckBox(
|
||||||
|
"Test content",
|
||||||
|
None,
|
||||||
|
self.hide_content,
|
||||||
|
ContextMenuAction::ToggleSomeAction,
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
menu::Item::Divider,
|
menu::Item::Divider,
|
||||||
menu::Item::Button("Quit", None, ContextMenuAction::WindowClose),
|
menu::Item::Button("Quit", None, ContextMenuAction::WindowClose),
|
||||||
|
|
@ -144,6 +154,7 @@ impl App {
|
||||||
pub enum ContextMenuAction {
|
pub enum ContextMenuAction {
|
||||||
WindowClose,
|
WindowClose,
|
||||||
ToggleHideContent,
|
ToggleHideContent,
|
||||||
|
ToggleSomeAction,
|
||||||
WindowNew,
|
WindowNew,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -153,6 +164,7 @@ impl menu::Action for ContextMenuAction {
|
||||||
match self {
|
match self {
|
||||||
ContextMenuAction::WindowClose => Message::WindowClose,
|
ContextMenuAction::WindowClose => Message::WindowClose,
|
||||||
ContextMenuAction::ToggleHideContent => Message::ToggleHideContent,
|
ContextMenuAction::ToggleHideContent => Message::ToggleHideContent,
|
||||||
|
ContextMenuAction::ToggleSomeAction => Message::ToggleSomeAction,
|
||||||
ContextMenuAction::WindowNew => Message::WindowNew,
|
ContextMenuAction::WindowNew => Message::WindowNew,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -650,7 +650,7 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
state.pressed = false;
|
state.pressed = false;
|
||||||
|
|
||||||
// process close condition
|
// process close condition
|
||||||
if state
|
if state.open && state
|
||||||
.view_cursor
|
.view_cursor
|
||||||
.position()
|
.position()
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
|
|
@ -1428,47 +1428,48 @@ where
|
||||||
state.view_cursor = view_cursor;
|
state.view_cursor = view_cursor;
|
||||||
|
|
||||||
// * remove invalid menus
|
// * 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::<Vec<_>>();
|
||||||
|
|
||||||
let mut prev_bounds = std::iter::once(menu.bar_bounds)
|
if menu.is_overlay && menu.close_condition.leave {
|
||||||
.chain(
|
for i in (0..state.menu_states.len()).rev() {
|
||||||
if menu.is_overlay {
|
let mb = &state.menu_states[i].menu_bounds;
|
||||||
state.menu_states[..state.menu_states.len().saturating_sub(1)].iter()
|
|
||||||
} else {
|
if mb.parent_bounds.contains(overlay_cursor)
|
||||||
state.menu_states[..menu.depth].iter()
|
|| 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),
|
} else if menu.is_overlay {
|
||||||
)
|
for i in (0..state.menu_states.len()).rev() {
|
||||||
.collect::<Vec<_>>();
|
let mb = &state.menu_states[i].menu_bounds;
|
||||||
|
|
||||||
if menu.is_overlay && menu.close_condition.leave {
|
if mb.parent_bounds.contains(overlay_cursor)
|
||||||
for i in (0..state.menu_states.len()).rev() {
|
|| mb.children_bounds.contains(overlay_cursor)
|
||||||
let mb = &state.menu_states[i].menu_bounds;
|
|| prev_bounds.iter().all(|pvb| !pvb.contains(overlay_cursor))
|
||||||
|
{
|
||||||
if mb.parent_bounds.contains(overlay_cursor)
|
break;
|
||||||
|| menu.is_overlay && mb.children_bounds.contains(overlay_cursor)
|
}
|
||||||
|| mb.offset_bounds.contains(overlay_cursor)
|
prev_bounds.pop();
|
||||||
|| (mb.check_bounds.contains(overlay_cursor)
|
state.active_root.pop();
|
||||||
&& prev_bounds.iter().all(|pvb| !pvb.contains(overlay_cursor)))
|
state.menu_states.pop();
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue