Reapply support for pasting images on x11 (#32121)
This brings back [linux(x11): Add support for pasting images from clipboard · Pull Request #29387](https://github.com/zed-industries/zed/pull/29387) while fixing #30523 (which caused it to be reverted). Commit message from that PR: > Closes: https://github.com/zed-industries/zed/pull/29177#issuecomment-2823359242 > > Removes dependency on [quininer/x11-clipboard](https://github.com/quininer/x11-clipboard) as it is in [maintenance mode](https://github.com/quininer/x11-clipboard/issues/19). > > X11 clipboard functionality is now built-in to GPUI which was accomplished by stripping the non-x11-related code/abstractions from [1Password/arboard](https://github.com/1Password/arboard) and extending it to support all image formats already supported by GPUI on wayland and macos. > > A benefit of switching over to the `arboard` implementation, is that we now make an attempt to have an X11 "clipboard manager" (if available - something the user has to setup themselves) save the contents of clipboard (if the last copy operation was within Zed) so that the copied contents can still be pasted once Zed has completely stopped. Before the fix for reapply, it was iterating through the formats and requesting conversion to each. Some clipboard providers just respond with a different format rather than saying the format is unsupported. The fix is to use this response if it matches a supported format. It also now typically avoids this iteration by requesting the `TARGETS` and taking the highest precedence supported target. Closes #30523 Release Notes: - Linux (X11): Restored the ability to paste images. --------- Co-authored-by: Ben <ben@zed.dev>
This commit is contained in:
parent
a2e98e9f0e
commit
3d9881121f
3 changed files with 126 additions and 66 deletions
|
@ -1,4 +1,3 @@
|
|||
use crate::platform::scap_screen_capture::scap_screen_sources;
|
||||
use core::str;
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
|
@ -41,8 +40,9 @@ use xkbc::x11::ffi::{XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSIO
|
|||
use xkbcommon::xkb::{self as xkbc, LayoutIndex, ModMask, STATE_LAYOUT_EFFECTIVE};
|
||||
|
||||
use super::{
|
||||
ButtonOrScroll, ScrollDirection, button_or_scroll_from_event_detail, get_valuator_axis_index,
|
||||
modifiers_from_state, pressed_button_from_mask,
|
||||
ButtonOrScroll, ScrollDirection, button_or_scroll_from_event_detail,
|
||||
clipboard::{self, Clipboard},
|
||||
get_valuator_axis_index, modifiers_from_state, pressed_button_from_mask,
|
||||
};
|
||||
use super::{X11Display, X11WindowStatePtr, XcbAtoms};
|
||||
use super::{XimCallbackEvent, XimHandler};
|
||||
|
@ -56,6 +56,7 @@ use crate::platform::{
|
|||
reveal_path_internal,
|
||||
xdg_desktop_portal::{Event as XDPEvent, XDPEventSource},
|
||||
},
|
||||
scap_screen_capture::scap_screen_sources,
|
||||
};
|
||||
use crate::{
|
||||
AnyWindowHandle, Bounds, ClipboardItem, CursorStyle, DisplayId, FileDropEvent, Keystroke,
|
||||
|
@ -201,7 +202,7 @@ pub struct X11ClientState {
|
|||
pointer_device_states: BTreeMap<xinput::DeviceId, PointerDeviceState>,
|
||||
|
||||
pub(crate) common: LinuxCommon,
|
||||
pub(crate) clipboard: x11_clipboard::Clipboard,
|
||||
pub(crate) clipboard: Clipboard,
|
||||
pub(crate) clipboard_item: Option<ClipboardItem>,
|
||||
pub(crate) xdnd_state: Xdnd,
|
||||
}
|
||||
|
@ -388,7 +389,7 @@ impl X11Client {
|
|||
.reply()
|
||||
.unwrap();
|
||||
|
||||
let clipboard = x11_clipboard::Clipboard::new().unwrap();
|
||||
let clipboard = Clipboard::new().unwrap();
|
||||
|
||||
let xcb_connection = Rc::new(xcb_connection);
|
||||
|
||||
|
@ -1504,39 +1505,36 @@ impl LinuxClient for X11Client {
|
|||
let state = self.0.borrow_mut();
|
||||
state
|
||||
.clipboard
|
||||
.store(
|
||||
state.clipboard.setter.atoms.primary,
|
||||
state.clipboard.setter.atoms.utf8_string,
|
||||
item.text().unwrap_or_default().as_bytes(),
|
||||
.set_text(
|
||||
std::borrow::Cow::Owned(item.text().unwrap_or_default()),
|
||||
clipboard::ClipboardKind::Primary,
|
||||
clipboard::WaitConfig::None,
|
||||
)
|
||||
.ok();
|
||||
.context("Failed to write to clipboard (primary)")
|
||||
.log_with_level(log::Level::Debug);
|
||||
}
|
||||
|
||||
fn write_to_clipboard(&self, item: crate::ClipboardItem) {
|
||||
let mut state = self.0.borrow_mut();
|
||||
state
|
||||
.clipboard
|
||||
.store(
|
||||
state.clipboard.setter.atoms.clipboard,
|
||||
state.clipboard.setter.atoms.utf8_string,
|
||||
item.text().unwrap_or_default().as_bytes(),
|
||||
.set_text(
|
||||
std::borrow::Cow::Owned(item.text().unwrap_or_default()),
|
||||
clipboard::ClipboardKind::Clipboard,
|
||||
clipboard::WaitConfig::None,
|
||||
)
|
||||
.ok();
|
||||
.context("Failed to write to clipboard (clipboard)")
|
||||
.log_with_level(log::Level::Debug);
|
||||
state.clipboard_item.replace(item);
|
||||
}
|
||||
|
||||
fn read_from_primary(&self) -> Option<crate::ClipboardItem> {
|
||||
let state = self.0.borrow_mut();
|
||||
state
|
||||
return state
|
||||
.clipboard
|
||||
.load(
|
||||
state.clipboard.getter.atoms.primary,
|
||||
state.clipboard.getter.atoms.utf8_string,
|
||||
state.clipboard.getter.atoms.property,
|
||||
Duration::from_secs(3),
|
||||
)
|
||||
.map(|text| crate::ClipboardItem::new_string(String::from_utf8(text).unwrap()))
|
||||
.ok()
|
||||
.get_any(clipboard::ClipboardKind::Primary)
|
||||
.context("Failed to read from clipboard (primary)")
|
||||
.log_with_level(log::Level::Debug);
|
||||
}
|
||||
|
||||
fn read_from_clipboard(&self) -> Option<crate::ClipboardItem> {
|
||||
|
@ -1545,26 +1543,15 @@ impl LinuxClient for X11Client {
|
|||
// which has metadata attached.
|
||||
if state
|
||||
.clipboard
|
||||
.setter
|
||||
.connection
|
||||
.get_selection_owner(state.clipboard.setter.atoms.clipboard)
|
||||
.ok()
|
||||
.and_then(|r| r.reply().ok())
|
||||
.map(|reply| reply.owner == state.clipboard.setter.window)
|
||||
.unwrap_or(false)
|
||||
.is_owner(clipboard::ClipboardKind::Clipboard)
|
||||
{
|
||||
return state.clipboard_item.clone();
|
||||
}
|
||||
state
|
||||
return state
|
||||
.clipboard
|
||||
.load(
|
||||
state.clipboard.getter.atoms.clipboard,
|
||||
state.clipboard.getter.atoms.utf8_string,
|
||||
state.clipboard.getter.atoms.property,
|
||||
Duration::from_secs(3),
|
||||
)
|
||||
.map(|text| crate::ClipboardItem::new_string(String::from_utf8(text).unwrap()))
|
||||
.ok()
|
||||
.get_any(clipboard::ClipboardKind::Clipboard)
|
||||
.context("Failed to read from clipboard (clipboard)")
|
||||
.log_with_level(log::Level::Debug);
|
||||
}
|
||||
|
||||
fn run(&self) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue