ltk/event_loop/
clipboard.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// SPDX-License-Identifier: LGPL-2.1-only
// Copyright (C) 2026 Liberux Labs, S. L. <info@liberux.net>

use super::app_data::AppData;
use super::surface::SurfaceFocus;
use crate::app::App;
use crate::tree::find_handlers;

impl<A: App> AppData<A>
{
	/// Copy the currently-selected text into the process-local
	/// clipboard. No-op when there is no selection.
	pub( crate ) fn handle_copy( &mut self, focus: SurfaceFocus )
	{
		if let Some( text ) = self.focused_selection_text( focus )
		{
			self.clipboard = text;
			self.publish_clipboard_selection();
		}
	}

	/// Copy + delete: the selected text lands in the clipboard, then
	/// the range is removed from the value.
	pub( crate ) fn handle_cut( &mut self, focus: SurfaceFocus )
	{
		let idx = match self.surface( focus ).focused_idx { Some( i ) => i, None => return };
		if let Some( text ) = self.focused_selection_text( focus )
		{
			self.clipboard = text;
			self.publish_clipboard_selection();
		}
		if let Some( new_value ) = self.delete_selection( focus )
		{
			let msg = find_handlers( &self.surface( focus ).widget_rects, idx )
				.and_then( |h| h.text_change_msg( &new_value ) );
			if let Some( m ) = msg { self.pending_msgs.push( m ); }
		}
	}

	/// Insert the clipboard contents at the cursor (replacing the
	/// selection if there is one). No-op when the clipboard is empty.
	pub( crate ) fn handle_paste( &mut self, focus: SurfaceFocus )
	{
		if self.clipboard.is_empty() { return; }
		// Carbon-copy of the clipboard to break the borrow on `self`
		// before `handle_text_insert` runs.
		let text = self.clipboard.clone();
		self.handle_text_insert( focus, &text );
	}
}