diff --git a/README.md b/README.md index 29adf88..fd580df 100644 --- a/README.md +++ b/README.md @@ -1511,3 +1511,8 @@ MIT License - `claw-code`의 가상화 메시지 리스트에 바로 가기 전 단계로, AX transcript에 `실행 중 렌더 윈도우 축소`를 적용했습니다. 코워크/코드 스트리밍 중에는 최근 항목 위주로 더 작은 타임라인만 렌더하고, 평상시에는 기존 범위를 유지합니다. - [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)에 `GetActiveTimelineRenderLimit()`를 추가해, 일반 스트리밍은 96개, 경량 라이브 진행 모드는 60개만 렌더하도록 조정했습니다. - `ScheduleExecutionHistoryRender`, `ScheduleAgentUiEvent`, `ScheduleTaskSummaryRefresh`, `ScheduleInputUiRefresh`도 경량 모드에서는 이미 타이머가 대기 중일 때 다시 stop/start 하지 않게 바꿔, 이벤트 폭주 시 dispatcher 예약 churn을 줄였습니다. +- 업데이트: 2026-04-08 12:40 (KST) + - 코워크/코드 경량 라이브 진행 모드에서는 메시지 진입 애니메이션과 진행 마커 펄스도 줄였습니다. + - [ChatWindow.MessageInteractions.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.MessageInteractions.cs)의 메시지 엔트리 애니메이션은 실행 중 경량 모드에서 즉시 표시로 바뀌어, 새 UI 요소가 들어올 때마다 opacity/translate 애니메이션이 누적되지 않게 했습니다. + - [ChatWindow.AgentEventRendering.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.AgentEventRendering.cs)의 진행 마커 펄스는 경량 모드에서 정적 점 상태로 간소화했습니다. + - [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs)의 AX Agent 라이브 카드도 경량 모드에서는 등장/퇴장 애니메이션과 아이콘 opacity 펄스를 줄여, 실행 중 레이아웃/애니메이션 비용을 더 낮췄습니다. diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index d7aee05..a235713 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -5465,3 +5465,16 @@ ow + toggle ?쒓컖 ?몄뼱濡??ㅼ떆 ?뺣젹?덈떎. - 코워크/코드 실행 중 transcript 재구성 대상 수 자체 감소 - 高频 이벤트 환경에서 dispatcher timer 재예약 churn 감소 - `claw-code`의 virtualized list 이전 단계로서 실행 중 체감 부하를 더 낮춤 + +## 2026-04-08 12:40 (KST) + +- [ChatWindow.MessageInteractions.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.MessageInteractions.cs) + - `ApplyMessageEntryAnimation(...)`를 인스턴스 메서드로 전환하고, `스트리밍 + 경량 라이브 진행 모드`에서는 opacity/translate 애니메이션 없이 즉시 표시되도록 바꿨다. +- [ChatWindow.AgentEventRendering.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.AgentEventRendering.cs) + - `ApplyLiveWaitingPulseToMarker(...)`를 인스턴스 메서드로 바꾸고, 경량 모드에서는 펄스 애니메이션 대신 정적 마커만 남기도록 조정했다. +- [ChatWindow.xaml.cs](/E:/AX%20Copilot%20-%20Codex/src/AxCopilot/Views/ChatWindow.xaml.cs) + - AX Agent 라이브 카드의 등장/퇴장 애니메이션과 헤더 아이콘 opacity 펄스를 경량 모드에서는 생략하도록 변경했다. +- 기대 효과 + - 코워크/코드 실행 중 누적 애니메이션 수 감소 + - 긴 세션에서 opacity/translate/scale animation이 UI 스레드에 주는 부담 완화 + - 진행 카드는 유지하되 시각 효과 비용은 더 낮춘 상태로 동작 diff --git a/src/AxCopilot/Views/ChatWindow.AgentEventRendering.cs b/src/AxCopilot/Views/ChatWindow.AgentEventRendering.cs index 4d115a4..8c60a3f 100644 --- a/src/AxCopilot/Views/ChatWindow.AgentEventRendering.cs +++ b/src/AxCopilot/Views/ChatWindow.AgentEventRendering.cs @@ -568,8 +568,15 @@ public partial class ChatWindow }; } - private static void ApplyLiveWaitingPulseToMarker(Border marker) + private void ApplyLiveWaitingPulseToMarker(Border marker) { + if (_isStreaming && IsLightweightLiveProgressMode()) + { + marker.Opacity = 0.92; + marker.RenderTransform = Transform.Identity; + return; + } + marker.RenderTransformOrigin = new Point(0.5, 0.5); marker.RenderTransform = new ScaleTransform(1, 1); diff --git a/src/AxCopilot/Views/ChatWindow.MessageInteractions.cs b/src/AxCopilot/Views/ChatWindow.MessageInteractions.cs index 1bd1bfc..e89bf7f 100644 --- a/src/AxCopilot/Views/ChatWindow.MessageInteractions.cs +++ b/src/AxCopilot/Views/ChatWindow.MessageInteractions.cs @@ -272,8 +272,15 @@ public partial class ChatWindow }; } - private static void ApplyMessageEntryAnimation(FrameworkElement element) + private void ApplyMessageEntryAnimation(FrameworkElement element) { + if (_isStreaming && IsLightweightLiveProgressMode()) + { + element.Opacity = 1; + element.RenderTransform = Transform.Identity; + return; + } + element.Opacity = 0; element.RenderTransform = new TranslateTransform(0, 16); element.BeginAnimation(UIElement.OpacityProperty, diff --git a/src/AxCopilot/Views/ChatWindow.xaml.cs b/src/AxCopilot/Views/ChatWindow.xaml.cs index 8e0d58f..5f78d51 100644 --- a/src/AxCopilot/Views/ChatWindow.xaml.cs +++ b/src/AxCopilot/Views/ChatWindow.xaml.cs @@ -7039,16 +7039,21 @@ public partial class ChatWindow : Window Width = msgMaxWidth, MaxWidth = msgMaxWidth, Margin = new Thickness(0, 4, 0, 6), - Opacity = 0, - RenderTransform = new TranslateTransform(0, 8), + Opacity = IsLightweightLiveProgressMode(runTab) ? 1 : 0, + RenderTransform = IsLightweightLiveProgressMode(runTab) + ? Transform.Identity + : new TranslateTransform(0, 8), }; - container.BeginAnimation(UIElement.OpacityProperty, - new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(260))); - ((TranslateTransform)container.RenderTransform).BeginAnimation( - TranslateTransform.YProperty, - new DoubleAnimation(8, 0, TimeSpan.FromMilliseconds(280)) - { EasingFunction = new System.Windows.Media.Animation.QuadraticEase - { EasingMode = System.Windows.Media.Animation.EasingMode.EaseOut } }); + if (!IsLightweightLiveProgressMode(runTab)) + { + container.BeginAnimation(UIElement.OpacityProperty, + new DoubleAnimation(0, 1, TimeSpan.FromMilliseconds(260))); + ((TranslateTransform)container.RenderTransform).BeginAnimation( + TranslateTransform.YProperty, + new DoubleAnimation(8, 0, TimeSpan.FromMilliseconds(280)) + { EasingFunction = new System.Windows.Media.Animation.QuadraticEase + { EasingMode = System.Windows.Media.Animation.EasingMode.EaseOut } }); + } // 헤더: 펄싱 아이콘 + 에이전트 이름 + 경과 시간 var headerGrid = new Grid { Margin = new Thickness(2, 0, 0, 3) }; @@ -7057,10 +7062,13 @@ public partial class ChatWindow : Window headerGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); var liveIcon = CreateMiniLauncherIcon(pixelSize: 4.0); - liveIcon.BeginAnimation(UIElement.OpacityProperty, - new DoubleAnimation(1.0, 0.35, TimeSpan.FromMilliseconds(750)) - { AutoReverse = true, RepeatBehavior = System.Windows.Media.Animation.RepeatBehavior.Forever, - EasingFunction = new System.Windows.Media.Animation.SineEase() }); + if (!IsLightweightLiveProgressMode(runTab)) + { + liveIcon.BeginAnimation(UIElement.OpacityProperty, + new DoubleAnimation(1.0, 0.35, TimeSpan.FromMilliseconds(750)) + { AutoReverse = true, RepeatBehavior = System.Windows.Media.Animation.RepeatBehavior.Forever, + EasingFunction = new System.Windows.Media.Animation.SineEase() }); + } Grid.SetColumn(liveIcon, 0); headerGrid.Children.Add(liveIcon); @@ -7191,7 +7199,7 @@ public partial class ChatWindow : Window _agentLiveSubItemTexts.Clear(); _agentLiveCurrentCategory = null; - if (animated && MessagePanel != null && MessagePanel.Children.Contains(toRemove)) + if (animated && MessagePanel != null && MessagePanel.Children.Contains(toRemove) && !IsLightweightLiveProgressMode()) { var anim = new DoubleAnimation(toRemove.Opacity, 0, TimeSpan.FromMilliseconds(160)); anim.Completed += (_, _) => MessagePanel?.Children.Remove(toRemove);