권한 순환/슬래시 스크롤 체감 보강: claw-code 기준 코어 모드 정렬
Some checks failed
Release Gate / gate (push) Has been cancelled
Some checks failed
Release Gate / gate (push) Has been cancelled
- ChatWindow.NextPermission 순환을 Deny->Default->AcceptEdits->Plan->BypassPermissions->Deny로 정렬하고 DontAsk는 기본 순환에서 제외\n- AgentSettingsWindow 권한 모드 버튼 순환도 동일 코어 순환으로 맞춰 인라인/설정 체계를 일관화\n- SlashPopup_ScrollByDelta 개선: ScrollViewer 오프셋 이동 + 뷰포트 상단 기준 선택 동기화로 휠 스크롤 체감 개선\n- ChatWindowSlashPolicyTests에 NextPermission 순환 회귀 테스트 추가(Bypass/DontAsk 포함)\n- README.md, docs/DEVELOPMENT.md에 2026-04-04 17:27(KST) 이력 및 검증 결과 기록\n- 검증: dotnet build 경고0/오류0, dotnet test 필터 65 passed
This commit is contained in:
@@ -5574,6 +5574,40 @@ public partial class ChatWindow : Window
|
||||
_slashPalette.SelectedIndex = visibleOrder[currentPosition + 1];
|
||||
}
|
||||
|
||||
private int? FindSlashIndexClosestToViewportTop()
|
||||
{
|
||||
if (SlashScrollViewer == null || _slashVisibleAbsoluteOrder.Count == 0)
|
||||
return null;
|
||||
|
||||
var bestIndex = -1;
|
||||
var bestDistance = double.MaxValue;
|
||||
foreach (var absoluteIndex in _slashVisibleAbsoluteOrder)
|
||||
{
|
||||
if (!_slashVisibleItemByAbsoluteIndex.TryGetValue(absoluteIndex, out var item))
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
var bounds = item.TransformToAncestor(SlashScrollViewer)
|
||||
.TransformBounds(new Rect(0, 0, item.ActualWidth, item.ActualHeight));
|
||||
|
||||
// 뷰포트 상단에 가장 가까운 가시 항목을 선택 기준으로 사용.
|
||||
var distance = Math.Abs(bounds.Top);
|
||||
if (distance < bestDistance && bounds.Bottom >= 0)
|
||||
{
|
||||
bestDistance = distance;
|
||||
bestIndex = absoluteIndex;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 레이아웃 갱신 중 transform 예외는 무시.
|
||||
}
|
||||
}
|
||||
|
||||
return bestIndex >= 0 ? bestIndex : null;
|
||||
}
|
||||
|
||||
/// <summary>슬래시 팝업을 Delta 방향으로 스크롤합니다.</summary>
|
||||
private void SlashPopup_ScrollByDelta(int delta)
|
||||
{
|
||||
@@ -5587,11 +5621,24 @@ public partial class ChatWindow : Window
|
||||
return;
|
||||
}
|
||||
|
||||
var steps = Math.Max(1, Math.Abs(delta) / 120);
|
||||
// 터치패드/마우스 환경 모두에서 체감이 유사하도록 스크롤뷰도 함께 이동.
|
||||
if (SlashScrollViewer != null)
|
||||
{
|
||||
var target = Math.Max(0, Math.Min(
|
||||
SlashScrollViewer.ScrollableHeight,
|
||||
SlashScrollViewer.VerticalOffset - (delta / 3.0)));
|
||||
SlashScrollViewer.ScrollToVerticalOffset(target);
|
||||
}
|
||||
|
||||
var steps = Math.Max(1, (int)Math.Ceiling(Math.Abs(delta) / 120.0));
|
||||
var direction = delta > 0 ? -1 : 1;
|
||||
for (var i = 0; i < steps; i++)
|
||||
MoveSlashSelection(direction);
|
||||
|
||||
var viewportTopIndex = FindSlashIndexClosestToViewportTop();
|
||||
if (viewportTopIndex.HasValue)
|
||||
_slashPalette.SelectedIndex = viewportTopIndex.Value;
|
||||
|
||||
UpdateSlashSelectionVisualState();
|
||||
EnsureSlashSelectionVisible();
|
||||
}
|
||||
@@ -12842,7 +12889,10 @@ public partial class ChatWindow : Window
|
||||
"default" => "AcceptEdits",
|
||||
"acceptedits" => "Plan",
|
||||
"plan" => "BypassPermissions",
|
||||
"bypasspermissions" => "DontAsk",
|
||||
// claw-code 기준: 기본 순환은 코어 모드까지만 이동하고,
|
||||
// dontAsk는 명시 선택(고급 모드)으로만 진입.
|
||||
"bypasspermissions" => "Deny",
|
||||
"dontask" => "Deny",
|
||||
_ => "Deny",
|
||||
};
|
||||
private static string ServiceLabel(string service) => (service ?? "").ToLowerInvariant() switch
|
||||
|
||||
Reference in New Issue
Block a user