iced_winit: drop Clipboard before Window
Fixes #2482, avoids nasal daemons
This commit is contained in:
parent
1c8850023f
commit
f92e01e913
2 changed files with 24 additions and 9 deletions
|
|
@ -1,6 +1,8 @@
|
||||||
//! Access the clipboard.
|
//! Access the clipboard.
|
||||||
|
|
||||||
use crate::core::clipboard::Kind;
|
use crate::core::clipboard::Kind;
|
||||||
|
use winit::window::Window;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// A buffer for short-term storage and transfer within and between
|
/// A buffer for short-term storage and transfer within and between
|
||||||
/// applications.
|
/// applications.
|
||||||
|
|
@ -10,18 +12,31 @@ pub struct Clipboard {
|
||||||
}
|
}
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
Connected(window_clipboard::Clipboard),
|
Connected {
|
||||||
|
clipboard: window_clipboard::Clipboard,
|
||||||
|
// Held until drop to satisfy the safety invariants of
|
||||||
|
// `window_clipboard::Clipboard`.
|
||||||
|
//
|
||||||
|
// Note that the field ordering is load-bearing.
|
||||||
|
#[allow(dead_code)]
|
||||||
|
window: Arc<Window>,
|
||||||
|
},
|
||||||
Unavailable,
|
Unavailable,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clipboard {
|
impl Clipboard {
|
||||||
/// Creates a new [`Clipboard`] for the given window.
|
/// Creates a new [`Clipboard`] for the given window.
|
||||||
pub fn connect(window: &winit::window::Window) -> Clipboard {
|
pub fn connect(window: Arc<Window>) -> Clipboard {
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
let state = unsafe { window_clipboard::Clipboard::connect(window) }
|
// SAFETY: The window handle will stay alive throughout the entire
|
||||||
.ok()
|
// lifetime of the `window_clipboard::Clipboard` because we hold
|
||||||
.map(State::Connected)
|
// the `Arc<Window>` together with `State`, and enum variant fields
|
||||||
.unwrap_or(State::Unavailable);
|
// get dropped in declaration order.
|
||||||
|
let clipboard = unsafe { window_clipboard::Clipboard::connect(&window) };
|
||||||
|
let state = match clipboard {
|
||||||
|
Ok(clipboard) => State::Connected { clipboard, window },
|
||||||
|
Err(_) => State::Unavailable,
|
||||||
|
};
|
||||||
|
|
||||||
Clipboard { state }
|
Clipboard { state }
|
||||||
}
|
}
|
||||||
|
|
@ -37,7 +52,7 @@ impl Clipboard {
|
||||||
/// Reads the current content of the [`Clipboard`] as text.
|
/// Reads the current content of the [`Clipboard`] as text.
|
||||||
pub fn read(&self, kind: Kind) -> Option<String> {
|
pub fn read(&self, kind: Kind) -> Option<String> {
|
||||||
match &self.state {
|
match &self.state {
|
||||||
State::Connected(clipboard) => match kind {
|
State::Connected { clipboard, .. } => match kind {
|
||||||
Kind::Standard => clipboard.read().ok(),
|
Kind::Standard => clipboard.read().ok(),
|
||||||
Kind::Primary => clipboard.read_primary().and_then(Result::ok),
|
Kind::Primary => clipboard.read_primary().and_then(Result::ok),
|
||||||
},
|
},
|
||||||
|
|
@ -48,7 +63,7 @@ impl Clipboard {
|
||||||
/// Writes the given text contents to the [`Clipboard`].
|
/// Writes the given text contents to the [`Clipboard`].
|
||||||
pub fn write(&mut self, kind: Kind, contents: String) {
|
pub fn write(&mut self, kind: Kind, contents: String) {
|
||||||
match &mut self.state {
|
match &mut self.state {
|
||||||
State::Connected(clipboard) => {
|
State::Connected { clipboard, .. } => {
|
||||||
let result = match kind {
|
let result = match kind {
|
||||||
Kind::Standard => clipboard.write(contents),
|
Kind::Standard => clipboard.write(contents),
|
||||||
Kind::Primary => {
|
Kind::Primary => {
|
||||||
|
|
|
||||||
|
|
@ -307,7 +307,7 @@ where
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let clipboard = Clipboard::connect(&window);
|
let clipboard = Clipboard::connect(window.clone());
|
||||||
|
|
||||||
let finish_boot = async move {
|
let finish_boot = async move {
|
||||||
let mut compositor =
|
let mut compositor =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue