aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <metajack+bors@gmail.com>2015-07-29 11:26:00 -0600
committerbors-servo <metajack+bors@gmail.com>2015-07-29 11:26:00 -0600
commit28e163d6c44f1d85fbaea7f236da40972b6a63b1 (patch)
tree7a63a5b756256ecb7e8a4263396b16928411c1f9
parent65811cfa02e588660942fedd9a11868ec5c5525f (diff)
parent9ba18850dd12d6d5f100bc93b59af51d6ff2a4f3 (diff)
downloadservo-28e163d6c44f1d85fbaea7f236da40972b6a63b1.tar.gz
servo-28e163d6c44f1d85fbaea7f236da40972b6a63b1.zip
Auto merge of #6654 - aweinstock314:add-x11-copy-to-clipboard, r=jdm
Add copy-to-clipboard feature under x11 The main work is in the the rust-clipboard library, this PR updates Cargo.lock and adds plumbing. https://github.com/aweinstock314/rust-clipboard/commit/0337e48b3f1a8bbb274a10099a39d7d18e902494 <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/6654) <!-- Reviewable:end -->
-rw-r--r--components/compositing/constellation.rs7
-rw-r--r--components/msg/constellation_msg.rs2
-rw-r--r--components/script/clipboard_provider.rs10
-rw-r--r--components/script/textinput.rs109
-rw-r--r--components/servo/Cargo.lock2
-rw-r--r--ports/cef/Cargo.lock2
-rw-r--r--ports/gonk/Cargo.lock2
-rw-r--r--tests/unit/script/textinput.rs4
8 files changed, 86 insertions, 52 deletions
diff --git a/components/compositing/constellation.rs b/components/compositing/constellation.rs
index 695c6688e9a..8237908656f 100644
--- a/components/compositing/constellation.rs
+++ b/components/compositing/constellation.rs
@@ -475,6 +475,13 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
);
sender.send(result).unwrap();
}
+ ConstellationMsg::SetClipboardContents(s) => {
+ if let Some(ref mut ctx) = self.clipboard_ctx {
+ if let Err(e) = ctx.set_contents(s) {
+ debug!("Error setting clipboard contents ({})", e);
+ }
+ }
+ }
ConstellationMsg::WebDriverCommand(command) => {
debug!("constellation got webdriver command message");
self.handle_webdriver_msg(command);
diff --git a/components/msg/constellation_msg.rs b/components/msg/constellation_msg.rs
index fcd9afdf7f0..26b5a97ce09 100644
--- a/components/msg/constellation_msg.rs
+++ b/components/msg/constellation_msg.rs
@@ -247,6 +247,8 @@ pub enum Msg {
Focus(PipelineId),
/// Requests that the constellation retrieve the current contents of the clipboard
GetClipboardContents(IpcSender<String>),
+ /// Requests that the constellation set the contents of the clipboard
+ SetClipboardContents(String),
/// Dispatch a webdriver command
WebDriverCommand(WebDriverCommandMsg),
/// Notifies the constellation that the viewport has been constrained in some manner
diff --git a/components/script/clipboard_provider.rs b/components/script/clipboard_provider.rs
index facdf4aca14..ce57a82857d 100644
--- a/components/script/clipboard_provider.rs
+++ b/components/script/clipboard_provider.rs
@@ -13,7 +13,7 @@ pub trait ClipboardProvider {
// blocking method to get the clipboard contents
fn clipboard_contents(&mut self) -> String;
// blocking method to set the clipboard contents
- fn set_clipboard_contents(&mut self, &str);
+ fn set_clipboard_contents(&mut self, String);
}
impl ClipboardProvider for ConstellationChan {
@@ -22,8 +22,8 @@ impl ClipboardProvider for ConstellationChan {
self.0.send(ConstellationMsg::GetClipboardContents(tx)).unwrap();
rx.recv().unwrap()
}
- fn set_clipboard_contents(&mut self, _: &str) {
- panic!("not yet implemented");
+ fn set_clipboard_contents(&mut self, s: String) {
+ self.0.send(ConstellationMsg::SetClipboardContents(s)).unwrap();
}
}
@@ -43,7 +43,7 @@ impl ClipboardProvider for DummyClipboardContext {
fn clipboard_contents(&mut self) -> String {
self.content.clone()
}
- fn set_clipboard_contents(&mut self, s: &str) {
- self.content = s.to_owned();
+ fn set_clipboard_contents(&mut self, s: String) {
+ self.content = s;
}
}
diff --git a/components/script/textinput.rs b/components/script/textinput.rs
index c1fda44b5fb..9ce3a482a65 100644
--- a/components/script/textinput.rs
+++ b/components/script/textinput.rs
@@ -143,51 +143,71 @@ impl<T: ClipboardProvider> TextInput<T> {
self.replace_selection(s.into());
}
- pub fn get_sorted_selection(&self) -> (TextPoint, TextPoint) {
- let begin = self.selection_begin.unwrap();
- let end = self.edit_point;
+ pub fn get_sorted_selection(&self) -> Option<(TextPoint, TextPoint)> {
+ self.selection_begin.map(|begin| {
+ let end = self.edit_point;
- if begin.line < end.line || (begin.line == end.line && begin.index < end.index) {
- (begin, end)
- } else {
- (end, begin)
- }
+ if begin.line < end.line || (begin.line == end.line && begin.index < end.index) {
+ (begin, end)
+ } else {
+ (end, begin)
+ }
+ })
}
- pub fn replace_selection(&mut self, insert: String) {
- let (begin, end) = self.get_sorted_selection();
- self.clear_selection();
-
- let new_lines = {
- let prefix = self.lines[begin.line].slice_chars(0, begin.index);
- let suffix = self.lines[end.line].slice_chars(end.index, self.lines[end.line].chars().count());
- let lines_prefix = &self.lines[..begin.line];
- let lines_suffix = &self.lines[end.line + 1..];
-
- let mut insert_lines = if self.multiline {
- insert.split('\n').map(|s| s.to_owned()).collect()
+ pub fn get_selection_text(&self) -> Option<String> {
+ self.get_sorted_selection().map(|(begin, end)| {
+ if begin.line != end.line {
+ let mut s = String::new();
+ s.push_str(self.lines[begin.line].slice_chars(begin.index, self.lines[begin.line].len()));
+ for (_, line) in self.lines.iter().enumerate().filter(|&(i,_)| begin.line < i && i < end.line) {
+ s.push_str("\n");
+ s.push_str(line);
+ }
+ s.push_str("\n");
+ s.push_str(self.lines[end.line].slice_chars(0, end.index));
+ s
} else {
- vec!(insert)
- };
-
- let mut new_line = prefix.to_owned();
- new_line.push_str(&insert_lines[0]);
- insert_lines[0] = new_line;
-
- let last_insert_lines_index = insert_lines.len() - 1;
- self.edit_point.index = insert_lines[last_insert_lines_index].chars().count();
- self.edit_point.line = begin.line + last_insert_lines_index;
+ self.lines[begin.line].slice_chars(begin.index, end.index).to_owned()
+ }
+ })
+ }
- insert_lines[last_insert_lines_index].push_str(suffix);
+ pub fn replace_selection(&mut self, insert: String) {
+ if let Some((begin, end)) = self.get_sorted_selection() {
+ self.clear_selection();
- let mut new_lines = vec!();
- new_lines.push_all(lines_prefix);
- new_lines.push_all(&insert_lines);
- new_lines.push_all(lines_suffix);
- new_lines
- };
+ let new_lines = {
+ let prefix = self.lines[begin.line].slice_chars(0, begin.index);
+ let suffix = self.lines[end.line].slice_chars(end.index, self.lines[end.line].chars().count());
+ let lines_prefix = &self.lines[..begin.line];
+ let lines_suffix = &self.lines[end.line + 1..];
+
+ let mut insert_lines = if self.multiline {
+ insert.split('\n').map(|s| s.to_owned()).collect()
+ } else {
+ vec!(insert)
+ };
+
+ let mut new_line = prefix.to_owned();
+ new_line.push_str(&insert_lines[0]);
+ insert_lines[0] = new_line;
+
+ let last_insert_lines_index = insert_lines.len() - 1;
+ self.edit_point.index = insert_lines[last_insert_lines_index].chars().count();
+ self.edit_point.line = begin.line + last_insert_lines_index;
+
+ insert_lines[last_insert_lines_index].push_str(suffix);
+
+ let mut new_lines = vec!();
+ new_lines.push_all(lines_prefix);
+ new_lines.push_all(&insert_lines);
+ new_lines.push_all(lines_suffix);
+ new_lines
+ };
- self.lines = new_lines;
+ self.lines = new_lines;
+ }
}
/// Return the length of the current line under the editing point.
@@ -237,8 +257,7 @@ impl<T: ClipboardProvider> TextInput<T> {
self.selection_begin = Some(self.edit_point);
}
} else {
- if self.selection_begin.is_some() {
- let (begin, end) = self.get_sorted_selection();
+ if let Some((begin, end)) = self.get_sorted_selection() {
self.edit_point = if adjust < 0 {begin} else {end};
self.clear_selection();
return
@@ -304,11 +323,17 @@ impl<T: ClipboardProvider> TextInput<T> {
pub fn handle_keydown_aux(&mut self, key: Key, mods: KeyModifiers) -> KeyReaction {
let maybe_select = if mods.contains(SHIFT) { Selection::Selected } else { Selection::NotSelected };
match key {
- Key::A if is_control_key(mods) => {
+ Key::A if is_control_key(mods) => {
self.select_all();
KeyReaction::Nothing
},
- Key::V if is_control_key(mods) => {
+ Key::C if is_control_key(mods) => {
+ if let Some(text) = self.get_selection_text() {
+ self.clipboard_provider.set_clipboard_contents(text);
+ }
+ KeyReaction::DispatchInput
+ },
+ Key::V if is_control_key(mods) => {
let contents = self.clipboard_provider.clipboard_contents();
self.insert_string(contents);
KeyReaction::DispatchInput
diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock
index 60a3d00f48a..b176435974e 100644
--- a/components/servo/Cargo.lock
+++ b/components/servo/Cargo.lock
@@ -131,7 +131,7 @@ dependencies = [
[[package]]
name = "clipboard"
version = "0.0.1"
-source = "git+https://github.com/aweinstock314/rust-clipboard#d271be958151cbc90d4cea670f028afe05e75cbe"
+source = "git+https://github.com/aweinstock314/rust-clipboard#67ec94ac27b28ff4ed3a4dde212f57e302f7cc35"
dependencies = [
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"x11 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock
index 1b4702c0757..30924e32663 100644
--- a/ports/cef/Cargo.lock
+++ b/ports/cef/Cargo.lock
@@ -130,7 +130,7 @@ dependencies = [
[[package]]
name = "clipboard"
version = "0.0.1"
-source = "git+https://github.com/aweinstock314/rust-clipboard#d271be958151cbc90d4cea670f028afe05e75cbe"
+source = "git+https://github.com/aweinstock314/rust-clipboard#67ec94ac27b28ff4ed3a4dde212f57e302f7cc35"
dependencies = [
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"x11 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/ports/gonk/Cargo.lock b/ports/gonk/Cargo.lock
index 063aed15c59..06c6de27216 100644
--- a/ports/gonk/Cargo.lock
+++ b/ports/gonk/Cargo.lock
@@ -117,7 +117,7 @@ dependencies = [
[[package]]
name = "clipboard"
version = "0.0.1"
-source = "git+https://github.com/aweinstock314/rust-clipboard#d271be958151cbc90d4cea670f028afe05e75cbe"
+source = "git+https://github.com/aweinstock314/rust-clipboard#67ec94ac27b28ff4ed3a4dde212f57e302f7cc35"
dependencies = [
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"x11 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/tests/unit/script/textinput.rs b/tests/unit/script/textinput.rs
index 1c364d5739a..4d59ebf2869 100644
--- a/tests/unit/script/textinput.rs
+++ b/tests/unit/script/textinput.rs
@@ -50,14 +50,14 @@ fn test_textinput_get_sorted_selection() {
let mut textinput = TextInput::new(Lines::Single, "abcdefg".to_owned(), DummyClipboardContext::new(""));
textinput.adjust_horizontal(2, Selection::NotSelected);
textinput.adjust_horizontal(2, Selection::Selected);
- let (begin, end) = textinput.get_sorted_selection();
+ let (begin, end) = textinput.get_sorted_selection().unwrap();
assert_eq!(begin.index, 2);
assert_eq!(end.index, 4);
textinput.clear_selection();
textinput.adjust_horizontal(-2, Selection::Selected);
- let (begin, end) = textinput.get_sorted_selection();
+ let (begin, end) = textinput.get_sorted_selection().unwrap();
assert_eq!(begin.index, 2);
assert_eq!(end.index, 4);
}