mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-07-20 12:21:54 +08:00
🐛 fix(window): 适配分辨率变化后的窗口边界
- 运行期检测普通窗口是否超出当前可用屏幕并自动收回 - 启动恢复时同步裁剪超过当前屏幕的窗口尺寸 Fixes #594
This commit is contained in:
@@ -23,4 +23,18 @@ describe('windowRestoreBounds', () => {
|
||||
{ availWidth: 1600, availHeight: 900, availLeft: 0, availTop: 0 },
|
||||
)).toEqual({ width: 900, height: 640, x: 350, y: 130 });
|
||||
});
|
||||
|
||||
it('shrinks a restored window that is larger than the current visible screen', () => {
|
||||
expect(resolveVisibleStartupWindowBounds(
|
||||
{ width: 2560, height: 1440, x: 0, y: 0 },
|
||||
{ availWidth: 1440, availHeight: 860, availLeft: 0, availTop: 25 },
|
||||
)).toEqual({ width: 1440, height: 860, x: 0, y: 25 });
|
||||
});
|
||||
|
||||
it('keeps oversized restored bounds inside an offset visible screen', () => {
|
||||
expect(resolveVisibleStartupWindowBounds(
|
||||
{ width: 2400, height: 1200, x: 1800, y: 60 },
|
||||
{ availWidth: 1728, availHeight: 1040, availLeft: 1728, availTop: 40 },
|
||||
)).toEqual({ width: 1728, height: 1040, x: 1728, y: 40 });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,6 +14,31 @@ type VisibleViewport = {
|
||||
|
||||
const MIN_VISIBLE_WIDTH = 160;
|
||||
const MIN_VISIBLE_HEIGHT = 120;
|
||||
const MIN_RESTORED_WIDTH = 400;
|
||||
const MIN_RESTORED_HEIGHT = 300;
|
||||
|
||||
const resolveVisibleDimension = (
|
||||
rawDimension: number,
|
||||
visibleDimension: number,
|
||||
minimumDimension: number,
|
||||
): number => {
|
||||
const dimension = Math.trunc(Number(rawDimension) || 0);
|
||||
if (visibleDimension <= 0 || dimension <= 0) {
|
||||
return dimension;
|
||||
}
|
||||
const minimum = Math.min(minimumDimension, visibleDimension);
|
||||
return Math.min(Math.max(dimension, minimum), visibleDimension);
|
||||
};
|
||||
|
||||
const clampPosition = (
|
||||
position: number,
|
||||
dimension: number,
|
||||
visibleStart: number,
|
||||
visibleDimension: number,
|
||||
): number => {
|
||||
const maxPosition = visibleStart + Math.max(0, visibleDimension - dimension);
|
||||
return Math.min(Math.max(position, visibleStart), maxPosition);
|
||||
};
|
||||
|
||||
export const resolveVisibleStartupWindowBounds = (
|
||||
bounds: WindowRestoreBounds,
|
||||
@@ -29,19 +54,36 @@ export const resolveVisibleStartupWindowBounds = (
|
||||
const visibleTop = Math.trunc(Number(viewport.availTop) || 0);
|
||||
const visibleRight = visibleLeft + visibleWidth;
|
||||
const visibleBottom = visibleTop + visibleHeight;
|
||||
const nextWidth = resolveVisibleDimension(bounds.width, visibleWidth, MIN_RESTORED_WIDTH);
|
||||
const nextHeight = resolveVisibleDimension(bounds.height, visibleHeight, MIN_RESTORED_HEIGHT);
|
||||
const resizedBounds: WindowRestoreBounds = {
|
||||
...bounds,
|
||||
width: nextWidth,
|
||||
height: nextHeight,
|
||||
};
|
||||
|
||||
const overlapWidth = Math.min(bounds.x + bounds.width, visibleRight) - Math.max(bounds.x, visibleLeft);
|
||||
const overlapHeight = Math.min(bounds.y + bounds.height, visibleBottom) - Math.max(bounds.y, visibleTop);
|
||||
const overlapWidth = Math.min(resizedBounds.x + resizedBounds.width, visibleRight) - Math.max(resizedBounds.x, visibleLeft);
|
||||
const overlapHeight = Math.min(resizedBounds.y + resizedBounds.height, visibleBottom) - Math.max(resizedBounds.y, visibleTop);
|
||||
const sizeChanged = resizedBounds.width !== bounds.width || resizedBounds.height !== bounds.height;
|
||||
if (
|
||||
!sizeChanged &&
|
||||
overlapWidth >= Math.min(MIN_VISIBLE_WIDTH, bounds.width) &&
|
||||
overlapHeight >= Math.min(MIN_VISIBLE_HEIGHT, bounds.height)
|
||||
) {
|
||||
return bounds;
|
||||
}
|
||||
|
||||
if (sizeChanged && overlapWidth > 0 && overlapHeight > 0) {
|
||||
return {
|
||||
...resizedBounds,
|
||||
x: clampPosition(resizedBounds.x, resizedBounds.width, visibleLeft, visibleWidth),
|
||||
y: clampPosition(resizedBounds.y, resizedBounds.height, visibleTop, visibleHeight),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
...bounds,
|
||||
x: visibleLeft + Math.max(0, Math.trunc((visibleWidth - bounds.width) / 2)),
|
||||
y: visibleTop + Math.max(0, Math.trunc((visibleHeight - bounds.height) / 2)),
|
||||
...resizedBounds,
|
||||
x: visibleLeft + Math.max(0, Math.trunc((visibleWidth - resizedBounds.width) / 2)),
|
||||
y: visibleTop + Math.max(0, Math.trunc((visibleHeight - resizedBounds.height) / 2)),
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user