From 97f9fd8067fac6c614b3b3e930e3533abfcdaef0 Mon Sep 17 00:00:00 2001 From: ezhang7423 Date: Sat, 1 Jan 2022 03:00:51 -0800 Subject: [PATCH] finish --- alacritty.yml | 6 ++- alacritty/src/config/bindings.rs | 3 ++ alacritty/src/event.rs | 76 +++++++++++++++++++++++++++----- alacritty/src/input.rs | 5 +++ alacritty/src/window_context.rs | 9 ++-- 5 files changed, 84 insertions(+), 15 deletions(-) diff --git a/alacritty.yml b/alacritty.yml index 09abce3cda..948dc3345e 100644 --- a/alacritty.yml +++ b/alacritty.yml @@ -737,7 +737,11 @@ # # If the same trigger is assigned to multiple actions, all of them are executed # in the order they were defined in. -#key_bindings: +key_bindings: + - { key: A, mods: Control, action: "SelectCurrentLine" } + - { key: Q, mods: Control, action: "SelectCurrentLineCallback" } + - { key: E, mods: Control, action: "SelectCurrentLineCallback2" } + #- { key: Paste, action: Paste } #- { key: Copy, action: Copy } #- { key: L, mods: Control, action: ClearLogNotice } diff --git a/alacritty/src/config/bindings.rs b/alacritty/src/config/bindings.rs index c73bff52d3..c789177b15 100644 --- a/alacritty/src/config/bindings.rs +++ b/alacritty/src/config/bindings.rs @@ -115,6 +115,9 @@ pub enum Action { /// Select current line SelectCurrentLine, + SelectCurrentLineCallback, + SelectCurrentLineCallback2, + /// Paste contents of system clipboard. Paste, diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs index b43d6645fd..f753c9c033 100644 --- a/alacritty/src/event.rs +++ b/alacritty/src/event.rs @@ -13,7 +13,10 @@ use std::time::{Duration, Instant}; use std::{env, f32, mem}; use glutin::dpi::PhysicalSize; -use glutin::event::{ElementState, Event as GlutinEvent, ModifiersState, MouseButton, WindowEvent}; +use glutin::event::{ + ElementState, Event as GlutinEvent, KeyboardInput, ModifiersState, MouseButton, VirtualKeyCode, + WindowEvent, +}; use glutin::event_loop::{ControlFlow, EventLoop, EventLoopProxy, EventLoopWindowTarget}; use glutin::platform::run_return::EventLoopExtRunReturn; #[cfg(all(feature = "wayland", not(any(target_os = "macos", windows))))] @@ -25,6 +28,10 @@ use wayland_client::{Display as WaylandDisplay, EventQueue}; use crossfont::{self, Size}; +use x11_dl::keysym::{XK_Control_L, XK_End, XK_Home, XK_E, XK_Q}; +use x11_dl::xlib::CurrentTime; +use x11_dl::{xinput2, xlib, xtest}; + use alacritty_terminal::config::LOG_TARGET_CONFIG; use alacritty_terminal::event::{Event as TerminalEvent, EventListener, Notify}; use alacritty_terminal::event_loop::Notifier; @@ -170,6 +177,7 @@ impl Default for SearchState { } pub struct ActionContext<'a, N, T> { + pub tmp_point: &'a mut Box, pub notifier: &'a mut N, pub terminal: &'a mut Term, pub clipboard: &'a mut Clipboard, @@ -219,7 +227,6 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext for ActionCon let display_offset = self.terminal.grid().display_offset(); self.search_state.display_offset_delta += old_offset - display_offset as i32; } - // Update selection. if self.terminal.mode().contains(TermMode::VI) && self.terminal.selection.as_ref().map_or(true, |s| !s.is_empty()) @@ -238,18 +245,65 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext for ActionCon } fn select_current_line(&mut self) { - for val in &self.search_state.history { - info!("{}", val); + // self.event_proxy.send_event(Event()) + self.write_to_pty(String::from("").into_bytes()); + + if !self.event_loop.is_x11() { + return; + } + + unsafe { + let xlib = xlib::Xlib::open().unwrap(); + let xtest = xtest::Xf86vmode::open().unwrap(); + let xconn = self.event_loop.xlib_xconnection().unwrap(); + let display = xconn.display; + + let type_char = |display: *mut xlib::Display, key: u32| { + let modcode = (xlib.XKeysymToKeycode)(display, key as u64) as u32; + (xtest.XTestFakeKeyEvent)(display, modcode, xlib::False, CurrentTime); + (xtest.XTestFakeKeyEvent)(display, modcode, xlib::True, 0); + (xtest.XTestFakeKeyEvent)(display, modcode, xlib::False, 0); + }; + + // Open display connection. + let ctrl_l = (xlib.XKeysymToKeycode)(display, XK_Control_L as u64) as u32; + (xtest.XTestFakeKeyEvent)(display, ctrl_l, xlib::False, 0); // release control + type_char(display, XK_Home); + (xtest.XTestFakeKeyEvent)(display, ctrl_l, xlib::True, 0); // hold control + type_char(display, XK_Q); } - let point = self.terminal.grid().cursor.point; - self.start_selection(SelectionType::Simple, point, Direction::Left); - self.update_selection( - point.add(self.terminal, Boundary::None, self.terminal.last_column().0), - Direction::Right, - ) - // info!("hihaha"); } + fn scl_cb(&mut self) { + println!("Updating temporary point"); + **self.tmp_point = self.terminal.grid().cursor.point; + println!("{}. {}", self.tmp_point.line.0, self.tmp_point.column.0); + unsafe { + let xlib = xlib::Xlib::open().unwrap(); + let xtest = xtest::Xf86vmode::open().unwrap(); + let xconn = self.event_loop.xlib_xconnection().unwrap(); + let display = xconn.display; + + let type_char = |display: *mut xlib::Display, key: u32| { + let modcode = (xlib.XKeysymToKeycode)(display, key as u64) as u32; + (xtest.XTestFakeKeyEvent)(display, modcode, xlib::False, CurrentTime); + (xtest.XTestFakeKeyEvent)(display, modcode, xlib::True, 0); + (xtest.XTestFakeKeyEvent)(display, modcode, xlib::False, 0); + }; + + // Open display connection. + let ctrl_l = (xlib.XKeysymToKeycode)(display, XK_Control_L as u64) as u32; + (xtest.XTestFakeKeyEvent)(display, ctrl_l, xlib::False, 0); // release control + type_char(display, XK_End); + (xtest.XTestFakeKeyEvent)(display, ctrl_l, xlib::True, 0); // hold control + type_char(display, XK_E); + } + } + fn scl_cb2(&mut self) { + println!("in cb2: {}. {}", self.tmp_point.line.0, self.tmp_point.column.0); + self.start_selection(SelectionType::Simple, **self.tmp_point, Direction::Left); + self.update_selection(self.terminal.grid().cursor.point, Direction::Right); + } // Copy text selection. fn copy_selection(&mut self, ty: ClipboardType) { let text = match self.terminal.selection_to_string().filter(|s| !s.is_empty()) { diff --git a/alacritty/src/input.rs b/alacritty/src/input.rs index f13d87b82b..def6883e7d 100644 --- a/alacritty/src/input.rs +++ b/alacritty/src/input.rs @@ -65,6 +65,8 @@ pub trait ActionContext { fn mark_dirty(&mut self) {} fn size_info(&self) -> SizeInfo; fn select_current_line(&mut self) {} + fn scl_cb(&mut self) {} + fn scl_cb2(&mut self) {} fn copy_selection(&mut self, _ty: ClipboardType) {} fn start_selection(&mut self, _ty: SelectionType, _point: Point, _side: Side) {} fn toggle_selection(&mut self, _ty: SelectionType, _point: Point, _side: Side) {} @@ -140,6 +142,9 @@ impl Execute for Action { #[inline] fn execute>(&self, ctx: &mut A) { match self { + Action::SelectCurrentLineCallback => ctx.scl_cb(), + Action::SelectCurrentLineCallback2 => ctx.scl_cb2(), + Action::Esc(s) => { ctx.on_typing_start(); diff --git a/alacritty/src/window_context.rs b/alacritty/src/window_context.rs index 130f42d685..9fbdd81525 100644 --- a/alacritty/src/window_context.rs +++ b/alacritty/src/window_context.rs @@ -23,7 +23,7 @@ use alacritty_terminal::config::PtyConfig; use alacritty_terminal::event::Event as TerminalEvent; use alacritty_terminal::event_loop::{EventLoop as PtyEventLoop, Msg, Notifier}; use alacritty_terminal::grid::{Dimensions, Scroll}; -use alacritty_terminal::index::Direction; +use alacritty_terminal::index::{Column, Direction, Line, Point}; use alacritty_terminal::sync::FairMutex; use alacritty_terminal::term::{Term, TermMode}; use alacritty_terminal::tty; @@ -38,6 +38,7 @@ use crate::scheduler::Scheduler; /// Event context for one individual Alacritty window. pub struct WindowContext { + tmp_point: Box, pub message_buffer: MessageBuffer, pub display: Display, event_queue: Vec>, @@ -132,6 +133,7 @@ impl WindowContext { // Create context for the Alacritty window. Ok(WindowContext { + tmp_point: Box::new(Point { column: Column(0), line: Line(0) }), font_size: config.font.size(), notifier: Notifier(loop_tx), terminal, @@ -220,7 +222,7 @@ impl WindowContext { // Skip further event handling with no staged updates. GlutinEvent::RedrawEventsCleared if self.event_queue.is_empty() && !self.dirty => { return; - }, + } // Continue to process all pending events. GlutinEvent::RedrawEventsCleared => (), // Remap DPR change event to remove the lifetime. @@ -232,7 +234,7 @@ impl WindowContext { let event = Event::new(EventType::DprChanged(scale_factor, size), window_id); self.event_queue.push(event.into()); return; - }, + } // Transmute to extend lifetime, which exists only for `ScaleFactorChanged` event. // Since we remap that event to remove the lifetime, this is safe. event => unsafe { @@ -246,6 +248,7 @@ impl WindowContext { let old_is_searching = self.search_state.history_index.is_some(); let context = ActionContext { + tmp_point: &mut self.tmp_point, message_buffer: &mut self.message_buffer, received_count: &mut self.received_count, suppress_chars: &mut self.suppress_chars,