앱 시작 직후 AX Agent 창을 미리 생성하던 경로를 제거하고 실제로 AX Agent를 열 때만 ChatWindow를 만들도록 정리했습니다. 런처 검색 인덱스 전체 스캔과 파일 감시 시작도 부팅 시 즉시 실행하지 않고, 런처를 실제로 표시할 때 한 번만 지연 시작하도록 변경했습니다. README와 DEVELOPMENT 문서를 2026-04-06 17:35(KST) 기준으로 갱신했고, Release 빌드 검증에서 경고 0 오류 0을 확인했습니다.
This commit is contained in:
@@ -1301,3 +1301,7 @@ MIT License
|
||||
- 선택 텍스트 AI 명령의 기본값을 보수적으로 다시 조정했다. [AppSettings.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Models/AppSettings.cs), [SettingsViewModel.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/ViewModels/SettingsViewModel.cs) 에서 `선택 텍스트 명령 사용` 기본값을 `false`로 바꾸고, 활성 AI 명령 목록도 기본은 빈 리스트가 되도록 변경했다.
|
||||
- [SettingsWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/SettingsWindow.xaml.cs) 의 `BuildTextActionCommandsPanel()`에서 `최소 1개 유지`를 강제하던 로직을 제거해 `다시 쓰기`를 포함한 모든 텍스트 AI 명령을 실제로 비활성화할 수 있게 수정했다.
|
||||
- [SettingsWindow.xaml](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/SettingsWindow.xaml) 의 안내 문구도 현재 동작 기준으로 갱신해, 모든 명령을 꺼두면 선택 텍스트 팝업에는 `AX Commander 열기`만 남는다는 점을 명확히 안내하도록 정리했다.
|
||||
- 업데이트: 2026-04-06 17:35 (KST)
|
||||
- 앱이 아무 창도 열지 않은 유휴 상태에서 PC를 무겁게 만들던 추가 초기화 경로를 줄였다. [App.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/App.xaml.cs) 에서 앱 시작 직후 숨겨진 [ChatWindow](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs) 를 미리 생성하던 `PrewarmChatWindow()` 호출을 제거해, AX Agent를 실제로 열기 전에는 무거운 UI 트리를 만들지 않도록 바꿨다.
|
||||
- 같은 파일에서 [IndexService](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Services/IndexService.cs) 의 전체 인덱스 빌드와 `FileSystemWatcher` 시작도 앱 시작 시 즉시 수행하지 않고, 사용자가 실제로 런처를 열 때 `EnsureIndexWarmupStarted()`로 한 번만 지연 시작하도록 바꿨다.
|
||||
- 이 변경으로 런처/AX Agent를 열지 않은 상태에서 불필요한 전체 파일 스캔과 감시 훅, 숨겨진 대형 창 초기화가 줄어들어 PC 전체 체감 부하를 더 낮추도록 정리했다.
|
||||
|
||||
@@ -4988,3 +4988,5 @@ ow + toggle ?쒓컖 ?몄뼱濡??ㅼ떆 ?뺣젹?덈떎.
|
||||
- Document update: 2026-04-06 17:18 (KST) - `FileDialogWatcher` is no longer started at app boot when file-dialog integration is disabled. `App.xaml.cs` now toggles the global WinEvent hook through `UpdateFileDialogWatcherState()`, and `SchedulerService.cs` now self-stops when no enabled schedules remain. This directly targets the 3–5% idle CPU symptom reported while neither the launcher nor AX Agent was open.
|
||||
- Document update: 2026-04-06 17:24 (KST) - Changed the default launcher text-action profile to opt-in. `AppSettings.cs` and `SettingsViewModel.cs` now default `EnableTextAction` to `false`, and `TextActionCommands` now defaults to an empty list instead of all commands enabled.
|
||||
- Document update: 2026-04-06 17:24 (KST) - Removed the forced “at least one command must remain enabled” behavior from `SettingsWindow.xaml.cs`. The text-action command panel now allows every AI command, including `rewrite`, to be turned off, and the hint text in `SettingsWindow.xaml` now explains that the popup falls back to showing only `AX Commander 열기` when all AI commands are disabled.
|
||||
- Document update: 2026-04-06 17:35 (KST) - Reduced another startup performance hotspot in `App.xaml.cs` by removing the idle-time `PrewarmChatWindow()` path. AX Agent is no longer instantiated in the background at app startup and is created only when the user actually opens it.
|
||||
- Document update: 2026-04-06 17:35 (KST) - Changed launcher search warmup from eager startup work to on-demand initialization. `App.xaml.cs` now starts the first `IndexService.BuildAsync()` scan and `StartWatchers()` only when the launcher is actually shown through `ShowLauncherWindow()`, instead of running a full index scan and watcher hookup at boot even when the launcher is never opened.
|
||||
|
||||
@@ -24,6 +24,7 @@ public partial class App : System.Windows.Application
|
||||
private DockBarWindow? _dockBar;
|
||||
private FileDialogWatcher? _fileDialogWatcher;
|
||||
private volatile IndexService? _indexService;
|
||||
private int _indexWarmupStarted;
|
||||
public IndexService? IndexService => _indexService;
|
||||
public SettingsService? SettingsService => _settings;
|
||||
public ClipboardHistoryService? ClipboardHistoryService => _clipboardHistory;
|
||||
@@ -287,14 +288,8 @@ public partial class App : System.Windows.Application
|
||||
() => _clipboardHistory?.Initialize(),
|
||||
System.Windows.Threading.DispatcherPriority.ApplicationIdle);
|
||||
|
||||
// ─── ChatWindow 미리 생성 (앱 유휴 시점에 숨겨진 채로 초기화) ──────────
|
||||
// 이후 OpenAiChat() 시 창 생성 비용 없이 즉시 열림
|
||||
Dispatcher.BeginInvoke(
|
||||
() => PrewarmChatWindow(),
|
||||
System.Windows.Threading.DispatcherPriority.SystemIdle);
|
||||
|
||||
// ─── 인덱스 빌드 (백그라운드) + 완료 후 FileSystemWatcher 시작 ────────
|
||||
_ = indexService.BuildAsync().ContinueWith(_ => indexService.StartWatchers());
|
||||
// ─── 인덱스 빌드/감시는 실제 런처를 사용할 때 시작 ───────────────────
|
||||
// 앱 시작 직후 전체 스캔과 감시 훅을 붙이지 않아 유휴 체감 부하를 줄임
|
||||
|
||||
// ─── 글로벌 훅 + 스니펫 확장기 ───────────────────────────────────────
|
||||
_inputListener = new InputListener();
|
||||
@@ -327,7 +322,7 @@ public partial class App : System.Windows.Application
|
||||
if (_launcher == null || _launcher.IsVisible) return;
|
||||
if (_settings?.Settings.Launcher.EnableFileDialogIntegration != true) return;
|
||||
WindowTracker.Capture();
|
||||
_launcher.Show();
|
||||
ShowLauncherWindow();
|
||||
Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Input,
|
||||
() => _launcher.SetInputText("cd "));
|
||||
});
|
||||
@@ -375,7 +370,7 @@ public partial class App : System.Windows.Application
|
||||
{
|
||||
if (_launcher == null) return;
|
||||
UsageStatisticsService.RecordLauncherOpen();
|
||||
_launcher.Show();
|
||||
ShowLauncherWindow();
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -423,7 +418,7 @@ public partial class App : System.Windows.Application
|
||||
{
|
||||
case TextActionPopup.ActionResult.OpenLauncher:
|
||||
UsageStatisticsService.RecordLauncherOpen();
|
||||
_launcher.Show();
|
||||
ShowLauncherWindow();
|
||||
break;
|
||||
case TextActionPopup.ActionResult.None:
|
||||
break; // Esc 또는 포커스 잃음
|
||||
@@ -438,7 +433,7 @@ public partial class App : System.Windows.Application
|
||||
else
|
||||
{
|
||||
UsageStatisticsService.RecordLauncherOpen();
|
||||
_launcher.Show();
|
||||
ShowLauncherWindow();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -514,7 +509,7 @@ public partial class App : System.Windows.Application
|
||||
};
|
||||
|
||||
// ! 프리픽스로 AX Agent에 전달
|
||||
_launcher?.Show();
|
||||
ShowLauncherWindow();
|
||||
_launcher?.SetInputText($"! {prompt}");
|
||||
}
|
||||
|
||||
@@ -581,7 +576,7 @@ public partial class App : System.Windows.Application
|
||||
_trayMenu
|
||||
.AddHeader(versionText)
|
||||
.AddItem("\uE7C5", "AX Commander 호출하기", () =>
|
||||
Dispatcher.Invoke(() => _launcher?.Show()))
|
||||
Dispatcher.Invoke(ShowLauncherWindow))
|
||||
.AddItem("\uE8BD", "AX Agent 대화하기", () =>
|
||||
Dispatcher.Invoke(OpenAiChat), out var aiTrayItem)
|
||||
.AddItem("\uE8A7", "독 바 표시", () =>
|
||||
@@ -644,7 +639,7 @@ public partial class App : System.Windows.Application
|
||||
if (settings.Settings.AiEnabled)
|
||||
OpenAiChat();
|
||||
else
|
||||
_launcher?.Show();
|
||||
ShowLauncherWindow();
|
||||
});
|
||||
}
|
||||
else if (e.Button == System.Windows.Forms.MouseButtons.Right)
|
||||
@@ -679,14 +674,30 @@ public partial class App : System.Windows.Application
|
||||
/// <summary>AX Agent 창 열기 (트레이 메뉴 등에서 호출).</summary>
|
||||
private Views.ChatWindow? _chatWindow;
|
||||
|
||||
/// <summary>
|
||||
/// ChatWindow를 백그라운드에서 미리 생성합니다 (앱 시작 후 저우선순위로 호출).
|
||||
/// 이후 OpenAiChat() 시 창 생성 비용 없이 즉시 Show/Activate만 수행합니다.
|
||||
/// </summary>
|
||||
internal void PrewarmChatWindow()
|
||||
private void EnsureIndexWarmupStarted()
|
||||
{
|
||||
if (_chatWindow != null || _settings == null) return;
|
||||
_chatWindow = new Views.ChatWindow(_settings);
|
||||
if (_indexService == null) return;
|
||||
if (Interlocked.Exchange(ref _indexWarmupStarted, 1) == 1) return;
|
||||
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await _indexService.BuildAsync().ConfigureAwait(false);
|
||||
_indexService.StartWatchers();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogService.Warn($"런처 인덱스 초기화 실패: {ex.Message}");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void ShowLauncherWindow()
|
||||
{
|
||||
if (_launcher == null) return;
|
||||
EnsureIndexWarmupStarted();
|
||||
_launcher.Show();
|
||||
}
|
||||
|
||||
private void OpenAiChat()
|
||||
@@ -714,7 +725,7 @@ public partial class App : System.Windows.Application
|
||||
_dockBar.OnQuickSearch = query =>
|
||||
{
|
||||
if (_launcher == null) return;
|
||||
_launcher.Show();
|
||||
ShowLauncherWindow();
|
||||
_launcher.Activate(); // 독 바 뒤가 아닌 전면에 표시
|
||||
if (!string.IsNullOrEmpty(query))
|
||||
Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Input,
|
||||
@@ -729,7 +740,7 @@ public partial class App : System.Windows.Application
|
||||
_dockBar.OnOpenAgent = () =>
|
||||
{
|
||||
if (_launcher == null) return;
|
||||
_launcher.Show();
|
||||
ShowLauncherWindow();
|
||||
Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Input,
|
||||
() => _launcher.SetInputText("!"));
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user