diff --git a/spec/pane-container-spec.coffee b/spec/pane-container-spec.coffee index cd1a5208c..3ba7785b3 100644 --- a/spec/pane-container-spec.coffee +++ b/spec/pane-container-spec.coffee @@ -158,6 +158,32 @@ describe "PaneContainer", -> pane2.activate() expect(observed).toEqual [pane1.itemAtIndex(0), pane2.itemAtIndex(0)] + describe "::onDidStopChangingActivePaneItem()", -> + [container, pane1, pane2, observed] = [] + + beforeEach -> + container = new PaneContainer(params) + container.getRoot().addItems([new Object, new Object]) + container.getRoot().splitRight(items: [new Object, new Object]) + [pane1, pane2] = container.getPanes() + + observed = [] + container.onDidStopChangingActivePaneItem (item) -> observed.push(item) + + it "invokes observers once when the active item of the active pane changes", -> + pane2.activateNextItem() + pane2.activateNextItem() + expect(observed).toEqual [] + advanceClock 100 + expect(observed).toEqual [pane2.itemAtIndex(0)] + + it "invokes observers once when the active pane changes", -> + pane1.activate() + pane2.activate() + expect(observed).toEqual [] + advanceClock 100 + expect(observed).toEqual [pane2.itemAtIndex(0)] + describe "::onDidActivatePane", -> it "invokes observers when a pane is activated (even if it was already active)", -> container = new PaneContainer(params) diff --git a/src/pane-container.js b/src/pane-container.js index c914cc37f..5647a3db1 100644 --- a/src/pane-container.js +++ b/src/pane-container.js @@ -5,6 +5,7 @@ const ItemRegistry = require('./item-registry') const PaneContainerElement = require('./pane-container-element') const SERIALIZATION_VERSION = 1 +const STOPPED_CHANGING_ACTIVE_PANE_ITEM_DELAY = 100 module.exports = class PaneContainer { @@ -15,6 +16,7 @@ class PaneContainer { this.subscriptions = new CompositeDisposable() this.itemRegistry = new ItemRegistry() this.alive = true + this.stoppedChangingActivePaneItemTimeout = null this.setRoot(new Pane({container: this, config: this.config, applicationDelegate, notificationManager, deserializerManager, viewRegistry: this.viewRegistry})) this.didActivatePane(this.getRoot()) @@ -29,6 +31,7 @@ class PaneContainer { destroy () { this.alive = false for (let pane of this.getRoot().getPanes()) { pane.destroy() } + this.cancelStoppedChangingActivePaneItemTimeout() this.subscriptions.dispose() this.emitter.dispose() } @@ -280,6 +283,21 @@ class PaneContainer { didChangeActiveItemOnPane (pane, activeItem) { if (pane === this.getActivePane()) { this.emitter.emit('did-change-active-pane-item', activeItem) + + this.cancelStoppedChangingActivePaneItemTimeout() + // `setTimeout()` isn't available during the snapshotting phase, but that's okay. + if (typeof setTimeout === 'function') { + this.stoppedChangingActivePaneItemTimeout = setTimeout(() => { + this.stoppedChangingActivePaneItemTimeout = null + this.emitter.emit('did-stop-changing-active-pane-item', activeItem) + }, STOPPED_CHANGING_ACTIVE_PANE_ITEM_DELAY) + } + } + } + + cancelStoppedChangingActivePaneItemTimeout () { + if (this.stoppedChangingActivePaneItemTimeout != null) { + clearTimeout(this.stoppedChangingActivePaneItemTimeout) } } }