fix: preserve UTF-8 clipboard text in native macOS launches
Verify Tessera GUI / verify (push) Failing after 7m14s
Verify Tessera GUI / verify (push) Failing after 7m14s
This commit is contained in:
+12
-23
@@ -105,31 +105,20 @@ impl TesseraApp {
|
||||
if command && let Key::Character(value) = &event.logical_key {
|
||||
match value.to_lowercase().as_str() {
|
||||
"a" => self.developer_tools.selection = true,
|
||||
"v" => {
|
||||
#[cfg(target_os = "macos")]
|
||||
if let Ok(output) = std::process::Command::new("pbpaste").output()
|
||||
&& output.status.success()
|
||||
{
|
||||
self.developer_tools
|
||||
.insert(&String::from_utf8_lossy(&output.stdout));
|
||||
}
|
||||
}
|
||||
"v" => match crate::clipboard::read() {
|
||||
Ok(value) => self.developer_tools.insert(&value),
|
||||
Err(error) => self.developer_tools.input_error = format!("Clipboard: {error}"),
|
||||
},
|
||||
"c" | "x" => {
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
use std::io::Write;
|
||||
let selected = self.developer_tools.selected_text();
|
||||
if !selected.is_empty()
|
||||
&& let Ok(mut child) = std::process::Command::new("pbcopy")
|
||||
.stdin(std::process::Stdio::piped())
|
||||
.spawn()
|
||||
{
|
||||
if let Some(mut stdin) = child.stdin.take() {
|
||||
let _ = stdin.write_all(selected.as_bytes());
|
||||
let selected = self.developer_tools.selected_text();
|
||||
if !selected.is_empty() {
|
||||
match crate::clipboard::write(&selected) {
|
||||
Ok(()) if value.eq_ignore_ascii_case("x") => {
|
||||
self.developer_tools.insert("")
|
||||
}
|
||||
let _ = child.wait();
|
||||
if value.eq_ignore_ascii_case("x") {
|
||||
self.developer_tools.insert("");
|
||||
Ok(()) => {}
|
||||
Err(error) => {
|
||||
self.developer_tools.input_error = format!("Clipboard: {error}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
//! Clipboard text is always UTF-8, including Finder/LaunchServices launches without LANG.
|
||||
use anyhow::{Result, bail};
|
||||
#[cfg(target_os = "macos")]
|
||||
fn command(program: &str) -> std::process::Command {
|
||||
let mut cmd = std::process::Command::new(program);
|
||||
cmd.env("LC_ALL", "en_US.UTF-8")
|
||||
.env("LC_CTYPE", "en_US.UTF-8")
|
||||
.env("LANG", "en_US.UTF-8");
|
||||
cmd
|
||||
}
|
||||
pub fn read() -> Result<String> {
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
let output = command("/usr/bin/pbpaste")
|
||||
.arg("-Prefer")
|
||||
.arg("txt")
|
||||
.output()?;
|
||||
if !output.status.success() {
|
||||
bail!("system clipboard read failed");
|
||||
}
|
||||
// Never silently replace invalid bytes in the user's source.
|
||||
Ok(String::from_utf8(output.stdout)?)
|
||||
}
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
bail!("system clipboard adapter is not available on this platform")
|
||||
}
|
||||
}
|
||||
pub fn write(value: &str) -> Result<()> {
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
use std::io::Write;
|
||||
let mut child = command("/usr/bin/pbcopy")
|
||||
.stdin(std::process::Stdio::piped())
|
||||
.spawn()?;
|
||||
let mut stdin = child
|
||||
.stdin
|
||||
.take()
|
||||
.ok_or_else(|| anyhow::anyhow!("clipboard stdin is unavailable"))?;
|
||||
stdin.write_all(value.as_bytes())?;
|
||||
drop(stdin);
|
||||
if !child.wait()?.success() {
|
||||
bail!("system clipboard write failed");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
let _ = value;
|
||||
bail!("system clipboard adapter is not available on this platform")
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
mod activity;
|
||||
mod api;
|
||||
mod app;
|
||||
mod clipboard;
|
||||
mod developer_tools;
|
||||
mod display_list;
|
||||
mod document;
|
||||
|
||||
Reference in New Issue
Block a user