diff --git a/CHANGELOG.md b/CHANGELOG.md index db03166..211f020 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -165,6 +165,10 @@ from this file and posts it as the GitHub release body. the ReaPack ones — still name it, since there it is the truth. (Reported by Scott Chesworth from Q&A.) +- **Enter** on the **Review** page now starts the install, as the default + **Install** button promises. Focus lands on the page's read-only summary, + and that text box kept the key for itself. + - On macOS, **Space** now ticks and unticks rows in the **Packages** list, and VoiceOver says whether the row is now checked. Before, only VO+Space while interacting with the list changed a checkbox, so the list could not diff --git a/crates/rabbit-ui-wxdragon/src/wx_app.rs b/crates/rabbit-ui-wxdragon/src/wx_app.rs index ace3fc6..19fbe7e 100644 --- a/crates/rabbit-ui-wxdragon/src/wx_app.rs +++ b/crates/rabbit-ui-wxdragon/src/wx_app.rs @@ -58,11 +58,12 @@ use crate::wx_app::shell::{launch_reaper, open_resource_folder, seat_macos_apple use crate::wx_app::version_check::{VersionCheckUi, start_version_check}; use crate::wx_app::widgets::{ append_done_status, bind_done_page_enter_closes, bind_reapack_ack_navigation_updates, - bind_target_navigation_updates, can_launch_last_reaper_path, checked_package_indices, - clone_last_path, clone_last_resource_path, effective_can_install, osara_keymap_choice, - planned_reaper_launch_path_for_target, progress_details_for_start, reapack_ack_confirmed, - refresh_target_choice, refreshed_target_index, selected_target_row, set_last_path, - set_last_report, set_last_resource_path, step_status, target_is_valid, update_navigation, + bind_review_enter_installs, bind_target_navigation_updates, can_launch_last_reaper_path, + checked_package_indices, clone_last_path, clone_last_resource_path, effective_can_install, + osara_keymap_choice, planned_reaper_launch_path_for_target, progress_details_for_start, + reapack_ack_confirmed, refresh_target_choice, refreshed_target_index, selected_target_row, + set_last_path, set_last_report, set_last_resource_path, step_status, target_is_valid, + update_navigation, }; pub(crate) const TARGET_STEP: usize = 0; @@ -437,7 +438,9 @@ pub fn run() { let last_reaper_app_path = Arc::clone(&last_reaper_app_path); let last_resource_path = Arc::clone(&last_resource_path); let install_run = Arc::clone(&install_run); - install.on_click(move |_| { + let review_text = widgets.review_text; + let review_step = Arc::clone(¤t_step); + let start_install = Rc::new(move || { // Catch a running REAPER here, while the user can still do // something about it. The install's preflight would refuse // too, but only after the wizard has moved to its progress @@ -939,6 +942,11 @@ pub fn run() { })); }); }); + install.on_click({ + let start_install = Rc::clone(&start_install); + move |_| start_install() + }); + bind_review_enter_installs(&review_text, &install, &review_step, start_install); } let frame_for_close = frame; diff --git a/crates/rabbit-ui-wxdragon/src/wx_app/widgets.rs b/crates/rabbit-ui-wxdragon/src/wx_app/widgets.rs index 9260619..4cec368 100644 --- a/crates/rabbit-ui-wxdragon/src/wx_app/widgets.rs +++ b/crates/rabbit-ui-wxdragon/src/wx_app/widgets.rs @@ -3,6 +3,7 @@ use std::cell::Cell; use std::path::{Path, PathBuf}; +use std::rc::Rc; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::{Arc, Mutex}; @@ -351,6 +352,40 @@ pub(crate) fn bind_reapack_ack_navigation_updates( }); } +/// Make Enter on the Review page's summary start the install, as the default +/// Install button would. +/// +/// The summary is a read-only multiline TextCtrl and holds focus on that +/// page, and a multiline text box eats Enter (the NSTextView on macOS, +/// DLGC_WANTALLKEYS on MSW) before the default button sees it: the same trap +/// `bind_done_page_enter_closes` works around on the Done page. Guarded on +/// the step and on Install being enabled, so Enter never starts anything the +/// button itself would refuse. +pub(crate) fn bind_review_enter_installs( + text: &TextCtrl, + install: &Button, + current_step: &Arc, + start_install: Rc, +) { + let install = *install; + let current_step = Arc::clone(current_step); + text.on_key_down(move |event| { + let key_code = if let WindowEventData::Keyboard(kbd) = &event { + kbd.get_key_code() + } else { + None + }; + if !matches!(key_code, Some(WXK_RETURN) | Some(WXK_NUMPAD_ENTER)) { + return; + } + if current_step.load(Ordering::SeqCst) != REVIEW_STEP || !install.is_enabled() { + return; + } + event.skip(false); + start_install(); + }); +} + /// A multiline `wxTextCtrl` claims Enter for itself (it reports /// `DLGC_WANTALLKEYS` on MSW and the NSTextView swallows the key on macOS), /// so the window's default button never sees it. The Done page deliberately