ltk/event_loop/
clipboard.rsuse std::time::Duration;
use super::app_data::AppData;
use super::surface::SurfaceFocus;
use crate::app::App;
use crate::platform::Platform;
use crate::time::Instant;
use crate::tree::find_handlers;
const PRIMARY_WAIT: Duration = Duration::from_millis( 500 );
const PRIMARY_POLL: Duration = Duration::from_millis( 10 );
pub( crate ) enum PrimaryPaste
{
Field( SurfaceFocus, usize ),
App,
}
impl<A: App, P: Platform> AppData<A, P>
{
pub( crate ) fn paste_primary( &mut self, target: PrimaryPaste )
{
if self.platform.primary_selection_pending()
{
self.pending_primary_paste = Some( ( target, Instant::now() ) );
return;
}
self.deliver_primary( target );
}
pub( crate ) fn check_primary_paste( &mut self )
{
let Some( ( _, since ) ) = &self.pending_primary_paste else { return };
if self.platform.primary_selection_pending() && since.elapsed() < PRIMARY_WAIT { return; }
if let Some( ( target, _ ) ) = self.pending_primary_paste.take() { self.deliver_primary( target ); }
}
pub( crate ) fn next_primary_paste_wakeup( &self ) -> Option<Duration>
{
self.pending_primary_paste.as_ref().map( |_| PRIMARY_POLL )
}
fn deliver_primary( &mut self, target: PrimaryPaste )
{
let text = self.primary_selection.clone();
if text.is_empty() { return; }
match target
{
PrimaryPaste::Field( focus, idx ) =>
{
if self.try_surface( focus ).is_some_and( |ss| ss.focused_idx == Some( idx ) ) { self.handle_text_insert( focus, &text ); }
}
PrimaryPaste::App => self.app.on_paste( &text ),
}
}
pub( crate ) fn publish_clipboard( &mut self, text: String )
{
self.platform.publish_clipboard( &text );
self.clipboard = text;
}
pub( crate ) fn publish_primary_selection( &mut self, text: String )
{
self.platform.publish_primary_selection( &text );
self.primary_selection = text;
}
pub( crate ) fn sync_text_field( &mut self )
{
let focus = self.keyboard_focus;
if self.try_surface( focus ).is_none_or( |ss| ss.gesture.pressed_idx.is_some() ) { return; }
let secure = self.surface( focus ).focused_idx
.and_then( |idx| self.text_input_geometry( focus, idx ) )
.is_some_and( |( _, _, _, secure, _, _ )| secure );
let selected = if secure { None } else { self.focused_selection_text( focus ) };
if selected == self.primary_field { return; }
self.primary_field = selected.clone();
if let Some( text ) = selected { self.publish_primary_selection( text ); }
}
pub( crate ) fn handle_copy( &mut self, focus: SurfaceFocus )
{
if let Some( text ) = self.focused_selection_text( focus )
{
self.publish_clipboard( text );
}
}
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.publish_clipboard( text );
}
if let Some( new_value ) = self.delete_selection( focus )
{
let msg = find_handlers( &self.surface( focus ).frame.widget_rects, idx )
.and_then( |h| h.text_change_msg( &new_value ) );
if let Some( m ) = msg { self.pending_msgs.push( m ); }
}
}
pub( crate ) fn handle_paste( &mut self, focus: SurfaceFocus )
{
if self.clipboard.is_empty() { return; }
let text = self.clipboard.clone();
self.handle_text_insert( focus, &text );
}
}