diff --git a/lib/program.js b/lib/program.js index d59448a..ab78d8f 100644 --- a/lib/program.js +++ b/lib/program.js @@ -443,12 +443,35 @@ Program.prototype._listenOutput = function() { Program.prototype.destroy = function() { var index = Program.instances.indexOf(this); + if (~index) { Program.instances.splice(index, 1); Program.total--; + + this.flush(); + this._exiting = true; + if (Program.total === 0) { Program.global = null; + + process.removeAllListeners('exit'); + + this.input.removeAllListeners('keypress'); + this.input.removeAllListeners('data'); + this.input.removeAllListeners('newListener'); + this.output.removeAllListeners('resize'); + + if (this.input.setRawMode) { + if (this.input.isRaw) { + this.input.setRawMode(false); + } + if (!this.input.destroyed) { + this.input.pause(); + } + } } + + this.destroyed = true; this.emit('destroy'); } }; diff --git a/lib/widgets/element.js b/lib/widgets/element.js index ace5c04..13de251 100644 --- a/lib/widgets/element.js +++ b/lib/widgets/element.js @@ -305,12 +305,6 @@ Element.prototype.free = function() { delete this._slisteners; }; -Element.prototype.destroy = function() { - this.detach(); - this.free(); - this.emit('destroy'); -}; - Element.prototype.hide = function() { if (this.hidden) return; this.clearPos(); diff --git a/lib/widgets/node.js b/lib/widgets/node.js index 3936b14..cdcfca8 100644 --- a/lib/widgets/node.js +++ b/lib/widgets/node.js @@ -135,6 +135,19 @@ Node.prototype.detach = function() { if (this.parent) this.parent.remove(this); }; +Node.prototype.free = function() { + return; +}; + +Node.prototype.destroy = function() { + this.detach(); + this.forDescendants(function(el) { + el.free(); + el.destroyed = true; + el.emit('destroy'); + }, this); +}; + Node.prototype.forDescendants = function(iter, s) { if (s) iter(this); this.children.forEach(function emit(el) { diff --git a/lib/widgets/screen.js b/lib/widgets/screen.js index 70e424f..8710653 100644 --- a/lib/widgets/screen.js +++ b/lib/widgets/screen.js @@ -35,7 +35,7 @@ function Screen(options) { return new Screen(options); } - Screen.bind(this); + Screen.bind(this, options || {}); options = options || {}; if (options.rsety && options.listen) { @@ -195,9 +195,12 @@ Screen.instances = []; Screen.signals = true; -Screen.bind = function(screen) { +Screen.bind = function(screen, options) { if (!Screen.global) { Screen.global = screen; + if (options.signals === false) { + Screen.signals = false; + } } if (!~Screen.instances.indexOf(screen)) { @@ -209,7 +212,7 @@ Screen.bind = function(screen) { Screen._bound = true; process.on('uncaughtException', function(err) { - if (process.listeners('uncaughtException').length > Screen.total) { + if (process.listeners('uncaughtException').length > 1) { return; } Screen.instances.slice().forEach(function(screen) { @@ -217,6 +220,9 @@ Screen.bind = function(screen) { }); err = err || new Error('Uncaught Exception.'); console.error(err.stack ? err.stack + '' : err + ''); + if (Screen.total === 0) { + return process.exit(1); + } nextTick(function() { process.exit(1); }); @@ -227,9 +233,12 @@ Screen.bind = function(screen) { if (Screen.signals) { ['SIGTERM', 'SIGINT', 'SIGQUIT'].forEach(function(signal) { process.on(signal, function() { - if (process.listeners(signal).length > Screen.total) { + if (process.listeners(signal).length > 1) { return; } + if (Screen.total === 0) { + return process.exit(0); + } nextTick(function() { process.exit(0); }); @@ -383,6 +392,7 @@ Screen.prototype.postEnter = function() { } }; +Screen.prototype._destroy = Screen.prototype.destroy; Screen.prototype.destroy = function() { this.leave(); @@ -390,10 +400,16 @@ Screen.prototype.destroy = function() { if (~index) { Screen.instances.splice(index, 1); Screen.total--; + if (Screen.total === 0) { Screen.global = null; + + process.removeAllListeners('uncaughtException'); } + + this.destroyed = true; this.emit('destroy'); + this._destroy(); } this.program.destroy(); diff --git a/lib/widgets/terminal.js b/lib/widgets/terminal.js index 165d52f..1997daa 100644 --- a/lib/widgets/terminal.js +++ b/lib/widgets/terminal.js @@ -209,6 +209,7 @@ Terminal.prototype.bootstrap = function() { this.on('destroy', function() { self.kill(); + self.screen.program.removeListener('data', self._onData); }); if (this.handler) { @@ -252,11 +253,6 @@ Terminal.prototype.bootstrap = function() { }); this.screen._listenKeys(this); - - this.on('destroy', function() { - self.screen.program.removeListener('data', self._onData); - self.pty.destroy(); - }); }; Terminal.prototype.write = function(data) {