aboutsummaryrefslogtreecommitdiff
path: root/src/app
diff options
context:
space:
mode:
Diffstat (limited to 'src/app')
-rw-r--r--src/app/mod.rs38
-rw-r--r--src/app/runtime.rs4
-rw-r--r--src/app/state.rs6
3 files changed, 42 insertions, 6 deletions
diff --git a/src/app/mod.rs b/src/app/mod.rs
index bcbd40cf..0b4c792c 100644
--- a/src/app/mod.rs
+++ b/src/app/mod.rs
@@ -386,7 +386,7 @@ impl App {
request_submit_worktree_open: false,
request_submit_worktree_remove: false,
request_reload_config: false,
- request_client_sound_config_reload: false,
+ request_client_config_reload: false,
request_clipboard_write: None,
creating_new_tab: false,
requested_new_tab_name: None,
@@ -458,6 +458,7 @@ impl App {
sidebar_section_split,
agent_panel_scope,
mouse_capture: config.ui.mouse_capture,
+ redraw_on_focus_gained: config.ui.redraw_on_focus_gained,
mouse_scroll_lines: config.ui.mouse_scroll_lines(),
confirm_close: config.ui.confirm_close,
prompt_new_tab_name: config.ui.prompt_new_tab_name,
@@ -1055,6 +1056,10 @@ impl App {
.sidebar_width
.clamp(self.state.sidebar_min_width, self.state.sidebar_max_width);
self.state.mouse_capture = config.ui.mouse_capture;
+ if self.state.redraw_on_focus_gained != config.ui.redraw_on_focus_gained {
+ self.state.request_client_config_reload = true;
+ }
+ self.state.redraw_on_focus_gained = config.ui.redraw_on_focus_gained;
self.state.mouse_scroll_lines = config.ui.mouse_scroll_lines();
self.state.confirm_close = config.ui.confirm_close;
self.state.prompt_new_tab_name = config.ui.prompt_new_tab_name;
@@ -1065,7 +1070,7 @@ impl App {
self.state.agent_panel_scroll = 0;
self.state.accent = crate::config::parse_color(&config.ui.accent);
if !self.state.local_sound_playback && self.state.sound != config.ui.sound {
- self.state.request_client_sound_config_reload = true;
+ self.state.request_client_config_reload = true;
}
self.state.sound = config.ui.sound.clone();
self.state.toast_config = config.ui.toast.clone();
@@ -1501,6 +1506,17 @@ mod tests {
}
#[test]
+ fn startup_uses_redraw_on_focus_gained_config() {
+ let mut config = Config::default();
+ config.ui.redraw_on_focus_gained = false;
+ let (_api_tx, api_rx) = tokio::sync::mpsc::unbounded_channel();
+
+ let app = App::new(&config, true, None, api_rx, crate::api::EventHub::default());
+
+ assert!(!app.state.redraw_on_focus_gained);
+ }
+
+ #[test]
fn startup_restores_preview_update_available_from_saved_notes() {
let _guard = config_env_lock().lock().unwrap();
let path = temp_config_path("startup-preview-update-available");
@@ -1610,7 +1626,7 @@ mod tests {
std::fs::create_dir_all(path.parent().unwrap()).unwrap();
std::fs::write(
&path,
- "[terminal]\ndefault_shell = \"nu\"\nnew_cwd = \"home\"\n[keys]\nnew_workspace = \"prefix+m\"\nprefix = \"ctrl+a\"\n[ui]\nagent_panel_scope = \"current\"\n[ui.toast]\ndelivery = \"herdr\"\n",
+ "[terminal]\ndefault_shell = \"nu\"\nnew_cwd = \"home\"\n[keys]\nnew_workspace = \"prefix+m\"\nprefix = \"ctrl+a\"\n[ui]\nagent_panel_scope = \"current\"\nredraw_on_focus_gained = false\n[ui.toast]\ndelivery = \"herdr\"\n",
)
.unwrap();
std::env::set_var(crate::config::CONFIG_PATH_ENV_VAR, &path);
@@ -1634,6 +1650,8 @@ mod tests {
app.state.agent_panel_scope,
state::AgentPanelScope::CurrentWorkspace
);
+ assert!(!app.state.redraw_on_focus_gained);
+ assert!(app.state.request_client_config_reload);
assert_eq!(app.state.default_shell, "nu");
assert_eq!(
app.state.new_terminal_cwd,
@@ -2074,6 +2092,20 @@ mod tests {
}
#[tokio::test]
+ async fn outer_focus_gained_does_not_require_full_redraw_when_disabled() {
+ let mut app = test_app();
+ app.state.redraw_on_focus_gained = false;
+
+ let handled = app
+ .handle_raw_input_event(crate::raw_input::RawInputEvent::OuterFocusGained)
+ .await;
+
+ assert!(handled);
+ assert_eq!(app.state.outer_terminal_focus, Some(true));
+ assert!(!app.full_redraw_pending);
+ }
+
+ #[tokio::test]
async fn repeat_key_events_are_ignored_outside_terminal_mode() {
let mut app = test_app();
app.state.mode = Mode::ReleaseNotes;
diff --git a/src/app/runtime.rs b/src/app/runtime.rs
index 284fb882..85bdb8dd 100644
--- a/src/app/runtime.rs
+++ b/src/app/runtime.rs
@@ -106,7 +106,9 @@ impl App {
true
}
crate::raw_input::RawInputEvent::OuterFocusGained => {
- self.request_full_redraw();
+ if self.state.redraw_on_focus_gained {
+ self.request_full_redraw();
+ }
self.state.outer_terminal_focus = Some(true);
self.state.mark_active_tab_seen();
true
diff --git a/src/app/state.rs b/src/app/state.rs
index 422664ff..b22dc6a3 100644
--- a/src/app/state.rs
+++ b/src/app/state.rs
@@ -1057,7 +1057,7 @@ pub struct AppState {
pub request_reload_config: bool,
/// Set when the headless server should ask attached clients to reload
/// their client-local sound config from disk.
- pub request_client_sound_config_reload: bool,
+ pub request_client_config_reload: bool,
/// Set when UI interaction requested a clipboard write that must be
/// handled by the outer App/event loop instead of directly from AppState.
pub request_clipboard_write: Option<Vec<u8>>,
@@ -1115,6 +1115,7 @@ pub struct AppState {
/// Capture mouse input for Herdr's own mouse UI. When false, Herdr only
/// captures mouse while the focused pane app requests mouse reporting.
pub mouse_capture: bool,
+ pub redraw_on_focus_gained: bool,
pub mouse_scroll_lines: usize,
pub confirm_close: bool,
pub prompt_new_tab_name: bool,
@@ -1351,7 +1352,7 @@ impl AppState {
request_submit_worktree_open: false,
request_submit_worktree_remove: false,
request_reload_config: false,
- request_client_sound_config_reload: false,
+ request_client_config_reload: false,
request_clipboard_write: None,
creating_new_tab: false,
requested_new_tab_name: None,
@@ -1414,6 +1415,7 @@ impl AppState {
sidebar_section_split: 0.5,
agent_panel_scope: AgentPanelScope::AllWorkspaces,
mouse_capture: true,
+ redraw_on_focus_gained: true,
mouse_scroll_lines: crate::config::DEFAULT_MOUSE_SCROLL_LINES,
confirm_close: true,
prompt_new_tab_name: true,