{"record":{"id":"b21a5431eb5b64c4","repo":"nwjs/nw.js","slug":"only-following-event-can-be-listened-displaybound","errorCode":null,"errorMessage":"only following event can be listened: displayBoundsChanged, displayAdded, displayRemoved","messagePattern":"only following event can be listened: displayBoundsChanged, displayAdded, displayRemoved","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/api/screen/screen.js","lineNumber":32,"sourceCode":"// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM\n// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES\n// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS\n//  OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH\n// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n//  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar screenInstance = null;\n\nfunction Screen() {\n  nw.allocateObject(this, {});\n  this._numListener = 0;\n}\nrequire('util').inherits(Screen, exports.Base);\n\n// Override the addListener method.\nScreen.prototype.on = Screen.prototype.addListener = function(ev, callback) {\n  if ( ev != \"displayBoundsChanged\" && ev != \"displayAdded\" && ev != \"displayRemoved\" && ev != \"chooseDesktopMedia\")\n    throw new TypeError('only following event can be listened: displayBoundsChanged, displayAdded, displayRemoved');\n  \n  var onRemoveListener = function (type, listener) {\n    if (this._numListener > 0) {\n      this._numListener--;\n      if (this._numListener == 0) {\n        process.EventEmitter.prototype.removeListener.apply(this, [\"removeListener\", onRemoveListener]);\n        nw.callStaticMethodSync('Screen', 'RemoveScreenChangeCallback', [ this.id ]);\n      }\n    }\n  };\n\n  if(this._numListener == 0) {\n    if (nw.callStaticMethodSync('Screen', 'AddScreenChangeCallback', [ this.id ])[0] == false ) {\n      throw new Error('nw.callStaticMethodSync(Screen, AddScreenChangeCallback) fails');\n      return;\n    }\n    process.EventEmitter.prototype.addListener.apply(this, [\"removeListener\", onRemoveListener]);\n  }","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/nwjs/nw.js/blob/e15da848e9e08e6e467532dae78995c6ad2f55ee/src/api/screen/screen.js#L14-L50","documentation":"Screen overrides `on`/`addListener` and rejects any event name outside its whitelist. Note a discrepancy: the condition ALSO accepts 'chooseDesktopMedia', but the error message lists only the three display events — so the message under-reports the allowed set. Any other event name throws a TypeError.","triggerScenarios":"Calling nw.Screen.on('resize', fn), .on('change', fn), or any custom event. Even a typo like 'displayBoundChanged' (missing 's') throws.","commonSituations":"Assuming Screen is a general EventEmitter and listening for arbitrary names. Migrating from Electron's `screen.on('display-metrics-changed')`. Typos in the long event names.","solutions":["Use one of the supported events: 'displayBoundsChanged', 'displayAdded', 'displayRemoved' (and 'chooseDesktopMedia' for the dedicated API).","Copy event names exactly, including camelCase and the trailing 'Changed'/'Added'/'Removed'.","For desktop-media capture, prefer nw.Screen.chooseDesktopMedia(...) which wires the callback internally."],"exampleFix":"// before\nnw.Screen.on('displays-changed', fn); // throws\n\n// after\nnw.Screen.on('displayBoundsChanged', fn);\nnw.Screen.on('displayAdded', fn);\nnw.Screen.on('displayRemoved', fn);","handlingStrategy":"validation","validationCode":"var SCREEN_EVENTS = ['displayBoundsChanged', 'displayAdded', 'displayRemoved', 'chooseDesktopMedia'];\nfunction onScreen(ev, cb) {\n  if (SCREEN_EVENTS.indexOf(ev) === -1)\n    throw new TypeError('Unsupported screen event: ' + ev);\n  nw.Screen.on(ev, cb);\n}","typeGuard":"function isScreenEvent(ev) {\n  return ['displayBoundsChanged','displayAdded','displayRemoved','chooseDesktopMedia'].indexOf(ev) !== -1;\n}","tryCatchPattern":"try { nw.Screen.on(ev, cb); }\ncatch (e) {\n  if (e instanceof TypeError && /only following event/.test(e.message)) {\n    console.warn('Ignoring unsupported screen event:', ev);\n  } else throw e;\n}","preventionTips":["Copy event names exactly (camelCase, correct suffixes).","Note 'chooseDesktopMedia' is allowed even though the message omits it.","Centralize screen-event subscription in one module."],"tags":["nwjs","screen","events","validation","whitelist"],"backgroundTag":null,"analyzedSha":"e15da848e9e08e6e467532dae78995c6ad2f55ee","analyzedAt":"2026-08-13T04:15:35.452Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}