mirror of
https://github.com/wez/wezterm.git
synced 2024-11-10 15:04:32 +03:00
macos: try to set the IME cursor position a bit better
Use the current terminal cursor position as the basis for the position of the IME.
This commit is contained in:
parent
e3f6375551
commit
cb5e351187
@ -291,6 +291,9 @@ impl WindowCallbacks for TermWindow {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
self.update_text_cursor(&tab);
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
if let Err(err) = self.paint_tab(&tab, ctx) {
|
||||
if let Some(&OutOfTextureSpace { size }) = err.downcast_ref::<OutOfTextureSpace>() {
|
||||
@ -323,6 +326,7 @@ impl WindowCallbacks for TermWindow {
|
||||
return;
|
||||
}
|
||||
};
|
||||
self.update_text_cursor(&tab);
|
||||
let start = std::time::Instant::now();
|
||||
if let Err(err) = self.paint_tab_opengl(&tab, frame) {
|
||||
if let Some(&OutOfTextureSpace { size }) = err.downcast_ref::<OutOfTextureSpace>() {
|
||||
@ -486,6 +490,21 @@ impl TermWindow {
|
||||
}
|
||||
}
|
||||
|
||||
fn update_text_cursor(&mut self, tab: &Rc<dyn Tab>) {
|
||||
let term = tab.renderer();
|
||||
let cursor = term.get_cursor_position();
|
||||
if let Some(win) = self.window.as_ref() {
|
||||
let r = Rect::new(
|
||||
Point::new(
|
||||
cursor.x.max(0) as isize * self.render_metrics.cell_size.width,
|
||||
cursor.y.max(0) as isize * self.render_metrics.cell_size.height,
|
||||
),
|
||||
self.render_metrics.cell_size,
|
||||
);
|
||||
win.set_text_cursor_position(r);
|
||||
}
|
||||
}
|
||||
|
||||
fn activate_tab(&mut self, tab_idx: usize) -> Fallible<()> {
|
||||
let mux = Mux::get().unwrap();
|
||||
let mut window = mux
|
||||
|
@ -172,6 +172,11 @@ pub trait WindowOps {
|
||||
/// Resize the inner or client area of the window
|
||||
fn set_inner_size(&self, width: usize, height: usize);
|
||||
|
||||
/// inform the windowing system of the current textual
|
||||
/// cursor input location. This is used primarily for
|
||||
/// the platform specific input method editor
|
||||
fn set_text_cursor_position(&self, _cursor: Rect) {}
|
||||
|
||||
/// Schedule a callback on the data associated with the window.
|
||||
/// The `Any` that is passed in corresponds to the WindowCallbacks
|
||||
/// impl you passed to `new_window`, pre-converted to Any so that
|
||||
@ -214,4 +219,9 @@ pub trait WindowOpsMut {
|
||||
|
||||
/// Resize the inner or client area of the window
|
||||
fn set_inner_size(&self, width: usize, height: usize);
|
||||
|
||||
/// inform the windowing system of the current textual
|
||||
/// cursor input location. This is used primarily for
|
||||
/// the platform specific input method editor
|
||||
fn set_text_cursor_position(&mut self, _cursor: Rect) {}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use crate::connection::ConnectionOps;
|
||||
use crate::os::macos::bitmap::BitmapRef;
|
||||
use crate::{
|
||||
BitmapImage, Color, Connection, Dimensions, KeyCode, KeyEvent, Modifiers, MouseButtons,
|
||||
MouseCursor, MouseEvent, MouseEventKind, MousePress, Operator, PaintContext, Point, Rect,
|
||||
MouseCursor, MouseEvent, MouseEventKind, MousePress, Operator, PaintContext, Point, Rect, Size,
|
||||
WindowCallbacks, WindowOps, WindowOpsMut,
|
||||
};
|
||||
use cocoa::appkit::{
|
||||
@ -281,6 +281,7 @@ impl Window {
|
||||
window_id,
|
||||
#[cfg(feature = "opengl")]
|
||||
gl_context_pair: None,
|
||||
text_cursor_position: Rect::new(Point::new(0, 0), Size::new(0, 0)),
|
||||
}));
|
||||
|
||||
let window = StrongPtr::new(
|
||||
@ -364,6 +365,10 @@ impl WindowOps for Window {
|
||||
Connection::with_window_inner(self.0, move |inner| inner.set_inner_size(width, height));
|
||||
}
|
||||
|
||||
fn set_text_cursor_position(&self, cursor: Rect) {
|
||||
Connection::with_window_inner(self.0, move |inner| inner.set_text_cursor_position(cursor));
|
||||
}
|
||||
|
||||
fn apply<F: Send + 'static + Fn(&mut dyn Any, &dyn WindowOps)>(&self, func: F)
|
||||
where
|
||||
Self: Sized,
|
||||
@ -462,6 +467,16 @@ impl WindowOpsMut for WindowInner {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn set_text_cursor_position(&mut self, cursor: Rect) {
|
||||
if let Some(window_view) = WindowView::get_this(unsafe { &**self.view }) {
|
||||
window_view.inner.borrow_mut().text_cursor_position = cursor;
|
||||
}
|
||||
unsafe {
|
||||
let input_context: id = msg_send![&**self.view, inputContext];
|
||||
let () = msg_send![input_context, invalidateCharacterCoordinates];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Inner {
|
||||
@ -470,6 +485,7 @@ struct Inner {
|
||||
window_id: usize,
|
||||
#[cfg(feature = "opengl")]
|
||||
gl_context_pair: Option<opengl::GlContextPair>,
|
||||
text_cursor_position: Rect,
|
||||
}
|
||||
|
||||
const CLS_NAME: &str = "WezTermWindowView";
|
||||
@ -727,9 +743,29 @@ impl WindowView {
|
||||
"firstRectForCharacterRange: range:{:?} actual:{:?}",
|
||||
range, actual
|
||||
);
|
||||
unsafe {
|
||||
let frame = unsafe {
|
||||
let window: id = msg_send![this, window];
|
||||
let frame = NSWindow::frame(window);
|
||||
NSWindow::frame(window)
|
||||
};
|
||||
let backing_frame: NSRect = unsafe { msg_send![this, convertRectToBacking: frame] };
|
||||
let scale = frame.size.width / backing_frame.size.width;
|
||||
|
||||
if let Some(this) = Self::get_this(this) {
|
||||
let cursor_pos = this
|
||||
.inner
|
||||
.borrow()
|
||||
.text_cursor_position
|
||||
.to_f64()
|
||||
.scale(scale, scale);
|
||||
|
||||
NSRect::new(
|
||||
NSPoint::new(
|
||||
frame.origin.x + cursor_pos.origin.x,
|
||||
frame.origin.y + frame.size.height - cursor_pos.origin.y,
|
||||
),
|
||||
NSSize::new(cursor_pos.size.width, cursor_pos.size.height),
|
||||
)
|
||||
} else {
|
||||
frame
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user