diff --git a/presenter/README.md b/presenter/README.md
index 4c3fba3..89ecee3 100644
--- a/presenter/README.md
+++ b/presenter/README.md
@@ -20,11 +20,9 @@ This will make the current window the Presenter view, and will open another wind
You are meant to move the audience view to the projector screen, and interact with the presenter view yourself.
Navigation in the two views is synced (including `.delayed` items).
-If you refresh the presenter view, you need to press Ctrl + P again to reconnect with the audience view,
-but it will reuse the same tab.
-On the other hand, if you refresh the audience view, the presenter view will automatically reconnect.
+Refreshing either window will automatically reconnect the two views, reusing the existing tabs.
-To exit presenter view, simply refresh the window.
+To exit presenter view, close the audience window, then refresh the presenter window.
## Limitations
diff --git a/presenter/plugin.js b/presenter/plugin.js
index a4b000c..948c95f 100644
--- a/presenter/plugin.js
+++ b/presenter/plugin.js
@@ -3,29 +3,58 @@ import { $$ } from "@inspirejs/core/util";
export const hasCSS = true;
+// Set up this window as the presenter, connected to the given projector window
+function connectToProjector (projector) {
+ Inspire.projector = projector;
+
+ if (projector?.Inspire) {
+ // Make sure the projector points back to us (in case we were reloaded)
+ projector.Inspire.presenter = window;
+ }
+
+ // Switch this one to presenter view
+ document.body.classList.add("presenter", "show-next");
+
+ // Are there elements in the current slide? Open them
+ $$("details.notes", Inspire.currentSlide).forEach(d => (d.open = true));
+}
+
Inspire.hooks.add({
"init-end": me => {
if (window.name === "projector" && window.opener && opener.Inspire) {
- // Projector window was reloaded
+ // Projector window was (re)loaded: reconnect to the presenter
document.body.classList.add("projector");
Inspire.presenter = opener;
Inspire.presenter.Inspire.projector = window;
}
+ else if (window.name === "presenter") {
+ // Presenter window was reloaded: try to reconnect to the projector.
+ // Passing an empty URL returns the existing window (if any) without
+ // reloading it. If none exists, the lookup yields a blank window (or
+ // is blocked and yields null), which we discard.
+ let projector = open("", "projector");
+
+ if (projector && projector !== window && projector.Inspire) {
+ connectToProjector(projector);
+ }
+ else {
+ // No projector to reconnect to; clean up and forget we were one
+ projector?.close();
+ window.name = "";
+ }
+ }
},
keyup: env => {
// Ctrl+P : Open Presenter view
if (env.letter === "P") {
+ // Name this window so it can find the projector again after a refresh
+ window.name = "presenter";
+
// Open new window for projector view
- Inspire.projector = open(location, "projector");
+ connectToProjector(open(location, "projector"));
// Get the focus back
window.focus();
-
- // Switch this one to presenter view
- document.body.classList.add("presenter", "show-next");
-
- // Are there elements in the current slide? Open them
- $$("details.notes", Inspire.currentSlide).forEach(d => (d.open = true));
}
},
slidechange: env => {