Skip to content

fix(canvas): the Controls rail keeps its frame buttons, disabled, while the canvas is locked (v0.21.4) #338

Description

@MerciHanrim

The bug

When the canvas is edit-locked, two buttons disappear from the Controls rail instead of staying there disabled, so the rail changes height and every button above them moves. Measured on main at 70a9c37 (v0.21.3), desktop, in light, dark and forced colours alike:

  • "Group frame" (the draw-a-frame tool, rf-frame) is removed from the DOM whenever the canvas is locked; "Clear all frames" (rf-frame-clear) is removed too in a document that has frames.
  • In a document with saved frames (Coffee) the rail goes from 12 buttons to 10: its top moves down from 531 to 583 px and its height from 314 to 262 px; without frames, 10 to 9 buttons, 583 to 609 px and 262 to 236 px. The rail's bottom stays at 845 px and every button stays 26 px tall, so each removed button shifts everything above it by 26 px.
  • The Tab order loses the same stops (12 to 10, and 10 to 9).
  • The two buttons have been hidden while locked since v0.12.0 (feat(frames): a frame drag carries its contents — derived membership, one-entry gesture transaction (§LGR6.5 / LGR-D9) #243, 2026-09-20). It is not a v0.21.3 regression: fix(canvas): a new document starts unlocked, and the edit lock blocks every user edit (v0.21.3) #334 made the other editing controls disabled while locked but did not cover these two.
  • A related case: a frame tool armed before locking stays armed after it. A drag on the empty canvas then starts a frame draft that the stores refuse, and drag-to-pan stays off, while the button that would turn the tool off is gone.

The contract (decided)

  • While the canvas is locked, "Group frame" and "Clear all frames" stay in the rail where they are, as native disabled buttons; a disabled button is left out of the Tab order, like the other controls fix(canvas): a new document starts unlocked, and the edit lock blocks every user edit (v0.21.3) #334 disables.
  • In the same document, the rail has the same buttons, the same 26 px button height and the same overall height before and after locking.
  • Locking turns an armed frame tool off.
  • The stores keep refusing a frame drawn or cleared while locked (fix(canvas): a new document starts unlocked, and the edit lock blocks every user edit (v0.21.3) #334).
  • Light, dark and forced colours: a disabled rail button reads as disabled (forced colours: GrayText), and keyboard focus stays visible on the enabled buttons.
  • Out of scope: the rail buttons that appear only when they apply, such as "Clear all frames" in a document with no frames, "Suggest frames" and "Clear suggested frames"; their presence still follows the document, as before.

Tests

  • e2e: in a document with saved frames and in one without, the rail's button list, each button's height and the rail's top and height are identical before and after locking, in light, dark and forced colours.
  • e2e: while locked both buttons are disabled, Tab skips them, and clicking them changes nothing; unlocking enables them again.
  • e2e: arming the frame tool and then locking turns it off, and a drag on the empty canvas then pans and draws no frame.
  • The existing store tests keep proving that a frame cannot be added or cleared while locked.

Released as v0.21.4. The special-silhouette work (#337) moves to v0.21.5 and resumes after this release. Related: #330, #334.

Activity

  1. MerciHanrim commented on Oct 8, 2026

    @MerciHanrim
    OwnerAuthor

    Shipped in v0.21.4 by #339, together with #340, squash-merged as 707fcc8 on 2026-10-08 at 16:55 Seoul time (07:55 UTC) from the approved head commit 703f00d; the two commits share the tree 823f8c3.

    • Scope delivered: while the canvas is locked, "Group frame" and "Clear all frames" stay in the Controls rail as native disabled buttons, left out of the Tab order, so in the same document the rail has the same buttons, the same 26 px button height and the same overall height locked and unlocked; locking turns an armed frame tool off. A bug since v0.12.0 (feat(frames): a frame drag carries its contents — derived membership, one-entry gesture transaction (§LGR6.5 / LGR-D9) #243), not a v0.21.3 regression.
    • Pull request CI (run 37744530957 at 703f00d, attempt 1): every job passed, the aggregate e2e job included; the five shards ran exactly the 2,034 listed tests, each once (2,027 passed, 7 skipped by design, 0 failed, 0 retried); the production bundle 16 of 16, the PWA 19 of 19.
    • Main CI (run 37746429564 at 707fcc8, attempt 1): every job passed, the aggregate e2e job included; the 2,034 listed tests each ran once: 2,027 passed, 7 skipped by design, 0 failed, 0 retried.
    • Production: https://cozy-loop-studio.pages.dev serves v0.21.4 · build 707fcc8 (the desktop toolbar label and the phone's ⋯ menu). An automated check through the UI only, in fresh Chrome contexts, passed 29 of 29: with saved frames and without, in light, dark and forced colours, the rail's buttons, their places and 26 px heights and the rail's top and height are identical locked and unlocked; locked, exactly the frame button(s) are native disabled, Tab never lands on them and clicking them changes nothing; unlocked they work; arming the tool and then locking turns it off, and a drag on the empty canvas then pans and draws no frame; the phone shows no frame button; no dev bridge and no page error.

    Baselines: the gacha and Early MMO Template views (light and dark) were replaced, as their rails now show the disabled button(s); the other 72 are byte-identical. Out of scope, as decided: the buttons that appear only when they apply ("Clear all frames" with no frame, "Suggest frames", "Clear suggested frames").

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions