fix: focus button for permanently delete dialog

This commit is contained in:
Ashley Wulber 2025-10-17 14:14:59 -04:00 committed by Ashley Wulber
parent 2aa7b6f063
commit 6615e0a2b7
2 changed files with 68 additions and 41 deletions

View file

@ -31,6 +31,7 @@ use cosmic::{
window::{self, Event as WindowEvent, Id as WindowId},
},
iced_runtime::clipboard,
iced_widget::button::focus,
style, surface, theme,
widget::{
self,
@ -58,7 +59,7 @@ use std::{
path::{Path, PathBuf},
pin::Pin,
process,
sync::{Arc, Mutex},
sync::{Arc, LazyLock, Mutex},
time::{self, Duration, Instant},
};
use tokio::sync::mpsc;
@ -91,6 +92,9 @@ use crate::{
};
use crate::{config::State, dialog::DialogSettings};
static PERMANENT_DELETE_BUTTON_ID: LazyLock<widget::Id> =
LazyLock::new(|| widget::Id::new("permanent-delete-button"));
#[derive(Clone, Debug)]
pub enum Mode {
App,
@ -315,7 +319,7 @@ pub enum Message {
DialogComplete,
Eject,
FileDialogMessage(DialogMessage),
DialogPush(DialogPage),
DialogPush(DialogPage, Option<widget::Id>),
DialogUpdate(DialogPage),
DialogUpdateComplete(DialogPage),
ExtractHere(Option<Entity>),
@ -694,6 +698,15 @@ pub struct App {
}
impl App {
fn push_dialog(&mut self, page: DialogPage, focus_id: Option<widget::Id>) -> Task<Message> {
let t = self.dialog_pages.push_back(page);
if let Some(focus_id) = focus_id {
Task::batch(vec![t, focus(focus_id)])
} else {
t
}
}
fn open_file(&mut self, paths: &[impl AsRef<Path>]) -> Task<Message> {
let mut tasks = Vec::new();
@ -1091,9 +1104,12 @@ impl App {
let mut tasks = Vec::new();
if !dialog_paths.is_empty() {
tasks.push(self.dialog_pages.push_back(DialogPage::PermanentlyDelete {
paths: dialog_paths,
}));
tasks.push(self.update(Message::DialogPush(
DialogPage::PermanentlyDelete {
paths: dialog_paths,
},
Some(PERMANENT_DELETE_BUTTON_ID.clone()),
)));
}
if !trash_paths.is_empty() {
tasks.push(self.operation(Operation::Delete { paths: trash_paths }));
@ -2855,8 +2871,8 @@ impl Application for App {
return Task::batch(tasks);
}
}
Message::DialogPush(dialog_page) => {
return self.dialog_pages.push_back(dialog_page);
Message::DialogPush(dialog_page, focused_id) => {
return self.push_dialog(dialog_page, focused_id);
}
Message::DialogUpdate(dialog_page) => {
self.dialog_pages.update_front(dialog_page);
@ -3342,17 +3358,20 @@ impl Application for App {
let Some(path) = item.path_opt() else {
continue;
};
return self.update(Message::DialogPush(DialogPage::OpenWith {
path: path.to_path_buf(),
mime: item.mime.clone(),
selected: 0,
store_opt: "x-scheme-handler/mime"
.parse::<mime_guess::Mime>()
.ok()
.and_then(|mime| {
self.mime_app_cache.get(&mime).first().cloned()
}),
}));
return self.push_dialog(
DialogPage::OpenWith {
path: path.to_path_buf(),
mime: item.mime.clone(),
selected: 0,
store_opt: "x-scheme-handler/mime"
.parse::<mime_guess::Mime>()
.ok()
.and_then(|mime| {
self.mime_app_cache.get(&mime).first().cloned()
}),
},
None, // TODO which id to focus?
);
}
}
}
@ -3530,9 +3549,10 @@ impl Application for App {
Message::PermanentlyDelete(entity_opt) => {
let paths = self.selected_paths(entity_opt);
if !paths.is_empty() {
return self
.dialog_pages
.push_back(DialogPage::PermanentlyDelete { paths });
return self.push_dialog(
DialogPage::PermanentlyDelete { paths },
Some(PERMANENT_DELETE_BUTTON_ID.clone()),
);
}
}
Message::Preview(entity_opt) => {
@ -4404,17 +4424,20 @@ impl Application for App {
{
match tab::item_from_path(&path, IconSizes::default()) {
Ok(item) => {
return self.update(Message::DialogPush(DialogPage::OpenWith {
path: path.to_path_buf(),
mime: item.mime.clone(),
selected: 0,
store_opt: "x-scheme-handler/mime"
.parse::<mime_guess::Mime>()
.ok()
.and_then(|mime| {
self.mime_app_cache.get(&mime).first().cloned()
}),
}));
return self.push_dialog(
DialogPage::OpenWith {
path: path.to_path_buf(),
mime: item.mime.clone(),
selected: 0,
store_opt: "x-scheme-handler/mime"
.parse::<mime_guess::Mime>()
.ok()
.and_then(|mime| {
self.mime_app_cache.get(&mime).first().cloned()
}),
},
None,
);
}
Err(err) => {
log::warn!("failed to get item for path {:?}: {}", path, err);
@ -5283,7 +5306,8 @@ impl Application for App {
.title(fl!("permanently-delete-question"))
.primary_action(
widget::button::destructive(fl!("delete"))
.on_press(Message::DialogComplete),
.on_press(Message::DialogComplete)
.id(PERMANENT_DELETE_BUTTON_ID.clone()),
)
.secondary_action(
widget::button::standard(fl!("cancel")).on_press(Message::DialogCancel),

View file

@ -53,13 +53,16 @@ async fn handle_replace(
let _ = msg_tx
.lock()
.await
.send(Message::DialogPush(DialogPage::Replace {
from: item_from,
to: item_to,
multiple,
apply_to_all: false,
tx,
}))
.send(Message::DialogPush(
DialogPage::Replace {
from: item_from,
to: item_to,
multiple,
apply_to_all: false,
tx,
},
None, // TODO which widget to focus?
))
.await;
rx.recv().await.unwrap_or(ReplaceResult::Cancel)
}
@ -1198,7 +1201,7 @@ mod tests {
let handle_messages = async move {
while let Some(msg) = rx.next().await {
match msg {
Message::DialogPush(DialogPage::Replace { tx, .. }) => {
Message::DialogPush(DialogPage::Replace { tx, .. }, _id_to_focus) => {
debug!("[{id}] Replace request");
tx.send(ReplaceResult::Cancel)
.await