Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/guides/presenter-view.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ See [Authoring slides](slides.md#speaker-notes) and
## Using a second screen

To present on a projector while keeping the panel on your laptop screen,
click the "Open presenter view" button in the status bar.
It opens a second window at the same position
click the "Open a synced window" button in the status bar.
It opens another window at the same position
(see [Multi-window sync](#multi-window-sync) for what makes this work in a static build).
In the window on your laptop screen, press <kbd>p</kbd> to open the panel.
Leave the other window full-screen on the projector.
Expand All @@ -90,7 +90,7 @@ How position sync reaches other windows depends on how the deck is running:
- **`inkflow build` output** (including a bare `file://` double-click, with no server at all)
has no WebSocket to relay over,
so it syncs exactly **two** windows directly:
the one you launch "Open presenter view" from, and the window it opens.
the one you launch "Open a synced window" from, and the window it opens.
They talk to each other over a direct browser-to-browser link
that only exists between opener and opened window,
so a second window opened independently
Expand Down
45 changes: 45 additions & 0 deletions src/css/presenter/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,51 @@ body {
background: rgba(0, 0, 0, 0.08);
}

/* ── Status-bar tooltips: driven by data-tooltip (not title) so the slow, unstyled
native browser tooltip never doubles up with this one. Anchored above the bar,
since #statusbar sits at the bottom of the viewport. ── */
.hud-btn[data-tooltip] {
position: relative;
}
.hud-btn[data-tooltip]::after {
content: attr(data-tooltip);
position: absolute;
bottom: calc(100% + 8px);
left: 50%;
transform: translateX(-50%);
background: var(--surface);
color: var(--text);
border: 1px solid var(--overlay);
border-radius: 4px;
padding: 0.3rem 0.5rem;
font-size: 0.72rem;
white-space: nowrap;
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
pointer-events: none;
opacity: 0;
transition: opacity 0.1s ease;
z-index: 40;
}
.hud-btn[data-tooltip]:hover::after,
.hud-btn[data-tooltip]:focus-visible::after {
opacity: 1;
transition-delay: 0.35s;
}
/* Suppress while the sync dropdown is open — the tooltip would sit under the menu. */
#btn-sync[aria-expanded="true"]:hover::after {
opacity: 0;
transition-delay: 0s;
}
/* Edge buttons: keep the bubble on-screen instead of centering off the bar. */
#btn-theme[data-tooltip]::after {
left: 0;
transform: none;
}
#log-indicator[data-tooltip]::after {
left: auto;
right: 0;
}

.hud-sep {
width: 1px;
height: 16px;
Expand Down
39 changes: 39 additions & 0 deletions src/inkflow/bundles/presenter.css
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,45 @@ body {
[data-theme=light] .hud-btn:hover {
background: rgba(0, 0, 0, 0.08);
}
.hud-btn[data-tooltip] {
position: relative;
}
.hud-btn[data-tooltip]::after {
content: attr(data-tooltip);
position: absolute;
bottom: calc(100% + 8px);
left: 50%;
transform: translateX(-50%);
background: var(--surface);
color: var(--text);
border: 1px solid var(--overlay);
border-radius: 4px;
padding: 0.3rem 0.5rem;
font-size: 0.72rem;
white-space: nowrap;
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
pointer-events: none;
opacity: 0;
transition: opacity 0.1s ease;
z-index: 40;
}
.hud-btn[data-tooltip]:hover::after,
.hud-btn[data-tooltip]:focus-visible::after {
opacity: 1;
transition-delay: 0.35s;
}
#btn-sync[aria-expanded=true]:hover::after {
opacity: 0;
transition-delay: 0s;
}
#btn-theme[data-tooltip]::after {
left: 0;
transform: none;
}
#log-indicator[data-tooltip]::after {
left: auto;
right: 0;
}
.hud-sep {
width: 1px;
height: 16px;
Expand Down
2 changes: 1 addition & 1 deletion src/inkflow/bundles/presenter.js
Original file line number Diff line number Diff line change
Expand Up @@ -2858,7 +2858,7 @@
function renderSyncButton() {
btnSync.dataset.mode = state.syncMode;
const label = SYNC_LABELS[state.syncMode];
btnSync.title = `Sync: ${label} (s)`;
btnSync.dataset.tooltip = `Sync: ${label} (s)`;
btnSync.setAttribute("aria-label", `Sync mode: ${label}`);
for (const row of syncMenu.querySelectorAll(".sync-row")) {
const active = row.dataset.mode === state.syncMode;
Expand Down
18 changes: 9 additions & 9 deletions src/inkflow/presenter.html
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ <h2>KEYBINDINGS</h2>
</aside>
</div>
<div id="statusbar">
<button type="button" class="hud-btn" id="btn-theme" title="Toggle dark/light">
<button type="button" class="hud-btn" id="btn-theme" data-tooltip="Toggle dark/light" aria-label="Toggle dark/light">
<svg class="icon-sun" viewBox="0 0 16 16" width="17" height="17" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true" style="pointer-events:none">
<circle cx="8" cy="8" r="3"/>
<line x1="8" y1="1" x2="8" y2="2.5"/><line x1="8" y1="13.5" x2="8" y2="15"/>
Expand All @@ -153,31 +153,31 @@ <h2>KEYBINDINGS</h2>
</svg>
</button>
<span class="hud-sep"></span>
<button type="button" class="hud-btn" id="btn-prev" title="Previous (← h Backspace)">
<button type="button" class="hud-btn" id="btn-prev" data-tooltip="Previous (← h Backspace)" aria-label="Previous">
<svg viewBox="0 0 16 16" width="17" height="17" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" style="pointer-events:none">
<path d="M10 12L6 8l4-4"/>
</svg>
</button>
<button type="button" class="hud-btn" id="btn-fullscreen" title="Fullscreen (f)">
<button type="button" class="hud-btn" id="btn-fullscreen" data-tooltip="Fullscreen (f)" aria-label="Fullscreen">
<svg viewBox="0 0 16 16" width="17" height="17" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" style="pointer-events:none">
<path d="M1 5V2h3M12 2h3v3M15 11v3h-3M4 14H1v-3"/>
</svg>
</button>
<button type="button" class="hud-btn" id="btn-next" title="Next (→ l Space)">
<button type="button" class="hud-btn" id="btn-next" data-tooltip="Next (→ l Space)" aria-label="Next">
<svg viewBox="0 0 16 16" width="17" height="17" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" style="pointer-events:none">
<path d="M6 4l4 4-4 4"/>
</svg>
</button>
<span class="hud-sep"></span>
<button type="button" class="hud-btn" id="btn-overview" title="Overview (o)">
<button type="button" class="hud-btn" id="btn-overview" data-tooltip="Overview (o)" aria-label="Overview">
<svg viewBox="0 0 16 16" width="17" height="17" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true" style="pointer-events:none">
<rect x="1.5" y="1.5" width="5" height="5" rx="0.75"/>
<rect x="9.5" y="1.5" width="5" height="5" rx="0.75"/>
<rect x="1.5" y="9.5" width="5" height="5" rx="0.75"/>
<rect x="9.5" y="9.5" width="5" height="5" rx="0.75"/>
</svg>
</button>
<button type="button" class="hud-btn" id="btn-presenter" title="Presenter view (p)">
<button type="button" class="hud-btn" id="btn-presenter" data-tooltip="Presenter view (p)" aria-label="Presenter view">
<svg viewBox="0 0 16 16" width="17" height="17" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" style="pointer-events:none">
<rect x="1" y="2" width="14" height="10" rx="1.5"/>
<path d="M5.5 15h5M8 12v3"/>
Expand All @@ -188,7 +188,7 @@ <h2>KEYBINDINGS</h2>
that direction is off. The same glyph drives the collapsed button and every
menu row (fade state keyed off data-mode in sync.css). Menu opens upward. -->
<span class="sync-wrap">
<button type="button" class="hud-btn" id="btn-sync" aria-haspopup="true" aria-expanded="false" title="Sync mode (s)">
<button type="button" class="hud-btn" id="btn-sync" aria-haspopup="true" aria-expanded="false" data-tooltip="Sync mode (s)" aria-label="Sync mode">
<svg class="sync-glyph" viewBox="0 0 16 16" width="19" height="19" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" style="pointer-events:none">
<g class="arrow-up"><path d="M4.5 14V3"/><path d="M1.5 6 4.5 3 7.5 6"/></g>
<g class="arrow-down"><path d="M11.5 2v11"/><path d="M8.5 10 11.5 13 14.5 10"/></g>
Expand Down Expand Up @@ -225,7 +225,7 @@ <h2>KEYBINDINGS</h2>
</button>
</div>
</span>
<button type="button" class="hud-btn" id="btn-presenter-view" title="Open presenter view" aria-label="Open presenter view">
<button type="button" class="hud-btn" id="btn-presenter-view" data-tooltip="Open a synced window" aria-label="Open a synced window">
<svg viewBox="0 0 16 16" width="17" height="17" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" style="pointer-events:none">
<path d="M6.5 2H2.75A.75.75 0 0 0 2 2.75v10.5c0 .414.336.75.75.75h10.5a.75.75 0 0 0 .75-.75V9.5"/>
<path d="M9.5 2h4v4"/>
Expand All @@ -239,7 +239,7 @@ <h2>KEYBINDINGS</h2>
<span class="sep">|</span>
<span id="step-info">step –</span>
<span class="hud-sep"></span>
<button type="button" class="hud-btn" id="log-indicator" title="Show messages" aria-label="Show messages">
<button type="button" class="hud-btn" id="log-indicator" data-tooltip="Show messages" aria-label="Show messages">
<svg class="log-ic log-ic-debug" viewBox="0 0 16 16" width="17" height="17" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" style="pointer-events:none">
<circle cx="8" cy="8" r="4"/>
</svg>
Expand Down
2 changes: 1 addition & 1 deletion src/ts/presenter/syncmenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const SYNC_LABELS: Record<SyncMode, string> = {
function renderSyncButton(): void {
btnSync.dataset.mode = state.syncMode;
const label = SYNC_LABELS[state.syncMode];
btnSync.title = `Sync: ${label} (s)`;
btnSync.dataset.tooltip = `Sync: ${label} (s)`;
btnSync.setAttribute("aria-label", `Sync mode: ${label}`);
for (const row of syncMenu.querySelectorAll<HTMLElement>(".sync-row")) {
const active = row.dataset.mode === state.syncMode;
Expand Down