Skip to content

fix(infra): 接入 tauri-plugin-single-instance 防双实例双插入 (closes #50)#71

Merged
appergb merged 1 commit into
developfrom
fix/50-single-instance
Apr 30, 2026
Merged

fix(infra): 接入 tauri-plugin-single-instance 防双实例双插入 (closes #50)#71
appergb merged 1 commit into
developfrom
fix/50-single-instance

Conversation

@appergb
Copy link
Copy Markdown
Collaborator

@appergb appergb commented Apr 30, 2026

问题

两份 OpenLess (`/Applications/OpenLess.app` + dev build) 同时跑时,两进程各自抓全局热键 → 按一次键被识别两次 → 文本插入两份。

修复

`tauri-plugin-single-instance` v2 + 二进程启动回调聚焦已有主窗口。

Test plan

  • cargo check 通过
  • 手动:从 `/Applications/OpenLess.app` 启动一份,再 `open .../release/bundle/macos/OpenLess.app` → 第二个秒退,第一个被聚焦
  • 临时绕过仍可:`pkill -f OpenLess` 再启动想要的那一个

关联

closes #50

Summary by Sourcery

Enforce single-instance behavior for the Tauri desktop app to prevent duplicate processing when multiple builds are running simultaneously.

New Features:

  • Integrate the tauri-plugin-single-instance plugin to route secondary launches to the existing main window and exit the new process.

Bug Fixes:

  • Prevent duplicate global hotkey handling and double text insertion when multiple OpenLess instances are started.

Build:

  • Add tauri-plugin-single-instance as a runtime dependency in the Tauri app Cargo.toml.

closes #50

现象:/Applications/OpenLess.app 与 dev build 同时存在时,两个进程各自注册
macOS CGEventTap 监听全局热键。用户按 Right Option 一次:
- A 实例捕获 → ASR session 1 → polish → Cmd+V
- B 实例同时捕获 → ASR session 2 → polish → Cmd+V
结果:用户口述被插入两份。

修复:
- Cargo.toml: 加入 tauri-plugin-single-instance v2
- lib.rs: builder 第一个 plugin 即注册它;第二个进程启动时回调聚焦已有主窗口

激活信号通过 plugin 内部 socket 传递,无需额外 IPC 设计。
@appergb appergb merged commit 0d5bfa9 into develop Apr 30, 2026
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Apr 30, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Integrates the tauri-plugin-single-instance to enforce a single running instance of the Tauri app and focus the existing main window when a second instance is launched, preventing duplicated hotkey handling and double text insertion, along with the necessary dependency wiring in Cargo.toml/lock.

Sequence diagram for handling a second OpenLess instance launch

sequenceDiagram
    actor User
    participant macOS
    participant SecondInstance
    participant SingleInstancePlugin
    participant FirstInstance
    participant MainWindow

    User->>macOS: Launch OpenLess second instance
    macOS->>SecondInstance: Start process
    SecondInstance->>SingleInstancePlugin: Initialize single instance lock
    SingleInstancePlugin-->>SecondInstance: Detect existing running instance
    SingleInstancePlugin->>FirstInstance: Send activation signal
    FirstInstance->>MainWindow: Call show_main_window
    MainWindow-->>User: Existing main window focused
    SingleInstancePlugin->>SecondInstance: Instruct immediate exit
    SecondInstance-->>macOS: Terminate process
Loading

File-Level Changes

Change Details Files
Enforce single-instance behavior in the Tauri application and focus the existing main window when a second instance is launched.
  • Register the tauri-plugin-single-instance plugin in the Tauri builder pipeline before other plugins.
  • Provide a callback that logs when a second instance launches and calls the existing show_main_window helper to focus the main window of the already-running app.
openless-all/app/src-tauri/src/lib.rs
Add tauri-plugin-single-instance dependency to the Tauri project.
  • Declare tauri-plugin-single-instance version 2 under [dependencies] in Cargo.toml.
  • Update Cargo.lock to resolve and lock the new dependency graph.
openless-all/app/src-tauri/Cargo.toml
openless-all/app/src-tauri/Cargo.lock

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@appergb appergb deleted the fix/50-single-instance branch April 30, 2026 05:28
Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

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