Is there a hook or signal when the tab closes or goes out of focus?

Hi,

I have a mime renderer that allows the user to modify the displayed data but all of the user’s changes are reverted when the user focuses on another tab and then refocuses on the data tab. I know this happens because renderModel is called whenever the tab comes into focus which re-reads the data from the file and reverts all of the changes.

I want to save the file when the user changes or closes the tab so that when they refocus the changes are persistent.

Is there an event when the user changes tabs or closes the tab that we can listen for in typescript? Or would it be better to implement saving on a timer, similar to a notebook?

Thanks in advance for your help.

Hi @makaylas, you can listen to the app.shell.currentChanged signal to know when a new tab is focused. I suppose you could also save the changes whenever the user edits the model as well (with possibly some throttling). Are you using the setData hook for saving the relevant changes?

Hi Ian,

Thanks for your response! I will definitely look at app.shell.currentChanged.

Yes, I am using setData to save.

@ian-r-rose, I’m having trouble getting app.shell.currentchanged to work as shown in this application level plugin or finding another mime-renderer that uses it. I also looked into IMimeDocumentTracker but I can’t figure out how to use that either.

Could you point me to a mime-renderer example that uses app.shell.currentChanged or more beginner friendly documentation on it?

Thanks

Oh, shoot, you’re absolutely right @makaylas, my mistake. The rendermime plugin interface is deliberately simplified to be an easier and more stable option for extension developers. As such, it doesn’t actually have access to the application shell.

Another way to accomplish this (which I probably should have suggested in the first place) is to hook into the onBeforeHide handler on your widget. This is called (as the name suggests), before the widget is hidden, and you can use it to do some extra work before a rerender occurs.

An example of this is in the PDF rendermime extension, which uses this to discard URL fragments: https://github.com/jupyterlab/jupyterlab/blob/32451a627a9443003edf65d7a1e452ff06026a91/packages/pdf-extension/src/index.ts#L90-L101

@ian-r-rose Thanks!

I got the hook working but it seems that setData only makes a temporary instance of the file and that the user has to save from the JupyterLab interface, either by a shortcut or the drop-down menu.

Is that the intended behavior of setData or am I missing a step to actually save the file to disk?

Thanks again

setData is only intended to change the in-memory representation of the document (this is because not all mime renderers are actually backed by a file on disk, such as the outputs in a console). So it doesn’t actually save the data, nor does it provide a hook to do so.

Is there a reason that it is not good enough to change the data in memory, and then let the user/autosave save it whenever?

Thanks for clarifying what setData does.

It would be enough to save in memory, if it were also autosaving to disc but we aren’t observing that behavior.

How would we implement autosave? That could solve our problem.

Autosave is a configuration settable by the user. It should be available via the settings menu, as well as in the advanced settings editor. It should default to on, is it not doing that?

You’re right, it is autosaving. I didn’t realize that I was saving on a 2 minute timer. Changing the timer to be smaller will serve our purposes.

Thanks for all of your help!

1 Like