Use standard desktop application menus
Some checks failed
Dependency security audit / rustsec (push) Has been cancelled

This commit is contained in:
Georg Bauer
2026-08-26 15:59:45 +02:00
parent 7d21abd5c1
commit 59cd8951f6
5 changed files with 77 additions and 43 deletions

View File

@@ -29,6 +29,7 @@ path = "src/main.rs"
[dependencies]
iced.workspace = true
iced_aw.workspace = true
ironstorage = { workspace = true, features = ["ssh"] }
tokio.workspace = true
zeroize.workspace = true

View File

@@ -31,6 +31,7 @@ use iced::{
},
window,
};
use iced_aw::menu::{Item, Menu, MenuBar};
use ironstorage::{
authentication::{
AuthenticationClock, AuthenticationError, AuthenticationHandle, AuthenticationSession,
@@ -98,7 +99,6 @@ struct RecipientSuccess {
enum Message {
Action(UiAction),
FieldAction(EntryFieldId, UiAction),
ToggleMenu(MenuGroup),
PaletteQueryChanged(String),
PaletteCancel,
PaletteInvoke(UiAction),
@@ -358,7 +358,6 @@ struct App {
generation_form: Option<GenerateForm>,
conflict: bool,
status: String,
open_menu: Option<MenuGroup>,
utility: Option<UtilityView>,
context_target: Option<TreeNodeId>,
palette: CommandPalette,
@@ -1064,7 +1063,6 @@ impl App {
generation_form: None,
conflict: false,
status: "Loading shared configuration…".to_owned(),
open_menu: None,
utility: None,
context_target: None,
palette: CommandPalette::default(),
@@ -1097,9 +1095,6 @@ impl App {
}
return self.invoke_action(action);
}
Message::ToggleMenu(group) => {
self.open_menu = (self.open_menu != Some(group)).then_some(group);
}
Message::PaletteQueryChanged(query) => {
self.palette.update_query(query);
return iced::widget::operation::snap_to(
@@ -2680,7 +2675,6 @@ impl App {
}
fn invoke_action(&mut self, action: UiAction) -> Task<Message> {
self.open_menu = None;
if !action::enabled(action, self.action_context()) {
if self.content_mode == ContentMode::Editor
&& matches!(
@@ -2870,7 +2864,6 @@ impl App {
self.status = reason.to_owned();
return Task::none();
}
self.open_menu = None;
self.utility = None;
self.palette.open();
iced::widget::operation::focus(command_palette_input_id())
@@ -4340,41 +4333,44 @@ fn platform_menu_bar(app: &App) -> Element<'_, Message> {
if cfg!(target_os = "macos") {
return container(row![]).height(Length::Fixed(0.0)).into();
}
let mut headers = row![].spacing(2).padding([0, 8]);
let context = app.action_context();
let mut menus = Vec::new();
for group in MenuGroup::ALL {
headers = headers.push(
button(group.label())
.on_press(Message::ToggleMenu(group))
.style(if app.open_menu == Some(group) {
button::primary
let width = match group {
MenuGroup::Window => 140.0,
MenuGroup::Help => 180.0,
_ => 240.0,
};
let items = action::actions_in(group)
.map(|spec| {
let label = action::shortcut_label(spec.action).map_or_else(
|| spec.label.to_owned(),
|key| format!("{} {key}", spec.label),
);
let item = button(
text(label)
.width(Length::Fill)
.align_x(iced::alignment::Horizontal::Left),
)
.width(width)
.padding([3, 8])
.style(button::text);
Item::new(if action::enabled(spec.action, context) {
item.on_press(Message::Action(spec.action))
} else {
button::text
}),
);
item
})
})
.collect();
menus.push(Item::with_menu(
button(group.label()).padding([3, 8]).style(button::text),
Menu::new(items).width(width),
));
}
let mut menu = column![headers].spacing(4);
if let Some(group) = app.open_menu {
let context = app.action_context();
let mut actions = row![].spacing(4).padding([6, 8]);
for spec in action::actions_in(group) {
let label = action::shortcut_label(spec.action).map_or_else(
|| spec.label.to_owned(),
|key| format!("{} {key}", spec.label),
);
let item = button(text(label));
actions = actions.push(if action::enabled(spec.action, context) {
item.on_press(Message::Action(spec.action))
} else {
item
});
}
menu = menu.push(
scrollable(actions).direction(scrollable::Direction::Horizontal(
scrollable::Scrollbar::default(),
)),
);
}
container(menu).width(Length::Fill).into()
MenuBar::new(menus)
.close_on_item_click(true)
.close_on_background_click(true)
.into()
}
fn utility_title(utility: &UtilityView) -> &'static str {
@@ -6734,7 +6730,6 @@ mod tests {
generation_form: None,
conflict: false,
status: String::new(),
open_menu: None,
utility: None,
context_target: None,
palette: CommandPalette::default(),