Skip to content

feat: add pinch-to-zoom support to editor - #2963

Open
gahanad wants to merge 12 commits into
Acode-Foundation:mainfrom
gahanad:feat/editor-pinch-to-zoom
Open

gahanad wants to merge 12 commits into
Acode-Foundation:mainfrom
gahanad:feat/editor-pinch-to-zoom

Conversation

@gahanad

@gahanad gahanad commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Description

Adds pinch-to-zoom support to the editor to make editing more convenient on mobile devices.

Users can adjust the editor's font size using a two-finger pinch gesture, improving readability and usability on smaller screens.

Changes Made

  • Added a pinch-to-zoom extension for the editor.
  • Dynamically adjusts the editor font size based on the pinch gesture.
  • Enforces minimum and maximum font-size limits.
  • Saves the updated font size setting when the gesture ends.
  • Cleans up touch event listeners when the extension is destroyed.
  • Added unit tests covering pinch-zoom behavior and font-size calculations.

Testing

  • Added unit tests for pinch-zoom functionality.
  • Verified the targeted unit tests pass.
  • Manually tested pinch-to-zoom on an Android device.
  • Verified the full test suite and CI checks.

Related Issue

Closes #2426

@github-actions github-actions Bot added the enhancement New feature or request label Oct 9, 2026
@greptile-apps

greptile-apps Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge, with two non-blocking fixes recommended.

Findings

  1. P2 Tests ignore the event target ▶
  2. P2 Saved presets change shape ▶

Summary

Adds pinch-to-zoom to the editor and saves the font size when the gesture ends.

  • Editor users can change font size with a two-finger pinch.
  • Android browser sessions can reopen with a saved device preview.
  • The devcontainer lock and README badge link are updated.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Two fingers touch the editor] --> B[Track their identifiers]
  B --> C[Observe movement on document]
  C --> D{Movement confirmed?}
  D -->|Yes| E[Preview font size]
  D -->|No| F[Keep current size]
  E --> G[Gesture ends]
  G --> H[Apply final movement and save]
  H --> I[Remove gesture listeners]
Loading

Reviews (7) · Last reviewed commit: "style: apply biome import order and form..." · Reviewed by Greptile

Comment thread src/cm/pinchZoom.ts Outdated
Comment thread src/cm/pinchZoom.ts Outdated
Comment thread src/cm/pinchZoom.ts Outdated
Comment thread src/cm/pinchZoom.ts Outdated
@gahanad

This comment was marked as outdated.

Comment thread src/cm/pinchZoom.ts Outdated
@gahanad

This comment was marked as outdated.

Comment thread src/cm/pinchZoom.ts Outdated
@gahanad

This comment was marked as outdated.

@bajrangCoder

bajrangCoder commented Oct 11, 2026 •

Copy link
Copy Markdown
Member

There several accidental zoom in/zoom out

screen-20261011-164227.mp4

Comment thread src/cm/pinchZoom.ts Outdated
Comment thread src/cm/pinchZoom.ts Outdated
Comment thread src/cm/pinchZoom.ts Outdated
Comment thread src/cm/pinchZoom.ts Outdated
Comment thread src/cm/pinchZoom.ts Outdated
Comment thread src/cm/pinchZoom.ts Outdated
Comment thread src/cm/pinchZoom.ts Outdated
Comment thread src/cm/pinchZoom.ts Outdated
Comment thread src/cm/mainEditorExtensions.ts Outdated
@gahanad

This comment was marked as outdated.

Comment thread src/cm/pinchZoom.ts
Comment thread src/cm/touchSelectionMenu.js Outdated
@gahanad

gahanad commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

@greptile

@gahanad
gahanad requested a review from bajrangCoder October 13, 2026 21:32
Comment thread src/cm/pinchZoom.ts
persistFontSize();
}

const target = view.contentDOM;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Touch events keep targeting the element where each finger first landed, even after that element is removed from the DOM. Since move/end/cancel are only listened for on contentDOM, the gesture can get stuck:

  1. Two fingers start on lines in the lower part of the editor; spread to ~2x.
  2. The preview font change + requestMeasure() makes CM recompute a smaller viewport (visible area + ~500px margin), and the .cm-line under a finger is unmounted.
  3. That finger's touchmove/touchend now dispatch to a detached node and never reach contentDOM.

Result: gesture.pinching stays true, the inline preview is never cleared or persisted, and every subsequent two-finger touchstart bails on if (gesture.pinching ...) — pinch is dead until the editor state is swapped.

Suggest attaching the move/end/cancel listeners to window/document (capture) when a pinch starts and removing them in endPinch/destroy.

@bajrangCoder

Copy link
Copy Markdown
Member

Also isn't the line number area and editor area pinch-to-zoom at same time for better and smooth feel? as currently line number area adjusted itself after leaving zoom.

Also in some cases some accidental scrolls maybe using three finger/two finger etc does nothing but normally in acode those just scrolls so removing that will be a bit weird(if there is no valid reason)

dependabot Bot and others added 5 commits October 16, 2026 02:45
…on#2961)

Bumps ghcr.io/devcontainers/features/node from 2.1.0 to 2.1.1.

---
updated-dependencies:
- dependency-name: ghcr.io/devcontainers/features/node
  dependency-version: 2.1.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updated Discord badge URL to a new endpoint.
…e-Foundation#2966)

* refactor(browser): keep a list of devices in the emulator device list

* refactor(browser): register each device when added to the list

* feat(browser): apply the saved default preview size once layout is ready

* feat(browser): save and restore a default device preview size

* feat(browser): add "Set as Default" and "Clear Default" menu items

* feat(browser): handle "Set as Default" and "Clear Default" actions

* feat(browser): show default menu items only while Devices mode is on

* feat(browser): open the preview in Devices mode when a default is set

* feat(browser): restore the default preview mode on startup

* refactor(browser): allow applying desktop mode without reloading

* refactor(browser): make the reload in setDesktopMode optional

* fix(browser): apply saved desktop mode before the first load to avoid a reload

* fix(browser): only apply dimensions after layout, not desktop mode

* fix(browser): re-fit saved presets to the current screen on restore

* fix(browser): reload once after the saved size is applied

* fix(browser): don't resize the webview before the emulator is set up

* fix(browser): add reloadAfterLayout helper, only when a page was requested

* fix(browser): show "Clear Default" only when a default is saved

* fix(browser): refresh default menu items after Set as Default

* fix(browser): refresh default menu items after Clear Default
@gahanad

gahanad commented Oct 18, 2026

Copy link
Copy Markdown
Contributor Author

@greptile

clientY: number;
identifier?: number;
}>,
target: EventTarget = view.contentDOM,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Tests ignore the event target

The new target argument in fireTouch() is never used. Every event still goes to view.contentDOM, so the new tests do not check document-only events or lost events from a detached line. These tests can pass even when those paths are broken. Dispatch through target so they exercise the paths they describe.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

scaleSeekBar.getMax()
);
scaleSeekBar.setProgress(scale);
listener.onChange(getWidthProgress(), getHeightProgress(), scale / 100f);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Saved presets change shape

Restoring a saved preset uses the slider values instead of the dimensions calculated by selectDevice(). Each slider has a minimum of 300, but a fitted preset can be narrower. For example, an iPhone X fitted into a 600px-high preview is about 277px wide. Selecting it uses that width, but reopening the saved default uses 300px and changes its shape. Keep the fitted dimensions when applying the restored scale.

@gahanad

gahanad commented Oct 18, 2026

Copy link
Copy Markdown
Contributor Author

Also isn't the line number area and editor area pinch-to-zoom at same time for better and smooth feel? as currently line number area adjusted itself after leaving zoom.

Also in some cases some accidental scrolls maybe using three finger/two finger etc does nothing but normally in acode those just scrolls so removing that will be a bit weird(if there is no valid reason)

I've added a guard so a three-finger touch no longer starts a pinch and keeps Acode's normal behaviour. For two fingers inside the editor the gesture is now claimed by pinch-to-zoom , that's the intended feature tradeoff , but if the browser starts native scrolling before the pinch is recognized, the code bails out and the scroll continues as before. Single-finger scrolling is untouched.

@gahanad

gahanad commented Oct 18, 2026

Copy link
Copy Markdown
Contributor Author

Also isn't the line number area and editor area pinch-to-zoom at same time for better and smooth feel? as currently line number area adjusted itself after leaving zoom.

Also in some cases some accidental scrolls maybe using three finger/two finger etc does nothing but normally in acode those just scrolls so removing that will be a bit weird(if there is no valid reason)

About the line numbers: the preview writes the font size on the editor root (.cm-editor), which is the same element makeFontTheme() applies the persistent fontSize to, and the gutter rule only sets font-family , so line numbers inherit the live size and should zoom together with the content. Could you kindly re-check on the latest push?

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

Labels

community enhancement New feature or request

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

Request featured "Zoom"

4 participants