feat(FN-4939): complete Step 1 — add window-state display clamp helper
Fusion-Task-Id: FN-4939 Fusion-Task-Lineage: b2a00edb-5245-4223-97e4-0a16dd2c3289
This commit is contained in:
committed by
gsxdsm
parent
bd48f1961c
commit
e257ca6603
@@ -425,6 +425,72 @@ describe("native integrations", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("clampWindowStateToVisibleDisplay", () => {
|
||||
const baseState = {
|
||||
x: 100,
|
||||
y: 100,
|
||||
width: 800,
|
||||
height: 600,
|
||||
isMaximized: false,
|
||||
};
|
||||
|
||||
it("passes through when x/y are undefined", async () => {
|
||||
const { clampWindowStateToVisibleDisplay } = await importNativeModule();
|
||||
const state = { width: 800, height: 600, isMaximized: false };
|
||||
|
||||
expect(clampWindowStateToVisibleDisplay(state, [{ workArea: { x: 0, y: 0, width: 1920, height: 1080 } }])).toEqual(
|
||||
state,
|
||||
);
|
||||
});
|
||||
|
||||
it("passes through when fully on screen", async () => {
|
||||
const { clampWindowStateToVisibleDisplay } = await importNativeModule();
|
||||
|
||||
expect(
|
||||
clampWindowStateToVisibleDisplay(baseState, [{ workArea: { x: 0, y: 0, width: 1920, height: 1080 } }]),
|
||||
).toEqual(baseState);
|
||||
});
|
||||
|
||||
it("drops position when fully off-screen", async () => {
|
||||
const { clampWindowStateToVisibleDisplay } = await importNativeModule();
|
||||
const state = { ...baseState, x: -3000, y: -2000 };
|
||||
|
||||
expect(
|
||||
clampWindowStateToVisibleDisplay(state, [{ workArea: { x: 0, y: 0, width: 1920, height: 1080 } }]),
|
||||
).toEqual({ width: 800, height: 600, isMaximized: false });
|
||||
});
|
||||
|
||||
it("drops position when overlap is below 64x64 threshold", async () => {
|
||||
const { clampWindowStateToVisibleDisplay } = await importNativeModule();
|
||||
const state = { ...baseState, x: 1870, y: 1030 };
|
||||
|
||||
expect(
|
||||
clampWindowStateToVisibleDisplay(state, [{ workArea: { x: 0, y: 0, width: 1920, height: 1080 } }]),
|
||||
).toEqual({ width: 800, height: 600, isMaximized: false });
|
||||
});
|
||||
|
||||
it("keeps position when overlap meets 64x64 threshold", async () => {
|
||||
const { clampWindowStateToVisibleDisplay } = await importNativeModule();
|
||||
const state = { ...baseState, x: 1856, y: 1016 };
|
||||
|
||||
expect(
|
||||
clampWindowStateToVisibleDisplay(state, [{ workArea: { x: 0, y: 0, width: 1920, height: 1080 } }]),
|
||||
).toEqual(state);
|
||||
});
|
||||
|
||||
it("keeps position when overlap is on a secondary display", async () => {
|
||||
const { clampWindowStateToVisibleDisplay } = await importNativeModule();
|
||||
const state = { ...baseState, x: 2000, y: 100 };
|
||||
|
||||
expect(
|
||||
clampWindowStateToVisibleDisplay(state, [
|
||||
{ workArea: { x: 0, y: 0, width: 1920, height: 1080 } },
|
||||
{ workArea: { x: 1920, y: 0, width: 1920, height: 1080 } },
|
||||
]),
|
||||
).toEqual(state);
|
||||
});
|
||||
});
|
||||
|
||||
describe("window state", () => {
|
||||
it("loadWindowState returns parsed state", async () => {
|
||||
const { loadWindowState } = await importNativeModule();
|
||||
|
||||
@@ -17,6 +17,53 @@ export interface WindowState {
|
||||
isMaximized: boolean;
|
||||
}
|
||||
|
||||
export interface DisplayWorkAreaLike {
|
||||
workArea: {
|
||||
x: number;
|
||||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
};
|
||||
}
|
||||
|
||||
const MIN_VISIBLE_OVERLAP_PX = 64;
|
||||
|
||||
export function clampWindowStateToVisibleDisplay(
|
||||
state: WindowState,
|
||||
displays: DisplayWorkAreaLike[],
|
||||
): WindowState {
|
||||
if (state.x === undefined || state.y === undefined) {
|
||||
return state;
|
||||
}
|
||||
|
||||
const windowLeft = state.x;
|
||||
const windowTop = state.y;
|
||||
const windowRight = state.x + state.width;
|
||||
const windowBottom = state.y + state.height;
|
||||
|
||||
const hasSufficientOverlap = displays.some(({ workArea }) => {
|
||||
const displayLeft = workArea.x;
|
||||
const displayTop = workArea.y;
|
||||
const displayRight = workArea.x + workArea.width;
|
||||
const displayBottom = workArea.y + workArea.height;
|
||||
|
||||
const overlapWidth = Math.max(0, Math.min(windowRight, displayRight) - Math.max(windowLeft, displayLeft));
|
||||
const overlapHeight = Math.max(0, Math.min(windowBottom, displayBottom) - Math.max(windowTop, displayTop));
|
||||
|
||||
return overlapWidth >= MIN_VISIBLE_OVERLAP_PX && overlapHeight >= MIN_VISIBLE_OVERLAP_PX;
|
||||
});
|
||||
|
||||
if (hasSufficientOverlap) {
|
||||
return state;
|
||||
}
|
||||
|
||||
return {
|
||||
width: state.width,
|
||||
height: state.height,
|
||||
isMaximized: state.isMaximized,
|
||||
};
|
||||
}
|
||||
|
||||
export type DesktopLaunchMode = "choose" | "local" | "remote";
|
||||
|
||||
export interface DesktopRemoteProfileLike {
|
||||
|
||||
Reference in New Issue
Block a user