mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 17:26:09 +03:00
gtk: enable non-discrete scrolling
Remove the flag which reports all scrolls as discrete scrolls. This enables precision scrolling in GTK. We have to track a flag between continuous scroll events.
This commit is contained in:
@ -304,6 +304,9 @@ cgroup_path: ?[]const u8 = null,
|
|||||||
/// Our context menu.
|
/// Our context menu.
|
||||||
context_menu: Menu(Surface, "context_menu", false),
|
context_menu: Menu(Surface, "context_menu", false),
|
||||||
|
|
||||||
|
/// True when we have a precision scroll in progress
|
||||||
|
precision_scroll: bool = false,
|
||||||
|
|
||||||
/// The state of the key event while we're doing IM composition.
|
/// The state of the key event while we're doing IM composition.
|
||||||
/// See gtkKeyPressed for detailed descriptions.
|
/// See gtkKeyPressed for detailed descriptions.
|
||||||
pub const IMKeyEvent = enum {
|
pub const IMKeyEvent = enum {
|
||||||
@ -418,10 +421,7 @@ pub fn init(self: *Surface, app: *App, opts: Options) !void {
|
|||||||
c.gtk_widget_add_controller(@ptrCast(@alignCast(overlay)), ec_motion);
|
c.gtk_widget_add_controller(@ptrCast(@alignCast(overlay)), ec_motion);
|
||||||
|
|
||||||
// Scroll events
|
// Scroll events
|
||||||
const ec_scroll = c.gtk_event_controller_scroll_new(
|
const ec_scroll = c.gtk_event_controller_scroll_new(c.GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES);
|
||||||
c.GTK_EVENT_CONTROLLER_SCROLL_BOTH_AXES |
|
|
||||||
c.GTK_EVENT_CONTROLLER_SCROLL_DISCRETE,
|
|
||||||
);
|
|
||||||
errdefer c.g_object_unref(ec_scroll);
|
errdefer c.g_object_unref(ec_scroll);
|
||||||
c.gtk_widget_add_controller(@ptrCast(overlay), ec_scroll);
|
c.gtk_widget_add_controller(@ptrCast(overlay), ec_scroll);
|
||||||
|
|
||||||
@ -532,6 +532,8 @@ pub fn init(self: *Surface, app: *App, opts: Options) !void {
|
|||||||
_ = c.g_signal_connect_data(ec_motion, "motion", c.G_CALLBACK(>kMouseMotion), self, null, c.G_CONNECT_DEFAULT);
|
_ = c.g_signal_connect_data(ec_motion, "motion", c.G_CALLBACK(>kMouseMotion), self, null, c.G_CONNECT_DEFAULT);
|
||||||
_ = c.g_signal_connect_data(ec_motion, "leave", c.G_CALLBACK(>kMouseLeave), self, null, c.G_CONNECT_DEFAULT);
|
_ = c.g_signal_connect_data(ec_motion, "leave", c.G_CALLBACK(>kMouseLeave), self, null, c.G_CONNECT_DEFAULT);
|
||||||
_ = c.g_signal_connect_data(ec_scroll, "scroll", c.G_CALLBACK(>kMouseScroll), self, null, c.G_CONNECT_DEFAULT);
|
_ = c.g_signal_connect_data(ec_scroll, "scroll", c.G_CALLBACK(>kMouseScroll), self, null, c.G_CONNECT_DEFAULT);
|
||||||
|
_ = c.g_signal_connect_data(ec_scroll, "scroll-begin", c.G_CALLBACK(>kMouseScrollPrecisionBegin), self, null, c.G_CONNECT_DEFAULT);
|
||||||
|
_ = c.g_signal_connect_data(ec_scroll, "scroll-end", c.G_CALLBACK(>kMouseScrollPrecisionEnd), self, null, c.G_CONNECT_DEFAULT);
|
||||||
_ = c.g_signal_connect_data(im_context, "preedit-start", c.G_CALLBACK(>kInputPreeditStart), self, null, c.G_CONNECT_DEFAULT);
|
_ = c.g_signal_connect_data(im_context, "preedit-start", c.G_CALLBACK(>kInputPreeditStart), self, null, c.G_CONNECT_DEFAULT);
|
||||||
_ = c.g_signal_connect_data(im_context, "preedit-changed", c.G_CALLBACK(>kInputPreeditChanged), self, null, c.G_CONNECT_DEFAULT);
|
_ = c.g_signal_connect_data(im_context, "preedit-changed", c.G_CALLBACK(>kInputPreeditChanged), self, null, c.G_CONNECT_DEFAULT);
|
||||||
_ = c.g_signal_connect_data(im_context, "preedit-end", c.G_CALLBACK(>kInputPreeditEnd), self, null, c.G_CONNECT_DEFAULT);
|
_ = c.g_signal_connect_data(im_context, "preedit-end", c.G_CALLBACK(>kInputPreeditEnd), self, null, c.G_CONNECT_DEFAULT);
|
||||||
@ -1523,6 +1525,22 @@ fn gtkMouseLeave(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn gtkMouseScrollPrecisionBegin(
|
||||||
|
_: *c.GtkEventControllerScroll,
|
||||||
|
ud: ?*anyopaque,
|
||||||
|
) callconv(.C) void {
|
||||||
|
const self = userdataSelf(ud.?);
|
||||||
|
self.precision_scroll = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gtkMouseScrollPrecisionEnd(
|
||||||
|
_: *c.GtkEventControllerScroll,
|
||||||
|
ud: ?*anyopaque,
|
||||||
|
) callconv(.C) void {
|
||||||
|
const self = userdataSelf(ud.?);
|
||||||
|
self.precision_scroll = false;
|
||||||
|
}
|
||||||
|
|
||||||
fn gtkMouseScroll(
|
fn gtkMouseScroll(
|
||||||
_: *c.GtkEventControllerScroll,
|
_: *c.GtkEventControllerScroll,
|
||||||
x: c.gdouble,
|
x: c.gdouble,
|
||||||
@ -1533,15 +1551,17 @@ fn gtkMouseScroll(
|
|||||||
const scaled = self.scaledCoordinates(x, y);
|
const scaled = self.scaledCoordinates(x, y);
|
||||||
|
|
||||||
// GTK doesn't support any of the scroll mods.
|
// GTK doesn't support any of the scroll mods.
|
||||||
const scroll_mods: input.ScrollMods = .{};
|
const scroll_mods: input.ScrollMods = .{ .precision = self.precision_scroll };
|
||||||
|
// Multiply precision scrolls by 10 to get a better response from touchpad scrolling
|
||||||
|
const multiplier: f64 = if (self.precision_scroll) 10 else 1;
|
||||||
|
|
||||||
self.core_surface.scrollCallback(
|
self.core_surface.scrollCallback(
|
||||||
// We invert because we apply natural scrolling to the values.
|
// We invert because we apply natural scrolling to the values.
|
||||||
// This behavior has existed for years without Linux users complaining
|
// This behavior has existed for years without Linux users complaining
|
||||||
// but I suspect we'll have to make this configurable in the future
|
// but I suspect we'll have to make this configurable in the future
|
||||||
// or read a system setting.
|
// or read a system setting.
|
||||||
scaled.x * -1,
|
scaled.x * -1 * multiplier,
|
||||||
scaled.y * -1,
|
scaled.y * -1 * multiplier,
|
||||||
scroll_mods,
|
scroll_mods,
|
||||||
) catch |err| {
|
) catch |err| {
|
||||||
log.err("error in scroll callback err={}", .{err});
|
log.err("error in scroll callback err={}", .{err});
|
||||||
|
Reference in New Issue
Block a user