Skip to content

v1.11.0

Choose a tag to compare

@github-actions github-actions released this 19 Sep 15:55
· 445 commits to main since this release

[1.11.0] — 2026-09-19

Schema: 31 (V30 photos.content_hash / main_uid / group_key, V31 photos.resolved_at); SDK bumped to proton-sdk /
proton-drive-rs 0.6.5.

Changed

  • The gallery lays photos out in justified rows. Every tile is now its own photo's shape:
    photos are taken in capture order until they no longer fit the target height, and the row is
    then scaled to land exactly on the right margin. Nothing is cropped and nothing is
    letterboxed, which is what the square centre-cropped tiles used to do to portraits and
    panoramas. The last row of a day stays at the target height rather than being stretched, and
    Ctrl+scroll / Ctrl+± now changes that target height. Gaps and tile corners are smaller, so the
    page reads as photos rather than as cards.

  • Thumbnails stay on screen while you scroll. A decoded thumbnail now lands in the texture
    cache even when the tile that asked for it has already been recycled, the cache is a real LRU
    holding 1500 textures instead of 600, and the rows just past the edge of the window are
    fetched ahead of the scroll direction. Scrolling fast through a large timeline no longer
    leaves a screen of blank tiles behind.

  • Refresh on the Photos page really refreshes. Instead of only clearing the freshness stamp
    and letting the next read serve the stale page, it starts the timeline re-read and follows it:
    the page paints from what the daemon holds, then paints again when the new timeline lands. The
    timeline is also considered stale after 60 s rather than 5 minutes. pdfs refresh photos
    blocks until the re-read is done, as it reads.

  • Restore puts back the whole tree. The trash is a flat list, but you delete a shape: a
    folder, and often things you had already deleted inside it. Restoring a folder now also
    restores the items that were trashed inside it, and restoring one of those items first
    restores the trashed folders above it — otherwise the file came back into a folder that is
    still in the trash, which is to say nowhere you can see it. Parents are restored before their
    children, and each node is still restored individually, so one node the server refuses does
    not cancel the rest.

Added

  • A RAW and its JPEG are one photo. A camera that writes both put two tiles of the same shot
    in the timeline; now it puts one, badged RAW, and the lightbox has a control that switches
    between the files. The Raw tab still lists every raw file individually, because that is what
    the tab is for. Grouping follows the server's own photo relation where it has one — which
    also collapses live photos and bursts — and otherwise pairs files with the same name taken on
    the same day where one is raw and the other is not. Deleting the tile deletes the whole shot,
    and the confirmation says how many files that is.

  • Delete from the gallery. Select photos with the Select button, with Ctrl+click or with
    Shift+click, then Move to Trash — or press Delete in the lightbox. The tiles leave the grid
    immediately with an Undo toast, and the photos land in Proton's trash, where they stay
    recoverable. A photo the server refuses to trash comes back into the grid.

  • A photo deleted on your phone disappears here. The daemon now follows the photos volume's
    own event stream, so a photo trashed on another device leaves the gallery within about ten
    seconds instead of waiting for the timeline to go stale.

  • pdfs diagnostics. Reports what the daemon is doing right now: every worker thread with the job
    it holds and for how long, queue depths per lane, the control requests still in flight, resident
    size and the pending-op count. Answers even while the daemon is wedged, which is the only time
    anyone asks (B91).

  • A stall watchdog. The daemon warns in the journal when a worker has held one job for two
    minutes, when a control request has run that long, or when a queue is not draining — and it now
    answers the systemd watchdog, but only after a real round trip over its own control socket. A
    daemon that stops answering is restarted instead of sitting there looking healthy (B91).

Fixed

  • A Pixel raw capture groups with its JPEG. Pixel names the two files of one shot
    PXL_….RAW-01.COVER.jpg and PXL_….RAW-02.ORIGINAL.dng, so their stems differ and the pairing
    rule never saw them as one shot. The part-of-a-shot marker is now cut off before the names are
    compared, and the grid shows the cover JPEG once. The grouping is computed by a timeline
    refresh, so an existing library pairs up after the next one.
  • The Raw tab no longer decodes a raw it does not have to. A raw file that was written next
    to a JPEG of the same shot is now given that JPEG's thumbnail, which the server usually already
    has. No raw download and no raw decode for those tiles.
  • Photos can be moved to Trash from the gallery again. Photos live on the photo volume, which
    the mount never holds, so the write check found no node to consult and refused every photo with
    "trash access: not allowed". Membership of our own timeline now answers for them; an album photo
    on someone else's volume is still refused.
  • A photos refresh no longer fails with "Resource temporarily unavailable" (B92). Re-reading a
    twelve-thousand-photo library resolves the nodes in batches of 200 and takes minutes, but the
    daemon held the control reply until it had finished — well past the client's 120 s read bound.
    The caller therefore saw io: Resource temporarily unavailable (os error 11) for a refresh that
    was running perfectly, and the gallery reloaded from the old timeline. The daemon now answers as
    soon as the refresh is running, and the new PhotosRefreshStatus request reports when it is
    done. Each refresh also logs its photo count, batch count and duration.
  • A worker no longer panics during shutdown (B91). The FUSE worker pool is joined before the
    tokio runtime is dropped, so a worker still inside a job does not find a runtime that is going
    away underneath it.
  • A permanently rejected block upload is no longer retried (SDK 0.6.5). The SDK now knows
    which API errors are worth replaying: 4xx is permanent, except 404, 408 and 429.
  • Long downloads no longer fail on expired block URLs (SDK 0.6.5). A download whose block
    URLs lapse mid-transfer re-mints them once instead of failing, on the whole-file path and on
    public links, as reads already did.
  • A long rate-limit answer can no longer look like a hang (SDK 0.6.5). A server-supplied
    Retry-After is now capped at 120 s.