mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-09-23 11:38:34 +00:00
macos: emoji keyboard works
This commit is contained in:
@@ -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_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_pos(ghostty_surface_t, double, double);
|
||||||
void ghostty_surface_mouse_scroll(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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@@ -404,7 +404,22 @@ class TerminalSurfaceView_Real: NSView, NSTextInputClient, ObservableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func firstRect(forCharacterRange range: NSRange, actualRange: NSRangePointer?) -> NSRect {
|
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) {
|
func insertText(_ string: Any, replacementRange: NSRange) {
|
||||||
|
@@ -462,4 +462,10 @@ pub const CAPI = struct {
|
|||||||
export fn ghostty_surface_mouse_scroll(win: *Window, x: f64, y: f64) void {
|
export fn ghostty_surface_mouse_scroll(win: *Window, x: f64, y: f64) void {
|
||||||
win.window.scrollCallback(x, y);
|
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;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@@ -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 {
|
fn clipboardRead(self: *const Window, kind: u8) !void {
|
||||||
if (!self.config.@"clipboard-read") {
|
if (!self.config.@"clipboard-read") {
|
||||||
log.info("application attempted to read clipboard, but 'clipboard-read' setting is off", .{});
|
log.info("application attempted to read clipboard, but 'clipboard-read' setting is off", .{});
|
||||||
|
@@ -17,3 +17,9 @@ pub const CursorPos = struct {
|
|||||||
x: f32,
|
x: f32,
|
||||||
y: f32,
|
y: f32,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Input Method Editor (IME) position.
|
||||||
|
pub const IMEPos = struct {
|
||||||
|
x: f64,
|
||||||
|
y: f64,
|
||||||
|
};
|
||||||
|
Reference in New Issue
Block a user