mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-04-06 07:38:21 +00:00
gtk: disable kinetic scrolling for trackpads until 4.20.1
Until gtk 4.20.1 trackpads have kinetic scrolling behavior regardless
of `Gtk.ScrolledWindow.kinetic_scrolling`. As a workaround, set
EventControllerScroll.kinetic to false on all controllers.
`observeControllers()` has this warning:
> Calling this function will enable extra internal bookkeeping to track controllers and emit signals on the returned listmodel. It may slow down operations a lot.
> Applications should try hard to avoid calling this function because of the slowdowns.
but judging from the [source](5301a91f1c/gtk/gtkwidget.c (L12375-L12383))
this is a one time penalty since we free the result immediately afterwards.
Fixes https://github.com/ghostty-org/ghostty/discussions/11460
This commit is contained in:
@@ -2,6 +2,7 @@ const std = @import("std");
|
||||
const adw = @import("adw");
|
||||
const gobject = @import("gobject");
|
||||
const gtk = @import("gtk");
|
||||
const gtk_version = @import("../gtk_version.zig");
|
||||
|
||||
const gresource = @import("../build/gresource.zig");
|
||||
const Common = @import("../class.zig").Common;
|
||||
@@ -59,11 +60,29 @@ pub const SurfaceScrolledWindow = extern struct {
|
||||
config: ?*Config = null,
|
||||
config_binding: ?*gobject.Binding = null,
|
||||
surface: ?*Surface = null,
|
||||
scrolled_window: *gtk.ScrolledWindow,
|
||||
pub var offset: c_int = 0;
|
||||
};
|
||||
|
||||
fn init(self: *Self, _: *Class) callconv(.c) void {
|
||||
gtk.Widget.initTemplate(self.as(gtk.Widget));
|
||||
if (gtk_version.runtimeUntil(4, 20, 1)) self.disableKineticScroll();
|
||||
}
|
||||
|
||||
fn disableKineticScroll(self: *Self) void {
|
||||
// Until gtk 4.20.1 trackpads have kinetic scrolling behavior regardless
|
||||
// of `Gtk.ScrolledWindow.kinetic_scrolling`. As a workaround, disable
|
||||
// EventControllerScroll.kinetic
|
||||
const controllers = self.private().scrolled_window.as(gtk.Widget).observeControllers();
|
||||
defer controllers.unref();
|
||||
var i: c_uint = 0;
|
||||
while (controllers.getObject(i)) |obj| : (i += 1) {
|
||||
defer obj.unref();
|
||||
const controller = gobject.ext.cast(gtk.EventControllerScroll, obj) orelse continue;
|
||||
var flags = controller.getFlags();
|
||||
flags.kinetic = false;
|
||||
controller.setFlags(flags);
|
||||
}
|
||||
}
|
||||
|
||||
fn dispose(self: *Self) callconv(.c) void {
|
||||
@@ -189,6 +208,7 @@ pub const SurfaceScrolledWindow = extern struct {
|
||||
// Bindings
|
||||
class.bindTemplateCallback("scrollbar_policy", &closureScrollbarPolicy);
|
||||
class.bindTemplateCallback("notify_surface", &propSurface);
|
||||
class.bindTemplateChildPrivate("scrolled_window", .{});
|
||||
|
||||
// Properties
|
||||
gobject.ext.registerProperties(class, &.{
|
||||
|
||||
@@ -4,7 +4,7 @@ using Adw 1;
|
||||
template $GhostttySurfaceScrolledWindow: Adw.Bin {
|
||||
notify::surface => $notify_surface();
|
||||
|
||||
Gtk.ScrolledWindow {
|
||||
Gtk.ScrolledWindow scrolled_window {
|
||||
hscrollbar-policy: never;
|
||||
vscrollbar-policy: bind $scrollbar_policy(template.config) as <Gtk.PolicyType>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user