From f74e2ad4ddbda7598e928740d81abe0215dc803a Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Thu, 11 Apr 2024 17:31:19 +0100 Subject: [PATCH] WIP: Let apps request to be headless This is a bit of an awkward API at the moment: - READY message is delayed until DOMContentLoaded - This lets app code call puter.ui.configureWindow() before that happens - The window configuration is then included in the READY message It works but it's not my favourite! --- src/modules/UI.js | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/modules/UI.js b/src/modules/UI.js index a671f93..b93276c 100644 --- a/src/modules/UI.js +++ b/src/modules/UI.js @@ -123,6 +123,14 @@ class UI extends EventListener { // The most recent value that we received for a given broadcast, by name. #lastBroadcastValue = new Map(); // name -> data + // Sent as the `windowConfig` field of the READY message. + #windowConfig = { + headless: false, + }; + + // Whether we've sent the READY message. + #readyMessageSent = false; + // Replaces boilerplate for most methods: posts a message to the GUI with a unique ID, and sets a callback for it. #postMessageWithCallback = function(name, resolve, args = {}) { const msg_id = this.#messageID++; @@ -162,10 +170,14 @@ class UI extends EventListener { // Tell the host environment that this app is using the Puter SDK and is ready to receive messages, // this will allow the OS to send custom messages to the app - this.messageTarget?.postMessage({ - msg: "READY", - appInstanceID: this.appInstanceID, - }, '*'); + document.addEventListener('DOMContentLoaded', () => { + this.messageTarget?.postMessage({ + msg: "READY", + appInstanceID: this.appInstanceID, + windowConfig: this.#windowConfig, + }, '*'); + this.#readyMessageSent = true; + }); // When this app's window is focused send a message to the host environment window.addEventListener('focus', (e) => { @@ -405,6 +417,18 @@ class UI extends EventListener { }); } + // Available options: + // - headless: Run app with no visible window + configureWindow = function(options) { + if (this.#readyMessageSent) { + throw new Error('Window configuration has already been sent; this call to puter.ui.configureWindow will have no effect! ' + + 'Make sure to call it before the DOMContentLoaded event.'); + } + this.#windowConfig = { + headless: options?.headless ?? false, + }; + } + onWindowClose = function(callback) { this.#onWindowClose = callback; }