diff --git a/completions/bash/riverctl b/completions/bash/riverctl index f6abf88..68684d5 100644 --- a/completions/bash/riverctl +++ b/completions/bash/riverctl @@ -93,6 +93,7 @@ function __riverctl_completion () disable-while-trackpointing \ middle-emulation \ natural-scroll \ + scroll-factor \ left-handed \ tap \ tap-button-map \ diff --git a/completions/fish/riverctl.fish b/completions/fish/riverctl.fish index 5d8d804..65fad0a 100644 --- a/completions/fish/riverctl.fish +++ b/completions/fish/riverctl.fish @@ -113,6 +113,7 @@ complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_ complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 3' -a 'disable-while-trackpointing' -d 'Enable or disable the disable-while-trackpointing functionality' complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 3' -a 'middle-emulation' -d 'Enable or disable the middle-emulation functionality' complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 3' -a 'natural-scroll' -d 'Enable or disable the natural-scroll functionality' +complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 3' -a 'scroll-factor' -d 'Set the scroll factor' complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 3' -a 'left-handed' -d 'Enable or disable the left handed mode' complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 3' -a 'tap' -d 'Enable or disable the tap functionality' complete -c riverctl -n '__fish_seen_subcommand_from input; and __fish_riverctl_complete_arg 3' -a 'tap-button-map' -d 'Configure the button mapping for tapping' diff --git a/completions/zsh/_riverctl b/completions/zsh/_riverctl index f3a655e..ade30e5 100644 --- a/completions/zsh/_riverctl +++ b/completions/zsh/_riverctl @@ -120,6 +120,7 @@ _riverctl() 'disable-while-trackpointing:Enable or disable the disable-while-trackpointing functionality' 'middle-emulation:Enable or disable the middle click emulation functionality' 'natural-scroll:Enable or disable the natural scroll functionality' + 'scroll-factor:Set the scroll factor' 'left-handed:Enable or disable the left handed mode' 'tap:Enable or disable the tap functionality' 'tap-button-map:Configure the button mapping for tapping' diff --git a/doc/riverctl.1.scd b/doc/riverctl.1.scd index d0ac744..0fb809b 100644 --- a/doc/riverctl.1.scd +++ b/doc/riverctl.1.scd @@ -505,6 +505,9 @@ However note that not every input device supports every property. Enable or disable the natural scroll functionality of the input device. If active, the scroll direction is inverted. +*input* _name_ *scroll-factor* _factor_ + Set the scroll factor of the input device. Needs a non-negative float. + *input* _name_ *left-handed* *enabled*|*disabled* Enable or disable the left handed mode of the input device. diff --git a/river/Cursor.zig b/river/Cursor.zig index b214b95..54e17ae 100644 --- a/river/Cursor.zig +++ b/river/Cursor.zig @@ -304,6 +304,7 @@ fn clearFocus(cursor: *Cursor) void { /// Axis event is a scroll wheel or similiar fn handleAxis(listener: *wl.Listener(*wlr.Pointer.event.Axis), event: *wlr.Pointer.event.Axis) void { const cursor = @fieldParentPtr(Cursor, "axis", listener); + const device: *InputDevice = @ptrFromInt(event.device.data); cursor.seat.handleActivity(); cursor.unhide(); @@ -312,8 +313,8 @@ fn handleAxis(listener: *wl.Listener(*wlr.Pointer.event.Axis), event: *wlr.Point cursor.seat.wlr_seat.pointerNotifyAxis( event.time_msec, event.orientation, - event.delta, - event.delta_discrete, + event.delta * device.scroll_factor, + @intFromFloat(@as(f32, @floatFromInt(event.delta_discrete)) * device.scroll_factor), event.source, ); } diff --git a/river/InputConfig.zig b/river/InputConfig.zig index 220589a..4e01f21 100644 --- a/river/InputConfig.zig +++ b/river/InputConfig.zig @@ -252,6 +252,14 @@ pub const MapToOutput = struct { } }; +pub const ScrollFactor = struct { + value: ?f32, + + fn apply(scroll_factor: ScrollFactor, device: *InputDevice) void { + device.scroll_factor = scroll_factor.value orelse 1.0; + } +}; + glob: []const u8, // Note: Field names equal name of the setting in the 'input' command. @@ -264,6 +272,7 @@ drag: ?DragState = null, @"disable-while-trackpointing": ?DwtpState = null, @"middle-emulation": ?MiddleEmulation = null, @"natural-scroll": ?NaturalScroll = null, +@"scroll-factor": ScrollFactor = .{ .value = 1.0 }, @"left-handed": ?LeftHanded = null, tap: ?TapState = null, @"tap-button-map": ?TapButtonMap = null, @@ -288,6 +297,8 @@ pub fn apply(config: *const InputConfig, device: *InputDevice) void { if (comptime mem.eql(u8, field.name, "map-to-output")) { @field(config, field.name).apply(device); + } else if (comptime mem.eql(u8, field.name, "scroll-factor")) { + @field(config, field.name).apply(device); } else if (@field(config, field.name)) |setting| { log.debug("applying setting: {s}", .{field.name}); setting.apply(libinput_device); @@ -305,6 +316,10 @@ pub fn parse(config: *InputConfig, setting: []const u8, value: []const u8) !void config.@"pointer-accel" = PointerAccel{ .value = math.clamp(try std.fmt.parseFloat(f32, value), -1.0, 1.0), }; + } else if (comptime mem.eql(u8, field.name, "scroll-factor")) { + config.@"scroll-factor" = ScrollFactor{ + .value = @max(try std.fmt.parseFloat(f32, value), 0.0), + }; } else if (comptime mem.eql(u8, field.name, "scroll-button")) { const ret = c.libevdev_event_code_from_name(c.EV_KEY, value.ptr); if (ret < 1) return error.InvalidButton; @@ -346,6 +361,10 @@ pub fn write(config: *InputConfig, writer: anytype) !void { if (@field(config, field.name).output_name) |output_name| { try writer.print("\tmap-to-output: {s}\n", .{output_name}); } + } else if (comptime mem.eql(u8, field.name, "scroll-factor")) { + if (@field(config, field.name).value) |value| { + try writer.print("\tscroll-factor: {d}\n", .{value}); + } } else if (@field(config, field.name)) |setting| { // Special-case the settings which are not enums. if (comptime mem.eql(u8, field.name, "pointer-accel")) { diff --git a/river/InputDevice.zig b/river/InputDevice.zig index 9e89e74..90e7bc2 100644 --- a/river/InputDevice.zig +++ b/river/InputDevice.zig @@ -34,6 +34,7 @@ const Tablet = @import("Tablet.zig"); const log = std.log.scoped(.input_manager); +scroll_factor: f32, seat: *Seat, wlr_device: *wlr.InputDevice, @@ -73,6 +74,7 @@ pub fn init(device: *InputDevice, seat: *Seat, wlr_device: *wlr.InputDevice) !vo } device.* = .{ + .scroll_factor = 1.0, .seat = seat, .wlr_device = wlr_device, .identifier = identifier,