Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

X11 clipboard support #5479

Closed
wants to merge 10 commits into from
Next

Implement X11 clipboard integration (Issue #5376).

  • Loading branch information
aweinstock314 committed Apr 1, 2015
commit f4fd1d5c5ccbf63a13730a0d9fbd4d6add50cb8f
@@ -66,6 +66,9 @@ git = "https://github.com/servo/string-cache"
[dependencies.string_cache_plugin]
git = "https://github.com/servo/string-cache"

[dependencies.xlib]
git = "https://github.com/servo/rust-xlib"

[dependencies]
encoding = "0.2"
url = "0.2.16"
@@ -0,0 +1,72 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::trace::JSTraceable;

// X11 clipboard support
#[cfg(target_os="linux")]
mod x11_clipboard {
use xlib::{Display, Window};
use xlib::{XOpenDisplay, XCloseDisplay};
use xlib::{XCreateSimpleWindow, XDefaultRootWindow};
use libc::*;

#[jstraceable]
pub struct ClipboardContext {
display: *mut Display,
window: Window,
}
no_jsmanaged_fields!(ClipboardContext);

impl ClipboardContext {
pub fn new() -> Result<ClipboardContext, &'static str> {
// http://sourceforge.net/p/xclip/code/HEAD/tree/trunk/xclip.c
let dpy = XOpenDisplay(0 as *mut c_char);
if dpy == 0 {
return Err("XOpenDisplay")
}
let win = XCreateSimpleWindow(dpy, XDefaultRootWindow(dpy), 0, 0, 1, 1, 0, 0, 0);
if win == 0 {
return Err("XCreateSimpleWindow")
}
Ok(ClipboardContext {
display: dpy,
window: win,
})
}
pub fn get_contents(&self) -> String {
"dummy string".to_owned()
}
}

impl Drop for ClipboardContext {
fn drop(&mut self) {
// TODO: error checking of some sort
if XCloseDisplay(self.display) == 0 {
panic!("XCloseDisplay failed.");
}
}
}
}

// catch-all "not-yet-implemented" clipboard
#[cfg(not(target_os="linux"))]
mod notyetimplemented_clipboard {
#[jstraceable]
pub struct ClipboardContext;
impl ClipBoardContext {
pub fn new() -> Result<ClipboardContext, &'static str> {
Ok(ClipboardContext)
}
pub fn get_contents(&self) -> String {
"Clipboard not yet implemented on $PLATFORM".to_owned()
}
}
}

#[cfg(target_os="linux")]
pub use self::x11_clipboard::*;
#[cfg(not(target_os="linux"))]
pub use self::notyetimplemented_clipboard::*;

@@ -28,6 +28,7 @@
extern crate log;

#[macro_use] extern crate bitflags;
//#[macro_use] extern crate lazy_static;
extern crate core;
extern crate devtools_traits;
extern crate cssparser;
@@ -52,6 +53,8 @@ extern crate style;
extern crate url;
extern crate uuid;
extern crate string_cache;
#[cfg(target_os="linux")]
extern crate xlib;

pub mod cors;

@@ -64,6 +67,7 @@ pub mod layout_interface;
pub mod page;
pub mod script_task;
mod timers;
pub mod clipboard;
pub mod textinput;
mod devtools;

@@ -14,6 +14,8 @@ use std::cmp::{min, max};
use std::default::Default;
use std::num::SignedInt;

use clipboard::ClipboardContext;

#[derive(Copy, PartialEq)]
enum Selection {
Selected,
@@ -40,8 +42,15 @@ pub struct TextInput {
selection_begin: Option<TextPoint>,
/// Is this a multiline input?
multiline: bool,
/// Means of accessing the clipboard
clipboard_ctx: ClipboardContext,
}

/*
lazy_static! {
static ref clipboard_ctx: Result<ClipboardContext, &'static str> = ClipboardContext::new();
}*/

/// Resulting action to be taken by the owner of a text input that is handling an event.
pub enum KeyReaction {
TriggerDefaultAction,
@@ -93,6 +102,7 @@ impl TextInput {
edit_point: Default::default(),
selection_begin: None,
multiline: lines == Lines::Multiple,
clipboard_ctx: ClipboardContext::new().unwrap(),
};
i.set_content(initial);
i
@@ -118,6 +128,15 @@ impl TextInput {
self.replace_selection(ch.to_string());
}

/// Insert a string at the current editing point
fn insert_string(&mut self, s: &str) {
// it looks like this could be made performant by avoiding some redundant
// selection-related checks, but use the simple implementation for now
for ch in s.chars() {
self.insert_char(ch);
}
}

fn get_sorted_selection(&self) -> (TextPoint, TextPoint) {
let begin = self.selection_begin.unwrap();
let end = self.edit_point;
@@ -282,10 +301,14 @@ impl TextInput {
self.select_all();
KeyReaction::Nothing
},
"v" if is_control_key(event) => {
self.insert_string(self.clipboard_ctx.get_contents().as_slice());
KeyReaction::DispatchInput
},
// printable characters have single-character key values
c if c.len() == 1 => {
self.insert_char(c.char_at(0));
return KeyReaction::DispatchInput;
KeyReaction::DispatchInput
}
"Space" => {
self.insert_char(' ');

Some generated files are not rendered by default. Learn more.

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.