diff --git a/html/navigation.html b/html/navigation.html
index 64d43c8..4ccbed5 100644
--- a/html/navigation.html
+++ b/html/navigation.html
@@ -186,7 +186,10 @@
ipcRenderer.send("button-click", { id: e.target.id });
});
});
- document.querySelectorAll("input").forEach((input) => {
+ document.querySelectorAll("input").forEach((input) => {
+ input.addEventListener("blur", (e) => {
+ ipcRenderer.send("input-blur", { id: e.target.id });
+ });
input.addEventListener("focus", (e) => {
ipcRenderer.send("input-focus", { id: e.target.id });
});
diff --git a/js/hardware.js b/js/hardware.js
index c900832..1a06e12 100644
--- a/js/hardware.js
+++ b/js/hardware.js
@@ -962,18 +962,20 @@ const dbusMonitor = (path, callback) => {
proc.stdout.on("data", (data) => {
try {
const signal = data.toString();
- if (signal.includes("member=PropertiesChanged") && signal.includes(`path=${path}`)) {
+ if (signal.includes(`string "Visible"`)) {
const dicts = [...signal.matchAll(/dict entry\(\s*([^)]*?)\)/g)].map((dict) => dict[1].trim());
if (dicts.length) {
dicts.forEach((dict) => {
const key = dict.match(/string "(.*?)"/);
const value = dict.match(/(?<=variant\s+)(.*)/);
- if (key && value && typeof callback === "function") {
- callback({ [key[1].trim()]: value[1].trim().split(" ").pop() }, null);
+ if (key && value) {
+ const property = { [key[1].trim()]: value[1].trim().split(" ").pop() };
+ if (typeof callback === "function") callback(property, null);
}
});
} else {
- callback({ Visible: `${HARDWARE.keyboard.visibility}` }, null);
+ const property = { Visible: `${HARDWARE.keyboard.visibility}` };
+ if (typeof callback === "function") callback(property, null);
}
}
} catch (error) {
diff --git a/js/integration.js b/js/integration.js
index db6db8a..0f53187 100644
--- a/js/integration.js
+++ b/js/integration.js
@@ -363,30 +363,7 @@ const initKiosk = () => {
const status = message.toString();
console.log("Set Kiosk Status:", status);
hardware.setDisplayStatus("ON", () => {
- switch (status) {
- case "Framed":
- WEBVIEW.window.restore();
- WEBVIEW.window.unmaximize();
- WEBVIEW.window.setFullScreen(false);
- break;
- case "Fullscreen":
- WEBVIEW.window.restore();
- WEBVIEW.window.unmaximize();
- WEBVIEW.window.setFullScreen(true);
- break;
- case "Maximized":
- WEBVIEW.window.restore();
- WEBVIEW.window.setFullScreen(false);
- WEBVIEW.window.maximize();
- break;
- case "Minimized":
- WEBVIEW.window.restore();
- WEBVIEW.window.setFullScreen(false);
- WEBVIEW.window.minimize();
- break;
- case "Terminated":
- app.quit();
- }
+ WEBVIEW.window.setStatus(status);
});
}
})
@@ -529,18 +506,6 @@ const initKeyboard = () => {
const status = message.toString();
console.log("Set Keyboard Visibility:", status);
hardware.setDisplayStatus("ON", () => {
- switch (status) {
- case "OFF":
- WEBVIEW.window.restore();
- WEBVIEW.window.unmaximize();
- WEBVIEW.window.setFullScreen(true);
- break;
- case "ON":
- WEBVIEW.window.restore();
- WEBVIEW.window.setFullScreen(false);
- WEBVIEW.window.maximize();
- break;
- }
hardware.setKeyboardVisibility(status);
});
}
@@ -1010,6 +975,7 @@ const initLastActive = () => {
name: "Last Active",
unique_id: `${INTEGRATION.node}_last_active`,
state_topic: `${root}/state`,
+ json_attributes_topic: `${root}/attributes`,
value_template: "{{ (value | float) | round(0) }}",
unit_of_measurement: "min",
icon: "mdi:gesture-tap-hold",
@@ -1027,6 +993,7 @@ const updateLastActive = async () => {
const then = WEBVIEW.tracker.pointer.time;
const lastActive = (now - then) / (1000 * 60);
publishState("last_active", lastActive);
+ publishAttributes("last_active", WEBVIEW.tracker.pointer);
};
module.exports = {
diff --git a/js/webview.js b/js/webview.js
index 89d8f16..4ad0326 100644
--- a/js/webview.js
+++ b/js/webview.js
@@ -56,12 +56,11 @@ const init = async () => {
WEBVIEW.window = new BaseWindow({
title: APP.title,
icon: path.join(APP.path, "img", "icon.png"),
+ fullscreen: fullscreen,
+ autoHideMenuBar: true,
+ frame: true,
});
WEBVIEW.window.setMenuBarVisibility(false);
- WEBVIEW.window.setFullScreen(fullscreen);
- if (!fullscreen) {
- WEBVIEW.window.maximize();
- }
// Init global webview
WEBVIEW.views = [];
@@ -117,6 +116,13 @@ const init = async () => {
WEBVIEW.window.contentView.addChildView(WEBVIEW.navigation);
WEBVIEW.navigation.webContents.loadFile(path.join(APP.path, "html", "navigation.html"));
+ // Register local events
+ await windowEvents();
+ await widgetEvents();
+ await navigationEvents();
+ await viewEvents();
+ await appEvents();
+
// Register global events
EVENTS.on("reloadView", reloadView);
EVENTS.on("updateView", updateView);
@@ -126,13 +132,20 @@ const init = async () => {
WEBVIEW.tracker.display[status.toLowerCase()] = new Date();
}
});
-
- // Register local events
- await windowEvents();
- await widgetEvents();
- await navigationEvents();
- await viewEvents();
- await appEvents();
+ EVENTS.on("updateStatus", () => {
+ const visibility = hardware.getKeyboardVisibility();
+ if (visibility === "ON" && (WEBVIEW.window.isFullScreen() || WEBVIEW.window.isMinimized())) {
+ hardware.setKeyboardVisibility("OFF");
+ }
+ });
+ EVENTS.on("updateKeyboard", () => {
+ const visibility = hardware.getKeyboardVisibility();
+ if (visibility === "ON" && WEBVIEW.window.isFullScreen()) {
+ WEBVIEW.window.setStatus("maximized");
+ } else if (visibility === "OFF" && WEBVIEW.window.isMaximized()) {
+ WEBVIEW.window.setStatus("fullscreen");
+ }
+ });
return true;
};
@@ -146,15 +159,7 @@ const update = async () => {
}
// Update window status
- if (WEBVIEW.window.isFullScreen()) {
- WEBVIEW.tracker.status = "Fullscreen";
- } else if (WEBVIEW.window.isMinimized()) {
- WEBVIEW.tracker.status = "Minimized";
- } else if (WEBVIEW.window.isMaximized()) {
- WEBVIEW.tracker.status = "Maximized";
- } else {
- WEBVIEW.tracker.status = "Framed";
- }
+ updateStatus();
// Update widget status
updateWidget();
@@ -163,7 +168,6 @@ const update = async () => {
updateNavigation();
// Update integration sensor
- console.log("Update Kiosk Status:", WEBVIEW.tracker.status);
integration.update();
};
@@ -189,6 +193,25 @@ const updateView = () => {
update();
};
+/**
+ * Updates the window status.
+ */
+const updateStatus = () => {
+ if (WEBVIEW.window.isFullScreen()) {
+ WEBVIEW.tracker.status = "Fullscreen";
+ } else if (WEBVIEW.window.isMinimized()) {
+ WEBVIEW.tracker.status = "Minimized";
+ } else if (WEBVIEW.window.isMaximized()) {
+ WEBVIEW.tracker.status = "Maximized";
+ } else {
+ WEBVIEW.tracker.status = "Framed";
+ }
+
+ // Update window status
+ console.log("Update Kiosk Status:", WEBVIEW.tracker.status);
+ EVENTS.emit("updateStatus");
+};
+
/**
* Updates the widget control.
*/
@@ -444,12 +467,61 @@ const windowEvents = async () => {
resizeView();
// Handle window status updates
- WEBVIEW.window.on("minimize", update);
- WEBVIEW.window.on("restore", update);
- WEBVIEW.window.on("maximize", update);
- WEBVIEW.window.on("unmaximize", update);
- WEBVIEW.window.on("enter-full-screen", update);
- WEBVIEW.window.on("leave-full-screen", update);
+ WEBVIEW.window.setStatus = async (status) => {
+ const apply = (f, ...args) => {
+ f.apply(WEBVIEW.window, args);
+ return new Promise((r) => setTimeout(r, 50));
+ };
+ if (WEBVIEW.window.isMinimized()) {
+ await apply(WEBVIEW.window.restore);
+ }
+ switch (status.toLowerCase()) {
+ case "framed":
+ if (WEBVIEW.window.isFullScreen()) {
+ await apply(WEBVIEW.window.setFullScreen, false);
+ }
+ if (WEBVIEW.window.isMaximized()) {
+ await apply(WEBVIEW.window.unmaximize);
+ }
+ break;
+ case "fullscreen":
+ if (!WEBVIEW.window.isMaximized()) {
+ await apply(WEBVIEW.window.maximize);
+ }
+ if (!WEBVIEW.window.isFullScreen()) {
+ await apply(WEBVIEW.window.setFullScreen, true);
+ }
+ break;
+ case "maximized":
+ if (WEBVIEW.window.isFullScreen()) {
+ await apply(WEBVIEW.window.setFullScreen, false);
+ }
+ if (!WEBVIEW.window.isMaximized()) {
+ await apply(WEBVIEW.window.maximize);
+ }
+ break;
+ case "minimized":
+ if (WEBVIEW.window.isFullScreen()) {
+ await apply(WEBVIEW.window.setFullScreen, false);
+ }
+ if (!WEBVIEW.window.isMinimized()) {
+ await apply(WEBVIEW.window.minimize);
+ }
+ break;
+ case "terminated":
+ app.quit();
+ }
+ };
+ WEBVIEW.window.onStatus = () => {
+ clearTimeout(WEBVIEW.window.onStatus.timeout);
+ WEBVIEW.window.onStatus.timeout = setTimeout(update, 200);
+ };
+ WEBVIEW.window.on("restore", WEBVIEW.window.onStatus);
+ WEBVIEW.window.on("minimize", WEBVIEW.window.onStatus);
+ WEBVIEW.window.on("maximize", WEBVIEW.window.onStatus);
+ WEBVIEW.window.on("unmaximize", WEBVIEW.window.onStatus);
+ WEBVIEW.window.on("enter-full-screen", WEBVIEW.window.onStatus);
+ WEBVIEW.window.on("leave-full-screen", WEBVIEW.window.onStatus);
// Handle global shortcut events
globalShortcut.register("Control+Left", () => {
@@ -530,41 +602,20 @@ const widgetEvents = async () => {
switch (button.id) {
case "keyboard":
const toggle = hardware.getKeyboardVisibility() === "ON" ? "OFF" : "ON";
- switch (toggle) {
- case "OFF":
- WEBVIEW.window.restore();
- WEBVIEW.window.unmaximize();
- WEBVIEW.window.setFullScreen(true);
- break;
- case "ON":
- WEBVIEW.window.restore();
- WEBVIEW.window.setFullScreen(false);
- WEBVIEW.window.maximize();
- break;
- }
hardware.setKeyboardVisibility(toggle, () => {
WEBVIEW.views[WEBVIEW.viewActive].webContents.focus();
});
break;
case "fullscreen":
if (WEBVIEW.window.isFullScreen()) {
- WEBVIEW.window.restore();
- WEBVIEW.window.unmaximize();
- WEBVIEW.window.setFullScreen(false);
+ WEBVIEW.window.setStatus("framed");
} else {
- WEBVIEW.window.restore();
- WEBVIEW.window.unmaximize();
- WEBVIEW.window.setFullScreen(true);
+ WEBVIEW.window.setStatus("fullscreen");
}
- hardware.setKeyboardVisibility("OFF", () => {
- WEBVIEW.views[WEBVIEW.viewActive].webContents.focus();
- });
+ WEBVIEW.views[WEBVIEW.viewActive].webContents.focus();
break;
case "minimize":
- WEBVIEW.window.restore();
- WEBVIEW.window.setFullScreen(false);
- WEBVIEW.window.minimize();
- hardware.setKeyboardVisibility("OFF");
+ WEBVIEW.window.setStatus("minimized");
break;
case "navigation":
toggleNavigation();
@@ -582,34 +633,39 @@ const navigationEvents = async () => {
}
// Handle navigation blur events
- let ignoreBlur = false;
+ let selected = false;
WEBVIEW.navigation.webContents.on("blur", () => {
const visibility = hardware.getKeyboardVisibility();
- if (visibility === "ON" && !ignoreBlur) {
- WEBVIEW.window.restore();
- WEBVIEW.window.unmaximize();
- WEBVIEW.window.setFullScreen(true);
- hardware.setKeyboardVisibility("OFF");
+ if (visibility === "ON" && selected) {
WEBVIEW.navigation.webContents.send("input-blur", { id: "url" });
}
});
+ // Handle input blur events
+ ipcMain.on("input-blur", (e, input) => {
+ const visibility = hardware.getKeyboardVisibility();
+ switch (input.id) {
+ case "url":
+ if (visibility === "ON" && selected) {
+ hardware.setKeyboardVisibility("OFF");
+ }
+ break;
+ }
+ });
+
// Handle input focus events
ipcMain.on("input-focus", (e, input) => {
const visibility = hardware.getKeyboardVisibility();
switch (input.id) {
case "url":
if (visibility === "OFF") {
- ignoreBlur = true;
- WEBVIEW.window.restore();
- WEBVIEW.window.setFullScreen(false);
- WEBVIEW.window.maximize();
+ selected = false;
hardware.setKeyboardVisibility("ON", () => {
setTimeout(() => {
+ selected = true;
WEBVIEW.navigation.webContents.focus();
WEBVIEW.navigation.webContents.send("input-select", { id: "url" });
- ignoreBlur = false;
- }, 500);
+ }, 400);
});
}
break;
@@ -638,35 +694,27 @@ const navigationEvents = async () => {
switch (button.id) {
case "home":
homeView();
- hardware.setKeyboardVisibility("OFF");
break;
case "refresh":
reloadView();
- hardware.setKeyboardVisibility("OFF");
break;
case "previous":
previousView();
- hardware.setKeyboardVisibility("OFF");
break;
case "next":
nextView();
- hardware.setKeyboardVisibility("OFF");
break;
case "minus":
zoomMinus();
- hardware.setKeyboardVisibility("OFF");
break;
case "plus":
zoomPlus();
- hardware.setKeyboardVisibility("OFF");
break;
case "backward":
historyBackward();
- hardware.setKeyboardVisibility("OFF");
break;
case "forward":
historyForward();
- hardware.setKeyboardVisibility("OFF");
break;
}
});