TeaSpeak-Client/modules/shared/window.ts

112 lines
3.8 KiB
TypeScript
Raw Normal View History

2019-10-25 19:51:40 -04:00
import * as electron from "electron";
import * as fs from "fs-extra";
import * as path from "path";
2020-08-21 07:37:10 -04:00
/* We read/write to this file every time again because this file could be used by multiple processes */
const data_file: string = path.join((electron.app || electron.remote.app).getPath('userData'), "window-bounds.json");
2019-10-25 19:51:40 -04:00
import BrowserWindow = Electron.BrowserWindow;
import Rectangle = Electron.Rectangle;
2020-08-21 07:37:10 -04:00
let changedData: {[key: string]:Rectangle} = {};
2020-12-02 12:08:49 -05:00
let changedDataSaveTimeout: number;
2019-10-25 19:51:40 -04:00
export async function save_changes() {
2020-08-21 07:37:10 -04:00
clearTimeout(changedDataSaveTimeout);
2019-10-25 19:51:40 -04:00
try {
const data = (await fs.pathExists(data_file) ? await fs.readJson(data_file) : {}) || {};
2020-08-21 07:37:10 -04:00
Object.assign(data, changedData);
2019-10-25 19:51:40 -04:00
await fs.ensureFile(data_file);
await fs.writeJson(data_file, data);
path_exists = true;
2020-08-21 07:37:10 -04:00
changedData = {};
2019-10-25 19:51:40 -04:00
} catch(error) {
console.warn("Failed to save window bounds: %o", error);
}
console.log("Window bounds have been successfully saved!");
}
let path_exists = undefined;
export async function get_last_bounds(key: string) : Promise<Rectangle> {
try {
if(typeof(path_exists) === "undefined" ? !(path_exists = await fs.pathExists(data_file)) : !path_exists)
throw "skip!";
const data = await fs.readJson(data_file) || {};
if(data[key])
return data[key];
} catch(error) {
if(error !== "skip!")
console.warn("Failed to load window bounds for %s: %o", key, error);
}
return {
height: undefined,
width: undefined,
x: undefined,
y: undefined
}
}
2020-08-21 07:37:10 -04:00
export function startTrackWindowBounds(windowId: string, window: BrowserWindow) {
2019-10-25 19:51:40 -04:00
const events = ['move', 'moved', 'resize'];
2020-08-21 07:37:10 -04:00
const onWindowBoundsChanged = () => {
changedData[windowId] = window.getBounds();
2019-10-25 19:51:40 -04:00
2020-08-21 07:37:10 -04:00
clearTimeout(changedDataSaveTimeout);
changedDataSaveTimeout = setTimeout(save_changes, 1000);
2019-10-25 19:51:40 -04:00
};
for(const event of events)
2020-08-21 07:37:10 -04:00
window.on(event as any, onWindowBoundsChanged);
2019-10-25 19:51:40 -04:00
window.on('closed', () => {
for(const event of events)
2020-08-21 07:37:10 -04:00
window.removeListener(event as any, onWindowBoundsChanged);
});
2019-10-25 19:51:40 -04:00
}
2020-08-21 07:37:10 -04:00
export async function loadWindowBounds(windowId: string, window: BrowserWindow, bounds?: Rectangle, options?: { applySize?: boolean; applyPosition?: boolean }) {
const screen = electron.screen || electron.remote.screen;
2019-10-25 19:51:40 -04:00
2020-08-21 07:37:10 -04:00
if(!bounds) {
bounds = await get_last_bounds(windowId);
}
2019-10-25 19:51:40 -04:00
2020-08-21 07:37:10 -04:00
if(!options) {
2019-10-25 19:51:40 -04:00
options = {};
2020-08-21 07:37:10 -04:00
}
2019-10-25 19:51:40 -04:00
const original_bounds = window.getBounds();
2020-08-21 07:37:10 -04:00
if(typeof(options.applySize) !== "boolean" || options.applySize) {
2019-10-25 19:51:40 -04:00
let height = bounds.height > 0 ? bounds.height : original_bounds.height;
let width = bounds.width > 0 ? bounds.width : original_bounds.width;
if(height != original_bounds.height || width != original_bounds.width)
window.setSize(width, height, true);
}
2020-08-21 07:37:10 -04:00
if(typeof(options.applyPosition) !== "boolean" || options.applyPosition) {
2019-10-25 19:51:40 -04:00
let x = typeof(bounds.x) === "number" ? bounds.x : original_bounds.x;
let y = typeof(bounds.y) === "number" ? bounds.y : original_bounds.y;
if(x != original_bounds.x || y != original_bounds.y) {
const display = screen.getDisplayNearestPoint({ x: x, y: y });
if(display) {
const bounds = display.workArea || display.bounds;
let flag_invalid = false;
flag_invalid = flag_invalid || bounds.x > x || (bounds.x + bounds.width) < x;
flag_invalid = flag_invalid || bounds.y > x || (bounds.y + bounds.height) < y;
if(!flag_invalid) {
window.setPosition(x, y, true);
2020-08-21 07:37:10 -04:00
console.log("Updating position for %s", windowId);
2019-10-25 19:51:40 -04:00
}
}
}
}
}