Added Wayland clipboard support. (#666)
* Fixed MPRIS OpenUri function not respecting ncspot's shuffle setting. * Added support for Wayland clipboard. * Formatted code properly using cargo fmt. * Added is_wayland() function to check if using Wayland. * Added wayland_clipboard feature flag. It can be used to enable Wayland clipboard support. Changed is_wayland() function to check wayland related environment variables at runtime and not compile time.
This commit is contained in:
192
src/sharing.rs
192
src/sharing.rs
@@ -1,35 +1,201 @@
|
||||
#![cfg(feature = "share_clipboard")]
|
||||
use std::env;
|
||||
|
||||
#[cfg(feature = "wayland_clipboard")]
|
||||
use {
|
||||
std::io::Read,
|
||||
wl_clipboard_rs::{
|
||||
copy,
|
||||
copy::{Options, Source},
|
||||
paste,
|
||||
paste::{get_contents, Error, Seat},
|
||||
},
|
||||
};
|
||||
|
||||
#[cfg(feature = "share_selection")]
|
||||
use clipboard::x11_clipboard::{Primary, X11ClipboardContext};
|
||||
use clipboard::{x11_clipboard, x11_clipboard::X11ClipboardContext};
|
||||
#[cfg(feature = "share_selection")]
|
||||
use wl_clipboard_rs::utils::{is_primary_selection_supported, PrimarySelectionCheckError};
|
||||
|
||||
#[cfg(not(feature = "share_selection"))]
|
||||
use clipboard::ClipboardContext;
|
||||
use clipboard::ClipboardProvider;
|
||||
|
||||
fn is_wayland() -> bool {
|
||||
fn session_type() -> String {
|
||||
env::var("XDG_SESSION_TYPE").unwrap_or_default()
|
||||
}
|
||||
fn wl_display() -> String {
|
||||
env::var("WAYLAND_DISPLAY").unwrap_or_default()
|
||||
}
|
||||
fn gdk_backend() -> String {
|
||||
env::var("GDK_BACKEND").unwrap_or_default()
|
||||
}
|
||||
session_type().as_str() == "wayland" || !wl_display().is_empty() || gdk_backend() == "wayland"
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "share_selection"))]
|
||||
pub fn read_share() -> Option<String> {
|
||||
ClipboardProvider::new()
|
||||
.and_then(|mut ctx: ClipboardContext| ctx.get_contents())
|
||||
.ok()
|
||||
if is_wayland() {
|
||||
#[allow(unused_mut, unused_assignments)]
|
||||
let mut string = None;
|
||||
#[cfg(feature = "wayland_clipboard")]
|
||||
{
|
||||
//use wayland clipboard
|
||||
let result = get_contents(
|
||||
paste::ClipboardType::Regular,
|
||||
Seat::Unspecified,
|
||||
paste::MimeType::Text,
|
||||
);
|
||||
match result {
|
||||
Ok((mut pipe, _)) => {
|
||||
let mut contents = vec![];
|
||||
pipe.read_to_end(&mut contents).ok();
|
||||
string = Some(String::from_utf8_lossy(&contents).to_string())
|
||||
}
|
||||
Err(Error::NoSeats) | Err(Error::ClipboardEmpty) | Err(Error::NoMimeType) => {
|
||||
//The clipboard is empty or doesn't contain text, nothing to worry about.
|
||||
string = None
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("{}", err);
|
||||
string = None
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(s) = string {
|
||||
Some(s)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
//use x11 clipboard
|
||||
ClipboardProvider::new()
|
||||
.and_then(|mut ctx: ClipboardContext| ctx.get_contents())
|
||||
.ok()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "share_selection")]
|
||||
pub fn read_share() -> Option<String> {
|
||||
ClipboardProvider::new()
|
||||
.and_then(|mut ctx: X11ClipboardContext<Primary>| ctx.get_contents())
|
||||
.ok()
|
||||
if is_wayland() {
|
||||
#[allow(unused_mut, unused_assignments)]
|
||||
let mut string = None;
|
||||
#[cfg(feature = "wayland_clipboard")]
|
||||
{
|
||||
//use wayland clipboard
|
||||
match is_primary_selection_supported() {
|
||||
Ok(supported) => {
|
||||
let result = get_contents(
|
||||
paste::ClipboardType::Primary,
|
||||
Seat::Unspecified,
|
||||
paste::MimeType::Text,
|
||||
);
|
||||
match result {
|
||||
Ok((mut pipe, _)) => {
|
||||
let mut contents = vec![];
|
||||
pipe.read_to_end(&mut contents).ok();
|
||||
Some(String::from_utf8_lossy(&contents).to_string())
|
||||
}
|
||||
Err(Error::NoSeats)
|
||||
| Err(Error::ClipboardEmpty)
|
||||
| Err(Error::NoMimeType) => {
|
||||
//The clipboard is empty or doesn't contain text, nothing to worry about.
|
||||
None
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("{}", err);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(PrimarySelectionCheckError::NoSeats) => {
|
||||
// Impossible to give a definitive result. Primary selection may or may not be
|
||||
// supported.
|
||||
|
||||
// The required protocol (data-control version 2) is there, but there are no seats.
|
||||
// Unfortunately, at least one seat is needed to check for the primary clipboard support.
|
||||
None
|
||||
}
|
||||
Err(PrimarySelectionCheckError::MissingProtocol { .. }) => {
|
||||
// The data-control protocol (required for wl-clipboard-rs operation) is not
|
||||
// supported by the compositor.
|
||||
None
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("{}", err);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(s) = string {
|
||||
Some(s)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
//use x11 clipboard
|
||||
ClipboardProvider::new()
|
||||
.and_then(|mut ctx: X11ClipboardContext<x11_clipboard::Primary>| ctx.get_contents())
|
||||
.ok()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "share_selection"))]
|
||||
pub fn write_share(url: String) -> Option<()> {
|
||||
ClipboardProvider::new()
|
||||
.and_then(|mut ctx: ClipboardContext| ctx.set_contents(url))
|
||||
.ok()
|
||||
if is_wayland() {
|
||||
#[allow(unused_mut, unused_assignments)]
|
||||
let mut option = None;
|
||||
#[cfg(feature = "wayland_clipboard")]
|
||||
{
|
||||
//use wayland clipboard
|
||||
let opts = Options::new();
|
||||
option = opts
|
||||
.copy(
|
||||
Source::Bytes(url.into_bytes().into()),
|
||||
copy::MimeType::Autodetect,
|
||||
)
|
||||
.ok()
|
||||
}
|
||||
if let Some(o) = option {
|
||||
Some(o)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
//use x11 clipboard
|
||||
ClipboardProvider::new()
|
||||
.and_then(|mut ctx: ClipboardContext| ctx.set_contents(url))
|
||||
.ok()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "share_selection")]
|
||||
pub fn write_share(url: String) -> Option<()> {
|
||||
ClipboardProvider::new()
|
||||
.and_then(|mut ctx: X11ClipboardContext<Primary>| ctx.set_contents(url))
|
||||
.ok()
|
||||
if is_wayland() {
|
||||
#[allow(unused_mut, unused_assignments)]
|
||||
let mut option = None;
|
||||
#[cfg(feature = "wayland_clipboard")]
|
||||
{
|
||||
//use wayland clipboard
|
||||
let mut opts = Options::new();
|
||||
opts.clipboard(copy::ClipboardType::Primary);
|
||||
option = opts
|
||||
.copy(
|
||||
Source::Bytes(url.into_bytes().into()),
|
||||
copy::MimeType::Autodetect,
|
||||
)
|
||||
.ok()
|
||||
}
|
||||
if let Some(o) = option {
|
||||
Some(o)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
//use x11 clipboard
|
||||
ClipboardProvider::new()
|
||||
.and_then(|mut ctx: X11ClipboardContext<x11_clipboard::Primary>| ctx.set_contents(url))
|
||||
.ok()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user