macos: emoji keyboard works

This commit is contained in:
Mitchell Hashimoto
2023-02-19 12:28:17 -08:00
parent 7fa02cae95
commit 8889dd7de2
5 changed files with 71 additions and 1 deletions

View File

@ -233,6 +233,7 @@ void ghostty_surface_char(ghostty_surface_t, uint32_t);
void ghostty_surface_mouse_button(ghostty_surface_t, ghostty_input_mouse_state_e, ghostty_input_mouse_button_e, ghostty_input_mods_e);
void ghostty_surface_mouse_pos(ghostty_surface_t, double, double);
void ghostty_surface_mouse_scroll(ghostty_surface_t, double, double);
void ghostty_surface_ime_point(ghostty_surface_t, double *, double *);
#ifdef __cplusplus
}

View File

@ -404,7 +404,22 @@ class TerminalSurfaceView_Real: NSView, NSTextInputClient, ObservableObject {
}
func firstRect(forCharacterRange range: NSRange, actualRange: NSRangePointer?) -> NSRect {
return NSMakeRect(frame.origin.x, frame.origin.y, 0, 0)
guard let surface = self.surface else {
return NSMakeRect(frame.origin.x, frame.origin.y, 0, 0)
}
// Ghostty will tell us where it thinks an IME keyboard should render.
var x: Double = 0;
var y: Double = 0;
ghostty_surface_ime_point(surface, &x, &y)
// Ghostty coordinates are in top-left (0, 0) so we have to convert to
// bottom-left since that is what UIKit expects
let rect = NSMakeRect(x, frame.size.height - y, 0, 0)
// Convert from view to screen coordinates
guard let window = self.window else { return rect }
return window.convertToScreen(rect)
}
func insertText(_ string: Any, replacementRange: NSRange) {

View File

@ -462,4 +462,10 @@ pub const CAPI = struct {
export fn ghostty_surface_mouse_scroll(win: *Window, x: f64, y: f64) void {
win.window.scrollCallback(x, y);
}
export fn ghostty_surface_ime_point(win: *Window, x: *f64, y: *f64) void {
const pos = win.imePoint();
x.* = pos.x;
y.* = pos.y;
}
};

View File

@ -553,6 +553,48 @@ pub fn handleMessage(self: *Window, msg: Message) !void {
}
}
/// Returns the x/y coordinate of where the IME (Input Method Editor)
/// keyboard should be rendered.
pub fn imePoint(self: *const Window) apprt.IMEPos {
self.renderer_state.mutex.lock();
const cursor = self.renderer_state.terminal.screen.cursor;
self.renderer_state.mutex.unlock();
// TODO: need to handle when scrolling and the cursor is not
// in the visible portion of the screen.
// Our sizes are all scaled so we need to send the unscaled values back.
const content_scale = self.window.getContentScale() catch .{ .x = 1, .y = 1 };
const x: f64 = x: {
// Simple x * cell width gives the top-left corner
var x: f64 = @floatCast(f64, @intToFloat(f32, cursor.x) * self.cell_size.width);
// We want the midpoint
x += self.cell_size.width / 2;
// And scale it
x /= content_scale.x;
break :x x;
};
const y: f64 = y: {
// Simple x * cell width gives the top-left corner
var y: f64 = @floatCast(f64, @intToFloat(f32, cursor.y) * self.cell_size.height);
// We want the bottom
y += self.cell_size.height;
// And scale it
y /= content_scale.y;
break :y y;
};
return .{ .x = x, .y = y };
}
fn clipboardRead(self: *const Window, kind: u8) !void {
if (!self.config.@"clipboard-read") {
log.info("application attempted to read clipboard, but 'clipboard-read' setting is off", .{});

View File

@ -17,3 +17,9 @@ pub const CursorPos = struct {
x: f32,
y: f32,
};
/// Input Method Editor (IME) position.
pub const IMEPos = struct {
x: f64,
y: f64,
};