110 lines
3.2 KiB
TypeScript
110 lines
3.2 KiB
TypeScript
import { screen } from "electron";
|
|
|
|
function ensureWindowOnScreen(
|
|
x: number | undefined,
|
|
y: number | undefined,
|
|
windowWidth: number,
|
|
windowHeight: number,
|
|
): { validX: number | undefined; validY: number | undefined } {
|
|
// If no coordinates stored, let Electron position window automatically
|
|
if (x === undefined || y === undefined) {
|
|
return { validX: undefined, validY: undefined };
|
|
}
|
|
|
|
const displays = screen.getAllDisplays();
|
|
|
|
// Minimum visible pixels required on each edge to be considered "visible enough"
|
|
const MIN_VISIBLE = 50; // Ensure at least 50px from each edge is visible
|
|
|
|
// Try to find a display where the window would be almost fully visible
|
|
for (const display of displays) {
|
|
const { bounds } = display;
|
|
|
|
// Check if window is mostly within this display
|
|
if (
|
|
x + MIN_VISIBLE >= bounds.x &&
|
|
x + windowWidth - MIN_VISIBLE <= bounds.x + bounds.width &&
|
|
y + MIN_VISIBLE >= bounds.y &&
|
|
y + windowHeight - MIN_VISIBLE <= bounds.y + bounds.height
|
|
) {
|
|
// Window is adequately visible on this display
|
|
return { validX: x, validY: y };
|
|
}
|
|
}
|
|
|
|
// If window isn't adequately visible on any display, try to adjust it to fit the closest display
|
|
const closestDisplay = findClosestDisplay(displays, x, y);
|
|
const { bounds } = closestDisplay;
|
|
|
|
// Adjust position to ensure window is fully on screen
|
|
let adjustedX = x;
|
|
let adjustedY = y;
|
|
|
|
// Adjust horizontal position if needed
|
|
if (x < bounds.x) {
|
|
adjustedX = bounds.x;
|
|
} else if (x + windowWidth > bounds.x + bounds.width) {
|
|
adjustedX = bounds.x + bounds.width - windowWidth;
|
|
}
|
|
|
|
// Adjust vertical position if needed
|
|
if (y < bounds.y) {
|
|
adjustedY = bounds.y;
|
|
} else if (y + windowHeight > bounds.y + bounds.height) {
|
|
adjustedY = bounds.y + bounds.height - windowHeight;
|
|
}
|
|
|
|
// If adjustments keep window on screen, use adjusted position
|
|
if (
|
|
adjustedX >= bounds.x &&
|
|
adjustedX + windowWidth <= bounds.x + bounds.width &&
|
|
adjustedY >= bounds.y &&
|
|
adjustedY + windowHeight <= bounds.y + bounds.height
|
|
) {
|
|
return { validX: adjustedX, validY: adjustedY };
|
|
}
|
|
|
|
// If all else fails, center on primary display
|
|
const primaryDisplay = screen.getPrimaryDisplay();
|
|
const primaryBounds = primaryDisplay.bounds;
|
|
|
|
return {
|
|
validX: Math.floor(
|
|
primaryBounds.x + (primaryBounds.width - windowWidth) / 2,
|
|
),
|
|
validY: Math.floor(
|
|
primaryBounds.y + (primaryBounds.height - windowHeight) / 2,
|
|
),
|
|
};
|
|
}
|
|
|
|
// Helper function to find the closest display to a point
|
|
function findClosestDisplay(
|
|
displays: Electron.Display[],
|
|
x: number,
|
|
y: number,
|
|
): Electron.Display {
|
|
let closestDisplay = displays[0];
|
|
let shortestDistance = Number.MAX_VALUE;
|
|
|
|
for (const display of displays) {
|
|
const { bounds } = display;
|
|
// Calculate distance to center of display
|
|
const displayCenterX = bounds.x + bounds.width / 2;
|
|
const displayCenterY = bounds.y + bounds.height / 2;
|
|
|
|
const distance = Math.sqrt(
|
|
Math.pow(x - displayCenterX, 2) + Math.pow(y - displayCenterY, 2),
|
|
);
|
|
|
|
if (distance < shortestDistance) {
|
|
shortestDistance = distance;
|
|
closestDisplay = display;
|
|
}
|
|
}
|
|
|
|
return closestDisplay;
|
|
}
|
|
|
|
export default ensureWindowOnScreen;
|