Skip to content

[ENG-1108] Canvas tool lock#851

Open
trangdoan982 wants to merge 2 commits intomainfrom
eng-1108-tool-lock
Open

[ENG-1108] Canvas tool lock#851
trangdoan982 wants to merge 2 commits intomainfrom
eng-1108-tool-lock

Conversation

@trangdoan982
Copy link
Collaborator

@trangdoan982 trangdoan982 commented Mar 3, 2026

@linear
Copy link

linear bot commented Mar 3, 2026

@supabase
Copy link

supabase bot commented Mar 3, 2026

This pull request has been ignored for the connected project zytfjzqyijgagqxrzbmz because there are no changes detected in packages/database/supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@trangdoan982 trangdoan982 changed the title [ENG-1108] Tool lock [ENG-1108] Canvas tool lock Mar 3, 2026
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

View 4 additional findings in Devin Review.

Open in Devin Review

Comment on lines +9 to +12
export const lockToolIfNeeded = (editor: Editor): void => {
if (!editor.getInstanceState().isToolLocked) {
editor.updateInstanceState({ isToolLocked: true });
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 lockToolIfNeeded unconditionally forces isToolLocked = true, overriding user preference

Every click on a tool in the DiscourseToolPanel calls lockToolIfNeeded(editor) before editor.setCurrentTool(...). This function unconditionally sets isToolLocked = true in the editor's global instance state whenever it's currently false.

Root Cause and Impact

The lockToolIfNeeded function at apps/roam/src/components/canvas/toolLock.ts:9-12 always forces isToolLocked to true:

export const lockToolIfNeeded = (editor: Editor): void => {
  if (!editor.getInstanceState().isToolLocked) {
    editor.updateInstanceState({ isToolLocked: true });
  }
};

This is called from DiscourseToolPanel.tsx:171 (panel click) and DiscourseToolPanel.tsx:198 (drag-drop relation). After this call, the global isToolLocked state is permanently set to true. This means:

  1. User has tool lock OFF (the default).
  2. User clicks any tool in the panel → lockToolIfNeeded silently forces isToolLocked = true.
  3. Now all tools (including those activated via keyboard shortcuts at apps/roam/src/components/canvas/uiOverrides.tsx:355,374,397) behave as locked, because the global state has been mutated.
  4. The user's preference is permanently overridden with no way to know it happened, and they must manually toggle the lock off via the tldraw UI.

Impact: The user's tool lock preference is silently and permanently overridden after any panel interaction. This changes the behavior of all subsequent tool usage across the entire canvas.

Prompt for agents
The lockToolIfNeeded function in apps/roam/src/components/canvas/toolLock.ts unconditionally forces isToolLocked to true, which permanently overrides the user's preference. There are two possible fixes depending on the intended behavior:

1. If the intent is that panel clicks should NOT modify the lock state (just respect whatever the user has set): Remove lockToolIfNeeded entirely and remove its calls at apps/roam/src/components/canvas/DiscourseToolPanel.tsx lines 171 and 198. The setCurrentToolToSelectIfUnlocked already handles the unlocked case correctly.

2. If the intent is that panel clicks should temporarily lock the tool (so one click = one use): Save and restore the previous isToolLocked state. For example, set isToolLocked to true before setCurrentTool, and after the shape is created (in setCurrentToolToSelectIfUnlocked), restore the original value. This would require threading the original state through or storing it somewhere accessible.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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