mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-04-01 10:01:07 +02:00
feat(core): add clipboard writeText and readText APIs (#2035)
This commit is contained in:
committed by
GitHub
parent
3280c4aa91
commit
285bf64bf9
8
.changes/clipboard-api.md
Normal file
8
.changes/clipboard-api.md
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
"api": patch
|
||||
"tauri": patch
|
||||
"tauri-runtime": patch
|
||||
"tauri-runtime-wry": patch
|
||||
---
|
||||
|
||||
Adds `clipboard` APIs (write and read text).
|
||||
@@ -13,8 +13,8 @@ use tauri_runtime::{
|
||||
dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Position, Size},
|
||||
DetachedWindow, PendingWindow, WindowEvent,
|
||||
},
|
||||
Dispatch, Error, GlobalShortcutManager, Icon, Params, Result, RunEvent, RunIteration, Runtime,
|
||||
RuntimeHandle, UserAttentionType,
|
||||
ClipboardManager, Dispatch, Error, GlobalShortcutManager, Icon, Params, Result, RunEvent,
|
||||
RunIteration, Runtime, RuntimeHandle, UserAttentionType,
|
||||
};
|
||||
|
||||
#[cfg(feature = "menu")]
|
||||
@@ -33,6 +33,7 @@ use uuid::Uuid;
|
||||
use wry::{
|
||||
application::{
|
||||
accelerator::{Accelerator, AcceleratorId},
|
||||
clipboard::Clipboard,
|
||||
dpi::{
|
||||
LogicalPosition as WryLogicalPosition, LogicalSize as WryLogicalSize,
|
||||
PhysicalPosition as WryPhysicalPosition, PhysicalSize as WryPhysicalSize,
|
||||
@@ -97,7 +98,7 @@ macro_rules! dispatcher_getter {
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! shortcut_getter {
|
||||
macro_rules! getter {
|
||||
($self: ident, $rx: expr, $message: expr) => {{
|
||||
if current_thread().id() == $self.context.main_thread_id
|
||||
&& !$self.context.is_event_loop_running.load(Ordering::Relaxed)
|
||||
@@ -113,22 +114,22 @@ macro_rules! shortcut_getter {
|
||||
}};
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct GlobalShortcutWrapper(GlobalShortcut);
|
||||
|
||||
unsafe impl Send for GlobalShortcutWrapper {}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct GlobalShortcutManagerContext {
|
||||
struct EventLoopContext {
|
||||
main_thread_id: ThreadId,
|
||||
is_event_loop_running: Arc<AtomicBool>,
|
||||
proxy: EventLoopProxy<Message>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct GlobalShortcutWrapper(GlobalShortcut);
|
||||
|
||||
unsafe impl Send for GlobalShortcutWrapper {}
|
||||
|
||||
/// Wrapper around [`WryShortcutManager`].
|
||||
#[derive(Clone)]
|
||||
pub struct GlobalShortcutManagerHandle {
|
||||
context: GlobalShortcutManagerContext,
|
||||
context: EventLoopContext,
|
||||
shortcuts: HashMap<String, (AcceleratorId, GlobalShortcutWrapper)>,
|
||||
listeners: GlobalShortcutListeners,
|
||||
}
|
||||
@@ -136,7 +137,7 @@ pub struct GlobalShortcutManagerHandle {
|
||||
impl GlobalShortcutManager for GlobalShortcutManagerHandle {
|
||||
fn is_registered(&self, accelerator: &str) -> Result<bool> {
|
||||
let (tx, rx) = channel();
|
||||
Ok(shortcut_getter!(
|
||||
Ok(getter!(
|
||||
self,
|
||||
rx,
|
||||
Message::GlobalShortcut(GlobalShortcutMessage::IsRegistered(
|
||||
@@ -150,7 +151,7 @@ impl GlobalShortcutManager for GlobalShortcutManagerHandle {
|
||||
let wry_accelerator: Accelerator = accelerator.parse().expect("invalid accelerator");
|
||||
let id = wry_accelerator.clone().id();
|
||||
let (tx, rx) = channel();
|
||||
let shortcut = shortcut_getter!(
|
||||
let shortcut = getter!(
|
||||
self,
|
||||
rx,
|
||||
Message::GlobalShortcut(GlobalShortcutMessage::Register(wry_accelerator, tx))
|
||||
@@ -164,7 +165,7 @@ impl GlobalShortcutManager for GlobalShortcutManagerHandle {
|
||||
|
||||
fn unregister_all(&mut self) -> Result<()> {
|
||||
let (tx, rx) = channel();
|
||||
shortcut_getter!(
|
||||
getter!(
|
||||
self,
|
||||
rx,
|
||||
Message::GlobalShortcut(GlobalShortcutMessage::UnregisterAll(tx))
|
||||
@@ -177,13 +178,10 @@ impl GlobalShortcutManager for GlobalShortcutManagerHandle {
|
||||
fn unregister(&mut self, accelerator: &str) -> Result<()> {
|
||||
if let Some((accelerator_id, shortcut)) = self.shortcuts.remove(accelerator) {
|
||||
let (tx, rx) = channel();
|
||||
shortcut_getter!(
|
||||
getter!(
|
||||
self,
|
||||
rx,
|
||||
Message::GlobalShortcut(GlobalShortcutMessage::Unregister(
|
||||
GlobalShortcutWrapper(shortcut.0),
|
||||
tx
|
||||
))
|
||||
Message::GlobalShortcut(GlobalShortcutMessage::Unregister(shortcut, tx))
|
||||
)?;
|
||||
self.listeners.lock().unwrap().remove(&accelerator_id);
|
||||
}
|
||||
@@ -191,6 +189,32 @@ impl GlobalShortcutManager for GlobalShortcutManagerHandle {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ClipboardManagerWrapper {
|
||||
context: EventLoopContext,
|
||||
}
|
||||
|
||||
impl ClipboardManager for ClipboardManagerWrapper {
|
||||
fn read_text(&self) -> Result<Option<String>> {
|
||||
let (tx, rx) = channel();
|
||||
Ok(getter!(
|
||||
self,
|
||||
rx,
|
||||
Message::Clipboard(ClipboardMessage::ReadText(tx))
|
||||
))
|
||||
}
|
||||
|
||||
fn write_text<T: Into<String>>(&mut self, text: T) -> Result<()> {
|
||||
let (tx, rx) = channel();
|
||||
getter!(
|
||||
self,
|
||||
rx,
|
||||
Message::Clipboard(ClipboardMessage::WriteText(text.into(), tx))
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper around a [`wry::application::window::Icon`] that can be created from an [`Icon`].
|
||||
pub struct WryIcon(WindowIcon);
|
||||
|
||||
@@ -650,6 +674,12 @@ pub(crate) enum GlobalShortcutMessage {
|
||||
UnregisterAll(Sender<Result<()>>),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) enum ClipboardMessage {
|
||||
WriteText(String, Sender<()>),
|
||||
ReadText(Sender<Option<String>>),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) enum Message {
|
||||
Task(MainTask),
|
||||
@@ -659,6 +689,7 @@ pub(crate) enum Message {
|
||||
Tray(TrayMessage),
|
||||
CreateWebview(Arc<Mutex<Option<CreateWebviewHandler>>>, Sender<WindowId>),
|
||||
GlobalShortcut(GlobalShortcutMessage),
|
||||
Clipboard(ClipboardMessage),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -1099,6 +1130,8 @@ pub struct Wry {
|
||||
main_thread_id: ThreadId,
|
||||
global_shortcut_manager: Arc<Mutex<WryShortcutManager>>,
|
||||
global_shortcut_manager_handle: GlobalShortcutManagerHandle,
|
||||
clipboard_manager: Arc<Mutex<Clipboard>>,
|
||||
clipboard_manager_handle: ClipboardManagerWrapper,
|
||||
is_event_loop_running: Arc<AtomicBool>,
|
||||
event_loop: EventLoop<Message>,
|
||||
webviews: Arc<Mutex<HashMap<WindowId, WebviewWrapper>>>,
|
||||
@@ -1159,28 +1192,39 @@ impl Runtime for Wry {
|
||||
type Dispatcher = WryDispatcher;
|
||||
type Handle = WryHandle;
|
||||
type GlobalShortcutManager = GlobalShortcutManagerHandle;
|
||||
type ClipboardManager = ClipboardManagerWrapper;
|
||||
#[cfg(feature = "system-tray")]
|
||||
type TrayHandler = SystemTrayHandle;
|
||||
|
||||
fn new() -> Result<Self> {
|
||||
let event_loop = EventLoop::<Message>::with_user_event();
|
||||
let global_shortcut_manager = WryShortcutManager::new(&event_loop);
|
||||
let global_shortcut_listeners = GlobalShortcutListeners::default();
|
||||
let proxy = event_loop.create_proxy();
|
||||
let main_thread_id = current_thread().id();
|
||||
let is_event_loop_running = Arc::new(AtomicBool::default());
|
||||
|
||||
let event_loop_context = EventLoopContext {
|
||||
main_thread_id,
|
||||
is_event_loop_running: is_event_loop_running.clone(),
|
||||
proxy,
|
||||
};
|
||||
|
||||
let global_shortcut_manager = WryShortcutManager::new(&event_loop);
|
||||
let global_shortcut_listeners = GlobalShortcutListeners::default();
|
||||
let clipboard_manager = Clipboard::new();
|
||||
let clipboard_manager_handle = ClipboardManagerWrapper {
|
||||
context: event_loop_context.clone(),
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
main_thread_id,
|
||||
global_shortcut_manager: Arc::new(Mutex::new(global_shortcut_manager)),
|
||||
global_shortcut_manager_handle: GlobalShortcutManagerHandle {
|
||||
context: GlobalShortcutManagerContext {
|
||||
main_thread_id,
|
||||
is_event_loop_running: is_event_loop_running.clone(),
|
||||
proxy,
|
||||
},
|
||||
context: event_loop_context,
|
||||
shortcuts: Default::default(),
|
||||
listeners: global_shortcut_listeners,
|
||||
},
|
||||
clipboard_manager: Arc::new(Mutex::new(clipboard_manager)),
|
||||
clipboard_manager_handle,
|
||||
is_event_loop_running,
|
||||
event_loop,
|
||||
webviews: Default::default(),
|
||||
@@ -1209,6 +1253,10 @@ impl Runtime for Wry {
|
||||
self.global_shortcut_manager_handle.clone()
|
||||
}
|
||||
|
||||
fn clipboard_manager(&self) -> Self::ClipboardManager {
|
||||
self.clipboard_manager_handle.clone()
|
||||
}
|
||||
|
||||
fn create_window<P: Params<Runtime = Self>>(
|
||||
&self,
|
||||
pending: PendingWindow<P>,
|
||||
@@ -1298,6 +1346,7 @@ impl Runtime for Wry {
|
||||
let tray_context = self.tray_context.clone();
|
||||
let global_shortcut_manager = self.global_shortcut_manager.clone();
|
||||
let global_shortcut_manager_handle = self.global_shortcut_manager_handle.clone();
|
||||
let clipboard_manager = self.clipboard_manager.clone();
|
||||
|
||||
let mut iteration = RunIteration::default();
|
||||
|
||||
@@ -1318,6 +1367,7 @@ impl Runtime for Wry {
|
||||
window_event_listeners: window_event_listeners.clone(),
|
||||
global_shortcut_manager: global_shortcut_manager.clone(),
|
||||
global_shortcut_manager_handle: global_shortcut_manager_handle.clone(),
|
||||
clipboard_manager: clipboard_manager.clone(),
|
||||
#[cfg(feature = "menu")]
|
||||
menu_event_listeners: menu_event_listeners.clone(),
|
||||
#[cfg(feature = "system-tray")]
|
||||
@@ -1340,6 +1390,7 @@ impl Runtime for Wry {
|
||||
let tray_context = self.tray_context;
|
||||
let global_shortcut_manager = self.global_shortcut_manager.clone();
|
||||
let global_shortcut_manager_handle = self.global_shortcut_manager_handle.clone();
|
||||
let clipboard_manager = self.clipboard_manager.clone();
|
||||
|
||||
self.event_loop.run(move |event, event_loop, control_flow| {
|
||||
handle_event_loop(
|
||||
@@ -1352,6 +1403,7 @@ impl Runtime for Wry {
|
||||
window_event_listeners: window_event_listeners.clone(),
|
||||
global_shortcut_manager: global_shortcut_manager.clone(),
|
||||
global_shortcut_manager_handle: global_shortcut_manager_handle.clone(),
|
||||
clipboard_manager: clipboard_manager.clone(),
|
||||
#[cfg(feature = "menu")]
|
||||
menu_event_listeners: menu_event_listeners.clone(),
|
||||
#[cfg(feature = "system-tray")]
|
||||
@@ -1368,6 +1420,7 @@ struct EventLoopIterationContext<'a> {
|
||||
window_event_listeners: WindowEventListeners,
|
||||
global_shortcut_manager: Arc<Mutex<WryShortcutManager>>,
|
||||
global_shortcut_manager_handle: GlobalShortcutManagerHandle,
|
||||
clipboard_manager: Arc<Mutex<Clipboard>>,
|
||||
#[cfg(feature = "menu")]
|
||||
menu_event_listeners: MenuEventListeners,
|
||||
#[cfg(feature = "system-tray")]
|
||||
@@ -1386,6 +1439,7 @@ fn handle_event_loop(
|
||||
window_event_listeners,
|
||||
global_shortcut_manager,
|
||||
global_shortcut_manager_handle,
|
||||
clipboard_manager,
|
||||
#[cfg(feature = "menu")]
|
||||
menu_event_listeners,
|
||||
#[cfg(feature = "system-tray")]
|
||||
@@ -1689,6 +1743,15 @@ fn handle_event_loop(
|
||||
)
|
||||
.unwrap(),
|
||||
},
|
||||
Message::Clipboard(message) => match message {
|
||||
ClipboardMessage::WriteText(text, tx) => {
|
||||
clipboard_manager.lock().unwrap().write_text(text);
|
||||
tx.send(()).unwrap();
|
||||
}
|
||||
ClipboardMessage::ReadText(tx) => tx
|
||||
.send(clipboard_manager.lock().unwrap().read_text())
|
||||
.unwrap(),
|
||||
},
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
|
||||
@@ -270,6 +270,25 @@ pub trait GlobalShortcutManager {
|
||||
fn unregister(&mut self, accelerator: &str) -> crate::Result<()>;
|
||||
}
|
||||
|
||||
/// Clipboard manager.
|
||||
pub trait ClipboardManager {
|
||||
/// Writes the text into the clipboard as plain text.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the `tauri::Builder#setup` closure.
|
||||
/// You can spawn a task to use the API using the `tauri::async_runtime` to prevent the panic.
|
||||
|
||||
fn write_text<T: Into<String>>(&mut self, text: T) -> Result<()>;
|
||||
/// Read the content in the clipboard as plain text.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the app is not running yet, usually when called on the `tauri::Builder#setup` closure.
|
||||
/// You can spawn a task to use the API using the `tauri::async_runtime` to prevent the panic.
|
||||
fn read_text(&self) -> Result<Option<String>>;
|
||||
}
|
||||
|
||||
/// The webview runtime interface.
|
||||
pub trait Runtime: Sized + 'static {
|
||||
/// The message dispatcher.
|
||||
@@ -278,6 +297,8 @@ pub trait Runtime: Sized + 'static {
|
||||
type Handle: RuntimeHandle<Runtime = Self>;
|
||||
/// The global shortcut manager type.
|
||||
type GlobalShortcutManager: GlobalShortcutManager + Clone + Send;
|
||||
/// The clipboard manager type.
|
||||
type ClipboardManager: ClipboardManager + Clone + Send;
|
||||
/// The tray handler type.
|
||||
#[cfg(feature = "system-tray")]
|
||||
type TrayHandler: menu::TrayHandle + Clone + Send;
|
||||
@@ -291,6 +312,9 @@ pub trait Runtime: Sized + 'static {
|
||||
/// Gets the global shortcut manager.
|
||||
fn global_shortcut_manager(&self) -> Self::GlobalShortcutManager;
|
||||
|
||||
/// Gets the clipboard manager.
|
||||
fn clipboard_manager(&self) -> Self::ClipboardManager;
|
||||
|
||||
/// Create a new webview window.
|
||||
fn create_window<P: Params<Runtime = Self>>(
|
||||
&self,
|
||||
|
||||
@@ -114,6 +114,7 @@ crate::manager::default_args! {
|
||||
runtime_handle: <P::Runtime as Runtime>::Handle,
|
||||
manager: WindowManager<P>,
|
||||
global_shortcut_manager: <P::Runtime as Runtime>::GlobalShortcutManager,
|
||||
clipboard_manager: <P::Runtime as Runtime>::ClipboardManager,
|
||||
#[cfg(feature = "system-tray")]
|
||||
tray_handle: Option<tray::SystemTrayHandle<P>>,
|
||||
}
|
||||
@@ -125,6 +126,7 @@ impl<P: Params> Clone for AppHandle<P> {
|
||||
runtime_handle: self.runtime_handle.clone(),
|
||||
manager: self.manager.clone(),
|
||||
global_shortcut_manager: self.global_shortcut_manager.clone(),
|
||||
clipboard_manager: self.clipboard_manager.clone(),
|
||||
#[cfg(feature = "system-tray")]
|
||||
tray_handle: self.tray_handle.clone(),
|
||||
}
|
||||
@@ -163,6 +165,7 @@ crate::manager::default_args! {
|
||||
runtime: Option<P::Runtime>,
|
||||
manager: WindowManager<P>,
|
||||
global_shortcut_manager: <P::Runtime as Runtime>::GlobalShortcutManager,
|
||||
clipboard_manager: <P::Runtime as Runtime>::ClipboardManager,
|
||||
#[cfg(feature = "system-tray")]
|
||||
tray_handle: Option<tray::SystemTrayHandle<P>>,
|
||||
handle: AppHandle<P>,
|
||||
@@ -220,11 +223,6 @@ macro_rules! shared_app_impl {
|
||||
.expect("tray not configured; use the `Builder#system_tray` API first.")
|
||||
}
|
||||
|
||||
/// Gets a copy of the global shortcut manager instance.
|
||||
pub fn global_shortcut_manager(&self) -> <P::Runtime as Runtime>::GlobalShortcutManager {
|
||||
self.global_shortcut_manager.clone()
|
||||
}
|
||||
|
||||
/// The path resolver for the application.
|
||||
pub fn path_resolver(&self) -> PathResolver {
|
||||
PathResolver {
|
||||
@@ -233,6 +231,16 @@ macro_rules! shared_app_impl {
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets a copy of the global shortcut manager instance.
|
||||
pub fn global_shortcut_manager(&self) -> <P::Runtime as Runtime>::GlobalShortcutManager {
|
||||
self.global_shortcut_manager.clone()
|
||||
}
|
||||
|
||||
/// Gets a copy of the clipboard manager instance.
|
||||
pub fn clipboard_manager(&self) -> <P::Runtime as Runtime>::ClipboardManager {
|
||||
self.clipboard_manager.clone()
|
||||
}
|
||||
|
||||
/// Gets the app's configuration, defined on the `tauri.conf.json` file.
|
||||
pub fn config(&self) -> Arc<Config> {
|
||||
self.manager.config()
|
||||
@@ -717,17 +725,20 @@ where
|
||||
let runtime = R::new()?;
|
||||
let runtime_handle = runtime.handle();
|
||||
let global_shortcut_manager = runtime.global_shortcut_manager();
|
||||
let clipboard_manager = runtime.clipboard_manager();
|
||||
|
||||
let mut app = App {
|
||||
runtime: Some(runtime),
|
||||
manager: manager.clone(),
|
||||
global_shortcut_manager: global_shortcut_manager.clone(),
|
||||
clipboard_manager: clipboard_manager.clone(),
|
||||
#[cfg(feature = "system-tray")]
|
||||
tray_handle: None,
|
||||
handle: AppHandle {
|
||||
runtime_handle,
|
||||
manager,
|
||||
global_shortcut_manager,
|
||||
clipboard_manager,
|
||||
#[cfg(feature = "system-tray")]
|
||||
tray_handle: None,
|
||||
},
|
||||
|
||||
@@ -14,6 +14,7 @@ use std::sync::Arc;
|
||||
|
||||
mod app;
|
||||
mod cli;
|
||||
mod clipboard;
|
||||
mod dialog;
|
||||
mod event;
|
||||
#[allow(unused_imports)]
|
||||
@@ -54,6 +55,7 @@ enum Module {
|
||||
Notification(notification::Cmd),
|
||||
Http(http::Cmd),
|
||||
GlobalShortcut(global_shortcut::Cmd),
|
||||
Clipboard(clipboard::Cmd),
|
||||
}
|
||||
|
||||
impl Module {
|
||||
@@ -152,6 +154,12 @@ impl Module {
|
||||
.and_then(|r| r.json)
|
||||
.map_err(InvokeError::from)
|
||||
}),
|
||||
Self::Clipboard(cmd) => resolver.respond_async(async move {
|
||||
cmd
|
||||
.run(window)
|
||||
.and_then(|r| r.json)
|
||||
.map_err(InvokeError::from)
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
30
core/tauri/src/endpoints/clipboard.rs
Normal file
30
core/tauri/src/endpoints/clipboard.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use super::InvokeResponse;
|
||||
use crate::{
|
||||
runtime::{ClipboardManager, Params},
|
||||
window::Window,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
|
||||
/// The API descriptor.
|
||||
#[derive(Deserialize)]
|
||||
#[serde(tag = "cmd", content = "data", rename_all = "camelCase")]
|
||||
pub enum Cmd {
|
||||
/// Write a text string to the clipboard.
|
||||
WriteText(String),
|
||||
/// Read clipboard content as text.
|
||||
ReadText,
|
||||
}
|
||||
|
||||
impl Cmd {
|
||||
pub fn run<P: Params>(self, window: Window<P>) -> crate::Result<InvokeResponse> {
|
||||
let mut clipboard = window.app_handle.clipboard_manager();
|
||||
match self {
|
||||
Self::WriteText(text) => Ok(clipboard.write_text(text)?.into()),
|
||||
Self::ReadText => Ok(clipboard.read_text()?.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -16,6 +16,7 @@
|
||||
import Shortcuts from "./components/Shortcuts.svelte";
|
||||
import Shell from "./components/Shell.svelte";
|
||||
import Updater from "./components/Updater.svelte";
|
||||
import Clipboard from "./components/Clipboard.svelte";
|
||||
|
||||
const MENU_TOGGLE_HOTKEY = 'ctrl+b';
|
||||
|
||||
@@ -69,7 +70,11 @@
|
||||
{
|
||||
label: "Updater",
|
||||
component: Updater,
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "Clipboard",
|
||||
component: Clipboard,
|
||||
}
|
||||
];
|
||||
|
||||
let selected = views[0];
|
||||
|
||||
36
examples/api/src/components/Clipboard.svelte
Normal file
36
examples/api/src/components/Clipboard.svelte
Normal file
@@ -0,0 +1,36 @@
|
||||
<script>
|
||||
import {
|
||||
writeText,
|
||||
readText
|
||||
} from "@tauri-apps/api/clipboard";
|
||||
|
||||
export let onMessage;
|
||||
let text = "clipboard message";
|
||||
|
||||
function write() {
|
||||
writeText(text)
|
||||
.then(() => {
|
||||
onMessage('Wrote to the clipboard');
|
||||
})
|
||||
.catch(onMessage);
|
||||
}
|
||||
|
||||
function read() {
|
||||
readText()
|
||||
.then((contents) => {
|
||||
onMessage(`Clipboard contents: ${contents}`);
|
||||
})
|
||||
.catch(onMessage);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<input
|
||||
placeholder="Text to write to the clipboard"
|
||||
bind:value={text}
|
||||
/>
|
||||
<button type="button" on:click={write}>Write</button>
|
||||
</div>
|
||||
<button type="button" on:click={read}>Read</button>
|
||||
</div>
|
||||
@@ -28,7 +28,8 @@ export default [
|
||||
cli: './src/cli.ts',
|
||||
notification: './src/notification.ts',
|
||||
globalShortcut: './src/globalShortcut.ts',
|
||||
process: './src/process.ts'
|
||||
process: './src/process.ts',
|
||||
clipboard: './src/clipboard.ts'
|
||||
},
|
||||
treeshake: true,
|
||||
perf: true,
|
||||
|
||||
43
tooling/api/src/clipboard.ts
Normal file
43
tooling/api/src/clipboard.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
/**
|
||||
* Read and write to the system clipboard.
|
||||
*
|
||||
* This package is also accessible with `window.__TAURI__.clipboard` when `tauri.conf.json > build > withGlobalTauri` is set to true.
|
||||
* @packageDocumentation
|
||||
*/
|
||||
|
||||
import { invokeTauriCommand } from './helpers/tauri'
|
||||
|
||||
/**
|
||||
* Writes a plain text to the clipboard.
|
||||
*
|
||||
* @returns A promise indicating the success or failure of the operation.
|
||||
*/
|
||||
async function writeText(text: string): Promise<void> {
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Clipboard',
|
||||
message: {
|
||||
cmd: 'writeText',
|
||||
data: text
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the clipboard content as plain text.
|
||||
*
|
||||
* @returns A promise resolving to the clipboard content as plain text.
|
||||
*/
|
||||
async function readText(): Promise<string | null> {
|
||||
return invokeTauriCommand({
|
||||
__tauriModule: 'Clipboard',
|
||||
message: {
|
||||
cmd: 'readText'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export { writeText, readText }
|
||||
@@ -19,6 +19,7 @@ type TauriModule =
|
||||
| 'Http'
|
||||
| 'GlobalShortcut'
|
||||
| 'Process'
|
||||
| 'Clipboard'
|
||||
|
||||
interface TauriCommand {
|
||||
__tauriModule: TauriModule
|
||||
|
||||
Reference in New Issue
Block a user