Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion gulpfile.js/thirdparty-lib-copy.js
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,9 @@ let copyThirdPartyLibs = series(
// jasmine-reporters
copyFiles.bind(copyFiles, ['node_modules/jasmine-reporters/src/**/*'],
'test/thirdparty/jasmine-reporters/'),
copyLicence.bind(copyLicence, 'node_modules/jasmine-reporters/LICENSE', 'jasmine-reporters')
copyLicence.bind(copyLicence, 'node_modules/jasmine-reporters/LICENSE', 'jasmine-reporters'),
// lmdb
copyLicence.bind(copyLicence, 'node_modules/lmdb/LICENSE', 'lmdb')

);

Expand Down
501 changes: 494 additions & 7 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
"jasmine-reporters": "^2.5.0",
"jsdoc-to-markdown": "^9.1.1",
"readable-stream": "^3.6.0",
"through2": "^4.0.2"
"through2": "^4.0.2",
"lmdb": "^3.5.1"
},
"scripts": {
"lint": "eslint --quiet src test",
Expand Down Expand Up @@ -121,4 +122,4 @@
"tinycolor2": "^1.4.2",
"underscore": "^1.13.4"
}
}
}
199 changes: 114 additions & 85 deletions src-node/package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src-node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@
"open": "^10.1.0",
"npm": "11.8.0",
"ws": "^8.17.1",
"lmdb": "^2.9.2",
"lmdb": "^3.5.1",
"mime-types": "^2.1.35",
"cross-spawn": "^7.0.6",
"which": "^2.0.1",
"@expo/sudo-prompt": "^9.3.2"
}
}
}
27 changes: 21 additions & 6 deletions src/document/DocumentCommandHandlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -1731,7 +1731,13 @@ define(function (require, exports, module) {
.finally(()=>{
raceAgainstTime(_safeNodeTerminate())
.finally(()=>{
Phoenix.app.closeWindow();
// In Electron, use allowClose() to bypass the close handler
// (which would otherwise trigger another cleanup cycle).
if(window.__ELECTRON__) {
window.electronAPI.allowClose();
} else {
Phoenix.app.closeWindow();
}
});
});
},
Expand All @@ -1742,8 +1748,10 @@ define(function (require, exports, module) {
}

function newPhoenixWindow(cliArgsArray = null, cwd=null) {
let width = window.innerWidth;
let height = window.innerHeight;
// Electron needs outerWidth/outerHeight (includes window chrome).
// Tauri needs innerWidth/innerHeight.
let width = window.__ELECTRON__ ? window.outerWidth : window.innerWidth;
let height = window.__ELECTRON__ ? window.outerHeight : window.innerHeight;
Phoenix.app.openNewPhoenixEditorWindow(width, height, cliArgsArray, cwd);
}

Expand Down Expand Up @@ -2252,7 +2260,7 @@ define(function (require, exports, module) {
Phoenix.app.closeWindow(true);
}
}
function attachTauriUnloadHandler() {
function _attachNativeUnloadHandler() {
Phoenix.app.onCloseWindowRequested(()=>{
_forceQuitIfNeeded();
if(closeInProgress){
Expand All @@ -2268,7 +2276,14 @@ define(function (require, exports, module) {
raceAgainstTime(_safeNodeTerminate())
.finally(()=>{
closeInProgress = false;
Phoenix.app.closeWindow();
// In Electron, we must call allowClose() to complete the original
// close request (sets forceClose=true). Calling closeWindow() would
// trigger a new close sequence and cause an infinite loop.
if(window.__ELECTRON__) {
window.electronAPI.allowClose();
} else {
Phoenix.app.closeWindow();
}
});
});
}, closeFail=>{
Expand All @@ -2282,7 +2297,7 @@ define(function (require, exports, module) {
let isTestWindow = (new window.URLSearchParams(window.location.search || "")).get("testEnvironment");
if (!isTestWindow) {
if(Phoenix.isNativeApp) {
attachTauriUnloadHandler();
_attachNativeUnloadHandler();
} else {
attachBrowserUnloadHandler();
}
Expand Down
4 changes: 3 additions & 1 deletion src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,9 @@
if(data && data.__fsError) {
throw new Error(data.message);
}
return data;
// fsReadFile returns binary data, decode to text
const decoder = new TextDecoder("utf-8");
return decoder.decode(data);
})
.catch(err => {
console.error("First boot detected or Failed to init storage from cache." +
Expand Down
17 changes: 14 additions & 3 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,8 @@ function confirmReload(title, message) {
});
copyButton.textContent = 'Copy Error';
getHelpButton.textContent = 'Get Help';
reloadButton.textContent = 'Restart App';
// In native apps, we can't reload because AES trust ring won't survive - must quit and restart manually
reloadButton.textContent = Phoenix.isNativeApp ? 'Quit App' : 'Restart App';
// Styling for visibility
// Define common styles for buttons
const buttonStyles = {
Expand Down Expand Up @@ -303,14 +304,22 @@ function confirmReload(title, message) {
return new Promise(resolve =>{
reloadButton.onclick = function() {
resolve(true);
reloadButton.textContent = 'Reloading...';
reloadButton.textContent = Phoenix.isNativeApp ? 'Quitting...' : 'Reloading...';
reloadButton.style.color = 'darkgray';
reloadButton.style.backgroundColor = 'grey';
};
});
}

function resetCacheAndRestart() {
// In native apps, we can't reload because AES trust ring won't survive - must quit
if (Phoenix.isNativeApp) {
// wait for 3 seconds for bugsnag to send report, then quit
setTimeout(() => {
Phoenix.app.closeWindow(true); // force close
}, 1000);
return;
}
// try a cache reset
if(window._resetCacheIfNeeded){
window._resetCacheIfNeeded(true)
Expand Down Expand Up @@ -341,7 +350,9 @@ async function _recoverOnFailure(err) {
'Critical error when loading brackets. Trying to reload again.');
const restartedOnce = sessionStorage.getItem(SESSION_RESTART_ONCE_DUE_TO_CRITICAL_ERROR);
let shouldRestart;
if(!restartedOnce){
// In native apps, we can't auto-restart because the AES trust ring won't survive a reload
// without proper dismantling. Always show confirmation dialog for native apps.
if(!restartedOnce && !Phoenix.isNativeApp){
sessionStorage.setItem(SESSION_RESTART_ONCE_DUE_TO_CRITICAL_ERROR, "true");
shouldRestart = true;
} else {
Expand Down
Loading
Loading