feat: additional MQTT controls and sensors #7
This commit is contained in:
+174
-11
@@ -19,6 +19,10 @@ global.HARDWARE = global.HARDWARE || {
|
||||
},
|
||||
notifiers: [],
|
||||
},
|
||||
keyboard: {
|
||||
visible: null,
|
||||
notifiers: [],
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -69,6 +73,23 @@ const init = async (args) => {
|
||||
console.log(`\nDisplay Status [${HARDWARE.display.status.path}]:`, getDisplayStatus());
|
||||
console.log(`Display Brightness [${HARDWARE.display.brightness.path}]:`, getDisplayBrightness(), "\n");
|
||||
|
||||
// Check for keyboard visibility changes
|
||||
HARDWARE.support.keyboardVisibility = processRuns("squeekboard");
|
||||
setKeyboardVisibility("OFF", (reply, error) => {
|
||||
if (!reply || error) {
|
||||
return;
|
||||
}
|
||||
dbusMonitor("/sm/puri/OSK0", (property, error) => {
|
||||
if (!property || error) {
|
||||
return;
|
||||
}
|
||||
HARDWARE.keyboard.visibility = property.Visible === "true";
|
||||
HARDWARE.keyboard.notifiers.forEach((notifier) => {
|
||||
notifier();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Check for display changes
|
||||
setInterval(update, 500);
|
||||
|
||||
@@ -124,9 +145,12 @@ const compatibleDevice = () => {
|
||||
/**
|
||||
* Queries the session type for the logged in user.
|
||||
*
|
||||
* @returns {string} Returns session type x11/wayland or null if an error occurs.
|
||||
* @returns {string} Returns session type 'x11'/'wayland' or null if an error occurs.
|
||||
*/
|
||||
const sessionType = () => {
|
||||
if (!commandExists("loginctl")) {
|
||||
return null;
|
||||
}
|
||||
return execSyncCommand("loginctl", [
|
||||
"show-session",
|
||||
"$(loginctl show-user $(whoami) -p Display --value)",
|
||||
@@ -146,7 +170,7 @@ const session = (type) => {
|
||||
/**
|
||||
* Gets the model name using `/sys/firmware/devicetree/base/model` or `/sys/class/dmi/id/product_name`.
|
||||
*
|
||||
* @returns {string|null} The model name of the device or "Generic" if not found.
|
||||
* @returns {string|null} The model name of the device or 'Generic' if not found.
|
||||
*/
|
||||
const getModel = () => {
|
||||
const paths = ["/sys/firmware/devicetree/base/model", "/sys/class/dmi/id/product_name"];
|
||||
@@ -161,7 +185,7 @@ const getModel = () => {
|
||||
/**
|
||||
* Gets the vendor name using `/sys/class/dmi/id/board_vendor`.
|
||||
*
|
||||
* @returns {string|null} The vendor name of the device or "Generic" if not found.
|
||||
* @returns {string|null} The vendor name of the device or 'Generic' if not found.
|
||||
*/
|
||||
const getVendor = () => {
|
||||
const paths = ["/sys/class/dmi/id/board_vendor"];
|
||||
@@ -180,7 +204,7 @@ const getVendor = () => {
|
||||
/**
|
||||
* Gets the serial number using `/sys/firmware/devicetree/base/serial-number` or `/sys/class/dmi/id/product_serial`.
|
||||
*
|
||||
* @returns {string|null} The serial number of the device or "123456" if not found.
|
||||
* @returns {string|null} The serial number of the device or '123456' if not found.
|
||||
*/
|
||||
const getSerialNumber = () => {
|
||||
const paths = ["/sys/firmware/devicetree/base/serial-number", "/sys/class/dmi/id/product_serial"];
|
||||
@@ -195,7 +219,7 @@ const getSerialNumber = () => {
|
||||
/**
|
||||
* Gets the host machine id using `/etc/machine-id`.
|
||||
*
|
||||
* @returns {string} The machine id of the system or "123456" if not found.
|
||||
* @returns {string} The machine id of the system or '123456' if not found.
|
||||
*/
|
||||
const getMachineId = () => {
|
||||
return execSyncCommand("cat", ["/etc/machine-id"]) || "123456";
|
||||
@@ -290,7 +314,7 @@ const getDisplayStatusPath = () => {
|
||||
/**
|
||||
* Gets the current display power status using `wlopm` or `xset`.
|
||||
*
|
||||
* @returns {string|null} The display status ON/OFF or null if an error occurs.
|
||||
* @returns {string|null} The display status as 'ON'/'OFF' or null if an error occurs.
|
||||
*/
|
||||
const getDisplayStatus = () => {
|
||||
if (!HARDWARE.support.displayStatus) {
|
||||
@@ -323,6 +347,7 @@ const getDisplayStatus = () => {
|
||||
*/
|
||||
const setDisplayStatus = (status, callback = null) => {
|
||||
if (!HARDWARE.support.displayStatus) {
|
||||
if (typeof callback === "function") callback(null, "Not supported");
|
||||
return;
|
||||
}
|
||||
if (status !== "ON" && status !== "OFF") {
|
||||
@@ -398,6 +423,7 @@ const getDisplayBrightness = () => {
|
||||
*/
|
||||
const setDisplayBrightness = (brightness, callback = null) => {
|
||||
if (!HARDWARE.support.displayBrightness) {
|
||||
if (typeof callback === "function") callback(null, "Not supported");
|
||||
return;
|
||||
}
|
||||
if (typeof brightness !== "number" || brightness < 1 || brightness > 100) {
|
||||
@@ -412,6 +438,52 @@ const setDisplayBrightness = (brightness, callback = null) => {
|
||||
proc.stdin.end();
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the keyboard visibility using global properties.
|
||||
*
|
||||
* @returns {string|null} The keyboard visibility as 'ON'/'OFF' or null if an error occurs.
|
||||
*/
|
||||
const getKeyboardVisibility = () => {
|
||||
if (!HARDWARE.support.keyboardVisibility) {
|
||||
return null;
|
||||
}
|
||||
return HARDWARE.keyboard.visibility ? "ON" : "OFF";
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the keyboard visibility using `dbus-send`.
|
||||
*
|
||||
* This function takes a desired visibility ('ON' or 'OFF') and executes
|
||||
* the appropriate command to show or hide the keyboard.
|
||||
*
|
||||
* @param {boolean} visibility - The desired visibility ('ON' or 'OFF').
|
||||
* @param {function} callback - A callback function that receives the output or error.
|
||||
*/
|
||||
const setKeyboardVisibility = (visibility, callback = null) => {
|
||||
if (!HARDWARE.support.keyboardVisibility) {
|
||||
if (typeof callback === "function") callback(null, "Not supported");
|
||||
return;
|
||||
}
|
||||
const visible = visibility === "ON";
|
||||
HARDWARE.keyboard.visibility = visible;
|
||||
dbusCall("/sm/puri/OSK0", "SetVisible", [`boolean:${visible}`], callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if system upgrades are available using `apt`.
|
||||
*
|
||||
* @returns {Array<string>} A list of package names that are available for upgrade.
|
||||
*/
|
||||
const checkPackageUpgrades = () => {
|
||||
if (!commandExists("apt")) {
|
||||
return [];
|
||||
}
|
||||
const output = execSyncCommand("apt", ["list", "--upgradable", "2>/dev/null"]);
|
||||
const packages = (output || "").trim().split("\n");
|
||||
packages.shift();
|
||||
return packages;
|
||||
};
|
||||
|
||||
/**
|
||||
* Shuts down the system using `sudo shutdown -h now`.
|
||||
*
|
||||
@@ -437,14 +509,27 @@ const rebootSystem = (callback = null) => {
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if a command exists using `which`.
|
||||
* Checks if a process is running using `pidof`.
|
||||
*
|
||||
* @param {string} cmd - The command name to check.
|
||||
* @returns {boolean} Returns true if the command exists.
|
||||
* @param {string} name - The process name to check.
|
||||
* @returns {boolean} Returns true if the process runs.
|
||||
*/
|
||||
const commandExists = (cmd) => {
|
||||
const processRuns = (name) => {
|
||||
try {
|
||||
return !!process.execSync(`which ${cmd}`, { encoding: "utf8" });
|
||||
return !!process.execSync(`pidof ${name}`, { encoding: "utf8" });
|
||||
} catch {}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if a command is available using `which`.
|
||||
*
|
||||
* @param {string} name - The command name to check.
|
||||
* @returns {boolean} Returns true if the command is available.
|
||||
*/
|
||||
const commandExists = (name) => {
|
||||
try {
|
||||
return !!process.execSync(`which ${name}`, { encoding: "utf8" });
|
||||
} catch {}
|
||||
return false;
|
||||
};
|
||||
@@ -499,6 +584,81 @@ const execAsyncCommand = (cmd, args = [], callback = null) => {
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Execute Async:", error.message);
|
||||
if (typeof callback === "function") {
|
||||
callback(null, error.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
return proc;
|
||||
};
|
||||
|
||||
/**
|
||||
* Executes a D-Bus method call synchronously using `dbus-send`.
|
||||
*
|
||||
* @param {string} path - The D-Bus object path.
|
||||
* @param {string} method - The D-Bus method name.
|
||||
* @param {Array<string>} values - The argument values for the D-Bus method.
|
||||
* @param {function} callback - A callback function that receives the output or error.
|
||||
*/
|
||||
const dbusCall = (path, method, values, callback = null) => {
|
||||
const cmd = "dbus-send";
|
||||
const iface = path.slice(1).replace(/\//g, ".");
|
||||
const dest = `${iface} ${path} ${iface}.${method} ${values.join(" ")}`;
|
||||
const args = ["--print-reply", "--type=method_call", `--dest=${dest}`];
|
||||
try {
|
||||
const output = process.execSync([cmd, ...args].join(" "), { encoding: "utf8" });
|
||||
if (typeof callback === "function") {
|
||||
callback(output.trim().replace(/\0/g, ""), null);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Call D-Bus:", error.message);
|
||||
if (typeof callback === "function") {
|
||||
callback(null, error.message);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Monitors D-Bus property changes asynchronously using `dbus-monitor`.
|
||||
*
|
||||
* @param {string} path - The D-Bus object path.
|
||||
* @param {function} callback - A callback function that receives the changed property.
|
||||
* @returns {object} The spawned process object.
|
||||
*/
|
||||
const dbusMonitor = (path, callback) => {
|
||||
const cmd = "dbus-monitor";
|
||||
const args = [`interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',path='${path}'`];
|
||||
const proc = process.spawn(cmd, args);
|
||||
proc.stdout.on("data", (data) => {
|
||||
try {
|
||||
const signal = data.toString();
|
||||
if (signal.includes("member=PropertiesChanged") && signal.includes(`path=${path}`)) {
|
||||
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);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
callback({ Visible: `${HARDWARE.keyboard.visibility}` }, null);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Monitor D-Bus:", error.message);
|
||||
if (typeof callback === "function") {
|
||||
callback(null, error.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
proc.stderr.on("data", (data) => {
|
||||
if (data) {
|
||||
console.error("Monitor D-Bus:", data.toString());
|
||||
if (typeof callback === "function") {
|
||||
callback(null, data.toString());
|
||||
}
|
||||
}
|
||||
});
|
||||
return proc;
|
||||
@@ -524,6 +684,9 @@ module.exports = {
|
||||
getDisplayBrightnessMax,
|
||||
getDisplayBrightness,
|
||||
setDisplayBrightness,
|
||||
getKeyboardVisibility,
|
||||
setKeyboardVisibility,
|
||||
checkPackageUpgrades,
|
||||
shutdownSystem,
|
||||
rebootSystem,
|
||||
};
|
||||
|
||||
+151
-6
@@ -37,15 +37,15 @@ const init = async (args) => {
|
||||
INTEGRATION.device = {
|
||||
name: `TouchKio ${deviceName}`,
|
||||
model: model,
|
||||
serial_number: serialNumber,
|
||||
manufacturer: vendor,
|
||||
serial_number: serialNumber,
|
||||
identifiers: [INTEGRATION.node],
|
||||
sw_version: `${app.getName()}-v${app.getVersion()}`,
|
||||
};
|
||||
|
||||
// Connection settings
|
||||
const masked = password === null ? "null" : "*".repeat(password.length);
|
||||
const options = user === null || password == null ? null : { username: user, password: password };
|
||||
const masked = password === null ? "null" : "*".repeat(password.length);
|
||||
console.log("MQTT Connecting:", `${user}:${masked}@${url.toString()}`);
|
||||
INTEGRATION.client = mqtt.connect(url.toString(), options);
|
||||
|
||||
@@ -60,6 +60,7 @@ const init = async (args) => {
|
||||
initRefresh(INTEGRATION.client);
|
||||
initKiosk(INTEGRATION.client);
|
||||
initDisplay(INTEGRATION.client);
|
||||
initKeyboard(INTEGRATION.client);
|
||||
|
||||
// Init client sensors
|
||||
initModel(INTEGRATION.client);
|
||||
@@ -70,7 +71,9 @@ const init = async (args) => {
|
||||
initMemoryUsage(INTEGRATION.client);
|
||||
initProcessorUsage(INTEGRATION.client);
|
||||
initProcessorTemperature(INTEGRATION.client);
|
||||
initPackageUpgrades(INTEGRATION.client);
|
||||
initHeartbeat(INTEGRATION.client);
|
||||
initLastActive(INTEGRATION.client);
|
||||
|
||||
// Integration initialized
|
||||
INTEGRATION.initialized = true;
|
||||
@@ -81,18 +84,29 @@ const init = async (args) => {
|
||||
INTEGRATION.status = "offline";
|
||||
});
|
||||
|
||||
// Update sensor states on display change
|
||||
// Update sensor states from notifiers
|
||||
HARDWARE.display.notifiers.push(() => {
|
||||
updateDisplay(INTEGRATION.client);
|
||||
});
|
||||
HARDWARE.keyboard.notifiers.push(() => {
|
||||
updateKeyboard(INTEGRATION.client);
|
||||
});
|
||||
|
||||
// Update heartbeat time periodically (30s)
|
||||
// Update time sensors periodically (30s)
|
||||
setInterval(() => {
|
||||
updateHeartbeat(INTEGRATION.client);
|
||||
updateLastActive(INTEGRATION.client);
|
||||
}, 30 * 1000);
|
||||
|
||||
// Update sensor states periodically (1min)
|
||||
setInterval(update, 60 * 1000);
|
||||
// Update system sensors periodically (1min)
|
||||
setInterval(() => {
|
||||
update();
|
||||
}, 60 * 1000);
|
||||
|
||||
// Update package sensors periodically (60min)
|
||||
setInterval(() => {
|
||||
updatePackageUpgrades(INTEGRATION.client);
|
||||
}, 3600 * 1000);
|
||||
|
||||
return true;
|
||||
};
|
||||
@@ -108,6 +122,7 @@ const update = () => {
|
||||
// Update client sensors
|
||||
updateKiosk(INTEGRATION.client);
|
||||
updateUpTime(INTEGRATION.client);
|
||||
updateLastActive(INTEGRATION.client);
|
||||
updateMemoryUsage(INTEGRATION.client);
|
||||
updateProcessorUsage(INTEGRATION.client);
|
||||
updateProcessorTemperature(INTEGRATION.client);
|
||||
@@ -264,6 +279,9 @@ const updateKiosk = (client) => {
|
||||
* @param {Object} client - Instance of the mqtt client.
|
||||
*/
|
||||
const initDisplay = (client) => {
|
||||
if (!HARDWARE.support.displayStatus) {
|
||||
return;
|
||||
}
|
||||
const root = `${INTEGRATION.discovery}/light/${INTEGRATION.node}/display`;
|
||||
const config = {
|
||||
name: `Display`,
|
||||
@@ -314,6 +332,62 @@ const updateDisplay = (client) => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the keyboard visibility and handles the execute logic.
|
||||
*
|
||||
* @param {Object} client - Instance of the mqtt client.
|
||||
*/
|
||||
const initKeyboard = (client) => {
|
||||
if (!HARDWARE.support.keyboardVisibility) {
|
||||
return;
|
||||
}
|
||||
const root = `${INTEGRATION.discovery}/switch/${INTEGRATION.node}/keyboard`;
|
||||
const config = {
|
||||
name: `Keyboard`,
|
||||
unique_id: `${INTEGRATION.node}_keyboard`,
|
||||
command_topic: `${root}/set`,
|
||||
state_topic: `${root}/status`,
|
||||
icon: "mdi:keyboard-close",
|
||||
device: INTEGRATION.device,
|
||||
};
|
||||
client
|
||||
.publish(`${root}/config`, JSON.stringify(config), { qos: 1, retain: true })
|
||||
.on("message", (topic, message) => {
|
||||
if (topic === `${root}/set`) {
|
||||
const status = message.toString();
|
||||
console.log("Set Keyboard Visibility:", status);
|
||||
hardware.setKeyboardVisibility(status);
|
||||
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;
|
||||
}
|
||||
}
|
||||
})
|
||||
.subscribe(`${root}/set`);
|
||||
updateKeyboard(client);
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the keyboard visibility via the mqtt connection.
|
||||
*
|
||||
* @param {Object} client - Instance of the mqtt client.
|
||||
*/
|
||||
const updateKeyboard = (client) => {
|
||||
const visibility = hardware.getKeyboardVisibility();
|
||||
const root = `${INTEGRATION.discovery}/switch/${INTEGRATION.node}/keyboard`;
|
||||
if (visibility !== null) {
|
||||
client.publish(`${root}/status`, `${visibility}`, { qos: 1, retain: true });
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the model sensor.
|
||||
*
|
||||
@@ -575,6 +649,44 @@ const updateProcessorTemperature = (client) => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the package upgrades sensor.
|
||||
*
|
||||
* @param {Object} client - Instance of the mqtt client.
|
||||
*/
|
||||
const initPackageUpgrades = (client) => {
|
||||
const root = `${INTEGRATION.discovery}/sensor/${INTEGRATION.node}/package_upgrades`;
|
||||
const config = {
|
||||
name: `Package Upgrades`,
|
||||
unique_id: `${INTEGRATION.node}_package_upgrades`,
|
||||
state_topic: `${root}/status`,
|
||||
json_attributes_topic: `${root}/attributes`,
|
||||
value_template: "{{ value }}",
|
||||
icon: "mdi:package-down",
|
||||
device: INTEGRATION.device,
|
||||
};
|
||||
client.publish(`${root}/config`, JSON.stringify(config), { qos: 1, retain: true });
|
||||
updatePackageUpgrades(client);
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the package upgrades sensor via the mqtt connection.
|
||||
*
|
||||
* @param {Object} client - Instance of the mqtt client.
|
||||
*/
|
||||
const updatePackageUpgrades = (client) => {
|
||||
const packages = hardware.checkPackageUpgrades();
|
||||
const root = `${INTEGRATION.discovery}/sensor/${INTEGRATION.node}/package_upgrades`;
|
||||
if (packages !== null) {
|
||||
const attributes = {
|
||||
total: packages.length,
|
||||
packages: packages.map((pkg) => pkg.replace(/\s*\[.*?\]\s*/g, "").trim()),
|
||||
};
|
||||
client.publish(`${root}/status`, `${attributes.total}`, { qos: 1, retain: true });
|
||||
client.publish(`${root}/attributes`, JSON.stringify(attributes), { qos: 1, retain: true });
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the heartbeat sensor.
|
||||
*
|
||||
@@ -607,6 +719,39 @@ const updateHeartbeat = (client) => {
|
||||
client.publish(`${root}/status`, `${heartbeat}`, { qos: 1, retain: true });
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the last active sensor.
|
||||
*
|
||||
* @param {Object} client - Instance of the mqtt client.
|
||||
*/
|
||||
const initLastActive = (client) => {
|
||||
const root = `${INTEGRATION.discovery}/sensor/${INTEGRATION.node}/last_active`;
|
||||
const config = {
|
||||
name: `Last Active`,
|
||||
unique_id: `${INTEGRATION.node}_last_active`,
|
||||
state_topic: `${root}/status`,
|
||||
value_template: "{{ (value | float) | round(0) }}",
|
||||
unit_of_measurement: "min",
|
||||
icon: "mdi:gesture-tap-hold",
|
||||
device: INTEGRATION.device,
|
||||
};
|
||||
client.publish(`${root}/config`, JSON.stringify(config), { qos: 1, retain: true });
|
||||
updateLastActive(client);
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the last active sensor via the mqtt connection.
|
||||
*
|
||||
* @param {Object} client - Instance of the mqtt client.
|
||||
*/
|
||||
const updateLastActive = (client) => {
|
||||
const now = new Date();
|
||||
const then = WEBVIEW.pointer.time;
|
||||
const lastActive = Math.abs(now - then) / (1000 * 60);
|
||||
const root = `${INTEGRATION.discovery}/sensor/${INTEGRATION.node}/last_active`;
|
||||
client.publish(`${root}/status`, `${lastActive}`, { qos: 1, retain: true });
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
init,
|
||||
update,
|
||||
|
||||
+47
-20
@@ -1,12 +1,16 @@
|
||||
const path = require("path");
|
||||
const hardware = require("./hardware");
|
||||
const integration = require("./integration");
|
||||
const { app, nativeTheme, BaseWindow, WebContentsView } = require("electron");
|
||||
const { app, screen, nativeTheme, BaseWindow, WebContentsView } = require("electron");
|
||||
|
||||
global.WEBVIEW = global.WEBVIEW || {
|
||||
initialized: false,
|
||||
status: "offline",
|
||||
locked: false,
|
||||
pointer: {
|
||||
position: {},
|
||||
time: new Date(),
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -40,6 +44,7 @@ const init = async (args) => {
|
||||
|
||||
// Register events
|
||||
windowEvents(WEBVIEW.window, zoom);
|
||||
touchEvents(WEBVIEW.window);
|
||||
viewEvents(WEBVIEW.view);
|
||||
|
||||
return true;
|
||||
@@ -86,24 +91,6 @@ const windowEvents = (window, zoom) => {
|
||||
window.on("resize", resize);
|
||||
resize();
|
||||
|
||||
// Handle focus change for webview lock
|
||||
HARDWARE.display.notifiers.push(() => {
|
||||
WEBVIEW.locked = hardware.getDisplayStatus() === "OFF";
|
||||
if (WEBVIEW.locked) {
|
||||
window.blur();
|
||||
}
|
||||
/* This also works, but it doesn't allow to react for screen wake up.
|
||||
window.setIgnoreMouseEvents(hardware.getDisplayStatus() === "OFF");
|
||||
*/
|
||||
});
|
||||
window.on("focus", () => {
|
||||
if (WEBVIEW.locked) {
|
||||
hardware.setDisplayStatus("ON");
|
||||
window.blur();
|
||||
}
|
||||
WEBVIEW.locked = false;
|
||||
});
|
||||
|
||||
// Handle window status updates
|
||||
window.on("minimize", update);
|
||||
window.on("restore", update);
|
||||
@@ -128,6 +115,46 @@ const windowEvents = (window, zoom) => {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Register touch events and handler.
|
||||
*
|
||||
* @param {Object} window - The root window object.
|
||||
*/
|
||||
const touchEvents = (window) => {
|
||||
// Handle focus change for webview lock
|
||||
window.on("focus", () => {
|
||||
if (WEBVIEW.locked) {
|
||||
hardware.setDisplayStatus("ON");
|
||||
window.blur();
|
||||
}
|
||||
WEBVIEW.locked = false;
|
||||
});
|
||||
HARDWARE.display.notifiers.push(() => {
|
||||
WEBVIEW.locked = hardware.getDisplayStatus() === "OFF";
|
||||
if (WEBVIEW.locked) {
|
||||
window.blur();
|
||||
}
|
||||
});
|
||||
|
||||
// Handle touch events for activity tracking
|
||||
setInterval(() => {
|
||||
const posOld = WEBVIEW.pointer.position;
|
||||
const posNew = screen.getCursorScreenPoint();
|
||||
if (posOld.x !== posNew.x || posOld.y !== posNew.y) {
|
||||
const now = new Date();
|
||||
const then = WEBVIEW.pointer.time;
|
||||
|
||||
// Update integration sensor
|
||||
WEBVIEW.pointer.time = now;
|
||||
if (Math.abs(now - then) / 1000 > 30) {
|
||||
console.log("Update Last Active");
|
||||
integration.update();
|
||||
}
|
||||
}
|
||||
WEBVIEW.pointer.position = posNew;
|
||||
}, 1 * 1000);
|
||||
};
|
||||
|
||||
/**
|
||||
* Register webview events and handler.
|
||||
*
|
||||
@@ -137,8 +164,8 @@ const viewEvents = (view) => {
|
||||
// Enable webview touch emulation
|
||||
view.webContents.debugger.attach("1.1");
|
||||
view.webContents.debugger.sendCommand("Emulation.setEmitTouchEventsForMouse", {
|
||||
enabled: true,
|
||||
configuration: "mobile",
|
||||
enabled: true,
|
||||
});
|
||||
|
||||
// Disable webview hyperlinks
|
||||
|
||||
Reference in New Issue
Block a user