summaryrefslogtreecommitdiffstats
path: root/winit
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2024-09-03 11:23:54 +0200
committerLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2024-09-03 11:23:54 +0200
commit9628dc20d5dab128b9fff2c4b73cc66b0071e149 (patch)
tree65053c9982f454b1ecab50e2dad0817e5b135d77 /winit
parent9957481d416f948f6af228013caa221a877c4db4 (diff)
downloadiced-9628dc20d5dab128b9fff2c4b73cc66b0071e149.tar.gz
iced-9628dc20d5dab128b9fff2c4b73cc66b0071e149.tar.bz2
iced-9628dc20d5dab128b9fff2c4b73cc66b0071e149.zip
Reconnect `Clipboard` on window close
Fixes #2564
Diffstat (limited to 'winit')
-rw-r--r--winit/src/clipboard.rs10
-rw-r--r--winit/src/program.rs54
-rw-r--r--winit/src/program/window_manager.rs4
3 files changed, 46 insertions, 22 deletions
diff --git a/winit/src/clipboard.rs b/winit/src/clipboard.rs
index 7ae646fc..d54a1fe0 100644
--- a/winit/src/clipboard.rs
+++ b/winit/src/clipboard.rs
@@ -2,7 +2,7 @@
use crate::core::clipboard::Kind;
use std::sync::Arc;
-use winit::window::Window;
+use winit::window::{Window, WindowId};
/// A buffer for short-term storage and transfer within and between
/// applications.
@@ -83,6 +83,14 @@ impl Clipboard {
State::Unavailable => {}
}
}
+
+ /// Returns the identifier of the window used to create the [`Clipboard`], if any.
+ pub fn window_id(&self) -> Option<WindowId> {
+ match &self.state {
+ State::Connected { window, .. } => Some(window.id()),
+ State::Unavailable => None,
+ }
+ }
}
impl crate::core::Clipboard for Clipboard {
diff --git a/winit/src/program.rs b/winit/src/program.rs
index 54221c68..89ec5ef9 100644
--- a/winit/src/program.rs
+++ b/winit/src/program.rs
@@ -307,8 +307,6 @@ where
}
};
- let clipboard = Clipboard::connect(window.clone());
-
let finish_boot = async move {
let mut compositor =
C::new(graphics_settings, window.clone()).await?;
@@ -318,10 +316,7 @@ where
}
sender
- .send(Boot {
- compositor,
- clipboard,
- })
+ .send(Boot { compositor })
.ok()
.expect("Send boot event");
@@ -617,7 +612,6 @@ where
struct Boot<C> {
compositor: C,
- clipboard: Clipboard,
}
#[derive(Debug)]
@@ -662,10 +656,7 @@ async fn run_instance<P, C>(
use winit::event;
use winit::event_loop::ControlFlow;
- let Boot {
- mut compositor,
- mut clipboard,
- } = boot.await.expect("Receive boot");
+ let Boot { mut compositor } = boot.await.expect("Receive boot");
let mut window_manager = WindowManager::new();
let mut is_window_opening = !is_daemon;
@@ -676,6 +667,7 @@ async fn run_instance<P, C>(
let mut ui_caches = FxHashMap::default();
let mut user_interfaces = ManuallyDrop::new(FxHashMap::default());
+ let mut clipboard = Clipboard::unconnected();
debug.startup_finished();
@@ -734,6 +726,10 @@ async fn run_instance<P, C>(
}),
));
+ if clipboard.window_id().is_none() {
+ clipboard = Clipboard::connect(window.raw.clone());
+ }
+
let _ = on_open.send(id);
is_window_opening = false;
}
@@ -979,14 +975,22 @@ async fn run_instance<P, C>(
winit::event::WindowEvent::CloseRequested
) && window.exit_on_close_request
{
- let _ = window_manager.remove(id);
- let _ = user_interfaces.remove(&id);
- let _ = ui_caches.remove(&id);
-
- events.push((
- id,
- core::Event::Window(window::Event::Closed),
- ));
+ run_action(
+ Action::Window(runtime::window::Action::Close(
+ id,
+ )),
+ &program,
+ &mut compositor,
+ &mut events,
+ &mut messages,
+ &mut clipboard,
+ &mut control_sender,
+ &mut debug,
+ &mut user_interfaces,
+ &mut window_manager,
+ &mut ui_caches,
+ &mut is_window_opening,
+ );
} else {
window.state.update(
&window.raw,
@@ -1223,10 +1227,18 @@ fn run_action<P, C>(
*is_window_opening = true;
}
window::Action::Close(id) => {
- let window = window_manager.remove(id);
let _ = ui_caches.remove(&id);
+ let _ = interfaces.remove(&id);
+
+ if let Some(window) = window_manager.remove(id) {
+ if clipboard.window_id() == Some(window.raw.id()) {
+ *clipboard = window_manager
+ .first()
+ .map(|window| window.raw.clone())
+ .map(Clipboard::connect)
+ .unwrap_or_else(Clipboard::unconnected);
+ }
- if window.is_some() {
events.push((
id,
core::Event::Window(core::window::Event::Closed),
diff --git a/winit/src/program/window_manager.rs b/winit/src/program/window_manager.rs
index 8cd9fab7..3d22e155 100644
--- a/winit/src/program/window_manager.rs
+++ b/winit/src/program/window_manager.rs
@@ -74,6 +74,10 @@ where
self.entries.is_empty()
}
+ pub fn first(&self) -> Option<&Window<P, C>> {
+ self.entries.first_key_value().map(|(_id, window)| window)
+ }
+
pub fn iter_mut(
&mut self,
) -> impl Iterator<Item = (Id, &mut Window<P, C>)> {