diff --git a/src/phoenix/shell.js b/src/phoenix/shell.js index f83b62dcdc..b61e2f792f 100644 --- a/src/phoenix/shell.js +++ b/src/phoenix/shell.js @@ -32,10 +32,27 @@ import initTauriShell from "./tauriShell.js"; initVFS(); -let windowLabelCount = 0; -// create a unique prefix for each window so that it doesnt collide with -// new window from other phoenix windows in same app session. -const labelPrefix = `phcode-${crypto.randomUUID().split("-")[0]}`; +// We can only have a maximum of 30 windows that have access to tauri apis +// This limit is set in file `tauri.conf.json` in phoenix-desktop repo at json paths +// this limit is there due to our use of phcode:// custom protocol. +// /tauri/security/dangerousRemoteDomainIpcAccess/0/windows and +// /tauri/security/dangerousRemoteDomainIpcAccess/1/windows +let MAX_ALLOWED_TAURI_WINDOWS = 30; + +async function getTauriWindowLabel() { + const tauriWindows = await window.__TAURI__.window.getAll(); + const windowLabels = {}; + for(let {label} of tauriWindows) { + windowLabels[label]=true; + } + for(let i=1; i<=MAX_ALLOWED_TAURI_WINDOWS; i++){ + const windowLabel = `phcode-${i}`; + if(!windowLabels[windowLabel]){ + return windowLabel; + } + } + throw new Error("Could not get a free window label to create tauri window"); +} Phoenix.app = { getNodeState: function (cbfn){ cbfn(new Error('Node cannot be run in phoenix browser mode')); @@ -99,22 +116,14 @@ Phoenix.app = { .catch(reject); }); }, - openURLInPhoenixWindow: function (url, { - windowTitle, windowLabel, fullscreen, resizable, + openURLInPhoenixWindow: async function (url, { + windowTitle, fullscreen, resizable, height, minHeight, width, minWidth, acceptFirstMouse, preferTabs } = {}){ const defaultHeight = 900, defaultWidth = 1366; if(window.__TAURI__){ - let tauriWindow; - if(windowLabel) { - tauriWindow = window.__TAURI__.window.WebviewWindow.getByLabel(windowLabel); - if(tauriWindow) { - console.error(`An existing window already exists for windowLabel:${windowLabel}, please close window and call openURLInPhoenixWindow!`); - return tauriWindow; - } - } - - tauriWindow = new window.__TAURI__.window.WebviewWindow(windowLabel || `${labelPrefix}-${windowLabelCount++}`, { + const windowLabel = await getTauriWindowLabel(); + const tauriWindow = new window.__TAURI__.window.WebviewWindow(windowLabel, { url, title: windowTitle || windowLabel || url, fullscreen, @@ -136,7 +145,7 @@ Phoenix.app = { if(preferTabs) { features = ""; } - const nativeWindow = window.open(url, windowLabel||'_blank', features); + const nativeWindow = window.open(url, '_blank', features); nativeWindow.isTauriWindow = false; return nativeWindow; }, diff --git a/test/spec/Tauri-platform-test.html b/test/spec/Tauri-platform-test.html new file mode 100644 index 0000000000..14732a90e3 --- /dev/null +++ b/test/spec/Tauri-platform-test.html @@ -0,0 +1,13 @@ + + + + + Test tauri apis accessible + + + +sending event with tauri api... + + \ No newline at end of file diff --git a/test/spec/Tauri-platform-test.js b/test/spec/Tauri-platform-test.js index 30719c1376..731e67150d 100644 --- a/test/spec/Tauri-platform-test.js +++ b/test/spec/Tauri-platform-test.js @@ -19,7 +19,7 @@ * */ -/*global describe, it, expect, beforeEach, afterEach, fs, path*/ +/*global describe, it, expect, beforeEach, afterEach, fs, path, Phoenix*/ define(function (require, exports, module) { if(!window.__TAURI__) { @@ -94,6 +94,41 @@ define(function (require, exports, module) { it("Should not be able to fetch files in appLocalData folder", async function () { await testAssetNotAccessibleFolder(await window.__TAURI__.path.appLocalDataDir()); }); + + function createWebView() { + return new Promise((resolve, reject)=>{ + let currentURL = new URL(location.href); + let pathParts = currentURL.pathname.split('/'); + pathParts[pathParts.length - 1] = 'spec/Tauri-platform-test.html'; + currentURL.pathname = pathParts.join('/'); + + let newURL = currentURL.href; + Phoenix.app.openURLInPhoenixWindow(newURL) + .then(tauriWindow =>{ + expect(tauriWindow.label.startsWith("phcode-")).toBeTrue(); + tauriWindow.listen('TAURI_API_WORKING', function () { + resolve(tauriWindow); + }); + }).catch(reject); + }); + + } + + it("Should be able to spawn tauri windows", async function () { + const tauriWindow = await createWebView(); + await tauriWindow.close(); + }); + + const maxWindows = 25; + it(`Should be able to spawn ${maxWindows} tauri windows`, async function () { + const tauriWindows = []; + for(let i=0; i