mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-10-21 20:52:19 +00:00
Make Wayland momentum scrolling configurable
This commit is contained in:
parent
1f43a75a07
commit
2ab0fcb373
11 changed files with 44 additions and 8 deletions
|
|
@ -155,7 +155,7 @@ Detailed list of changes
|
|||
|
||||
- Pixel scrolling for the kitty scrollback buffer controlled via :opt:`pixel_scroll` (:pull:`9330`)
|
||||
|
||||
- Wayland: Add momentum scrolling in the kitty scrollback buffer for touchpads and touchscreens
|
||||
- Wayland: momentum scrolling in the kitty scrollback buffer for touchpads and touchscreens, see :opt:`momentum_scroll`
|
||||
|
||||
- choose-files kitten: Fix JXL image preview not working (:iss:`9323`)
|
||||
|
||||
|
|
|
|||
|
|
@ -327,6 +327,7 @@ def generate_wrappers(glfw_header: str) -> None:
|
|||
bool glfwWaylandIsWindowFullyCreated(GLFWwindow *handle)
|
||||
bool glfwWaylandBeep(GLFWwindow *handle)
|
||||
pid_t glfwWaylandCompositorPID(void)
|
||||
void glfwConfigureMomentumScroller(double friction, double min_velocity, double max_velocity, unsigned timer_interval)
|
||||
unsigned long long glfwDBusUserNotify(const GLFWDBUSNotificationData *n, GLFWDBusnotificationcreatedfun callback, void *data)
|
||||
void glfwDBusSetUserNotificationHandler(GLFWDBusnotificationactivatedfun handler)
|
||||
int glfwSetX11LaunchCommand(GLFWwindow *handle, char **argv, int argc)
|
||||
|
|
|
|||
12
glfw/momentum-scroll.c
vendored
12
glfw/momentum-scroll.c
vendored
|
|
@ -42,16 +42,15 @@ static const MomentumScroller defaults = {
|
|||
.friction = 0.04,
|
||||
.min_velocity = 0.5,
|
||||
.max_velocity = 100,
|
||||
.velocity_scale = 0.9,
|
||||
.timer_interval = 10,
|
||||
};
|
||||
static MomentumScroller s = defaults;
|
||||
|
||||
GLFWAPI void
|
||||
glfwConfigureMomentumScroller(double friction, double min_velocity, double max_velocity, double velocity_scale, unsigned timer_interval_ms) {
|
||||
s.timer_interval = ms_to_monotonic_t(timer_interval_ms);
|
||||
glfwConfigureMomentumScroller(double friction, double min_velocity, double max_velocity, unsigned timer_interval_ms) {
|
||||
s.timer_interval = timer_interval_ms ? ms_to_monotonic_t(timer_interval_ms) : defaults.timer_interval;
|
||||
#define S(w) s.w = w >= 0 ? w : defaults.w
|
||||
S(friction); S(min_velocity); S(max_velocity); S(velocity_scale);
|
||||
S(friction); S(min_velocity); S(max_velocity);
|
||||
#undef S
|
||||
}
|
||||
|
||||
|
|
@ -94,7 +93,6 @@ trim_old_samples(monotonic_t now) {
|
|||
|
||||
static void
|
||||
add_velocity(double x, double y) {
|
||||
x *= s.velocity_scale; y *= s.velocity_scale;
|
||||
if (x == 0 || x * s.velocity.x >= 0) s.velocity.x += x;
|
||||
else s.velocity.x = x;
|
||||
if (y == 0 || y * s.velocity.y >= 0) s.velocity.y += y;
|
||||
|
|
@ -185,7 +183,7 @@ glfw_handle_scroll_event_for_momentum(
|
|||
_GLFWwindow *w, const GLFWScrollEvent *ev, bool stopped, bool is_finger_based
|
||||
) {
|
||||
if (!w) { cancel_existing_scroll(true); return; }
|
||||
if (!is_finger_based || ev->offset_type != GLFW_SCROLL_OFFEST_HIGHRES || s.friction <= 0) {
|
||||
if (!is_finger_based || ev->offset_type != GLFW_SCROLL_OFFEST_HIGHRES || s.friction < 0 || s.friction >= 1) {
|
||||
_glfwInputScroll(w, ev);
|
||||
return;
|
||||
}
|
||||
|
|
@ -210,7 +208,7 @@ glfw_handle_scroll_event_for_momentum(
|
|||
if (ldx * ev->x_offset < 0 || ldy * ev->y_offset < 0) cancel_existing_scroll(true);
|
||||
s.window_id = w->id;
|
||||
s.keyboard_modifiers = ev->keyboard_modifiers;
|
||||
if (ev->offset_type == GLFW_SCROLL_OFFEST_HIGHRES && s.friction > 0) {
|
||||
if (ev->offset_type == GLFW_SCROLL_OFFEST_HIGHRES) {
|
||||
add_sample(ev->unscaled.x, ev->unscaled.y, now);
|
||||
if (stopped) s.state = is_suitable_for_momentum() ? MOMENTUM_IN_PROGRESS : NONE;
|
||||
else s.state = PHYSICAL_EVENT_IN_PROGRESS;
|
||||
|
|
|
|||
3
kitty/glfw-wrapper.c
generated
3
kitty/glfw-wrapper.c
generated
|
|
@ -512,6 +512,9 @@ load_glfw(const char* path) {
|
|||
*(void **) (&glfwWaylandCompositorPID_impl) = dlsym(handle, "glfwWaylandCompositorPID");
|
||||
if (glfwWaylandCompositorPID_impl == NULL) dlerror(); // clear error indicator
|
||||
|
||||
*(void **) (&glfwConfigureMomentumScroller_impl) = dlsym(handle, "glfwConfigureMomentumScroller");
|
||||
if (glfwConfigureMomentumScroller_impl == NULL) dlerror(); // clear error indicator
|
||||
|
||||
*(void **) (&glfwDBusUserNotify_impl) = dlsym(handle, "glfwDBusUserNotify");
|
||||
if (glfwDBusUserNotify_impl == NULL) dlerror(); // clear error indicator
|
||||
|
||||
|
|
|
|||
4
kitty/glfw-wrapper.h
generated
4
kitty/glfw-wrapper.h
generated
|
|
@ -2406,6 +2406,10 @@ typedef pid_t (*glfwWaylandCompositorPID_func)(void);
|
|||
GFW_EXTERN glfwWaylandCompositorPID_func glfwWaylandCompositorPID_impl;
|
||||
#define glfwWaylandCompositorPID glfwWaylandCompositorPID_impl
|
||||
|
||||
typedef void (*glfwConfigureMomentumScroller_func)(double, double, double, unsigned);
|
||||
GFW_EXTERN glfwConfigureMomentumScroller_func glfwConfigureMomentumScroller_impl;
|
||||
#define glfwConfigureMomentumScroller glfwConfigureMomentumScroller_impl
|
||||
|
||||
typedef unsigned long long (*glfwDBusUserNotify_func)(const GLFWDBUSNotificationData*, GLFWDBusnotificationcreatedfun, void*);
|
||||
GFW_EXTERN glfwDBusUserNotify_func glfwDBusUserNotify_impl;
|
||||
#define glfwDBusUserNotify glfwDBusUserNotify_impl
|
||||
|
|
|
|||
|
|
@ -1354,6 +1354,7 @@ create_os_window(PyObject UNUSED *self, PyObject *args, PyObject *kw) {
|
|||
|
||||
static bool is_first_window = true;
|
||||
if (is_first_window) {
|
||||
if (global_state.is_wayland) glfwConfigureMomentumScroller(OPT(momentum_scroll), -1, -1, 0);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, OPENGL_REQUIRED_VERSION_MAJOR);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, OPENGL_REQUIRED_VERSION_MINOR);
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, true);
|
||||
|
|
|
|||
|
|
@ -597,6 +597,14 @@ running inside the terminal (for example full-screen TUIs) that handle scrolling
|
|||
themselves.
|
||||
''')
|
||||
|
||||
opt('momentum_scroll', '0.04', option_type='unit_float', ctype='float', long_text='''
|
||||
The amount of friction to apply to slow down momentum (inertial) scrolling. A number
|
||||
from 0 to 1, with 1 meaning no momentum scrolling. Note that this setting only
|
||||
applies on platforms such as Wayland, that do not provide native momentum scrolling.
|
||||
On macOS, the native OS based momentum scrolling is used. Also, momentum scrolling
|
||||
only applies to "finger" based devices such as touchpads and touchscreens. Changes
|
||||
to this setting only take effect after a kitty restart.
|
||||
''')
|
||||
egr() # }}}
|
||||
|
||||
|
||||
|
|
|
|||
3
kitty/options/parse.py
generated
3
kitty/options/parse.py
generated
|
|
@ -1143,6 +1143,9 @@ class Parser:
|
|||
for k, v in modify_font(val):
|
||||
ans["modify_font"][k] = v
|
||||
|
||||
def momentum_scroll(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
ans['momentum_scroll'] = unit_float(val)
|
||||
|
||||
def mouse_hide_wait(self, val: str, ans: dict[str, typing.Any]) -> None:
|
||||
ans['mouse_hide_wait'] = mouse_hide_wait(val)
|
||||
|
||||
|
|
|
|||
15
kitty/options/to-c-generated.h
generated
15
kitty/options/to-c-generated.h
generated
|
|
@ -512,6 +512,19 @@ convert_from_opts_pixel_scroll(PyObject *py_opts, Options *opts) {
|
|||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_python_momentum_scroll(PyObject *val, Options *opts) {
|
||||
opts->momentum_scroll = PyFloat_AsFloat(val);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_opts_momentum_scroll(PyObject *py_opts, Options *opts) {
|
||||
PyObject *ret = PyObject_GetAttrString(py_opts, "momentum_scroll");
|
||||
if (ret == NULL) return;
|
||||
convert_from_python_momentum_scroll(ret, opts);
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_from_python_mouse_hide_wait(PyObject *val, Options *opts) {
|
||||
mouse_hide_wait(val, opts);
|
||||
|
|
@ -1437,6 +1450,8 @@ convert_opts_from_python_opts(PyObject *py_opts, Options *opts) {
|
|||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_pixel_scroll(py_opts, opts);
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_momentum_scroll(py_opts, opts);
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_mouse_hide_wait(py_opts, opts);
|
||||
if (PyErr_Occurred()) return false;
|
||||
convert_from_opts_url_color(py_opts, opts);
|
||||
|
|
|
|||
2
kitty/options/types.py
generated
2
kitty/options/types.py
generated
|
|
@ -397,6 +397,7 @@ option_names = (
|
|||
'mark3_foreground',
|
||||
'menu_map',
|
||||
'modify_font',
|
||||
'momentum_scroll',
|
||||
'mouse_hide_wait',
|
||||
'mouse_map',
|
||||
'narrow_symbols',
|
||||
|
|
@ -589,6 +590,7 @@ class Options:
|
|||
mark2_foreground: Color = Color(0, 0, 0)
|
||||
mark3_background: Color = Color(242, 116, 188)
|
||||
mark3_foreground: Color = Color(0, 0, 0)
|
||||
momentum_scroll: float = 0.04
|
||||
mouse_hide_wait: MouseHideWait = MouseHideWait(hide_wait=0.0, show_wait=0.0, show_threshold=40, scroll_show=True) if is_macos else MouseHideWait(hide_wait=3.0, show_wait=0.0, show_threshold=40, scroll_show=True)
|
||||
notify_on_cmd_finish: NotifyOnCmdFinish = NotifyOnCmdFinish(when='never', duration=5.0, action='notify', cmdline=(), clear_on=('focus', 'next'))
|
||||
open_url_with: list[str] = ['default']
|
||||
|
|
|
|||
|
|
@ -139,6 +139,7 @@ typedef struct Options {
|
|||
unsigned undercurl_style;
|
||||
struct { float thickness; int unit; } underline_exclusion;
|
||||
float box_drawing_scale[4];
|
||||
double momentum_scroll;
|
||||
} Options;
|
||||
|
||||
typedef struct WindowLogoRenderData {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue