Skip to content

Commit

Permalink
Add support for excluding macos clipboard items from history (#159)
Browse files Browse the repository at this point in the history
* Adds support for excluding macos clipboard items from history
  • Loading branch information
Hinton authored Aug 27, 2024
1 parent ee39c47 commit dd43f44
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 7 deletions.
3 changes: 0 additions & 3 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,6 @@ impl<F: FnOnce()> Drop for ScopeGuard<F> {

/// Common trait for sealing platform extension traits.
pub(crate) mod private {
// This is currently unused on macOS, so silence the warning which appears
// since there's no extension traits making use of this trait sealing structure.
#[cfg_attr(target_vendor = "apple", allow(unreachable_pub, dead_code))]
pub trait Sealed {}

impl Sealed for crate::Get<'_> {}
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ pub use platform::{ClearExtLinux, GetExtLinux, LinuxClipboardKind, SetExtLinux};
#[cfg(windows)]
pub use platform::SetExtWindows;

#[cfg(target_os = "macos")]
pub use platform::SetExtApple;

/// The OS independent struct for accessing the clipboard.
///
/// Any number of `Clipboard` instances are allowed to exist at a single point in time. Note however
Expand Down
2 changes: 1 addition & 1 deletion src/platform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ pub use windows::*;
#[cfg(target_os = "macos")]
mod osx;
#[cfg(target_os = "macos")]
pub(crate) use osx::*;
pub use osx::*;
46 changes: 43 additions & 3 deletions src/platform/osx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ the Apache 2.0 or the MIT license at the licensee's choice. The terms
and conditions of the chosen license apply to this file.
*/

use crate::common::Error;
#[cfg(feature = "image-data")]
use crate::common::ImageData;
use crate::common::{private, Error};
use objc2::{
msg_send_id,
rc::{autoreleasepool, Id},
runtime::ProtocolObject,
ClassType,
};
use objc2_app_kit::{NSPasteboard, NSPasteboardTypeHTML, NSPasteboardTypeString};
use objc2_foundation::{NSArray, NSString};
use objc2_foundation::{ns_string, NSArray, NSString};
use std::{
borrow::Cow,
panic::{RefUnwindSafe, UnwindSafe},
Expand Down Expand Up @@ -235,11 +235,12 @@ impl<'clipboard> Get<'clipboard> {

pub(crate) struct Set<'clipboard> {
clipboard: &'clipboard mut Clipboard,
exclude_from_history: bool,
}

impl<'clipboard> Set<'clipboard> {
pub(crate) fn new(clipboard: &'clipboard mut Clipboard) -> Self {
Self { clipboard }
Self { clipboard, exclude_from_history: false }
}

pub(crate) fn text(self, data: Cow<'_, str>) -> Result<(), Error> {
Expand All @@ -248,6 +249,9 @@ impl<'clipboard> Set<'clipboard> {
let string_array =
NSArray::from_vec(vec![ProtocolObject::from_id(NSString::from_str(&data))]);
let success = unsafe { self.clipboard.pasteboard.writeObjects(&string_array) };

add_clipboard_exclusions(self.clipboard, self.exclude_from_history);

if success {
Ok(())
} else {
Expand Down Expand Up @@ -279,6 +283,9 @@ impl<'clipboard> Set<'clipboard> {
};
}
}

add_clipboard_exclusions(self.clipboard, self.exclude_from_history);

if success {
Ok(())
} else {
Expand All @@ -296,6 +303,9 @@ impl<'clipboard> Set<'clipboard> {

let image_array = NSArray::from_vec(vec![ProtocolObject::from_id(image)]);
let success = unsafe { self.clipboard.pasteboard.writeObjects(&image_array) };

add_clipboard_exclusions(self.clipboard, self.exclude_from_history);

if success {
Ok(())
} else {
Expand All @@ -322,3 +332,33 @@ impl<'clipboard> Clear<'clipboard> {
Ok(())
}
}

fn add_clipboard_exclusions(clipboard: &mut Clipboard, exclude_from_history: bool) {
// On Mac there isn't an official standard for excluding data from clipboard, however
// there is an unofficial standard which is to set `org.nspasteboard.ConcealedType`.
//
// See http://nspasteboard.org/ for details about the community standard.
if exclude_from_history {
unsafe {
clipboard
.pasteboard
.setString_forType(ns_string!(""), ns_string!("org.nspasteboard.ConcealedType"));
}
}
}

/// Apple-specific extensions to the [`Set`](crate::Set) builder.
pub trait SetExtApple: private::Sealed {
/// Excludes the data which will be set on the clipboard from being added to
/// third party clipboard history software.
///
/// See http://nspasteboard.org/ for details about the community standard.
fn exclude_from_history(self) -> Self;
}

impl SetExtApple for crate::Set<'_> {
fn exclude_from_history(mut self) -> Self {
self.platform.exclude_from_history = true;
self
}
}

0 comments on commit dd43f44

Please sign in to comment.