- ChatWindow slash 이동 경로를 RenderSlashPage 기반에서 선택 하이라이트 갱신 기반으로 전환 - 휠/방향키/Home/End 이동 시 UpdateSlashSelectionVisualState + EnsureSlashSelectionVisible 호출로 통일 - 항목 hover 시에도 동일 선택 상태 동기화 경로를 사용해 체감 일관성 개선 - README.md, docs/DEVELOPMENT.md에 2026-04-04 14:01(KST) 기준 이력 반영 - 검증: dotnet build 0경고/0오류, 관련 필터 테스트 84건 통과
This commit is contained in:
@@ -222,7 +222,7 @@ public class MyHandler : IActionHandler
|
||||
|
||||
### v0.7.3 — AX Agent 권한 코어 재구성 + 입력 계층 정리
|
||||
|
||||
업데이트: 2026-04-04 13:55 (KST)
|
||||
업데이트: 2026-04-04 14:01 (KST)
|
||||
|
||||
| 분류 | 내용 |
|
||||
|------|------|
|
||||
@@ -281,6 +281,7 @@ public class MyHandler : IActionHandler
|
||||
| 탭별 설정 해석기 도입 | `AgentTabSettingsResolver`를 추가해 Cowork/Code 분기(검증 활성/Code 전용 도구 비활성)를 단일 경로로 정리 |
|
||||
| L4 통합 회귀 보강 | `PermissionModeCatalogTests`/`PermissionModePresentationCatalogTests`/`SlashCommandCatalogTests`를 추가하고 deny 우선 규칙을 `OperationModePolicyTests`에 반영해 권한·슬래시 회귀망을 강화 |
|
||||
| 권한 팝업 핵심 4모드 정렬 | 권한 팝업을 `소극 활용/적극 활용/계획 중심/완전 자동` 중심으로 단순화하고 `활용하지 않음/질문 없이 진행`은 `고급 모드` 접힘 섹션으로 분리 |
|
||||
| slash 스크롤 체감 개선 | 휠/방향키 이동 시 전체 재렌더링을 제거하고 선택 하이라이트만 갱신하도록 바꿔 `/` 팝업 스크롤 반응성과 안정성을 개선 |
|
||||
| Slash palette 상태 분리 시작 | `ChatWindow`에 몰려 있던 slash 상태를 `SlashPaletteState`로 분리해 이후 Codex/Claude형 composer 개편 기반 마련 |
|
||||
| 런처 이미지 미리보기 추가 | `#` 클립보드 이미지 항목에서 `Shift+Enter`로 전용 미리보기 창을 열고, 줌·원본 해상도 확인·PNG/JPEG/BMP 저장·클립보드 복사를 지원 |
|
||||
| 검증 | `dotnet build` 경고 0 / 오류 0, `dotnet test` 436 passed / 0 failed |
|
||||
|
||||
@@ -3413,3 +3413,20 @@ else:
|
||||
- `dotnet build src/AxCopilot/AxCopilot.csproj -c Debug -p:UseSharedCompilation=false -nodeReuse:false` 통과 (경고 0, 오류 0).
|
||||
- 테스트 재빌드 시 WPF 임시 생성물 누락(CS2001, `AxCopilot_*_wpftmp.csproj`)이 간헐 발생하여 다음으로 회귀 확인:
|
||||
- `dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj --no-build --filter "FullyQualifiedName~ChatWindowSlashPolicyTests|FullyQualifiedName~OperationModePolicyTests|FullyQualifiedName~PermissionModeCatalogTests|FullyQualifiedName~PermissionModePresentationCatalogTests|FullyQualifiedName~OperationModeReadinessTests"` 통과 (86 passed, 0 failed).
|
||||
|
||||
## 2026-04-04 추가 진행 기록 (연속 실행 31차: slash 팝업 스크롤/선택 체감 개선)
|
||||
|
||||
업데이트: 2026-04-04 14:01 (KST)
|
||||
|
||||
### 1) slash 이동 시 재렌더링 제거
|
||||
- 기존: 휠/방향키 이동마다 `RenderSlashPage()`를 호출해 전체 항목을 다시 그림.
|
||||
- 변경: 이동 시 `UpdateSlashSelectionVisualState()` + `EnsureSlashSelectionVisible()`만 호출하도록 전환.
|
||||
- 효과: 스크롤 시 깜빡임/점프를 줄이고 선택 이동 체감이 더 부드러워짐.
|
||||
|
||||
### 2) 선택 하이라이트 동기화 경로 정리
|
||||
- 항목 Hover/Home/End 이동에서 동일한 하이라이트 갱신 경로를 사용하도록 통일.
|
||||
- 목록 재렌더가 필요한 경우(그룹 접힘/펼침, 검색 결과 변경)만 `RenderSlashPage()` 유지.
|
||||
|
||||
### 3) 품질 게이트
|
||||
- `dotnet build src/AxCopilot/AxCopilot.csproj -c Debug -p:UseSharedCompilation=false -nodeReuse:false` 통과 (경고 0, 오류 0).
|
||||
- `dotnet test src/AxCopilot.Tests/AxCopilot.Tests.csproj --no-build --filter "FullyQualifiedName~ChatWindowSlashPolicyTests|FullyQualifiedName~SlashCommandCatalogTests|FullyQualifiedName~OperationModePolicyTests|FullyQualifiedName~PermissionModeCatalogTests|FullyQualifiedName~PermissionModePresentationCatalogTests"` 통과 (84 passed, 0 failed).
|
||||
|
||||
@@ -5315,7 +5315,6 @@ public partial class ChatWindow : Window
|
||||
var skillAvailable = skillDef?.IsAvailable ?? true;
|
||||
|
||||
var absoluteIndex = i;
|
||||
var isSelected = absoluteIndex == _slashPalette.SelectedIndex;
|
||||
var hoverBrushItem = TryFindResource("ItemHoverBackground") as Brush ?? Brushes.LightGray;
|
||||
var itemBg = TryFindResource("ItemBackground") as Brush ?? Brushes.Transparent;
|
||||
var borderBrush = TryFindResource("BorderColor") as Brush ?? Brushes.Gray;
|
||||
@@ -5325,8 +5324,8 @@ public partial class ChatWindow : Window
|
||||
|
||||
var item = new Border
|
||||
{
|
||||
Background = isSelected ? hoverBrushItem : itemBg,
|
||||
BorderBrush = isSelected ? accent : borderBrush,
|
||||
Background = Brushes.Transparent,
|
||||
BorderBrush = borderBrush,
|
||||
BorderThickness = new Thickness(1),
|
||||
CornerRadius = new CornerRadius(10),
|
||||
Padding = new Thickness(10, 7, 10, 7),
|
||||
@@ -5440,14 +5439,9 @@ public partial class ChatWindow : Window
|
||||
item.MouseEnter += (_, _) =>
|
||||
{
|
||||
_slashPalette.SelectedIndex = absoluteIndex;
|
||||
item.Background = hoverBrushItem;
|
||||
item.BorderBrush = accent;
|
||||
};
|
||||
item.MouseLeave += (_, _) =>
|
||||
{
|
||||
item.Background = absoluteIndex == _slashPalette.SelectedIndex ? hoverBrushItem : itemBg;
|
||||
item.BorderBrush = absoluteIndex == _slashPalette.SelectedIndex ? accent : borderBrush;
|
||||
UpdateSlashSelectionVisualState();
|
||||
};
|
||||
item.MouseLeave += (_, _) => UpdateSlashSelectionVisualState();
|
||||
item.MouseLeftButtonDown += (_, _) =>
|
||||
{
|
||||
_slashPalette.SelectedIndex = absoluteIndex;
|
||||
@@ -5499,6 +5493,7 @@ public partial class ChatWindow : Window
|
||||
SlashPopupFooter.Text = $"Enter 실행 · ↑↓/PgUp/PgDn 이동 · Home/End · Esc 닫기 · 표시 {visibleCommandCount + visibleSkillCount}/{total}";
|
||||
}
|
||||
|
||||
UpdateSlashSelectionVisualState();
|
||||
EnsureSlashSelectionVisible();
|
||||
}
|
||||
|
||||
@@ -5546,7 +5541,8 @@ public partial class ChatWindow : Window
|
||||
for (var i = 0; i < steps; i++)
|
||||
MoveSlashSelection(direction);
|
||||
|
||||
RenderSlashPage();
|
||||
UpdateSlashSelectionVisualState();
|
||||
EnsureSlashSelectionVisible();
|
||||
}
|
||||
|
||||
/// <summary>키보드로 선택된 슬래시 아이템을 실행합니다.</summary>
|
||||
@@ -5591,6 +5587,28 @@ public partial class ChatWindow : Window
|
||||
SlashScrollViewer.ScrollToVerticalOffset(SlashScrollViewer.VerticalOffset + (bounds.Bottom - SlashScrollViewer.ViewportHeight) + 8);
|
||||
}
|
||||
|
||||
private void UpdateSlashSelectionVisualState()
|
||||
{
|
||||
if (_slashVisibleItemByAbsoluteIndex.Count == 0)
|
||||
return;
|
||||
|
||||
var selectedIndex = _slashPalette.SelectedIndex;
|
||||
var itemBg = TryFindResource("ItemBackground") as Brush ?? Brushes.Transparent;
|
||||
var hoverBrushItem = TryFindResource("ItemHoverBackground") as Brush ?? Brushes.LightGray;
|
||||
var borderBrush = TryFindResource("BorderColor") as Brush ?? Brushes.Gray;
|
||||
var accent = TryFindResource("AccentColor") as Brush ?? Brushes.Blue;
|
||||
|
||||
foreach (var (absoluteIndex, element) in _slashVisibleItemByAbsoluteIndex)
|
||||
{
|
||||
if (element is not Border border)
|
||||
continue;
|
||||
|
||||
var selected = absoluteIndex == selectedIndex;
|
||||
border.Background = selected ? hoverBrushItem : itemBg;
|
||||
border.BorderBrush = selected ? accent : borderBrush;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>슬래시 명령어 즐겨찾기를 토글하고 설정을 저장합니다.</summary>
|
||||
private void ToggleSlashFavorite(string cmd)
|
||||
{
|
||||
@@ -10881,14 +10899,16 @@ public partial class ChatWindow : Window
|
||||
{
|
||||
var visible = GetVisibleSlashOrderedIndices();
|
||||
_slashPalette.SelectedIndex = visible.Count > 0 ? visible[0] : GetFirstVisibleSlashIndex(_slashPalette.Matches);
|
||||
RenderSlashPage();
|
||||
UpdateSlashSelectionVisualState();
|
||||
EnsureSlashSelectionVisible();
|
||||
e.Handled = true;
|
||||
}
|
||||
else if (e.Key == Key.End)
|
||||
{
|
||||
var visible = GetVisibleSlashOrderedIndices();
|
||||
_slashPalette.SelectedIndex = visible.Count > 0 ? visible[^1] : GetFirstVisibleSlashIndex(_slashPalette.Matches);
|
||||
RenderSlashPage();
|
||||
UpdateSlashSelectionVisualState();
|
||||
EnsureSlashSelectionVisible();
|
||||
e.Handled = true;
|
||||
}
|
||||
else if (e.Key == Key.Enter && _slashPalette.SelectedIndex >= 0)
|
||||
|
||||
Reference in New Issue
Block a user