fix(text): copy and paste in text fields through the system clipboard (Issue #57)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e7e161e70c
commit
9dbe625eef
2 files changed
+43
No files matched your search
+39
@@ -573,6 +573,19 @@ impl ClipboardBridge {
|
||||
(!text.trim().is_empty()).then_some(text)
|
||||
}
|
||||
|
||||
/// Text copied or cut in a text field goes to the system clipboard, so it can be pasted
|
||||
/// into other apps (Issue #57).
|
||||
fn set_system_text(&mut self, text: String) {
|
||||
if self.system.is_none() {
|
||||
self.system = platform::clipboard::Clipboard::new().ok();
|
||||
}
|
||||
if let Some(system) = self.system.as_mut() {
|
||||
if let Err(err) = system.set_text(text) {
|
||||
eprintln!("[Zwischenablage] Text nicht gesetzt: {err}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Merkt sich beim internen Kopieren das aktuelle Systembild, den Text und das
|
||||
/// Quell-Notizbuch.
|
||||
fn note_internal_copy(&mut self, storage_dir: &Path) {
|
||||
@@ -2531,6 +2544,28 @@ pub fn run_with(
|
||||
consumed: false,
|
||||
}
|
||||
} else {
|
||||
// Ctrl+V in a text field: egui-winit is built without its own clipboard
|
||||
// access and would only paste what was copied inside the app, so it gets the
|
||||
// text of the system clipboard first (Issue #57)
|
||||
if let WindowEvent::KeyboardInput {
|
||||
event:
|
||||
KeyEvent {
|
||||
logical_key: Key::Character(c),
|
||||
state: ElementState::Pressed,
|
||||
..
|
||||
},
|
||||
..
|
||||
} = &event
|
||||
{
|
||||
if c.eq_ignore_ascii_case("v")
|
||||
&& egui_winit_state.egui_input().modifiers.command
|
||||
&& egui_ctx.wants_keyboard_input()
|
||||
{
|
||||
if let Some(text) = clipboard.system_text() {
|
||||
egui_winit_state.set_clipboard_text(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
egui_winit_state.on_window_event(&window, &event)
|
||||
};
|
||||
// egui-winit asks for a repaint after every RedrawRequested as well; following
|
||||
@@ -5638,6 +5673,10 @@ pub fn run_with(
|
||||
// 4. egui Frame beenden & Primitives tessellieren
|
||||
let full_output = egui_ctx.end_frame();
|
||||
let ime_active = full_output.platform_output.ime.is_some();
|
||||
if !full_output.platform_output.copied_text.is_empty() {
|
||||
clipboard
|
||||
.set_system_text(full_output.platform_output.copied_text.clone());
|
||||
}
|
||||
egui_winit_state
|
||||
.handle_platform_output(&window, full_output.platform_output);
|
||||
if let Some(requester) = keyboard_requester.as_mut() {
|
||||
|
||||
@@ -400,6 +400,10 @@ pub mod clipboard {
|
||||
pub fn set_image(&mut self, _image: ImageData) -> Result<(), &'static str> {
|
||||
Err("not available on Android")
|
||||
}
|
||||
|
||||
pub fn set_text(&mut self, _text: String) -> Result<(), &'static str> {
|
||||
Err("not available on Android")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user