Rust全局快捷键插件tauri-plugin-global-shortcut的使用,Tauri应用跨平台快捷键绑定与管理

plugin-global-shortcut

注册全局快捷键。

平台 支持情况
Linux
Windows
macOS
Android x
iOS x

安装

此插件要求Rust版本至少为1.77.2

我们推荐三种通用的安装方法。

  1. 使用crates.io和npm(最简单,需要您信任我们的发布流程正常工作)
  2. 使用git标签/修订哈希直接从Github拉取源代码(最安全)
  3. 在您的tauri项目中使用git子模块安装此仓库,然后使用文件协议引入源代码(最安全,但使用不便)

通过将以下内容添加到您的Cargo.toml文件来安装核心插件:

src-tauri/Cargo.toml

# 如果您不针对移动平台,可以在`[dependencies]`部分添加依赖
[target."cfg(not(any(target_os = \"android\", target_os = \"ios\")))".dependencies]
tauri-plugin-global-shortcut = "2.0.0"
# 或者使用Git:
tauri-plugin-global-shortcut = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }

您可以使用您喜欢的JavaScript包管理器安装JavaScript Guest绑定:

注意:由于大多数JavaScript包管理器无法从git monorepos安装包,我们为每个插件提供只读镜像。这使得安装选项2更易于使用。

pnpm add @tauri-apps/plugin-global-shortcut
# 或者
npm add @tauri-apps/plugin-global-shortcut
# 或者
yarn add @tauri-apps/plugin-global-shortcut

# 或者使用Git:
pnpm add https://github.com/tauri-apps/tauri-plugin-global-shortcut#v2
# 或者
npm add https://github.com/tauri-apps/tauri-plugin-global-shortcut#v2
# 或者
yarn add https://github.com/tauri-apps/tauri-plugin-global-shortcut#v2

用法

首先您需要向Tauri注册核心插件:

src-tauri/src/lib.rs

fn main() {
    tauri::Builder::default()
        .setup(|app| {
            #[cfg(desktop)]
            {
                use tauri::Manager;
                use tauri_plugin_global_shortcut::{Code, Modifiers, ShortcutState};

                app.handle().plugin(
                    tauri_plugin_global_shortcut::Builder::new()
                        .with_shortcuts(["ctrl+d", "alt+space"])?
                        .with_handler(|app, shortcut, event| {
                            if event.state == ShortcutState::Pressed  {
                                if shortcut.matches(Modifiers::CONTROL, Code::KeyD) {
                                    let _ = app.emit("shortcut-event", "Ctrl+D triggered");
                                }
                                if shortcut.matches(Modifiers::ALT, Code::Space) {
                                    let _ = app.emit("shortcut-event", "Alt+Space triggered");
                                }
                            }
                        })
                        .build(),
                )?;
            }

            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

之后,所有插件的API都可通过JavaScript绑定使用:

import { register } from '@tauri-apps/plugin-global-shortcut'
await register('CommandOrControl+Shift+C', (event) => {
  if (event.state === 'Pressed') {
    console.log('Shortcut triggered')
  }
})

贡献

接受PR。请在提交拉取请求之前确保阅读贡献指南。

合作伙伴

CrabNebula

有关赞助商的完整列表,请访问我们的网站和Open Collective。

许可证

代码:© 2015 - Present - The Tauri Programme within The Commons Conservancy。

MIT或MIT/Apache 2.0(适用时)。


完整示例代码

以下是一个完整的Tauri应用示例,展示如何使用tauri-plugin-global-shortcut插件:

src-tauri/Cargo.toml

[package]
name = "tauri-shortcut-demo"
version = "0.1.0"
description = "A Tauri app demonstrating global shortcuts"
authors = ["Your Name"]
license = "MIT OR Apache-2.0"

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tauri = { version = "1.0", features = ["api-all"] }

[build-dependencies]
tauri-build = { version = "1.0" }

# 全局快捷键插件依赖
[target."cfg(not(any(target_os = \"android\", target_os = \"ios\")))".dependencies]
tauri-plugin-global-shortcut = "2.0.0"

src-tauri/src/main.rs

fn main() {
    tauri::Builder::default()
        .setup(|app| {
            #[cfg(desktop)]
            {
                use tauri::Manager;
                use tauri_plugin_global_shortcut::{Code, Modifiers, ShortcutState};

                // 注册全局快捷键插件
                app.handle().plugin(
                    tauri_plugin_global_shortcut::Builder::new()
                        // 定义要注册的快捷键
                        .with_shortcuts(["Ctrl+Alt+T", "CommandOrControl+Shift+S", "Alt+Space"])?
                        // 设置快捷键处理程序
                        .with_handler(|app, shortcut, event| {
                            if event.state == ShortcutState::Pressed {
                                // 检查按下的快捷键并执行相应操作
                                if shortcut.matches(Modifiers::CONTROL | Modifiers::ALT, Code::KeyT) {
                                    let _ = app.emit("shortcut-event", "Ctrl+Alt+T pressed - Opening new tab");
                                    println!("New tab shortcut pressed");
                                }
                                
                                if shortcut.matches(Modifiers::SUPER | Modifiers::SHIFT, Code::KeyS) {
                                    let _ = app.emit("shortcut-event", "Cmd/Ctrl+Shift+S pressed - Saving file");
                                    println!("Save file shortcut pressed");
                                }
                                
                                if shortcut.matches(Modifiers::ALT, Code::Space) {
                                    let _ = app.emit("shortcut-event", "Alt+Space pressed - Showing command palette");
                                    println!("Command palette shortcut pressed");
                                }
                            }
                        })
                        .build(),
                )?;
            }
            Ok(())
        })
        .invoke_handler(tauri::generate_handler![register_custom_shortcut])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

// 自定义命令用于动态注册快捷键
#[tauri::command]
async fn register_custom_shortcut(shortcut: String, app_handle: tauri::AppHandle) -> Result<(), String> {
    #[cfg(desktop)]
    {
        use tauri_plugin_global_shortcut::ShortcutState;
        
        let shortcut_clone = shortcut.clone();
        tauri_plugin_global_shortcut::register(&shortcut, move |event| {
            if event.state == ShortcutState::Pressed {
                let _ = app_handle.emit("custom-shortcut-event", format!("{} pressed", shortcut_clone));
                println!("Custom shortcut pressed: {}", shortcut_clone);
            }
        }).map_err(|e| e.to_string())?;
    }
    
    Ok(())
}

src-tauri/src/lib.rs

#![cfg_attr(
    all(not(debug_assertions), target_os = "windows"),
    windows_subsystem = "windows"
)]

fn main() {
    tauri::Builder::default()
        .setup(|app| {
            #[cfg(desktop)]
            {
                use tauri::Manager;
                use tauri_plugin_global_shortcut::{Code, Modifiers, ShortcutState};

                app.handle().plugin(
                    tauri_plugin_global_shortcut::Builder::new()
                        .with_shortcuts(["ctrl+d", "alt+space"])?
                        .with_handler(|app, shortcut, event| {
                            if event.state == ShortcutState::Pressed  {
                                if shortcut.matches(Modifiers::CONTROL, Code::KeyD) {
                                    let _ = app.emit("shortcut-event", "Ctrl+D triggered");
                                }
                                if shortcut.matches(Modifiers::ALT, Code::Space) {
                                    let _ = app.emit("shortcut-event", "Alt+Space triggered");
                                }
                            }
                        })
                        .build(),
                )?;
            }

            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

前端JavaScript示例 (src/index.js):

import { register, unregister, isRegistered } from '@tauri-apps/plugin-global-shortcut'
import { invoke } from '@tauri-apps/api/core'
import { listen } from '@tauri-apps/api/event'

// 监听快捷键事件
const unlisten = await listen('shortcut-event', (event) => {
  console.log('Shortcut event:', event.payload)
  // 更新UI显示快捷键触发信息
  document.getElementById('shortcut-status').textContent = event.payload
})

// 监听自定义快捷键事件
const unlistenCustom = await listen('custom-shortcut-event', (event) => {
  console.log('Custom shortcut event:', event.payload)
})

// 动态注册新快捷键的示例函数
async function registerNewShortcut() {
  const shortcut = document.getElementById('shortcut-input').value
  try {
    await invoke('register_custom_shortcut', { shortcut })
    console.log(`Shortcut ${shortcut} registered successfully`)
  } catch (error) {
    console.error('Failed to register shortcut:', error)
  }
}

// 检查快捷键是否已注册
async function checkShortcut(shortcut) {
  const registered = await isRegistered(shortcut)
  console.log(`Shortcut ${shortcut} is registered:`, registered)
  return registered
}

// 取消注册快捷键
async function unregisterShortcut(shortcut) {
  await unregister(shortcut)
  console.log(`Shortcut ${shortcut} unregistered`)
}

// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', async () => {
  // 注册一些初始快捷键
  await register('CommandOrControl+Shift+C', (event) => {
    if (event.state === 'Pressed') {
      console.log('Custom shortcut triggered: CommandOrControl+Shift+C')
      document.getElementById('shortcut-status').textContent = 'Copy special triggered'
    }
  })
})

HTML界面示例:

<!DOCTYPE html>
<html>
<head>
    <title>Global Shortcut Demo</title>
</head>
<body>
    <h1>Tauri Global Shortcut Demo</h1>
    
    <div>
        <h2>当前快捷键状态</h2>
        <p id="shortcut-status">等待快捷键触发...</p>
    </div>
    
    <div>
        <h2>自定义快捷键</h2>
        <input type="text" id="shortcut-input" placeholder="例如: Ctrl+Shift+K" />
        <button onclick="registerNewShortcut()">注册快捷键</button>
    </div>
    
    <div>
        <h2>预定义快捷键</h2>
        <ul>
            <li>Ctrl+Alt+T - 打开新标签页</li>
            <li>Cmd/Ctrl+Shift+S - 保存文件</li>
            <li>Alt+Space - 显示命令面板</li>
            <li>Ctrl+D - 触发示例事件</li>
        </ul>
    </div>

    <script type="module" src="index.js"></script>
</body>
</html>

这个完整示例展示了如何在Tauri应用中:

  1. 在Rust端预定义多个全局快捷键
  2. 提供前端API来动态注册/取消注册快捷键
  3. 处理快捷键事件并在前后端之间通信
  4. 提供用户界面来管理快捷键

确保您的tauri.conf.json中正确配置了插件权限,并包含了必要的API调用权限。


1 回复

Rust全局快捷键插件:tauri-plugin-global-shortcut

介绍

tauri-plugin-global-shortcut是一个专为Tauri应用设计的跨平台全局快捷键插件。它允许开发者在应用程序处于后台运行时,仍然能够监听和响应系统级别的键盘快捷键。该插件支持Windows、macOS和Linux三大主流平台,提供了简单易用的API来注册、管理和处理全局快捷键。

使用方法

1. 添加依赖

首先在Cargo.toml中添加插件依赖:

[dependencies]
tauri-plugin-global-shortcut = "0.1"

2. 注册插件

在Tauri应用初始化时注册插件:

fn main() {
    tauri::Builder::default()
        .plugin(tauri_plugin_global_shortcut::init())
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

3. 基本使用示例

use tauri::Manager;

#[tauri::command]
fn register_shortcut(app_handle: tauri::AppHandle, shortcut: String) -> Result<(), String> {
    let app_handle = app_handle.clone();
    
    app_handle.global_shortcut_manager()
        .register(&shortcut, move || {
            println!("快捷键 {} 被触发!", shortcut);
            // 在这里处理快捷键触发的逻辑
        })
        .map_err(|e| e.to_string())
}

#[tauri::command]
fn unregister_shortcut(app_handle: tauri::AppHandle, shortcut: String) -> Result<(), String> {
    app_handle.global_shortcut_manager()
        .unregister(&shortcut)
        .map_err(|e| e.to_string())
}

fn main() {
    tauri::Builder::default()
        .plugin(tauri_plugin_global_shortcut::init())
        .invoke_handler(tauri::generate_handler![register_shortcut, unregister_shortcut])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

4. 前端调用示例

// 注册快捷键
async function registerShortcut(shortcut) {
    await invoke('register_shortcut', { shortcut });
    console.log(`已注册快捷键: ${shortcut}`);
}

// 注销快捷键
async function unregisterShortcut(shortcut) {
    await invoke('unregister_shortcut', { shortcut });
    console.log(`已注销快捷键: ${shortcut}`);
}

// 使用示例
registerShortcut('Ctrl+Shift+P');
registerShortcut('Alt+Space');

5. 快捷键格式说明

插件支持标准的快捷键格式:

  • Ctrl+Key (Windows/Linux)
  • Cmd+Key (macOS)
  • Alt+Key
  • Shift+Key
  • Super+Key (Windows键或Command键)

示例:Ctrl+Alt+T, Cmd+Shift+1, Alt+Space

6. 高级功能:检查快捷键是否已注册

#[tauri::command]
fn is_registered(app_handle: tauri::AppHandle, shortcut: String) -> Result<bool, String> {
    app_handle.global_shortcut_manager()
        .is_registered(&shortcut)
        .map_err(|e| e.to_string())
}

7. 错误处理最佳实践

#[tauri::command]
fn safe_register_shortcut(app_handle: tauri::AppHandle, shortcut: String) -> Result<(), String> {
    let manager = app_handle.global_shortcut_manager();
    
    // 检查是否已注册
    if manager.is_registered(&shortcut).unwrap_or(false) {
        return Err("快捷键已注册".into());
    }
    
    let app_handle_clone = app_handle.clone();
    manager.register(&shortcut, move || {
        // 处理快捷键触发事件
        println!("快捷键触发: {}", shortcut);
        // 可以在这里发送事件到前端
        app_handle_clone.emit_all("shortcut-triggered", &shortcut).unwrap();
    })
    .map_err(|e| format!("注册失败: {}", e))
}

完整示例代码

// main.rs
use tauri::Manager;

// 注册快捷键命令
#[tauri::command]
fn register_shortcut(app_handle: tauri::AppHandle, shortcut: String) -> Result<(), String> {
    let app_handle = app_handle.clone();
    
    app_handle.global_shortcut_manager()
        .register(&shortcut, move || {
            println!("快捷键 {} 被触发!", shortcut);
            // 在这里处理快捷键触发的逻辑
        })
        .map_err(|e| e.to_string())
}

// 注销快捷键命令
#[tauri::command]
fn unregister_shortcut(app_handle: tauri::AppHandle, shortcut: String) -> Result<(), String> {
    app_handle.global_shortcut_manager()
        .unregister(&shortcut)
        .map_err(|e| e.to_string())
}

// 检查快捷键是否已注册
#[tauri::command]
fn is_registered(app_handle: tauri::AppHandle, shortcut: String) -> Result<bool, String> {
    app_handle.global_shortcut_manager()
        .is_registered(&shortcut)
        .map_err(|e| e.to_string())
}

// 安全的快捷键注册(带错误处理)
#[tauri::command]
fn safe_register_shortcut(app_handle: tauri::AppHandle, shortcut: String) -> Result<(), String> {
    let manager = app_handle.global_shortcut_manager();
    
    // 检查是否已注册
    if manager.is_registered(&shortcut).unwrap_or(false) {
        return Err("快捷键已注册".into());
    }
    
    let app_handle_clone = app_handle.clone();
    manager.register(&shortcut, move || {
        // 处理快捷键触发事件
        println!("快捷键触发: {}", shortcut);
        // 发送事件到前端
        app_handle_clone.emit_all("shortcut-triggered", &shortcut).unwrap();
    })
    .map_err(|e| format!("注册失败: {}", e))
}

fn main() {
    tauri::Builder::default()
        // 注册全局快捷键插件
        .plugin(tauri_plugin_global_shortcut::init())
        // 注册命令处理器
        .invoke_handler(tauri::generate_handler![
            register_shortcut, 
            unregister_shortcut, 
            is_registered, 
            safe_register_shortcut
        ])
        // 运行应用
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
// 前端调用示例 (JavaScript)
// 注册快捷键
async function registerShortcut(shortcut) {
    try {
        await invoke('register_shortcut', { shortcut });
        console.log(`已注册快捷键: ${shortcut}`);
    } catch (error) {
        console.error(`注册失败: ${error}`);
    }
}

// 注销快捷键
async function unregisterShortcut(shortcut) {
    try {
        await invoke('unregister_shortcut', { shortcut });
        console.log(`已注销快捷键: ${shortcut}`);
    } catch (error) {
        console.error(`注销失败: ${error}`);
    }
}

// 检查快捷键是否已注册
async function checkShortcut(shortcut) {
    try {
        const isRegistered = await invoke('is_registered', { shortcut });
        console.log(`快捷键 ${shortcut} 注册状态: ${isRegistered}`);
        return isRegistered;
    } catch (error) {
        console.error(`检查失败: ${error}`);
        return false;
    }
}

// 安全注册快捷键
async function safeRegisterShortcut(shortcut) {
    try {
        await invoke('safe_register_shortcut', { shortcut });
        console.log(`安全注册快捷键: ${shortcut}`);
    } catch (error) {
        console.error(`安全注册失败: ${error}`);
    }
}

// 使用示例
registerShortcut('Ctrl+Shift+P');
registerShortcut('Alt+Space');
safeRegisterShortcut('Cmd+1');

注意事项

  1. 某些快捷键可能已被系统或其他应用程序占用
  2. macOS需要用户授权辅助功能权限
  3. 建议提供用户可配置的快捷键设置界面
  4. 及时清理不再使用的快捷键以避免资源泄漏

这个插件为Tauri应用提供了强大的全局快捷键功能,使得开发桌面应用时能够实现类似原生应用的快捷键体验。

回到顶部