add synchronized dual-display workbench
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
export interface SecondaryDisplayGeometry {
|
||||
left: number
|
||||
top: number
|
||||
width: number
|
||||
height: number
|
||||
}
|
||||
|
||||
function boundedInteger(value: unknown, minimum: number, maximum: number): number | null {
|
||||
const parsed = typeof value === 'number' ? value : Number(value)
|
||||
if (!Number.isFinite(parsed)) return null
|
||||
return Math.min(maximum, Math.max(minimum, Math.round(parsed)))
|
||||
}
|
||||
|
||||
export function parseSecondaryDisplayGeometry(value: string | null): SecondaryDisplayGeometry | null {
|
||||
if (!value) return null
|
||||
try {
|
||||
const parsed = JSON.parse(value) as Partial<SecondaryDisplayGeometry>
|
||||
const left = boundedInteger(parsed.left, -20_000, 20_000)
|
||||
const top = boundedInteger(parsed.top, -20_000, 20_000)
|
||||
const width = boundedInteger(parsed.width, 420, 3_840)
|
||||
const height = boundedInteger(parsed.height, 520, 2_160)
|
||||
return left === null || top === null || width === null || height === null
|
||||
? null
|
||||
: { left, top, width, height }
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export function secondaryDisplayFeatures(geometry: SecondaryDisplayGeometry): string {
|
||||
return [
|
||||
'popup=yes',
|
||||
`left=${geometry.left}`,
|
||||
`top=${geometry.top}`,
|
||||
`width=${geometry.width}`,
|
||||
`height=${geometry.height}`,
|
||||
'resizable=yes',
|
||||
'scrollbars=yes',
|
||||
].join(',')
|
||||
}
|
||||
Reference in New Issue
Block a user