Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions apps/desktop/e2e/settings.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,41 @@ test('settings hides expanded workbar chrome and restores it on close', async ({
await expect(workbarToolbar).toBeVisible();
await expect(taskTab).toBeVisible();
});

test('wide settings gutters scroll the whole main pane', async ({ window: page }) => {
await page.setViewportSize({ width: 1600, height: 520 });
await page.getByRole('button', { name: '设置' }).click();
await page.getByRole('button', { name: '通用', exact: true }).click();
await expect(page.getByRole('textbox', { name: '助手语气偏好' })).toBeEnabled();

const pane = page.locator('.settingsMainPane');
const content = pane.locator('.settingsPageStack').first();
const geometry = await pane.evaluate((element) => {
const paneRect = element.getBoundingClientRect();
const contentElement = element.querySelector('.settingsPageStack');
const contentRect = contentElement?.getBoundingClientRect();
const layoutContent = element.querySelector('.astryx-layout-content');
if (!contentRect || !layoutContent) throw new Error('Settings layout is incomplete');
return {
blankRight: paneRect.right - contentRect.right,
clientHeight: element.clientHeight,
contentOverflowY: getComputedStyle(layoutContent).overflowY,
paneOverflowY: getComputedStyle(element).overflowY,
scrollHeight: element.scrollHeight,
wheelPoint: {
x: Math.floor((contentRect.right + paneRect.right) / 2),
y: Math.floor(Math.min(contentRect.top + 120, paneRect.bottom - 40)),
},
};
});

expect(geometry.blankRight).toBeGreaterThan(40);
expect(geometry.scrollHeight).toBeGreaterThan(geometry.clientHeight);
expect(geometry.contentOverflowY).not.toBe('auto');
expect(geometry.paneOverflowY).toBe('auto');

await page.mouse.move(geometry.wheelPoint.x, geometry.wheelPoint.y);
await page.mouse.wheel(0, 600);
await expect.poll(() => pane.evaluate((element) => element.scrollTop)).toBeGreaterThan(0);
await expect(content).toBeVisible();
});
7 changes: 5 additions & 2 deletions apps/desktop/src/renderer/settings/settings-surface.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,10 @@ export function SettingsSurface(props: {
aria-label={copy.contentLabel}
>
<Layout
height="fill"
/* The rounded main pane owns page scrolling. Keeping scroll on
the centered LayoutContent made the wide gutters inert and
parked the scrollbar beside the 920px content column. */
height="auto"
padding={0}
/* One column width for EVERY section. Usage used to get 920
while the rest sat in a 640 column, so switching pages
Expand Down Expand Up @@ -709,7 +712,7 @@ export function SettingsSurface(props: {
</LayoutHeader>
)}
content={(
<LayoutContent padding={6}>
<LayoutContent padding={6} isScrollable={false}>
{loading ? (
<SettingsSkeleton />
) : requiresRuntimeHost && runtimeHostContentStatus === 'error' ? (
Expand Down
6 changes: 5 additions & 1 deletion apps/desktop/src/renderer/styles/settings/nav-sidebar.css
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,11 @@
border: 0;
border-radius: var(--radius-modal);
background: var(--agents-content-area-bg);
overflow: hidden;
/* The pane, not the centered 920px column, is the page scroll owner. This
lets wheel input from either wide gutter scroll and keeps the native
scrollbar against the pane's outer edge. */
overflow-x: hidden;
overflow-y: auto;
}

.settingsPageHeader {
Expand Down
4 changes: 2 additions & 2 deletions apps/desktop/stories/settings/provider-settings.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ function ProviderStoryFrame(props: {
window's width and hides exactly the layout question a page-level
form raises. */}
<Layout
height="fill"
height="auto"
padding={0}
contentWidth={920}
header={(
Expand All @@ -343,7 +343,7 @@ function ProviderStoryFrame(props: {
</LayoutHeader>
)}
content={(
<LayoutContent padding={6}>
<LayoutContent padding={6} isScrollable={false}>
<SettingsPage className="settingsModelsPage">
<ProvidersPanel bridge={props.bridge} />
</SettingsPage>
Expand Down