Skip to content

Commit

Permalink
feat(core): globalShortcut API (#1232)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasfernog committed Feb 14, 2021
1 parent 772d83e commit 855effa
Show file tree
Hide file tree
Showing 22 changed files with 481 additions and 15 deletions.
7 changes: 7 additions & 0 deletions .changes/shortcut-api.md
@@ -0,0 +1,7 @@
---
"api": minor
"tauri-api": minor
"tauri": minor
---

Adds a global shortcut API.
3 changes: 2 additions & 1 deletion api/package.json
Expand Up @@ -14,7 +14,8 @@
"./notification": "./dist/notification.js",
"./tauri": "./dist/tauri.js",
"./window": "./dist/window.js",
"./shell": "./dist/shell.js"
"./shell": "./dist/shell.js",
"./globalShortcut": "./dist/globalShortcut.js"
},
"funding": {
"type": "opencollective",
Expand Down
3 changes: 2 additions & 1 deletion api/rollup.config.js
Expand Up @@ -20,7 +20,8 @@ export default [
tauri: './src/tauri.ts',
window: './src/window.ts',
cli: './src/cli.ts',
notification: './src/notification.ts'
notification: './src/notification.ts',
globalShortcut: './src/globalShortcut.ts'
},
treeshake: true,
perf: true,
Expand Down
4 changes: 3 additions & 1 deletion api/src/bundle.ts
Expand Up @@ -9,6 +9,7 @@ import * as shell from './shell'
import * as tauri from './tauri'
import * as window from './window'
import * as notification from './notification'
import * as globalShortcut from './globalShortcut'

export {
cli,
Expand All @@ -20,5 +21,6 @@ export {
shell,
tauri,
window,
notification
notification,
globalShortcut
}
39 changes: 39 additions & 0 deletions api/src/globalShortcut.ts
@@ -0,0 +1,39 @@
import { promisified, transformCallback } from './tauri'

/**
* register a global shortcut
* @param shortcut shortcut definition, modifiers and key separated by "+" e.g. Alt+Q
* @param handler shortcut handler callback
*/
async function registerShortcut(
shortcut: string,
handler: () => void
): Promise<void> {
return await promisified({
module: 'GlobalShortcut',
message: {
cmd: 'register',
shortcut,
handler: transformCallback(handler)
}
})
}

/**
* unregister a global shortcut
* @param shortcut shortcut definition, modifiers and key separated by "+" e.g. Alt+Q
*/
async function unregisterShortcut(shortcut: string): Promise<void> {
return await promisified({
module: 'GlobalShortcut',
message: {
cmd: 'unregister',
shortcut
}
})
}

export {
registerShortcut,
unregisterShortcut
}
9 changes: 1 addition & 8 deletions api/src/http.ts
Expand Up @@ -155,11 +155,4 @@ async function deleteRequest<T>(
})
}

export {
request,
get,
post,
put,
patch,
deleteRequest as httpDelete,
}
export { request, get, post, put, patch, deleteRequest as httpDelete }
2 changes: 1 addition & 1 deletion api/src/window.ts
Expand Up @@ -187,7 +187,7 @@ function resize(width: number, height: number): void {
message: {
cmd: 'resize',
width,
height,
height
}
})
}
Expand Down
2 changes: 2 additions & 0 deletions tauri-api/Cargo.toml
Expand Up @@ -35,6 +35,7 @@ tauri-utils = { version = "0.5", path = "../tauri-utils" }
clap = { version = "=3.0.0-beta.2", optional = true }
notify-rust = { version = "4.2.2", optional = true }
once_cell = "1.5.2"
tauri-hotkey = { git = "https://github.com/tauri-apps/tauri-hotkey-rs", branch = "dev", optional = true }

[dev-dependencies]
quickcheck = "1.0.3"
Expand All @@ -43,3 +44,4 @@ quickcheck_macros = "1.0.0"
[features]
cli = [ "clap" ]
notification = [ "notify-rust" ]
global-shortcut = [ "tauri-hotkey" ]
4 changes: 4 additions & 0 deletions tauri-api/src/error.rs
Expand Up @@ -53,6 +53,10 @@ pub enum Error {
#[cfg(feature = "cli")]
#[error("failed to parse CLI arguments: {0}")]
ParseCliArguments(#[from] clap::Error),
/// Shortcut error.
#[cfg(feature = "global-shortcut")]
#[error("shortcut error: {0}")]
Shortcut(#[from] tauri_hotkey::Error),
}

impl From<attohttpc::StatusCode> for Error {
Expand Down
4 changes: 4 additions & 0 deletions tauri-api/src/lib.rs
Expand Up @@ -30,6 +30,10 @@ pub mod cli;
#[macro_use]
extern crate clap;

/// Global shortcuts interface.
#[cfg(feature = "global-shortcut")]
pub mod shortcuts;

/// The desktop notifications API module.
#[cfg(feature = "notification")]
pub mod notification;
Expand Down
30 changes: 30 additions & 0 deletions tauri-api/src/shortcuts.rs
@@ -0,0 +1,30 @@
use tauri_hotkey::{parse_hotkey, HotkeyManager};

/// The shortcut manager builder.
#[derive(Default)]
pub struct ShortcutManager(HotkeyManager);

impl ShortcutManager {
/// Initializes a new instance of the shortcut manager.
pub fn new() -> Self {
Default::default()
}

/// Registers a new shortcut handler.
pub fn register_shortcut<H: FnMut() + Send + 'static>(
&mut self,
shortcut: String,
handler: H,
) -> crate::Result<()> {
let hotkey = parse_hotkey(&shortcut.to_uppercase().replace(" ", ""))?;
self.0.register(hotkey, handler)?;
Ok(())
}

/// Unregister a previously registered shortcut handler.
pub fn unregister_shortcut(&mut self, shortcut: String) -> crate::Result<()> {
let hotkey = parse_hotkey(&shortcut.to_uppercase().replace(" ", ""))?;
self.0.unregister(&hotkey)?;
Ok(())
}
}
5 changes: 4 additions & 1 deletion tauri/Cargo.toml
Expand Up @@ -49,7 +49,7 @@ serde = { version = "1.0", features = [ "derive" ] }
[features]
cli = [ "tauri-api/cli" ]
embedded-server = [ "tiny_http" ]
all-api = [ "tauri-api/notification" ]
all-api = [ "tauri-api/notification", "tauri-api/global-shortcut" ]
updater = [ ]

# FS
Expand Down Expand Up @@ -83,6 +83,9 @@ http-request = [ ]
# notification
notification = [ "tauri-api/notification" ]

# global shortcut
global-shortcut = [ "tauri-api/global-shortcut" ]

[[example]]
name = "communication"
path = "examples/communication/src-tauri/src/main.rs"
Expand Down
3 changes: 3 additions & 0 deletions tauri/build.rs
Expand Up @@ -44,5 +44,8 @@ fn main() {

// notification
notification: { any(all_api, feature = "notification") },

// global shortcut
global_shortcut: { any(all_api, feature = "global_shortcut" )},
}
}
81 changes: 81 additions & 0 deletions tauri/examples/api/src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions tauri/examples/api/src/App.svelte
Expand Up @@ -9,6 +9,7 @@
import Http from './components/Http.svelte'
import Notifications from './components/Notifications.svelte'
import Window from './components/Window.svelte'
import Shortcuts from './components/Shortcuts.svelte'
const views = [{
label: 'Messages',
Expand All @@ -31,6 +32,9 @@
}, {
label: 'Window',
component: Window
}, {
label: 'Shortcuts',
component: Shortcuts
}]
let selected = views[0].label;
Expand Down
41 changes: 41 additions & 0 deletions tauri/examples/api/src/components/Shortcuts.svelte
@@ -0,0 +1,41 @@
<script>
import { writable } from 'svelte/store'
import { registerShortcut, unregisterShortcut } from '@tauri-apps/api/globalShortcut'
export let onMessage
const shortcuts = writable([])
let shortcut = 'CTRL+X'
function register() {
const shortcut_ = shortcut
registerShortcut(shortcut_, () => {
onMessage(`Shortcut ${shortcut_} triggered`)
}).then(() => {
shortcuts.update(shortcuts_ => [...shortcuts_, shortcut_])
onMessage(`Shortcut ${shortcut_} registered successfully`)
}).catch(onMessage)
}
function unregister(shortcut) {
const shortcut_ = shortcut
unregisterShortcut(shortcut_).then(() => {
shortcuts.update(shortcuts_ => shortcuts_.filter(s => s !== shortcut_))
onMessage(`Shortcut ${shortcut_} unregistered`)
}).catch(onMessage)
}
</script>

<div style="margin-top: 24px">
<div>
<input placeholder="Type a shortcut with '+' as separator..." bind:value={shortcut}>
<button type="button" on:click={register}>Register</button>
</div>
<div>
{#each $shortcuts as savedShortcut}
<div>
{savedShortcut}
<button type="button" on:click={()=> unregister(savedShortcut)}>Unregister</button>
</div>
{/each}
</div>
</div>
2 changes: 1 addition & 1 deletion tauri/examples/communication/dist/__tauri.js

Large diffs are not rendered by default.

0 comments on commit 855effa

Please sign in to comment.