From ccd2a84a666f0499152ffb3d1f2db92af7d9382b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Aslo-=C3=98stergaard?= Date: Sat, 9 May 2026 21:07:13 +0200 Subject: [PATCH 1/2] feat: auto-focus terminal when selecting a session (#13) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clicking a sidebar session now moves keyboard focus into that session's terminal so the user can start typing immediately — previously focus stayed on the WPF sidebar Border and keystrokes went nowhere until the user clicked the terminal pane. - TerminalBridge.FocusTerminal now calls _webView.Focus() in addition to posting the JS focus message, so WPF keyboard focus actually moves onto the WebView2 host (the JS term.focus() alone does not do this when another WPF control holds focus). - New AppSettings.AutoFocusTerminalOnSelect (default true) gates the focus call inside MainViewModel.FocusSession, so users who prefer the previous behaviour can opt out. ActiveSession and the active-terminal highlight still update either way. - Settings window exposes the toggle under SESSION SETTINGS as "Auto-focus terminal when selecting a session". Closes #13 --- src/CodeShellManager/MainWindow.xaml.cs | 1 + src/CodeShellManager/Models/AppState.cs | 1 + src/CodeShellManager/Terminal/TerminalBridge.cs | 10 +++++++++- src/CodeShellManager/ViewModels/MainViewModel.cs | 3 ++- src/CodeShellManager/Views/SettingsWindow.xaml | 3 +++ src/CodeShellManager/Views/SettingsWindow.xaml.cs | 3 +++ 6 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/CodeShellManager/MainWindow.xaml.cs b/src/CodeShellManager/MainWindow.xaml.cs index cb8bf39..0be50fd 100644 --- a/src/CodeShellManager/MainWindow.xaml.cs +++ b/src/CodeShellManager/MainWindow.xaml.cs @@ -1734,6 +1734,7 @@ private void SettingsButton_Click(object sender, RoutedEventArgs e) var edited = dialog.EditedSettings; _vm.Settings.AutoRestoreSessions = edited.AutoRestoreSessions; _vm.Settings.AutoResumeClaude = edited.AutoResumeClaude; + _vm.Settings.AutoFocusTerminalOnSelect = edited.AutoFocusTerminalOnSelect; _vm.Settings.ShowToastNotifications = edited.ShowToastNotifications; _vm.Settings.ShowNotificationSound = edited.ShowNotificationSound; _vm.Settings.AnthropicApiKey = edited.AnthropicApiKey; diff --git a/src/CodeShellManager/Models/AppState.cs b/src/CodeShellManager/Models/AppState.cs index 759a40f..e4e5829 100644 --- a/src/CodeShellManager/Models/AppState.cs +++ b/src/CodeShellManager/Models/AppState.cs @@ -6,6 +6,7 @@ public class AppSettings { public bool AutoRestoreSessions { get; set; } = true; public bool AutoResumeClaude { get; set; } = true; + public bool AutoFocusTerminalOnSelect { get; set; } = true; public bool ShowToastNotifications { get; set; } = false; public bool ShowNotificationSound { get; set; } = false; public string AnthropicApiKey { get; set; } = ""; diff --git a/src/CodeShellManager/Terminal/TerminalBridge.cs b/src/CodeShellManager/Terminal/TerminalBridge.cs index b00b577..9640aea 100644 --- a/src/CodeShellManager/Terminal/TerminalBridge.cs +++ b/src/CodeShellManager/Terminal/TerminalBridge.cs @@ -292,7 +292,15 @@ public void FocusTerminal() if (!_ready) return; WpfApplication.Current?.Dispatcher.BeginInvoke(() => { - try { _webView.CoreWebView2?.PostWebMessageAsString("{\"type\":\"focus\"}"); } + try + { + // Move WPF keyboard focus onto the WebView2 host. Without this, focus + // can stay on whichever WPF control was last clicked (e.g. a sidebar + // item Border), so the JS term.focus() below has no effect at the + // WPF level and typing goes nowhere. + _webView.Focus(); + _webView.CoreWebView2?.PostWebMessageAsString("{\"type\":\"focus\"}"); + } catch { } }); } diff --git a/src/CodeShellManager/ViewModels/MainViewModel.cs b/src/CodeShellManager/ViewModels/MainViewModel.cs index 2675f9a..f43f0f8 100644 --- a/src/CodeShellManager/ViewModels/MainViewModel.cs +++ b/src/CodeShellManager/ViewModels/MainViewModel.cs @@ -153,7 +153,8 @@ private void FocusSession(SessionViewModel vm) { ActiveSession = vm; vm.ClearAlert(); - vm.Bridge?.FocusTerminal(); + if (Settings.AutoFocusTerminalOnSelect) + vm.Bridge?.FocusTerminal(); vm.AlertDetector?.NotifyUserInteracted(); OnPropertyChanged(nameof(AlertCount)); } diff --git a/src/CodeShellManager/Views/SettingsWindow.xaml b/src/CodeShellManager/Views/SettingsWindow.xaml index b4c629e..632a7a8 100644 --- a/src/CodeShellManager/Views/SettingsWindow.xaml +++ b/src/CodeShellManager/Views/SettingsWindow.xaml @@ -208,6 +208,9 @@ + diff --git a/src/CodeShellManager/Views/SettingsWindow.xaml.cs b/src/CodeShellManager/Views/SettingsWindow.xaml.cs index 59b3a5d..0fcfd6f 100644 --- a/src/CodeShellManager/Views/SettingsWindow.xaml.cs +++ b/src/CodeShellManager/Views/SettingsWindow.xaml.cs @@ -24,6 +24,7 @@ public SettingsWindow(AppSettings current, SearchService? searchService = null) { AutoRestoreSessions = current.AutoRestoreSessions, AutoResumeClaude = current.AutoResumeClaude, + AutoFocusTerminalOnSelect = current.AutoFocusTerminalOnSelect, ShowToastNotifications = current.ShowToastNotifications, ShowNotificationSound = current.ShowNotificationSound, AnthropicApiKey = current.AnthropicApiKey, @@ -48,6 +49,7 @@ public SettingsWindow(AppSettings current, SearchService? searchService = null) DefaultFolderBox.Text = _edited.DefaultWorkingFolder; AutoRestoreCheck.IsChecked = _edited.AutoRestoreSessions; AutoResumeClaudeCheck.IsChecked = _edited.AutoResumeClaude; + AutoFocusTerminalOnSelectCheck.IsChecked = _edited.AutoFocusTerminalOnSelect; ShowToastCheck.IsChecked = _edited.ShowToastNotifications; ShowNotificationSoundCheck.IsChecked = _edited.ShowNotificationSound; ShowGitBranchCheck.IsChecked = _edited.ShowGitBranch; @@ -109,6 +111,7 @@ private void Save_Click(object sender, RoutedEventArgs e) _edited.DefaultWorkingFolder = DefaultFolderBox.Text.Trim(); _edited.AutoRestoreSessions = AutoRestoreCheck.IsChecked == true; _edited.AutoResumeClaude = AutoResumeClaudeCheck.IsChecked == true; + _edited.AutoFocusTerminalOnSelect = AutoFocusTerminalOnSelectCheck.IsChecked == true; _edited.ShowToastNotifications = ShowToastCheck.IsChecked == true; _edited.ShowNotificationSound = ShowNotificationSoundCheck.IsChecked == true; _edited.ShowGitBranch = ShowGitBranchCheck.IsChecked == true; From 10c6b07f5bc504a5e09e73659d04f197395872c4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 10 May 2026 14:10:53 +0000 Subject: [PATCH 2/2] fix: preserve custom launch commands in settings clone Agent-Logs-Url: https://github.com/umage-ai/CodeShellManager/sessions/f2b0ac4f-cae3-43f7-bd3b-7a2c42e51fe7 Co-authored-by: AThraen <5888420+AThraen@users.noreply.github.com> --- src/CodeShellManager/Views/SettingsWindow.xaml.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CodeShellManager/Views/SettingsWindow.xaml.cs b/src/CodeShellManager/Views/SettingsWindow.xaml.cs index 0fcfd6f..fbf4af3 100644 --- a/src/CodeShellManager/Views/SettingsWindow.xaml.cs +++ b/src/CodeShellManager/Views/SettingsWindow.xaml.cs @@ -43,6 +43,7 @@ public SettingsWindow(AppSettings current, SearchService? searchService = null) TerminalLineHeight = current.TerminalLineHeight, IndexTerminalOutput = current.IndexTerminalOutput, OutputRetentionDays = current.OutputRetentionDays, + LaunchCommands = current.LaunchCommands.ToList(), }; // Populate controls