Merge pull request #2282 from ghostty-org/movemods

apprt/macos,gtk: unfocused splits now highlight hovered links
This commit is contained in:
Mitchell Hashimoto
2024-09-21 15:28:05 -07:00
committed by GitHub
6 changed files with 49 additions and 11 deletions

View File

@ -556,7 +556,10 @@ bool ghostty_surface_mouse_button(ghostty_surface_t,
ghostty_input_mouse_state_e, ghostty_input_mouse_state_e,
ghostty_input_mouse_button_e, ghostty_input_mouse_button_e,
ghostty_input_mods_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,
ghostty_input_mods_e);
void ghostty_surface_mouse_scroll(ghostty_surface_t, void ghostty_surface_mouse_scroll(ghostty_surface_t,
double, double,
double, double,

View File

@ -505,7 +505,8 @@ extension Ghostty {
// Convert window position to view position. Note (0, 0) is bottom left. // Convert window position to view position. Note (0, 0) is bottom left.
let pos = self.convert(event.locationInWindow, from: nil) let pos = self.convert(event.locationInWindow, from: nil)
ghostty_surface_mouse_pos(surface, pos.x, frame.height - pos.y) let mods = Ghostty.ghosttyMods(event.modifierFlags)
ghostty_surface_mouse_pos(surface, pos.x, frame.height - pos.y, mods)
// If focus follows mouse is enabled then move focus to this surface. // If focus follows mouse is enabled then move focus to this surface.
if let window = self.window as? TerminalWindow, if let window = self.window as? TerminalWindow,

View File

@ -1459,7 +1459,7 @@ pub fn keyCallback(
// mod changes can affect link highlighting. // mod changes can affect link highlighting.
self.mouse.link_point = null; self.mouse.link_point = null;
const pos = self.rt_surface.getCursorPos() catch break :mouse_mods; const pos = self.rt_surface.getCursorPos() catch break :mouse_mods;
self.cursorPosCallback(pos) catch {}; self.cursorPosCallback(pos, null) catch {};
if (rehide) self.mouse.hidden = true; if (rehide) self.mouse.hidden = true;
} }
@ -2421,7 +2421,7 @@ pub fn mouseButtonCallback(
// expensive because it could block all our threads. // expensive because it could block all our threads.
if (self.hasSelection()) { if (self.hasSelection()) {
const pos = try self.rt_surface.getCursorPos(); const pos = try self.rt_surface.getCursorPos();
try self.cursorPosCallback(pos); try self.cursorPosCallback(pos, null);
return true; return true;
} }
} }
@ -2887,9 +2887,18 @@ pub fn mousePressureCallback(
} }
} }
/// Cursor position callback.
///
/// The mods parameter is optional because some apprts do not provide
/// modifier information on cursor position events. If mods is null then
/// we'll use the last known mods. This is usually accurate since mod events
/// will trigger key press events but on some platforms we don't get them.
/// For example, on macOS, unfocused surfaces don't receive key events but
/// do receive mouse events so we have to rely on updated mods.
pub fn cursorPosCallback( pub fn cursorPosCallback(
self: *Surface, self: *Surface,
pos: apprt.CursorPos, pos: apprt.CursorPos,
mods: ?input.Mods,
) !void { ) !void {
// Crash metadata in case we crash in here // Crash metadata in case we crash in here
crash.sentry.thread_state = self.crashThreadState(); crash.sentry.thread_state = self.crashThreadState();
@ -2898,6 +2907,9 @@ pub fn cursorPosCallback(
// Always show the mouse again if it is hidden // Always show the mouse again if it is hidden
if (self.mouse.hidden) self.showMouse(); if (self.mouse.hidden) self.showMouse();
// Update our modifiers if they changed
if (mods) |v| self.modsChanged(v);
// The mouse position in the viewport // The mouse position in the viewport
const pos_vp = self.posToViewport(pos.x, pos.y); const pos_vp = self.posToViewport(pos.x, pos.y);

View File

@ -763,7 +763,12 @@ pub const Surface = struct {
}; };
} }
pub fn cursorPosCallback(self: *Surface, x: f64, y: f64) void { pub fn cursorPosCallback(
self: *Surface,
x: f64,
y: f64,
mods: input.Mods,
) void {
// Convert our unscaled x/y to scaled. // Convert our unscaled x/y to scaled.
self.cursor_pos = self.cursorPosToPixels(.{ self.cursor_pos = self.cursorPosToPixels(.{
.x = @floatCast(x), .x = @floatCast(x),
@ -776,7 +781,7 @@ pub const Surface = struct {
return; return;
}; };
self.core_surface.cursorPosCallback(self.cursor_pos) catch |err| { self.core_surface.cursorPosCallback(self.cursor_pos, mods) catch |err| {
log.err("error in cursor pos callback err={}", .{err}); log.err("error in cursor pos callback err={}", .{err});
return; return;
}; };
@ -1716,8 +1721,20 @@ pub const CAPI = struct {
} }
/// Update the mouse position within the view. /// Update the mouse position within the view.
export fn ghostty_surface_mouse_pos(surface: *Surface, x: f64, y: f64) void { export fn ghostty_surface_mouse_pos(
surface.cursorPosCallback(x, y); surface: *Surface,
x: f64,
y: f64,
mods: c_int,
) void {
surface.cursorPosCallback(
x,
y,
@bitCast(@as(
input.Mods.Backing,
@truncate(@as(c_uint, @bitCast(mods))),
)),
);
} }
export fn ghostty_surface_mouse_scroll( export fn ghostty_surface_mouse_scroll(

View File

@ -1040,7 +1040,7 @@ pub const Surface = struct {
core_win.cursorPosCallback(.{ core_win.cursorPosCallback(.{
.x = @floatCast(pos.xpos), .x = @floatCast(pos.xpos),
.y = @floatCast(pos.ypos), .y = @floatCast(pos.ypos),
}) catch |err| { }, null) catch |err| {
log.err("error in cursor pos callback err={}", .{err}); log.err("error in cursor pos callback err={}", .{err});
return; return;
}; };

View File

@ -1386,7 +1386,7 @@ fn gtkMouseUp(
} }
fn gtkMouseMotion( fn gtkMouseMotion(
_: *c.GtkEventControllerMotion, ec: *c.GtkEventControllerMotion,
x: c.gdouble, x: c.gdouble,
y: c.gdouble, y: c.gdouble,
ud: ?*anyopaque, ud: ?*anyopaque,
@ -1415,7 +1415,12 @@ fn gtkMouseMotion(
self.grabFocus(); self.grabFocus();
} }
self.core_surface.cursorPosCallback(self.cursor_pos) catch |err| { // Get our modifiers
const event = c.gtk_event_controller_get_current_event(@ptrCast(ec));
const gtk_mods = c.gdk_event_get_modifier_state(event);
const mods = translateMods(gtk_mods);
self.core_surface.cursorPosCallback(self.cursor_pos, mods) catch |err| {
log.err("error in cursor pos callback err={}", .{err}); log.err("error in cursor pos callback err={}", .{err});
return; return;
}; };