macOS: firstRect should return full rect width/height
Fixes #2473 This commit changes `ghostty_surface_ime_point` to return a full rect with the width/height calculated for the preedit. The `firstRect` function, which calls `ghostty_surface_ime_point` was previously setting the width/height to zero. macOS didn't like this. We then changed it to just hardcode it to width/height of one cell. This worked but made it so the IME cursor didn't follow the preedit.pull/8492/head
parent
3664ee9f87
commit
e8217aa007
|
|
@ -964,7 +964,7 @@ void ghostty_surface_mouse_scroll(ghostty_surface_t,
|
||||||
double,
|
double,
|
||||||
ghostty_input_scroll_mods_t);
|
ghostty_input_scroll_mods_t);
|
||||||
void ghostty_surface_mouse_pressure(ghostty_surface_t, uint32_t, double);
|
void ghostty_surface_mouse_pressure(ghostty_surface_t, uint32_t, double);
|
||||||
void ghostty_surface_ime_point(ghostty_surface_t, double*, double*);
|
void ghostty_surface_ime_point(ghostty_surface_t, double*, double*, double*, double*);
|
||||||
void ghostty_surface_request_close(ghostty_surface_t);
|
void ghostty_surface_request_close(ghostty_surface_t);
|
||||||
void ghostty_surface_split(ghostty_surface_t, ghostty_action_split_direction_e);
|
void ghostty_surface_split(ghostty_surface_t, ghostty_action_split_direction_e);
|
||||||
void ghostty_surface_split_focus(ghostty_surface_t,
|
void ghostty_surface_split_focus(ghostty_surface_t,
|
||||||
|
|
|
||||||
|
|
@ -1683,8 +1683,10 @@ extension Ghostty.SurfaceView: NSTextInputClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ghostty will tell us where it thinks an IME keyboard should render.
|
// Ghostty will tell us where it thinks an IME keyboard should render.
|
||||||
var x: Double = 0;
|
var x: Double = 0
|
||||||
var y: Double = 0;
|
var y: Double = 0
|
||||||
|
var width: Double = cellSize.width
|
||||||
|
var height: Double = cellSize.height
|
||||||
|
|
||||||
// QuickLook never gives us a matching range to our selection so if we detect
|
// QuickLook never gives us a matching range to our selection so if we detect
|
||||||
// this then we return the top-left selection point rather than the cursor point.
|
// this then we return the top-left selection point rather than the cursor point.
|
||||||
|
|
@ -1702,15 +1704,19 @@ extension Ghostty.SurfaceView: NSTextInputClient {
|
||||||
// Free our text
|
// Free our text
|
||||||
ghostty_surface_free_text(surface, &text)
|
ghostty_surface_free_text(surface, &text)
|
||||||
} else {
|
} else {
|
||||||
ghostty_surface_ime_point(surface, &x, &y)
|
ghostty_surface_ime_point(surface, &x, &y, &width, &height)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ghostty_surface_ime_point(surface, &x, &y)
|
ghostty_surface_ime_point(surface, &x, &y, &width, &height)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ghostty coordinates are in top-left (0, 0) so we have to convert to
|
// Ghostty coordinates are in top-left (0, 0) so we have to convert to
|
||||||
// bottom-left since that is what UIKit expects
|
// bottom-left since that is what UIKit expects
|
||||||
let viewRect = NSMakeRect(x, frame.size.height - y, cellSize.width, cellSize.height)
|
let viewRect = NSMakeRect(
|
||||||
|
x,
|
||||||
|
frame.size.height - y,
|
||||||
|
max(width, cellSize.width),
|
||||||
|
max(height, cellSize.height))
|
||||||
|
|
||||||
// Convert the point to the window coordinates
|
// Convert the point to the window coordinates
|
||||||
let winRect = self.convert(viewRect, to: nil)
|
let winRect = self.convert(viewRect, to: nil)
|
||||||
|
|
|
||||||
|
|
@ -1730,6 +1730,7 @@ pub fn pwd(
|
||||||
pub fn imePoint(self: *const Surface) apprt.IMEPos {
|
pub fn imePoint(self: *const Surface) apprt.IMEPos {
|
||||||
self.renderer_state.mutex.lock();
|
self.renderer_state.mutex.lock();
|
||||||
const cursor = self.renderer_state.terminal.screen.cursor;
|
const cursor = self.renderer_state.terminal.screen.cursor;
|
||||||
|
const preedit_width: usize = if (self.renderer_state.preedit) |preedit| preedit.width() else 0;
|
||||||
self.renderer_state.mutex.unlock();
|
self.renderer_state.mutex.unlock();
|
||||||
|
|
||||||
// TODO: need to handle when scrolling and the cursor is not
|
// TODO: need to handle when scrolling and the cursor is not
|
||||||
|
|
@ -1764,7 +1765,38 @@ pub fn imePoint(self: *const Surface) apprt.IMEPos {
|
||||||
break :y y;
|
break :y y;
|
||||||
};
|
};
|
||||||
|
|
||||||
return .{ .x = x, .y = y };
|
// Our height for now is always just the cell height because our preedit
|
||||||
|
// rendering only renders in a single line.
|
||||||
|
const height: f64 = height: {
|
||||||
|
var height: f64 = @floatFromInt(self.size.cell.height);
|
||||||
|
height /= content_scale.y;
|
||||||
|
break :height height;
|
||||||
|
};
|
||||||
|
const width: f64 = width: {
|
||||||
|
var width: f64 = @floatFromInt(preedit_width * self.size.cell.width);
|
||||||
|
|
||||||
|
// Our max width is the remaining screen width after the cursor.
|
||||||
|
// We don't have to deal with wrapping because the preedit doesn't
|
||||||
|
// wrap right now.
|
||||||
|
const screen_width: f64 = @floatFromInt(self.size.terminal().width);
|
||||||
|
const x_offset: f64 = @floatFromInt((cursor.x + 1) * self.size.cell.width);
|
||||||
|
const max = screen_width - x_offset;
|
||||||
|
width = @min(width, max);
|
||||||
|
|
||||||
|
// Note: we don't apply content scale here because it looks like
|
||||||
|
// for some reason in macOS its already scaled. I'm not sure why
|
||||||
|
// that is so I'm going to just leave this comment here so its known
|
||||||
|
// that I left this out on purpose pending more investigation.
|
||||||
|
|
||||||
|
break :width width;
|
||||||
|
};
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.x = x,
|
||||||
|
.y = y,
|
||||||
|
.width = width,
|
||||||
|
.height = height,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clipboardWrite(self: *const Surface, data: []const u8, loc: apprt.Clipboard) !void {
|
fn clipboardWrite(self: *const Surface, data: []const u8, loc: apprt.Clipboard) !void {
|
||||||
|
|
|
||||||
|
|
@ -1822,10 +1822,18 @@ pub const CAPI = struct {
|
||||||
surface.mousePressureCallback(stage, pressure);
|
surface.mousePressureCallback(stage, pressure);
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn ghostty_surface_ime_point(surface: *Surface, x: *f64, y: *f64) void {
|
export fn ghostty_surface_ime_point(
|
||||||
|
surface: *Surface,
|
||||||
|
x: *f64,
|
||||||
|
y: *f64,
|
||||||
|
width: *f64,
|
||||||
|
height: *f64,
|
||||||
|
) void {
|
||||||
const pos = surface.core_surface.imePoint();
|
const pos = surface.core_surface.imePoint();
|
||||||
x.* = pos.x;
|
x.* = pos.x;
|
||||||
y.* = pos.y;
|
y.* = pos.y;
|
||||||
|
width.* = pos.width;
|
||||||
|
height.* = pos.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Request that the surface become closed. This will go through the
|
/// Request that the surface become closed. This will go through the
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ pub const CursorPos = struct {
|
||||||
pub const IMEPos = struct {
|
pub const IMEPos = struct {
|
||||||
x: f64,
|
x: f64,
|
||||||
y: f64,
|
y: f64,
|
||||||
|
width: f64,
|
||||||
|
height: f64,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The clipboard type.
|
/// The clipboard type.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue