Ensure window stays on screen after external monitor removed.
This commit is contained in:
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "bodyshop-desktop",
|
||||
"version": "0.0.1-alpha.10",
|
||||
"version": "0.0.1-alpha.11",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "bodyshop-desktop",
|
||||
"version": "0.0.1-alpha.10",
|
||||
"version": "0.0.1-alpha.11",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.13.6",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "bodyshop-desktop",
|
||||
"version": "0.0.1-alpha.11",
|
||||
"version": "0.0.1-alpha.13",
|
||||
"description": "Shop Management System Partner",
|
||||
"main": "./out/main/index.js",
|
||||
"author": "Convenient Brands, LLC",
|
||||
|
||||
@@ -33,6 +33,7 @@ import {
|
||||
isKeepAliveTaskInstalled,
|
||||
setupKeepAliveTask,
|
||||
} from "./setup-keep-alive-task";
|
||||
import ensureWindowOnScreen from "./util/ensureWindowOnScreen";
|
||||
|
||||
Sentry.init({
|
||||
dsn: "https://ba41d22656999a8c1fd63bcb7df98650@o492140.ingest.us.sentry.io/4509074139447296",
|
||||
@@ -56,11 +57,14 @@ function createWindow(): void {
|
||||
y: number | undefined;
|
||||
};
|
||||
|
||||
// Validate window position is on screen
|
||||
const { validX, validY } = ensureWindowOnScreen(x, y, width, height);
|
||||
|
||||
const mainWindow = new BrowserWindow({
|
||||
width,
|
||||
height,
|
||||
x,
|
||||
y,
|
||||
x: validX,
|
||||
y: validY,
|
||||
show: false, // Start hidden, show later if not keep-alive
|
||||
minWidth: 600,
|
||||
minHeight: 400,
|
||||
|
||||
109
src/main/util/ensureWindowOnScreen.ts
Normal file
109
src/main/util/ensureWindowOnScreen.ts
Normal file
@@ -0,0 +1,109 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user