aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ansi.rs17
-rw-r--r--src/display.rs4
-rw-r--r--src/lib.rs7
-rw-r--r--src/term/mod.rs39
-rw-r--r--src/window.rs15
5 files changed, 71 insertions, 11 deletions
diff --git a/src/ansi.rs b/src/ansi.rs
index ec139294..3d66b497 100644
--- a/src/ansi.rs
+++ b/src/ansi.rs
@@ -21,7 +21,7 @@ use vte;
use index::{Column, Line, Contains};
-use ::Rgb;
+use ::{MouseCursor, Rgb};
// Parse color arguments
//
@@ -178,6 +178,9 @@ pub trait Handler {
/// OSC to set window title
fn set_title(&mut self, &str) {}
+ /// Set the window's mouse cursor
+ fn set_mouse_cursor(&mut self, MouseCursor) {}
+
/// Set the cursor style
fn set_cursor_style(&mut self, _: Option<CursorStyle>) {}
@@ -402,7 +405,9 @@ pub enum Mode {
/// ?1000
ReportMouseClicks = 1000,
/// ?1002
- ReportMouseMotion = 1002,
+ ReportCellMouseMotion = 1002,
+ /// ?1003
+ ReportAllMouseMotion = 1003,
/// ?1004
ReportFocusInOut = 1004,
/// ?1006
@@ -427,12 +432,16 @@ impl Mode {
12 => Mode::BlinkingCursor,
25 => Mode::ShowCursor,
1000 => Mode::ReportMouseClicks,
- 1002 => Mode::ReportMouseMotion,
+ 1002 => Mode::ReportCellMouseMotion,
+ 1003 => Mode::ReportAllMouseMotion,
1004 => Mode::ReportFocusInOut,
1006 => Mode::SgrMouse,
1049 => Mode::SwapScreenAndSetRestoreCursor,
2004 => Mode::BracketedPaste,
- _ => return None
+ _ => {
+ trace!("[unhandled] mode={:?}", num);
+ return None
+ }
})
} else {
Some(match num {
diff --git a/src/display.rs b/src/display.rs
index 8e3d8814..89403194 100644
--- a/src/display.rs
+++ b/src/display.rs
@@ -327,6 +327,10 @@ impl Display {
self.window.set_title(&title);
}
+ if let Some(mouse_cursor) = terminal.get_next_mouse_cursor() {
+ self.window.set_mouse_cursor(mouse_cursor);
+ }
+
if let Some(is_urgent) = terminal.next_is_urgent.take() {
// We don't need to set the urgent flag if we already have the
// user's attention.
diff --git a/src/lib.rs b/src/lib.rs
index a8539328..1f3fcc96 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -81,6 +81,13 @@ use std::ops::Mul;
pub use grid::Grid;
pub use term::Term;
+/// Facade around [winit's MouseCursor](glutin::MouseCursor)
+#[derive(Debug, Eq, PartialEq, Copy, Clone)]
+pub enum MouseCursor {
+ Arrow,
+ Text,
+}
+
#[derive(Debug, Eq, PartialEq, Copy, Clone, Default, Serialize, Deserialize)]
pub struct Rgb {
pub r: u8,
diff --git a/src/term/mod.rs b/src/term/mod.rs
index 98e08e6c..712247c4 100644
--- a/src/term/mod.rs
+++ b/src/term/mod.rs
@@ -28,7 +28,7 @@ use grid::{BidirectionalIterator, Grid, ClearRegion, ToRange, Indexed};
use index::{self, Point, Column, Line, Linear, IndexRange, Contains, RangeInclusive};
use selection::{self, Span, Selection};
use config::{Config, VisualBellAnimation};
-use Rgb;
+use {MouseCursor, Rgb};
pub mod cell;
pub mod color;
@@ -648,6 +648,9 @@ pub struct Term {
/// Would be nice to avoid the allocation...
next_title: Option<String>,
+ /// Got a request to set the mouse cursor; it's buffered here until the next draw
+ next_mouse_cursor: Option<MouseCursor>,
+
/// Alternate grid
alt_grid: Grid<Cell>,
@@ -769,6 +772,11 @@ impl Term {
self.next_title.take()
}
+ #[inline]
+ pub fn get_next_mouse_cursor(&mut self) -> Option<MouseCursor> {
+ self.next_mouse_cursor.take()
+ }
+
pub fn new(config: &Config, size: SizeInfo) -> Term {
let template = Cell::default();
@@ -786,6 +794,7 @@ impl Term {
Term {
next_title: None,
+ next_mouse_cursor: None,
dirty: false,
visual_bell: VisualBell::new(config),
next_is_urgent: None,
@@ -1168,6 +1177,12 @@ impl ansi::Handler for Term {
}
}
+ /// Set the mouse cursor
+ #[inline]
+ fn set_mouse_cursor(&mut self, cursor: MouseCursor) {
+ self.next_mouse_cursor = Some(cursor);
+ }
+
/// A character to be displayed
#[inline]
fn input(&mut self, c: char) {
@@ -1767,8 +1782,15 @@ impl ansi::Handler for Term {
},
ansi::Mode::ShowCursor => self.mode.insert(mode::TermMode::SHOW_CURSOR),
ansi::Mode::CursorKeys => self.mode.insert(mode::TermMode::APP_CURSOR),
- ansi::Mode::ReportMouseClicks => self.mode.insert(mode::TermMode::MOUSE_REPORT_CLICK),
- ansi::Mode::ReportMouseMotion => self.mode.insert(mode::TermMode::MOUSE_MOTION),
+ ansi::Mode::ReportMouseClicks => {
+ self.mode.insert(mode::TermMode::MOUSE_REPORT_CLICK);
+ self.set_mouse_cursor(MouseCursor::Arrow);
+ },
+ ansi::Mode::ReportCellMouseMotion |
+ ansi::Mode::ReportAllMouseMotion => {
+ self.mode.insert(mode::TermMode::MOUSE_MOTION);
+ self.set_mouse_cursor(MouseCursor::Arrow);
+ },
ansi::Mode::ReportFocusInOut => self.mode.insert(mode::TermMode::FOCUS_IN_OUT),
ansi::Mode::BracketedPaste => self.mode.insert(mode::TermMode::BRACKETED_PASTE),
ansi::Mode::SgrMouse => self.mode.insert(mode::TermMode::SGR_MOUSE),
@@ -1797,8 +1819,15 @@ impl ansi::Handler for Term {
},
ansi::Mode::ShowCursor => self.mode.remove(mode::TermMode::SHOW_CURSOR),
ansi::Mode::CursorKeys => self.mode.remove(mode::TermMode::APP_CURSOR),
- ansi::Mode::ReportMouseClicks => self.mode.remove(mode::TermMode::MOUSE_REPORT_CLICK),
- ansi::Mode::ReportMouseMotion => self.mode.remove(mode::TermMode::MOUSE_MOTION),
+ ansi::Mode::ReportMouseClicks => {
+ self.mode.remove(mode::TermMode::MOUSE_REPORT_CLICK);
+ self.set_mouse_cursor(MouseCursor::Text);
+ },
+ ansi::Mode::ReportCellMouseMotion |
+ ansi::Mode::ReportAllMouseMotion => {
+ self.mode.remove(mode::TermMode::MOUSE_MOTION);
+ self.set_mouse_cursor(MouseCursor::Text);
+ },
ansi::Mode::ReportFocusInOut => self.mode.remove(mode::TermMode::FOCUS_IN_OUT),
ansi::Mode::BracketedPaste => self.mode.remove(mode::TermMode::BRACKETED_PASTE),
ansi::Mode::SgrMouse => self.mode.remove(mode::TermMode::SGR_MOUSE),
diff --git a/src/window.rs b/src/window.rs
index e42151fd..aec4b76d 100644
--- a/src/window.rs
+++ b/src/window.rs
@@ -16,9 +16,12 @@ use std::fmt::{self, Display};
use std::ops::Deref;
use gl;
-use glutin::{self, EventsLoop, WindowBuilder, Event, MouseCursor, CursorState, ControlFlow, ContextBuilder};
+use glutin::{self, ContextBuilder, ControlFlow, CursorState, Event, EventsLoop,
+ MouseCursor as GlutinMouseCursor, WindowBuilder};
use glutin::GlContext;
+use MouseCursor;
+
use config::WindowConfig;
/// Window errors
@@ -200,7 +203,7 @@ impl Window {
let window = ::glutin::GlWindow::new(window, context, &event_loop)?;
// Text cursor
- window.set_cursor(MouseCursor::Text);
+ window.set_cursor(GlutinMouseCursor::Text);
// Set OpenGL symbol loader
gl::load_with(|symbol| window.get_proc_address(symbol) as *const _);
@@ -284,6 +287,14 @@ impl Window {
self.window.set_title(title);
}
+ #[inline]
+ pub fn set_mouse_cursor(&self, cursor: MouseCursor) {
+ self.window.set_cursor(match cursor {
+ MouseCursor::Arrow => GlutinMouseCursor::Arrow,
+ MouseCursor::Text => GlutinMouseCursor::Text,
+ });
+ }
+
/// Set cursor visible
pub fn set_cursor_visible(&mut self, visible: bool) {
if visible != self.cursor_visible {