diff --git a/CHANGELOG.md b/CHANGELOG.md index 2bb734e3ad..742fc374a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,13 @@ # Changelog -## [15.4.0] (melonJS 2) - _2023-05-xx_ +## [15.4.0] (melonJS 2) - _2023-06-xx_ + +### Added +- Application: new `pauseOnBlur`, `resumeOnFocus` and `stopOnBlur` properties to configure a game behavior on blur and focus events ### Changed - Core: visibility and focus/blur events are now managed internally through new global `BLUR` and `FOCUS` events +- Device: `pauseOnBlur`, `resumeOnFocus` and `stopOnBlur` properties are now deprecated and replaced by their Application counterpart ### Fixed - Renderable : fix a potential issue with a Tile Layer not being properly redrawn when adding or clearing individual tiles diff --git a/src/application/application.js b/src/application/application.js index 429bb0e29a..b5ae986e91 100644 --- a/src/application/application.js +++ b/src/application/application.js @@ -85,6 +85,30 @@ import { CANVAS, WEBGL, AUTO } from "../const.js"; */ this.settings = undefined; + /** + * Specify whether to pause this app when losing focus + * @type {boolean} + * @default true + * @example + * // keep the default game instance running even when loosing focus + * me.game.pauseOnBlur = false; + */ + this.pauseOnBlur = true; + + /** + * Specify whether to unpause this app when gaining back focus + * @type {boolean} + * @default true + */ + this.resumeOnFocus = true; + + /** + * Specify whether to stop this app when losing focus + * @type {boolean} + * @default false + */ + this.stopOnBlur = false; + // to know when we have to refresh the display this.isDirty = true; @@ -234,6 +258,27 @@ import { CANVAS, WEBGL, AUTO } from "../const.js"; // render all game objects this.draw(); }, this); + + + // on blur event, pause the current + event.on(event.BLUR, () => { + if (this.stopOnBlur === true) { + state.stop(true); + } + if (this.pauseOnBlur === true) { + state.pause(true); + } + }); + + // on focus event, restart or resume the current + event.on(event.FOCUS, () => { + if (this.stopOnBlur === true) { + state.restart(true); + } + if (this.resumeOnFocus === true) { + state.resume(true); + } + }); } /** diff --git a/src/state/state.js b/src/state/state.js index 92db1f1977..b31c0fe104 100644 --- a/src/state/state.js +++ b/src/state/state.js @@ -2,7 +2,6 @@ import { pauseTrack, resumeTrack } from "./../audio/audio.js"; import * as fctUtil from "./../utils/function.js"; import * as event from "./../system/event.js"; import { game } from "../index.js"; -import * as device from "./../system/device.js"; import Stage from "./../state/stage.js"; import DefaultLoadingScreen from "./../loader/loadingscreen.js"; @@ -134,30 +133,6 @@ event.on(event.BOOT, () => { event.on(event.VIDEO_INIT, () => { state.change(state.DEFAULT, true); }); - - // on blur event, pause the current - event.on(event.BLUR, () => { - if (device.stopOnBlur === true) { - state.stop(true); - } - if (device.pauseOnBlur === true) { - state.pause(true); - } - }); - - // on focus event, restart or resume the current - event.on(event.FOCUS, () => { - if (device.stopOnBlur === true) { - state.restart(true); - } - if (device.resumeOnFocus === true) { - state.resume(true); - } - // force focus if autofocus is on - if (device.autoFocus === true) { - device.focus(); - } - }); }); /** diff --git a/src/system/device.js b/src/system/device.js index 359245092e..d47eaeb0d7 100644 --- a/src/system/device.js +++ b/src/system/device.js @@ -350,6 +350,8 @@ export let alpha = 0; * Specify whether to pause the game when losing focus * @name pauseOnBlur * @memberof device + * @deprecated since 15.4.0 + * @see Application.pauseOnBlur * @type {boolean} * @public * @default true @@ -360,6 +362,8 @@ export let pauseOnBlur = true; * Specify whether to unpause the game when gaining focus * @name resumeOnFocus * @memberof device + * @deprecated since 15.4.0 + * @see Application.resumeOnFocus * @type {boolean} * @public * @default true @@ -367,25 +371,27 @@ export let pauseOnBlur = true; export let resumeOnFocus = true; /** - * Specify whether to automatically bring the window to the front - * @name autoFocus + * Specify whether to stop the game when losing focus or not. + * The engine restarts on focus if this is enabled. + * @name stopOnBlur * @memberof device + * @deprecated since 15.4.0 + * @see Application.stopOnBlur * @type {boolean} * @public - * @default true + * @default false */ -export let autoFocus = true; +export let stopOnBlur = false; /** - * Specify whether to stop the game when losing focus or not. - * The engine restarts on focus if this is enabled. - * @name stopOnBlur + * Specify whether to automatically bring the window to the front + * @name autoFocus * @memberof device * @type {boolean} * @public - * @default false + * @default true */ -export let stopOnBlur = false; +export let autoFocus = true; /** * specify a function to execute when the Device is fully loaded and ready @@ -442,6 +448,10 @@ export function onReady(fn) { // set restart/resume action on gaining focus globalThis.addEventListener("focus", () => { event.emit(event.FOCUS); + // force focus if autofocus is on + if (autoFocus === true) { + this.focus(); + } }, false); } if (typeof globalThis.document !== "undefined") { @@ -450,6 +460,10 @@ export function onReady(fn) { globalThis.document.addEventListener("visibilitychange", () => { if (globalThis.document.visibilityState === "visible") { event.emit(event.FOCUS); + // force focus if autofocus is on + if (autoFocus === true) { + this.focus(); + } } else { event.emit(event.BLUR); }