Disable desktop exit in browsers
This commit is contained in:
1 parent
92491dd06e
commit
b8b5c360f2
3 files changed
+20
-18
No files matched your search
+2
-2
@@ -84,9 +84,9 @@ Your best score is saved in `localStorage` as `meatslicer_best` and shown on the
|
|||||||
|---|---|
|
|---|---|
|
||||||
| **Enter / Space / Click** | Start run (title), restart after death |
|
| **Enter / Space / Click** | Start run (title), restart after death |
|
||||||
|
|
||||||
The title screen has **[X] Exit to Desktop**. Pause has **[Q] Main Menu** and **[X] Exit**.
|
The desktop app title screen has **[X] Exit to Desktop**. Pause has **[Q] Main Menu** and **[X] Exit**.
|
||||||
The first matching press arms a 3-second confirmation; press it again to confirm. `P` or
|
The first matching press arms a 3-second confirmation; press it again to confirm. `P` or
|
||||||
`Escape` resumes. Electron quits directly; the browser fallback asks you to close the tab.
|
`Escape` resumes. In a web browser, desktop-exit controls are greyed out and non-interactive.
|
||||||
|
|
||||||
Right-click is disabled (context menu suppressed). There is **no dash, no interact key** — pickups are collected by walking over them.
|
Right-click is disabled (context menu suppressed). There is **no dash, no interact key** — pickups are collected by walking over them.
|
||||||
|
|
||||||
|
|||||||
+17
-16
@@ -121,13 +121,12 @@ function returnToMenu() {
|
|||||||
Music.playMenu();
|
Music.playMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function canQuitDesktop() {
|
||||||
|
return !!(window.MSDesktop && typeof window.MSDesktop.quit === 'function');
|
||||||
|
}
|
||||||
|
|
||||||
function quitToDesktop() {
|
function quitToDesktop() {
|
||||||
if (window.MSDesktop && typeof window.MSDesktop.quit === 'function') {
|
if (canQuitDesktop()) window.MSDesktop.quit();
|
||||||
window.MSDesktop.quit();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
window.close();
|
|
||||||
addToast('EXIT BLOCKED', 'close this browser tab to exit.');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function confirmAction(name, action) {
|
function confirmAction(name, action) {
|
||||||
@@ -181,7 +180,7 @@ function update(dt) {
|
|||||||
case 'menu': {
|
case 'menu': {
|
||||||
const sl = PRESSURE_SLIDER_RECT;
|
const sl = PRESSURE_SLIDER_RECT;
|
||||||
const exitClick = Input.mpressed && inRect(Input.mx, Input.my, MENU_EXIT_BUTTON);
|
const exitClick = Input.mpressed && inRect(Input.mx, Input.my, MENU_EXIT_BUTTON);
|
||||||
if (keyPressed('x') || exitClick) {
|
if (canQuitDesktop() && (keyPressed('x') || exitClick)) {
|
||||||
confirmAction('desktop', quitToDesktop);
|
confirmAction('desktop', quitToDesktop);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -221,7 +220,7 @@ function update(dt) {
|
|||||||
const menuClick = Input.mpressed && inRect(Input.mx, Input.my, PAUSE_MENU_BUTTON);
|
const menuClick = Input.mpressed && inRect(Input.mx, Input.my, PAUSE_MENU_BUTTON);
|
||||||
const exitClick = Input.mpressed && inRect(Input.mx, Input.my, PAUSE_EXIT_BUTTON);
|
const exitClick = Input.mpressed && inRect(Input.mx, Input.my, PAUSE_EXIT_BUTTON);
|
||||||
if (keyPressed('q') || menuClick) { confirmAction('menu', returnToMenu); break; }
|
if (keyPressed('q') || menuClick) { confirmAction('menu', returnToMenu); break; }
|
||||||
if (keyPressed('x') || exitClick) { confirmAction('desktop', quitToDesktop); break; }
|
if (canQuitDesktop() && (keyPressed('x') || exitClick)) { confirmAction('desktop', quitToDesktop); break; }
|
||||||
if (keyPressed('p', 'escape')) { G.mode = 'play'; G.confirmAction = null; G.confirmT = 0; Sfx.menu(); break; }
|
if (keyPressed('p', 'escape')) { G.mode = 'play'; G.confirmAction = null; G.confirmT = 0; Sfx.menu(); break; }
|
||||||
if (keyPressed('h') || (Input.mpressed && inRect(Input.mx, Input.my, HELP_BUTTON))) {
|
if (keyPressed('h') || (Input.mpressed && inRect(Input.mx, Input.my, HELP_BUTTON))) {
|
||||||
G.pauseHelp = true; G.helpPage = 0; G.confirmAction = null; G.confirmT = 0; Sfx.menu(); break;
|
G.pauseHelp = true; G.helpPage = 0; G.confirmAction = null; G.confirmT = 0; Sfx.menu(); break;
|
||||||
@@ -388,11 +387,12 @@ function drawMenu(ctx) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
const exitHover = inRect(Input.mx, Input.my, MENU_EXIT_BUTTON);
|
const exitHover = inRect(Input.mx, Input.my, MENU_EXIT_BUTTON);
|
||||||
const exitConfirm = G.confirmAction === 'desktop';
|
const desktopExit = canQuitDesktop();
|
||||||
drawPixelTag(ctx, exitConfirm ? '[X] CONFIRM EXIT' : '[X] EXIT TO DESKTOP', MENU_EXIT_BUTTON.x, MENU_EXIT_BUTTON.y, {
|
const exitConfirm = desktopExit && G.confirmAction === 'desktop';
|
||||||
|
drawPixelTag(ctx, !desktopExit ? '[X] DESKTOP APP ONLY' : (exitConfirm ? '[X] CONFIRM EXIT' : '[X] EXIT TO DESKTOP'), MENU_EXIT_BUTTON.x, MENU_EXIT_BUTTON.y, {
|
||||||
width: MENU_EXIT_BUTTON.w, height: MENU_EXIT_BUTTON.h,
|
width: MENU_EXIT_BUTTON.w, height: MENU_EXIT_BUTTON.h,
|
||||||
color: exitConfirm ? '#ffd36a' : (exitHover ? '#f5e9d6' : '#ad8f8c'),
|
color: !desktopExit ? '#65595b' : (exitConfirm ? '#ffd36a' : (exitHover ? '#f5e9d6' : '#ad8f8c')),
|
||||||
accent: exitConfirm ? '#d69a22' : (exitHover ? '#e22b46' : '#6e3843'),
|
accent: !desktopExit ? '#3a2d31' : (exitConfirm ? '#d69a22' : (exitHover ? '#e22b46' : '#6e3843')),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -488,17 +488,18 @@ function drawPause(ctx) {
|
|||||||
const menuHover = inRect(Input.mx, Input.my, PAUSE_MENU_BUTTON);
|
const menuHover = inRect(Input.mx, Input.my, PAUSE_MENU_BUTTON);
|
||||||
const exitHover = inRect(Input.mx, Input.my, PAUSE_EXIT_BUTTON);
|
const exitHover = inRect(Input.mx, Input.my, PAUSE_EXIT_BUTTON);
|
||||||
const menuConfirm = G.confirmAction === 'menu';
|
const menuConfirm = G.confirmAction === 'menu';
|
||||||
const exitConfirm = G.confirmAction === 'desktop';
|
const desktopExit = canQuitDesktop();
|
||||||
|
const exitConfirm = desktopExit && G.confirmAction === 'desktop';
|
||||||
drawPixelTag(ctx, '[M] MUTE AUDIO', gridX[0], 526, { width: 150, height: 28, color: '#bba9a1', accent: '#6e3843' });
|
drawPixelTag(ctx, '[M] MUTE AUDIO', gridX[0], 526, { width: 150, height: 28, color: '#bba9a1', accent: '#6e3843' });
|
||||||
drawPixelTag(ctx, menuConfirm ? '[Q] CONFIRM MENU' : '[Q] MAIN MENU', PAUSE_MENU_BUTTON.x, PAUSE_MENU_BUTTON.y, {
|
drawPixelTag(ctx, menuConfirm ? '[Q] CONFIRM MENU' : '[Q] MAIN MENU', PAUSE_MENU_BUTTON.x, PAUSE_MENU_BUTTON.y, {
|
||||||
width: PAUSE_MENU_BUTTON.w, height: PAUSE_MENU_BUTTON.h,
|
width: PAUSE_MENU_BUTTON.w, height: PAUSE_MENU_BUTTON.h,
|
||||||
color: menuConfirm ? '#ffd36a' : (menuHover ? '#f5e9d6' : '#bba9a1'),
|
color: menuConfirm ? '#ffd36a' : (menuHover ? '#f5e9d6' : '#bba9a1'),
|
||||||
accent: menuConfirm ? '#d69a22' : (menuHover ? '#b5243a' : '#6e3843'),
|
accent: menuConfirm ? '#d69a22' : (menuHover ? '#b5243a' : '#6e3843'),
|
||||||
});
|
});
|
||||||
drawPixelTag(ctx, exitConfirm ? '[X] CONFIRM EXIT' : '[X] EXIT', PAUSE_EXIT_BUTTON.x, PAUSE_EXIT_BUTTON.y, {
|
drawPixelTag(ctx, !desktopExit ? '[X] DESKTOP ONLY' : (exitConfirm ? '[X] CONFIRM EXIT' : '[X] EXIT'), PAUSE_EXIT_BUTTON.x, PAUSE_EXIT_BUTTON.y, {
|
||||||
width: PAUSE_EXIT_BUTTON.w, height: PAUSE_EXIT_BUTTON.h,
|
width: PAUSE_EXIT_BUTTON.w, height: PAUSE_EXIT_BUTTON.h,
|
||||||
color: exitConfirm ? '#ffd36a' : (exitHover ? '#f5e9d6' : '#bba9a1'),
|
color: !desktopExit ? '#65595b' : (exitConfirm ? '#ffd36a' : (exitHover ? '#f5e9d6' : '#bba9a1')),
|
||||||
accent: exitConfirm ? '#d69a22' : (exitHover ? '#b5243a' : '#6e3843'),
|
accent: !desktopExit ? '#3a2d31' : (exitConfirm ? '#d69a22' : (exitHover ? '#b5243a' : '#6e3843')),
|
||||||
});
|
});
|
||||||
|
|
||||||
const hb = HELP_BUTTON;
|
const hb = HELP_BUTTON;
|
||||||
|
|||||||
@@ -1582,6 +1582,7 @@ check('restart works', ctx.G.mode === 'play' && ctx.G.floor === 1);
|
|||||||
|
|
||||||
console.log('== confirmed destructive actions ==');
|
console.log('== confirmed destructive actions ==');
|
||||||
{
|
{
|
||||||
|
check('web renderer disables desktop-only exit', ctx.canQuitDesktop() === false);
|
||||||
let fired = 0;
|
let fired = 0;
|
||||||
ctx.confirmAction('probe', () => fired++);
|
ctx.confirmAction('probe', () => fired++);
|
||||||
check('first destructive action arms confirmation without firing', ctx.G.confirmAction === 'probe' && ctx.G.confirmT > 2.9 && fired === 0);
|
check('first destructive action arms confirmation without firing', ctx.G.confirmAction === 'probe' && ctx.G.confirmT > 2.9 && fired === 0);
|
||||||
|
|||||||
Reference in new issue
Block a user