diff --git a/examples/integration/src/main.rs b/examples/integration/src/main.rs
index ec01c4e6a5..b57c73d844 100644
--- a/examples/integration/src/main.rs
+++ b/examples/integration/src/main.rs
@@ -5,7 +5,7 @@ use controls::Controls;
use scene::Scene;
use iced_wgpu::{wgpu, Backend, Renderer, Settings, Viewport};
-use iced_winit::{conversion, futures, program, winit, Debug, Size};
+use iced_winit::{conversion, futures, program, winit, Clipboard, Debug, Size};
use futures::task::SpawnExt;
use winit::{
@@ -28,6 +28,7 @@ pub fn main() {
);
let mut cursor_position = PhysicalPosition::new(-1.0, -1.0);
let mut modifiers = ModifiersState::default();
+ let mut clipboard = Clipboard::connect(&window);
// Initialize wgpu
let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY);
@@ -141,8 +142,8 @@ pub fn main() {
cursor_position,
viewport.scale_factor(),
),
- None,
&mut renderer,
+ &mut clipboard,
&mut debug,
);
diff --git a/glutin/src/application.rs b/glutin/src/application.rs
index 42513feb1b..19eee2194e 100644
--- a/glutin/src/application.rs
+++ b/glutin/src/application.rs
@@ -136,7 +136,7 @@ async fn run_instance(
use glutin::event;
use iced_winit::futures::stream::StreamExt;
- let clipboard = Clipboard::new(context.window());
+ let mut clipboard = Clipboard::connect(context.window());
let mut state = application::State::new(&application, context.window());
let mut viewport_version = state.viewport_version();
@@ -170,8 +170,8 @@ async fn run_instance(
let statuses = user_interface.update(
&events,
state.cursor_position(),
- clipboard.as_ref().map(|c| c as _),
&mut renderer,
+ &mut clipboard,
&mut messages,
);
diff --git a/graphics/src/widget/canvas.rs b/graphics/src/widget/canvas.rs
index 95ede50f7e..7897c8ec7e 100644
--- a/graphics/src/widget/canvas.rs
+++ b/graphics/src/widget/canvas.rs
@@ -154,9 +154,9 @@ where
event: iced_native::Event,
layout: Layout<'_>,
cursor_position: Point,
- messages: &mut Vec,
_renderer: &Renderer,
- _clipboard: Option<&dyn Clipboard>,
+ _clipboard: &mut dyn Clipboard,
+ messages: &mut Vec,
) -> event::Status {
let bounds = layout.bounds();
diff --git a/native/src/clipboard.rs b/native/src/clipboard.rs
index ecdccabfe5..081b40046c 100644
--- a/native/src/clipboard.rs
+++ b/native/src/clipboard.rs
@@ -1,6 +1,23 @@
+//! Access the clipboard.
+
/// A buffer for short-term storage and transfer within and between
/// applications.
pub trait Clipboard {
- /// Returns the current content of the [`Clipboard`] as text.
- fn content(&self) -> Option;
+ /// Reads the current content of the [`Clipboard`] as text.
+ fn read(&self) -> Option;
+
+ /// Writes the given text contents to the [`Clipboard`].
+ fn write(&mut self, contents: String);
+}
+
+/// A null implementation of the [`Clipboard`] trait.
+#[derive(Debug, Clone, Copy)]
+pub struct Null;
+
+impl Clipboard for Null {
+ fn read(&self) -> Option {
+ None
+ }
+
+ fn write(&mut self, _contents: String) {}
}
diff --git a/native/src/element.rs b/native/src/element.rs
index d6e9639a7e..5c84a3887f 100644
--- a/native/src/element.rs
+++ b/native/src/element.rs
@@ -223,17 +223,17 @@ where
event: Event,
layout: Layout<'_>,
cursor_position: Point,
- messages: &mut Vec,
renderer: &Renderer,
- clipboard: Option<&dyn Clipboard>,
+ clipboard: &mut dyn Clipboard,
+ messages: &mut Vec,
) -> event::Status {
self.widget.on_event(
event,
layout,
cursor_position,
- messages,
renderer,
clipboard,
+ messages,
)
}
@@ -311,9 +311,9 @@ where
event: Event,
layout: Layout<'_>,
cursor_position: Point,
- messages: &mut Vec,
renderer: &Renderer,
- clipboard: Option<&dyn Clipboard>,
+ clipboard: &mut dyn Clipboard,
+ messages: &mut Vec,
) -> event::Status {
let mut original_messages = Vec::new();
@@ -321,9 +321,9 @@ where
event,
layout,
cursor_position,
- &mut original_messages,
renderer,
clipboard,
+ &mut original_messages,
);
original_messages
@@ -401,17 +401,17 @@ where
event: Event,
layout: Layout<'_>,
cursor_position: Point,
- messages: &mut Vec,
renderer: &Renderer,
- clipboard: Option<&dyn Clipboard>,
+ clipboard: &mut dyn Clipboard,
+ messages: &mut Vec,
) -> event::Status {
self.element.widget.on_event(
event,
layout,
cursor_position,
- messages,
renderer,
clipboard,
+ messages,
)
}
diff --git a/native/src/lib.rs b/native/src/lib.rs
index 0890785be5..20bbb1d025 100644
--- a/native/src/lib.rs
+++ b/native/src/lib.rs
@@ -33,6 +33,7 @@
#![deny(unused_results)]
#![forbid(unsafe_code)]
#![forbid(rust_2018_idioms)]
+pub mod clipboard;
pub mod event;
pub mod keyboard;
pub mod layout;
@@ -45,7 +46,6 @@ pub mod touch;
pub mod widget;
pub mod window;
-mod clipboard;
mod element;
mod hasher;
mod runtime;
diff --git a/native/src/overlay.rs b/native/src/overlay.rs
index ea8bb3845c..84145e7fad 100644
--- a/native/src/overlay.rs
+++ b/native/src/overlay.rs
@@ -67,9 +67,9 @@ where
_event: Event,
_layout: Layout<'_>,
_cursor_position: Point,
- _messages: &mut Vec,
_renderer: &Renderer,
- _clipboard: Option<&dyn Clipboard>,
+ _clipboard: &mut dyn Clipboard,
+ _messages: &mut Vec,
) -> event::Status {
event::Status::Ignored
}
diff --git a/native/src/overlay/element.rs b/native/src/overlay/element.rs
index 0f44a7810c..e48190376b 100644
--- a/native/src/overlay/element.rs
+++ b/native/src/overlay/element.rs
@@ -53,17 +53,17 @@ where
event: Event,
layout: Layout<'_>,
cursor_position: Point,
- messages: &mut Vec,
renderer: &Renderer,
- clipboard: Option<&dyn Clipboard>,
+ clipboard: &mut dyn Clipboard,
+ messages: &mut Vec,
) -> event::Status {
self.overlay.on_event(
event,
layout,
cursor_position,
- messages,
renderer,
clipboard,
+ messages,
)
}
@@ -117,9 +117,9 @@ where
event: Event,
layout: Layout<'_>,
cursor_position: Point,
- messages: &mut Vec,
renderer: &Renderer,
- clipboard: Option<&dyn Clipboard>,
+ clipboard: &mut dyn Clipboard,
+ messages: &mut Vec,
) -> event::Status {
let mut original_messages = Vec::new();
@@ -127,9 +127,9 @@ where
event,
layout,
cursor_position,
- &mut original_messages,
renderer,
clipboard,
+ &mut original_messages,
);
original_messages
diff --git a/native/src/overlay/menu.rs b/native/src/overlay/menu.rs
index 5ad1391f95..afb17bd3b9 100644
--- a/native/src/overlay/menu.rs
+++ b/native/src/overlay/menu.rs
@@ -219,17 +219,17 @@ where
event: Event,
layout: Layout<'_>,
cursor_position: Point,
- messages: &mut Vec,
renderer: &Renderer,
- clipboard: Option<&dyn Clipboard>,
+ clipboard: &mut dyn Clipboard,
+ messages: &mut Vec,
) -> event::Status {
self.container.on_event(
event.clone(),
layout,
cursor_position,
- messages,
renderer,
clipboard,
+ messages,
)
}
@@ -320,9 +320,9 @@ where
event: Event,
layout: Layout<'_>,
cursor_position: Point,
- _messages: &mut Vec,
renderer: &Renderer,
- _clipboard: Option<&dyn Clipboard>,
+ _clipboard: &mut dyn Clipboard,
+ _messages: &mut Vec,
) -> event::Status {
match event {
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => {
diff --git a/native/src/program/state.rs b/native/src/program/state.rs
index e630890a4d..3f5f606978 100644
--- a/native/src/program/state.rs
+++ b/native/src/program/state.rs
@@ -91,8 +91,8 @@ where
&mut self,
bounds: Size,
cursor_position: Point,
- clipboard: Option<&dyn Clipboard>,
renderer: &mut P::Renderer,
+ clipboard: &mut dyn Clipboard,
debug: &mut Debug,
) -> Option> {
let mut user_interface = build_user_interface(
@@ -109,8 +109,8 @@ where
let _ = user_interface.update(
&self.queued_events,
cursor_position,
- clipboard,
renderer,
+ clipboard,
&mut messages,
);
diff --git a/native/src/user_interface.rs b/native/src/user_interface.rs
index 7a64ac5925..475faf8d15 100644
--- a/native/src/user_interface.rs
+++ b/native/src/user_interface.rs
@@ -134,7 +134,7 @@ where
/// completing [the previous example](#example):
///
/// ```no_run
- /// use iced_native::{UserInterface, Cache, Size, Point};
+ /// use iced_native::{clipboard, UserInterface, Cache, Size, Point};
/// use iced_wgpu::Renderer;
///
/// # mod iced_wgpu {
@@ -157,6 +157,7 @@ where
/// let mut renderer = Renderer::new();
/// let mut window_size = Size::new(1024.0, 768.0);
/// let mut cursor_position = Point::default();
+ /// let mut clipboard = clipboard::Null;
///
/// // Initialize our event storage
/// let mut events = Vec::new();
@@ -176,8 +177,8 @@ where
/// let event_statuses = user_interface.update(
/// &events,
/// cursor_position,
- /// None,
/// &renderer,
+ /// &mut clipboard,
/// &mut messages
/// );
///
@@ -193,8 +194,8 @@ where
&mut self,
events: &[Event],
cursor_position: Point,
- clipboard: Option<&dyn Clipboard>,
renderer: &Renderer,
+ clipboard: &mut dyn Clipboard,
messages: &mut Vec,
) -> Vec {
let (base_cursor, overlay_statuses) = if let Some(mut overlay) =
@@ -215,9 +216,9 @@ where
event,
Layout::new(&layer.layout),
cursor_position,
- messages,
renderer,
clipboard,
+ messages,
)
})
.collect();
@@ -246,9 +247,9 @@ where
event,
Layout::new(&self.base.layout),
base_cursor,
- messages,
renderer,
clipboard,
+ messages,
);
event_status.merge(overlay_status)
@@ -269,7 +270,7 @@ where
/// [completing the last example](#example-1):
///
/// ```no_run
- /// use iced_native::{UserInterface, Cache, Size, Point};
+ /// use iced_native::{clipboard, UserInterface, Cache, Size, Point};
/// use iced_wgpu::Renderer;
///
/// # mod iced_wgpu {
@@ -292,6 +293,7 @@ where
/// let mut renderer = Renderer::new();
/// let mut window_size = Size::new(1024.0, 768.0);
/// let mut cursor_position = Point::default();
+ /// let mut clipboard = clipboard::Null;
/// let mut events = Vec::new();
/// let mut messages = Vec::new();
///
@@ -309,8 +311,8 @@ where
/// let event_statuses = user_interface.update(
/// &events,
/// cursor_position,
- /// None,
/// &renderer,
+ /// &mut clipboard,
/// &mut messages
/// );
///
diff --git a/native/src/widget.rs b/native/src/widget.rs
index d5c353dfd5..791c53a3e4 100644
--- a/native/src/widget.rs
+++ b/native/src/widget.rs
@@ -164,9 +164,9 @@ where
_event: Event,
_layout: Layout<'_>,
_cursor_position: Point,
- _messages: &mut Vec,
_renderer: &Renderer,
- _clipboard: Option<&dyn Clipboard>,
+ _clipboard: &mut dyn Clipboard,
+ _messages: &mut Vec,
) -> event::Status {
event::Status::Ignored
}
diff --git a/native/src/widget/button.rs b/native/src/widget/button.rs
index b8c146342a..59d6e21958 100644
--- a/native/src/widget/button.rs
+++ b/native/src/widget/button.rs
@@ -160,17 +160,17 @@ where
event: Event,
layout: Layout<'_>,
cursor_position: Point,
- messages: &mut Vec,
renderer: &Renderer,
- clipboard: Option<&dyn Clipboard>,
+ clipboard: &mut dyn Clipboard,
+ messages: &mut Vec,
) -> event::Status {
if let event::Status::Captured = self.content.on_event(
event.clone(),
layout.children().next().unwrap(),
cursor_position,
- messages,
renderer,
clipboard,
+ messages,
) {
return event::Status::Captured;
}
diff --git a/native/src/widget/checkbox.rs b/native/src/widget/checkbox.rs
index 77a82fad2e..6ce2e973fc 100644
--- a/native/src/widget/checkbox.rs
+++ b/native/src/widget/checkbox.rs
@@ -150,9 +150,9 @@ where
event: Event,
layout: Layout<'_>,
cursor_position: Point,
- messages: &mut Vec,
_renderer: &Renderer,
- _clipboard: Option<&dyn Clipboard>,
+ _clipboard: &mut dyn Clipboard,
+ messages: &mut Vec,
) -> event::Status {
match event {
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
diff --git a/native/src/widget/column.rs b/native/src/widget/column.rs
index e0e88d31f3..d7f0365a50 100644
--- a/native/src/widget/column.rs
+++ b/native/src/widget/column.rs
@@ -141,9 +141,9 @@ where
event: Event,
layout: Layout<'_>,
cursor_position: Point,
- messages: &mut Vec,
renderer: &Renderer,
- clipboard: Option<&dyn Clipboard>,
+ clipboard: &mut dyn Clipboard,
+ messages: &mut Vec,
) -> event::Status {
self.children
.iter_mut()
@@ -153,9 +153,9 @@ where
event.clone(),
layout,
cursor_position,
- messages,
renderer,
clipboard,
+ messages,
)
})
.fold(event::Status::Ignored, event::Status::merge)
diff --git a/native/src/widget/container.rs b/native/src/widget/container.rs
index 6576414883..69fe699bde 100644
--- a/native/src/widget/container.rs
+++ b/native/src/widget/container.rs
@@ -151,17 +151,17 @@ where
event: Event,
layout: Layout<'_>,
cursor_position: Point,
- messages: &mut Vec,
renderer: &Renderer,
- clipboard: Option<&dyn Clipboard>,
+ clipboard: &mut dyn Clipboard,
+ messages: &mut Vec,
) -> event::Status {
self.content.widget.on_event(
event,
layout.children().next().unwrap(),
cursor_position,
- messages,
renderer,
clipboard,
+ messages,
)
}
diff --git a/native/src/widget/image/viewer.rs b/native/src/widget/image/viewer.rs
index 5f0dda4e0d..a006c0af7b 100644
--- a/native/src/widget/image/viewer.rs
+++ b/native/src/widget/image/viewer.rs
@@ -155,9 +155,9 @@ where
event: Event,
layout: Layout<'_>,
cursor_position: Point,
- _messages: &mut Vec,
renderer: &Renderer,
- _clipboard: Option<&dyn Clipboard>,
+ _clipboard: &mut dyn Clipboard,
+ _messages: &mut Vec,
) -> event::Status {
let bounds = layout.bounds();
let is_mouse_over = bounds.contains(cursor_position);
diff --git a/native/src/widget/pane_grid.rs b/native/src/widget/pane_grid.rs
index c6fe4b60bb..9a3580e0a1 100644
--- a/native/src/widget/pane_grid.rs
+++ b/native/src/widget/pane_grid.rs
@@ -362,9 +362,9 @@ where
event: Event,
layout: Layout<'_>,
cursor_position: Point,
- messages: &mut Vec,
renderer: &Renderer,
- clipboard: Option<&dyn Clipboard>,
+ clipboard: &mut dyn Clipboard,
+ messages: &mut Vec,
) -> event::Status {
let mut event_status = event::Status::Ignored;
@@ -461,9 +461,9 @@ where
event.clone(),
layout,
cursor_position,
- messages,
renderer,
clipboard,
+ messages,
)
})
.fold(event_status, event::Status::merge)
diff --git a/native/src/widget/pane_grid/content.rs b/native/src/widget/pane_grid/content.rs
index 913cfe96e0..a5493fe282 100644
--- a/native/src/widget/pane_grid/content.rs
+++ b/native/src/widget/pane_grid/content.rs
@@ -143,9 +143,9 @@ where
event: Event,
layout: Layout<'_>,
cursor_position: Point,
- messages: &mut Vec,
renderer: &Renderer,
- clipboard: Option<&dyn Clipboard>,
+ clipboard: &mut dyn Clipboard,
+ messages: &mut Vec,
) -> event::Status {
let mut event_status = event::Status::Ignored;
@@ -156,9 +156,9 @@ where
event.clone(),
children.next().unwrap(),
cursor_position,
- messages,
renderer,
clipboard,
+ messages,
);
children.next().unwrap()
@@ -170,9 +170,9 @@ where
event,
body_layout,
cursor_position,
- messages,
renderer,
clipboard,
+ messages,
);
event_status.merge(body_status)
diff --git a/native/src/widget/pane_grid/title_bar.rs b/native/src/widget/pane_grid/title_bar.rs
index 2f9659e867..ff689ddbb0 100644
--- a/native/src/widget/pane_grid/title_bar.rs
+++ b/native/src/widget/pane_grid/title_bar.rs
@@ -199,9 +199,9 @@ where
event: Event,
layout: Layout<'_>,
cursor_position: Point,
- messages: &mut Vec,
renderer: &Renderer,
- clipboard: Option<&dyn Clipboard>,
+ clipboard: &mut dyn Clipboard,
+ messages: &mut Vec,
) -> event::Status {
if let Some(controls) = &mut self.controls {
let mut children = layout.children();
@@ -215,9 +215,9 @@ where
event,
controls_layout,
cursor_position,
- messages,
renderer,
clipboard,
+ messages,
)
} else {
event::Status::Ignored
diff --git a/native/src/widget/pick_list.rs b/native/src/widget/pick_list.rs
index 74f4508e2d..046d57791a 100644
--- a/native/src/widget/pick_list.rs
+++ b/native/src/widget/pick_list.rs
@@ -210,9 +210,9 @@ where
event: Event,
layout: Layout<'_>,
cursor_position: Point,
- messages: &mut Vec,
_renderer: &Renderer,
- _clipboard: Option<&dyn Clipboard>,
+ _clipboard: &mut dyn Clipboard,
+ messages: &mut Vec,
) -> event::Status {
match event {
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
diff --git a/native/src/widget/radio.rs b/native/src/widget/radio.rs
index 6995234586..9482a9b14e 100644
--- a/native/src/widget/radio.rs
+++ b/native/src/widget/radio.rs
@@ -156,9 +156,9 @@ where
event: Event,
layout: Layout<'_>,
cursor_position: Point,
- messages: &mut Vec,
_renderer: &Renderer,
- _clipboard: Option<&dyn Clipboard>,
+ _clipboard: &mut dyn Clipboard,
+ messages: &mut Vec,
) -> event::Status {
match event {
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
diff --git a/native/src/widget/row.rs b/native/src/widget/row.rs
index b71663bd05..5634ab1234 100644
--- a/native/src/widget/row.rs
+++ b/native/src/widget/row.rs
@@ -140,9 +140,9 @@ where
event: Event,
layout: Layout<'_>,
cursor_position: Point,
- messages: &mut Vec,
renderer: &Renderer,
- clipboard: Option<&dyn Clipboard>,
+ clipboard: &mut dyn Clipboard,
+ messages: &mut Vec,
) -> event::Status {
self.children
.iter_mut()
@@ -152,9 +152,9 @@ where
event.clone(),
layout,
cursor_position,
- messages,
renderer,
clipboard,
+ messages,
)
})
.fold(event::Status::Ignored, event::Status::merge)
diff --git a/native/src/widget/scrollable.rs b/native/src/widget/scrollable.rs
index 18cdf16974..70ebebe2db 100644
--- a/native/src/widget/scrollable.rs
+++ b/native/src/widget/scrollable.rs
@@ -162,9 +162,9 @@ where
event: Event,
layout: Layout<'_>,
cursor_position: Point,
- messages: &mut Vec,
renderer: &Renderer,
- clipboard: Option<&dyn Clipboard>,
+ clipboard: &mut dyn Clipboard,
+ messages: &mut Vec,
) -> event::Status {
let bounds = layout.bounds();
let is_mouse_over = bounds.contains(cursor_position);
@@ -205,9 +205,9 @@ where
event.clone(),
content,
cursor_position,
- messages,
renderer,
clipboard,
+ messages,
)
};
diff --git a/native/src/widget/slider.rs b/native/src/widget/slider.rs
index 010c6e539f..2a74d5a313 100644
--- a/native/src/widget/slider.rs
+++ b/native/src/widget/slider.rs
@@ -180,9 +180,9 @@ where
event: Event,
layout: Layout<'_>,
cursor_position: Point,
- messages: &mut Vec,
_renderer: &Renderer,
- _clipboard: Option<&dyn Clipboard>,
+ _clipboard: &mut dyn Clipboard,
+ messages: &mut Vec,
) -> event::Status {
let mut change = || {
let bounds = layout.bounds();
diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs
index 2fd9cec189..de6032b77a 100644
--- a/native/src/widget/text_input.rs
+++ b/native/src/widget/text_input.rs
@@ -243,9 +243,9 @@ where
event: Event,
layout: Layout<'_>,
cursor_position: Point,
- messages: &mut Vec,
renderer: &Renderer,
- clipboard: Option<&dyn Clipboard>,
+ clipboard: &mut dyn Clipboard,
+ messages: &mut Vec,
) -> event::Status {
match event {
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left))
@@ -501,45 +501,84 @@ where
self.state.cursor.move_to(self.value.len());
}
}
+ keyboard::KeyCode::C
+ if self
+ .state
+ .keyboard_modifiers
+ .is_command_pressed() =>
+ {
+ match self.state.cursor.selection(&self.value) {
+ Some((start, end)) => {
+ clipboard.write(
+ self.value.select(start, end).to_string(),
+ );
+ }
+ None => {}
+ }
+ }
+ keyboard::KeyCode::X
+ if self
+ .state
+ .keyboard_modifiers
+ .is_command_pressed() =>
+ {
+ match self.state.cursor.selection(&self.value) {
+ Some((start, end)) => {
+ clipboard.write(
+ self.value.select(start, end).to_string(),
+ );
+ }
+ None => {}
+ }
+
+ let mut editor = Editor::new(
+ &mut self.value,
+ &mut self.state.cursor,
+ );
+
+ editor.delete();
+
+ let message = (self.on_change)(editor.contents());
+ messages.push(message);
+ }
keyboard::KeyCode::V => {
if self.state.keyboard_modifiers.is_command_pressed() {
- if let Some(clipboard) = clipboard {
- let content = match self.state.is_pasting.take()
- {
- Some(content) => content,
- None => {
- let content: String = clipboard
- .content()
- .unwrap_or(String::new())
- .chars()
- .filter(|c| !c.is_control())
- .collect();
-
- Value::new(&content)
- }
- };
-
- let mut editor = Editor::new(
- &mut self.value,
- &mut self.state.cursor,
- );
+ let content = match self.state.is_pasting.take() {
+ Some(content) => content,
+ None => {
+ let content: String = clipboard
+ .read()
+ .unwrap_or(String::new())
+ .chars()
+ .filter(|c| !c.is_control())
+ .collect();
+
+ Value::new(&content)
+ }
+ };
+
+ let mut editor = Editor::new(
+ &mut self.value,
+ &mut self.state.cursor,
+ );
- editor.paste(content.clone());
+ editor.paste(content.clone());
- let message =
- (self.on_change)(editor.contents());
- messages.push(message);
+ let message = (self.on_change)(editor.contents());
+ messages.push(message);
- self.state.is_pasting = Some(content);
- }
+ self.state.is_pasting = Some(content);
} else {
self.state.is_pasting = None;
}
}
- keyboard::KeyCode::A => {
- if self.state.keyboard_modifiers.is_command_pressed() {
- self.state.cursor.select_all(&self.value);
- }
+ keyboard::KeyCode::A
+ if self
+ .state
+ .keyboard_modifiers
+ .is_command_pressed() =>
+ {
+ self.state.cursor.select_all(&self.value);
}
keyboard::KeyCode::Escape => {
self.state.is_focused = false;
diff --git a/native/src/widget/text_input/cursor.rs b/native/src/widget/text_input/cursor.rs
index e630e29388..1e7aee8326 100644
--- a/native/src/widget/text_input/cursor.rs
+++ b/native/src/widget/text_input/cursor.rs
@@ -48,6 +48,18 @@ impl Cursor {
}
}
+ /// Returns the current selection of the [`Cursor`] for the given [`Value`].
+ ///
+ /// `start` is guaranteed to be <= than `end`.
+ pub fn selection(&self, value: &Value) -> Option<(usize, usize)> {
+ match self.state(value) {
+ State::Selection { start, end } => {
+ Some((start.min(end), start.max(end)))
+ }
+ _ => None,
+ }
+ }
+
pub(crate) fn move_to(&mut self, position: usize) {
self.state = State::Index(position);
}
@@ -161,15 +173,6 @@ impl Cursor {
end.min(value.len())
}
- pub(crate) fn selection(&self, value: &Value) -> Option<(usize, usize)> {
- match self.state(value) {
- State::Selection { start, end } => {
- Some((start.min(end), start.max(end)))
- }
- _ => None,
- }
- }
-
fn left(&self, value: &Value) -> usize {
match self.state(value) {
State::Index(index) => index,
diff --git a/native/src/widget/text_input/value.rs b/native/src/widget/text_input/value.rs
index 86be279010..2034cca418 100644
--- a/native/src/widget/text_input/value.rs
+++ b/native/src/widget/text_input/value.rs
@@ -73,6 +73,15 @@ impl Value {
.unwrap_or(self.len())
}
+ /// Returns a new [`Value`] containing the graphemes from `start` until the
+ /// given `end`.
+ pub fn select(&self, start: usize, end: usize) -> Self {
+ let graphemes =
+ self.graphemes[start.min(self.len())..end.min(self.len())].to_vec();
+
+ Self { graphemes }
+ }
+
/// Returns a new [`Value`] containing the graphemes until the given
/// `index`.
pub fn until(&self, index: usize) -> Self {
diff --git a/native/src/widget/tooltip.rs b/native/src/widget/tooltip.rs
index ab07868c0b..276afd4102 100644
--- a/native/src/widget/tooltip.rs
+++ b/native/src/widget/tooltip.rs
@@ -120,17 +120,17 @@ where
event: Event,
layout: Layout<'_>,
cursor_position: Point,
- messages: &mut Vec,
renderer: &Renderer,
- clipboard: Option<&dyn Clipboard>,
+ clipboard: &mut dyn Clipboard,
+ messages: &mut Vec,
) -> event::Status {
self.content.widget.on_event(
event,
layout,
cursor_position,
- messages,
renderer,
clipboard,
+ messages,
)
}
diff --git a/winit/Cargo.toml b/winit/Cargo.toml
index 39a6a5faa6..ecee0e2efb 100644
--- a/winit/Cargo.toml
+++ b/winit/Cargo.toml
@@ -15,7 +15,7 @@ debug = ["iced_native/debug"]
[dependencies]
winit = "0.24"
-window_clipboard = "0.1"
+window_clipboard = "0.2"
log = "0.4"
thiserror = "1.0"
diff --git a/winit/src/application.rs b/winit/src/application.rs
index d1a94864f4..2cb2c01610 100644
--- a/winit/src/application.rs
+++ b/winit/src/application.rs
@@ -194,7 +194,7 @@ async fn run_instance(
use winit::event;
let surface = compositor.create_surface(&window);
- let clipboard = Clipboard::new(&window);
+ let mut clipboard = Clipboard::connect(&window);
let mut state = State::new(&application, &window);
let mut viewport_version = state.viewport_version();
@@ -237,8 +237,8 @@ async fn run_instance(
let statuses = user_interface.update(
&events,
state.cursor_position(),
- clipboard.as_ref().map(|c| c as _),
&mut renderer,
+ &mut clipboard,
&mut messages,
);
diff --git a/winit/src/clipboard.rs b/winit/src/clipboard.rs
index 93d53b11ad..15dc989f21 100644
--- a/winit/src/clipboard.rs
+++ b/winit/src/clipboard.rs
@@ -1,17 +1,44 @@
/// A buffer for short-term storage and transfer within and between
/// applications.
#[allow(missing_debug_implementations)]
-pub struct Clipboard(window_clipboard::Clipboard);
+pub struct Clipboard {
+ state: State,
+}
+
+enum State {
+ Connected(window_clipboard::Clipboard),
+ Unavailable,
+}
impl Clipboard {
/// Creates a new [`Clipboard`] for the given window.
- pub fn new(window: &winit::window::Window) -> Option {
- window_clipboard::Clipboard::new(window).map(Clipboard).ok()
+ pub fn connect(window: &winit::window::Window) -> Clipboard {
+ let state = window_clipboard::Clipboard::connect(window)
+ .ok()
+ .map(State::Connected)
+ .unwrap_or(State::Unavailable);
+
+ Clipboard { state }
}
}
impl iced_native::Clipboard for Clipboard {
- fn content(&self) -> Option {
- self.0.read().ok()
+ fn read(&self) -> Option {
+ match &self.state {
+ State::Connected(clipboard) => clipboard.read().ok(),
+ State::Unavailable => None,
+ }
+ }
+
+ fn write(&mut self, contents: String) {
+ match &mut self.state {
+ State::Connected(clipboard) => match clipboard.write(contents) {
+ Ok(()) => {}
+ Err(error) => {
+ log::warn!("error writing to clipboard: {}", error)
+ }
+ },
+ State::Unavailable => {}
+ }
}
}