Skip to content

Add previous and next buttons to the video Pip window - #31281

Open
meh7an wants to merge 1 commit into
telegramdesktop:devfrom
meh7an:feature/pip-navigation-buttons
Open

meh7an wants to merge 1 commit into
telegramdesktop:devfrom
meh7an:feature/pip-navigation-buttons

Conversation

@meh7an

@meh7an meh7an commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

The Picture-in-Picture window has no way to move between items in an album. Keyboard navigation does not reach it either, since it has no focus handling, so once a video opens there the only ways onward are closing the window or pressing Enlarge.

This adds Previous and Next buttons to the Pip window.

Changes

  • Two new OverState values and two Buttons, centred on the left and right edges, reusing the existing Pip button style and hover fade. They are painted and hit-tested only when a neighbour exists, so no dead arrow appears at either end of an album.
  • Pip::Delegate gains pipCanNavigate(int) and pipNavigate(int), implemented by OverlayWidget, which owns the shared media slice and moveToNext().
  • clearBeforeHide() takes a keepMediaContext flag. Handing a video to a Pip window previously cleared _message and the shared media, user photos and collage slices, so the album the video came from was gone and navigation was impossible. Streaming and UI resources are still released as before. A viewer hidden this way only follows its place in the album: shared media and user photo updates refresh the navigation state and return, and changingMsgId() leaves it alone.
  • A hidden viewer holding that context is not a visible one being toggled closed. show() runs its same-message toggle only while the viewer is shown; on a hidden one it asked close() for nothing and the request was swallowed. pipDismissed() replaces the plain _pip = nullptr where the window goes away for good (its close button, the message deleted, a passcode lock, an account change): if the viewer is hidden it releases the retained context the way hide() did before. Handovers, where the viewer or a new window takes over the stream, keep the plain reset.
  • pipNavigate() defers to the existing _showAsPip path. displayDocument() already moves a streaming video into a fresh Pip window while that flag is set, so the jump between two videos is handled there; a _pipGeneration counter distinguishes that from the case where nothing happened, and only the latter falls back to the viewer. A pointer comparison would not be safe here, since the previous PipWrap is destroyed and its address may be reused. The fallback shows the viewer through the same beforeShow() and moveToScreen() steps as displayFinished().
  • displayFinished() does not raise the viewer while a jump is in flight. A neighbour that had to be downloaded first re-displays in the background once it can be streamed, and displayDocument() moves it into the window at that moment, as it does for any playable video while _showAsPip is set.
  • _showAsPip stays set as before, so a jump that lands on a photo hands over to the viewer, since Pip cannot display one, and the next video, whether reached with the viewer's arrows, re-displayed after a download or opened from a chat, goes back into the window. Only Enlarge ends that, as on dev.
  • A new Pip takes over the hover state from the cursor position before its first paint, through the same handleMouseMove() a real hover uses, then finishes the controls fade at once. A window created under a cursor that is not moving receives no mouse move event, so its controls stayed hidden, faded back in and showed the default cursor until the mouse moved. Every jump builds a new window under the cursor, so a jump now looks like the same window changing its video.
  • kControlsCount goes from 7 to 9 in the OpenGL and RHI Pip renderers, with the two icons appended to their atlases at indices 7 and 8. The software renderer needs no atlas change.

Pip holds its document through a const pointer, so continuing in the window means building a new Pip rather than re-pointing the existing one. The request arrives from inside the Pip mouse handler, so the teardown is deferred until that handler has returned.

Testing

Built Debug on macOS against this base. Exercised by hand on both the OpenGL and the RHI renderer: video to video staying in the window, video to photo handing off to the viewer, returning to the window on a later video, and the controls remaining visible across a jump. The software renderer was not exercised, though it needs no atlas change.

After the review: open a video, Pip, close the window with its button, click the same video again. It reopens, as a Pip window, which is how dev reopens it as well since _showAsPip stays set (99501d8). Previous and Next between videos, onto a photo and back onto a video re-checked. The deleted-message and passcode paths share pipDismissed() and were not exercised by hand. Also: Pip, arrow onto a photo, close the viewer, open a video from a chat: it opens as a Pip; from that photo the viewer's own arrow onto a video returns to the window; after Enlarge the next video opens in the viewer.

Screenshot


2026-09-11_08-04-49

@meh7an meh7an closed this Sep 10, 2026
@meh7an meh7an reopened this Sep 10, 2026
@meh7an
meh7an marked this pull request as draft September 10, 2026 19:43
@meh7an
meh7an force-pushed the feature/pip-navigation-buttons branch from 3fe2c9b to bafb166 Compare September 10, 2026 23:05
@meh7an
meh7an marked this pull request as ready for review September 10, 2026 23:08
@meh7an
meh7an force-pushed the feature/pip-navigation-buttons branch 3 times, most recently from 2d21f99 to fdcf6f9 Compare September 16, 2026 15:10
@meh7an
meh7an marked this pull request as draft September 16, 2026 15:12
Keep the album alive while the viewer hands a video over, so the
window can walk it, and return to the window when a later jump
lands back on a video.

While hidden the viewer only follows its place in the album. A
request for the same message does not toggle it closed, and the
album is released once the window is dismissed for good.
@meh7an
meh7an force-pushed the feature/pip-navigation-buttons branch from fdcf6f9 to 77142a9 Compare September 16, 2026 15:57
@meh7an
meh7an marked this pull request as ready for review September 16, 2026 16:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant