AX Agent 창 드래그 성능 개선 및 레이아웃 재계산 지연 처리
Some checks failed
Release Gate / gate (push) Has been cancelled
Some checks failed
Release Gate / gate (push) Has been cancelled
- ChatWindow에 WM_ENTERSIZEMOVE/WM_EXITSIZEMOVE 감지를 추가해 창 이동·리사이즈 루프를 별도로 관리함 - 이동 중에는 루트 visual을 BitmapCache로 전환하고 무거운 transcript/layout 재계산을 지연시켜 드래그 버벅임을 줄임 - SizeChanged에서 주제 스크롤/반응형 레이아웃/메시지 재렌더를 즉시 수행하지 않고 종료 시 한 번만 반영하도록 정리함 - README와 DEVELOPMENT 문서에 변경 목적과 검증 결과를 로컬 시각 기준으로 기록함 - 검증: dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\ (경고 0, 오류 0)
This commit is contained in:
@@ -35,6 +35,9 @@ public partial class ChatWindow : Window
|
||||
private bool _isStreaming;
|
||||
private bool _sidebarVisible = true;
|
||||
private double _sidebarExpandedWidth = 262;
|
||||
private bool _isInWindowMoveSizeLoop;
|
||||
private bool _pendingResponsiveLayoutRefresh;
|
||||
private CacheMode? _cachedRootCacheModeBeforeMove;
|
||||
private string _selectedCategory = ""; // "" = 전체
|
||||
private readonly Dictionary<string, string> _tabSelectedCategory = new(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
@@ -274,6 +277,9 @@ public partial class ChatWindow : Window
|
||||
KeyDown += ChatWindow_KeyDown;
|
||||
MouseMove += (_, _) =>
|
||||
{
|
||||
if (_isInWindowMoveSizeLoop)
|
||||
return;
|
||||
|
||||
if (TokenUsagePopup?.IsOpen == true)
|
||||
CloseTokenUsagePopupIfIdle();
|
||||
};
|
||||
@@ -389,6 +395,12 @@ public partial class ChatWindow : Window
|
||||
};
|
||||
SizeChanged += (_, _) =>
|
||||
{
|
||||
if (_isInWindowMoveSizeLoop)
|
||||
{
|
||||
_pendingResponsiveLayoutRefresh = true;
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateTopicPresetScrollMode();
|
||||
if (UpdateResponsiveChatLayout())
|
||||
RenderMessages(preserveViewport: true);
|
||||
@@ -1067,6 +1079,15 @@ public partial class ChatWindow : Window
|
||||
|
||||
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
|
||||
{
|
||||
if (msg == 0x0231) // WM_ENTERSIZEMOVE
|
||||
{
|
||||
BeginWindowMoveSizeLoop();
|
||||
}
|
||||
else if (msg == 0x0232) // WM_EXITSIZEMOVE
|
||||
{
|
||||
EndWindowMoveSizeLoop();
|
||||
}
|
||||
|
||||
// WM_GETMINMAXINFO — 최대화 시 작업 표시줄 영역 확보
|
||||
if (msg == 0x0024)
|
||||
{
|
||||
@@ -1087,6 +1108,42 @@ public partial class ChatWindow : Window
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
private void BeginWindowMoveSizeLoop()
|
||||
{
|
||||
if (_isInWindowMoveSizeLoop)
|
||||
return;
|
||||
|
||||
_isInWindowMoveSizeLoop = true;
|
||||
_pendingResponsiveLayoutRefresh = false;
|
||||
|
||||
if (Content is UIElement rootElement)
|
||||
{
|
||||
_cachedRootCacheModeBeforeMove = rootElement.CacheMode;
|
||||
rootElement.CacheMode = new BitmapCache();
|
||||
}
|
||||
}
|
||||
|
||||
private void EndWindowMoveSizeLoop()
|
||||
{
|
||||
if (!_isInWindowMoveSizeLoop)
|
||||
return;
|
||||
|
||||
_isInWindowMoveSizeLoop = false;
|
||||
|
||||
if (Content is UIElement rootElement)
|
||||
rootElement.CacheMode = _cachedRootCacheModeBeforeMove;
|
||||
|
||||
_cachedRootCacheModeBeforeMove = null;
|
||||
|
||||
if (_pendingResponsiveLayoutRefresh)
|
||||
{
|
||||
_pendingResponsiveLayoutRefresh = false;
|
||||
UpdateTopicPresetScrollMode();
|
||||
if (UpdateResponsiveChatLayout())
|
||||
RenderMessages(preserveViewport: true);
|
||||
}
|
||||
}
|
||||
|
||||
private void BtnMinimize_Click(object sender, RoutedEventArgs e) => WindowState = WindowState.Minimized;
|
||||
private void BtnMaximize_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user