Skip to content

feat(SquirrelPanel): add right-click menu to delete a candidate - #1175

Open
sxin0 wants to merge 1 commit into
rime:masterfrom
sxin0:feat/delete-candidate-context-menu
Open

sxin0 wants to merge 1 commit into
rime:masterfrom
sxin0:feat/delete-candidate-context-menu

Conversation

@sxin0

@sxin0 sxin0 commented Sep 9, 2026

Copy link
Copy Markdown

What

Right-clicking a candidate opens a context menu with a single item that
forgets that candidate.

This wires up a librime API that Squirrel has never called:

RimeApi.delete_candidate_on_current_page(session, index)

Weasel has exposed the same operation as Shift+Delete for a long time;
Squirrel had no entry point for it at all.

Implementation notes

  • SquirrelInputController.deleteCandidate(_:) is deliberately symmetric
    with the existing selectCandidate(_:).
  • Hit testing reuses SquirrelView.click(at:), the same path left-click
    selection already goes through.
  • Window level. The panel is created at CGShieldingWindowLevel(),
    which is far above the level AppKit assigns to pop-up menus, so the
    menu would be drawn behind the candidate panel. The panel is lowered
    to NSWindow.Level.popUpMenu - 1 for the duration of menu tracking and
    restored afterwards. 100 is still above ordinary application windows,
    so the panel is not covered by the client app while the menu is open.
  • It deliberately does not call NSApp.activate. Activating would
    pull focus away from the client app and break the input session.
  • Adds one localized string with zh-Hans / zh-Hant translations.

Only deletion is implemented. There is no pin-to-top counterpart because
librime exposes no such API — candidate ordering is decided by translator
weights and user-dictionary learning, and a frontend cannot override it.

Testing

This has not been built or run. It was written on a machine with no
Xcode installed, so verification stopped at swiftc -parse. Two things
need checking on a real build before this is merged:

  1. Whether NSMenu.popUp(positioning:at:in:) tracks correctly from a
    non-activating panel in an LSUIElement app.
  2. Whether .rightMouseDown reaches the panel's sendEvent (left-click
    already does, so this is likely but unverified).

Flagging this explicitly rather than letting a reviewer assume it was
smoke-tested.

Right-clicking a candidate now opens a context menu whose single item
forgets that candidate, via the librime API that Squirrel had not been
wiring up so far:

  RimeApi.delete_candidate_on_current_page(session, index)

Hit testing reuses SquirrelView.click(at:), the same path the existing
left-click selection goes through.

The panel is created at CGShieldingWindowLevel, which is far above the
level AppKit assigns to pop-up menus, so the menu would otherwise be
drawn behind the candidate panel. Lower the panel to popUpMenu - 1 for
the duration of menu tracking and restore it afterwards; 100 is still
above ordinary application windows, so the panel is not covered by the
client app while the menu is open.
@LEOYoon-Tsaw

Copy link
Copy Markdown
Member

Mark 一下,有空我測測,這個有意思

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.

3 participants