forked from AuroraMiddleware/gtk
Merge branch 'jx/hi-res-scrolling' into 'main'
High-resolution scroll wheel support See merge request GNOME/gtk!3839
This commit is contained in:
commit
bbd6fdaa04
@ -21,7 +21,7 @@ stages:
|
||||
|
||||
# Common variables
|
||||
variables:
|
||||
COMMON_MESON_FLAGS: "-Dwerror=true -Dglib:werror=false -Dpango:werror=false -Dgtk-doc:werror=false -Dwayland-protocols:werror=false -Dsysprof:werror=false"
|
||||
COMMON_MESON_FLAGS: "-Dwerror=true -Dglib:werror=false -Dpango:werror=false -Dgtk-doc:werror=false -Dwayland-protocols:werror=false -Dsysprof:werror=false -Dwayland:werror=false"
|
||||
BACKEND_FLAGS: "-Dx11-backend=true -Dwayland-backend=true -Dbroadway-backend=true"
|
||||
FEATURE_FLAGS: "-Dvulkan=enabled -Dcloudproviders=enabled"
|
||||
MESON_TEST_TIMEOUT_MULTIPLIER: 3
|
||||
|
@ -2368,10 +2368,75 @@ gdk_scroll_event_new_discrete (GdkSurface *surface,
|
||||
GdkScrollDirection direction)
|
||||
{
|
||||
GdkScrollEvent *self = gdk_event_alloc (GDK_SCROLL, surface, device, time);
|
||||
double delta_x = 0, delta_y = 0;
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
case GDK_SCROLL_UP:
|
||||
delta_y = -1;
|
||||
break;
|
||||
case GDK_SCROLL_DOWN:
|
||||
delta_y = 1;
|
||||
break;
|
||||
case GDK_SCROLL_LEFT:
|
||||
delta_x = -1;
|
||||
break;
|
||||
case GDK_SCROLL_RIGHT:
|
||||
delta_x = 1;
|
||||
break;
|
||||
case GDK_SCROLL_SMOOTH:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
self->tool = tool != NULL ? g_object_ref (tool) : NULL;
|
||||
self->state = state;
|
||||
self->direction = direction;
|
||||
self->delta_x = delta_x;
|
||||
self->delta_y = delta_y;
|
||||
self->unit = GDK_SCROLL_UNIT_WHEEL;
|
||||
|
||||
return (GdkEvent *) self;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gtk_scroll_event_new_value120:
|
||||
* @surface: the `GdkSurface` of the event
|
||||
* @device: the `GdkDevice` of the event
|
||||
* @tool: (nullable): the tool that generated to event
|
||||
* @time: the event serial
|
||||
* @state: Flags to indicate the state of modifier keys and mouse buttons
|
||||
* in events.
|
||||
* @direction: scroll direction.
|
||||
* @delta_x: delta on the X axis in the 120.0 scale
|
||||
* @delta_x: delta on the Y axis in the 120.0 scale
|
||||
*
|
||||
* Creates a new discrete GdkScrollEvent for high resolution mouse wheels.
|
||||
*
|
||||
* Both axes send data in fractions of 120 where each multiple of 120
|
||||
* amounts to one logical scroll event. Fractions of 120 indicate a wheel
|
||||
* movement less than one detent.
|
||||
*
|
||||
* Returns: the newly created scroll event
|
||||
*/
|
||||
GdkEvent *
|
||||
gdk_scroll_event_new_value120 (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
GdkDeviceTool *tool,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkScrollDirection direction,
|
||||
double delta_x,
|
||||
double delta_y)
|
||||
{
|
||||
GdkScrollEvent *self = gdk_event_alloc (GDK_SCROLL, surface, device, time);
|
||||
|
||||
self->tool = tool != NULL ? g_object_ref (tool) : NULL;
|
||||
self->state = state;
|
||||
self->direction = direction;
|
||||
self->delta_x = delta_x / 120.0;
|
||||
self->delta_y = delta_y / 120.0;
|
||||
self->unit = GDK_SCROLL_UNIT_WHEEL;
|
||||
|
||||
return (GdkEvent *) self;
|
||||
|
@ -495,6 +495,15 @@ GdkEvent * gdk_scroll_event_new_discrete (GdkSurface *surface,
|
||||
GdkModifierType state,
|
||||
GdkScrollDirection direction);
|
||||
|
||||
GdkEvent * gdk_scroll_event_new_value120 (GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
GdkDeviceTool *tool,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GdkScrollDirection direction,
|
||||
double delta_x,
|
||||
double delta_y);
|
||||
|
||||
GdkEvent * gdk_touch_event_new (GdkEventType type,
|
||||
GdkEventSequence *sequence,
|
||||
GdkSurface *surface,
|
||||
|
@ -112,7 +112,7 @@ struct _GdkWaylandPointerFrameData
|
||||
|
||||
/* Specific to the scroll event */
|
||||
double delta_x, delta_y;
|
||||
int32_t discrete_x, discrete_y;
|
||||
int32_t value120_x, value120_y;
|
||||
gint8 is_scroll_stop;
|
||||
enum wl_pointer_axis_source source;
|
||||
};
|
||||
@ -1383,20 +1383,54 @@ static GdkDevice * get_scroll_device (GdkWaylandSeat *seat,
|
||||
|
||||
static void
|
||||
flush_discrete_scroll_event (GdkWaylandSeat *seat,
|
||||
GdkScrollDirection direction)
|
||||
gint value120_x,
|
||||
gint value120_y)
|
||||
{
|
||||
GdkEvent *event;
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (seat->display);
|
||||
GdkEvent *event = NULL;
|
||||
GdkDevice *source;
|
||||
GdkScrollDirection direction;
|
||||
|
||||
if (value120_x > 0)
|
||||
direction = GDK_SCROLL_LEFT;
|
||||
else if (value120_x < 0)
|
||||
direction = GDK_SCROLL_RIGHT;
|
||||
else if (value120_y > 0)
|
||||
direction = GDK_SCROLL_DOWN;
|
||||
else
|
||||
direction = GDK_SCROLL_UP;
|
||||
|
||||
source = get_scroll_device (seat, seat->pointer_info.frame.source);
|
||||
event = gdk_scroll_event_new_discrete (seat->pointer_info.focus,
|
||||
source,
|
||||
NULL,
|
||||
seat->pointer_info.time,
|
||||
device_get_modifiers (seat->logical_pointer),
|
||||
direction);
|
||||
|
||||
_gdk_wayland_display_deliver_event (seat->display, event);
|
||||
if (display_wayland->seat_version >= WL_POINTER_AXIS_VALUE120_SINCE_VERSION)
|
||||
{
|
||||
event = gdk_scroll_event_new_value120 (seat->pointer_info.focus,
|
||||
source,
|
||||
NULL,
|
||||
seat->pointer_info.time,
|
||||
device_get_modifiers (seat->logical_pointer),
|
||||
direction,
|
||||
value120_x,
|
||||
value120_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
gint discrete_x = value120_x / 120;
|
||||
gint discrete_y = value120_y / 120;
|
||||
|
||||
if (discrete_x != 0 || discrete_y != 0)
|
||||
{
|
||||
event = gdk_scroll_event_new_discrete (seat->pointer_info.focus,
|
||||
source,
|
||||
NULL,
|
||||
seat->pointer_info.time,
|
||||
device_get_modifiers (seat->logical_pointer),
|
||||
direction);
|
||||
}
|
||||
}
|
||||
|
||||
if (event)
|
||||
_gdk_wayland_display_deliver_event (seat->display, event);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1427,22 +1461,13 @@ flush_scroll_event (GdkWaylandSeat *seat,
|
||||
{
|
||||
gboolean is_stop = FALSE;
|
||||
|
||||
if (pointer_frame->discrete_x || pointer_frame->discrete_y)
|
||||
if (pointer_frame->value120_x || pointer_frame->value120_y)
|
||||
{
|
||||
GdkScrollDirection direction;
|
||||
|
||||
if (pointer_frame->discrete_x > 0)
|
||||
direction = GDK_SCROLL_LEFT;
|
||||
else if (pointer_frame->discrete_x < 0)
|
||||
direction = GDK_SCROLL_RIGHT;
|
||||
else if (pointer_frame->discrete_y > 0)
|
||||
direction = GDK_SCROLL_DOWN;
|
||||
else
|
||||
direction = GDK_SCROLL_UP;
|
||||
|
||||
flush_discrete_scroll_event (seat, direction);
|
||||
pointer_frame->discrete_x = 0;
|
||||
pointer_frame->discrete_y = 0;
|
||||
flush_discrete_scroll_event (seat,
|
||||
pointer_frame->value120_x,
|
||||
pointer_frame->value120_y);
|
||||
pointer_frame->value120_x = 0;
|
||||
pointer_frame->value120_y = 0;
|
||||
}
|
||||
else if (pointer_frame->is_scroll_stop ||
|
||||
pointer_frame->delta_x != 0 ||
|
||||
@ -1462,8 +1487,8 @@ flush_scroll_event (GdkWaylandSeat *seat,
|
||||
is_stop);
|
||||
}
|
||||
|
||||
pointer_frame->discrete_x = 0;
|
||||
pointer_frame->discrete_y = 0;
|
||||
pointer_frame->value120_x = 0;
|
||||
pointer_frame->value120_y = 0;
|
||||
pointer_frame->delta_x = 0;
|
||||
pointer_frame->delta_y = 0;
|
||||
pointer_frame->is_scroll_stop = FALSE;
|
||||
@ -1862,10 +1887,10 @@ pointer_handle_axis_discrete (void *data,
|
||||
switch (axis)
|
||||
{
|
||||
case WL_POINTER_AXIS_VERTICAL_SCROLL:
|
||||
pointer_frame->discrete_y = value;
|
||||
pointer_frame->value120_y = value * 120;
|
||||
break;
|
||||
case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
|
||||
pointer_frame->discrete_x = value;
|
||||
pointer_frame->value120_x = value * 120;
|
||||
break;
|
||||
default:
|
||||
g_return_if_reached ();
|
||||
@ -1876,6 +1901,35 @@ pointer_handle_axis_discrete (void *data,
|
||||
get_axis_name (axis), value, seat));
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_handle_axis_value120 (void *data,
|
||||
struct wl_pointer *pointer,
|
||||
uint32_t axis,
|
||||
int32_t value)
|
||||
{
|
||||
GdkWaylandSeat *seat = data;
|
||||
GdkWaylandPointerFrameData *pointer_frame = &seat->pointer_info.frame;
|
||||
|
||||
if (!seat->pointer_info.focus)
|
||||
return;
|
||||
|
||||
switch (axis)
|
||||
{
|
||||
case WL_POINTER_AXIS_VERTICAL_SCROLL:
|
||||
pointer_frame->value120_y = value;
|
||||
break;
|
||||
case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
|
||||
pointer_frame->value120_x = value;
|
||||
break;
|
||||
default:
|
||||
g_return_if_reached ();
|
||||
}
|
||||
|
||||
GDK_SEAT_NOTE (seat, EVENTS,
|
||||
g_message ("value120 scroll, axis %s, value %d, seat %p",
|
||||
get_axis_name (axis), value, seat));
|
||||
}
|
||||
|
||||
static int
|
||||
get_active_layout (GdkKeymap *keymap)
|
||||
{
|
||||
@ -3070,6 +3124,7 @@ static const struct wl_pointer_listener pointer_listener = {
|
||||
pointer_handle_axis_source,
|
||||
pointer_handle_axis_stop,
|
||||
pointer_handle_axis_discrete,
|
||||
pointer_handle_axis_value120,
|
||||
};
|
||||
|
||||
static const struct wl_keyboard_listener keyboard_listener = {
|
||||
|
@ -232,7 +232,7 @@ _gdk_wayland_display_add_seat (GdkWaylandDisplay *display_wayland,
|
||||
{
|
||||
struct wl_seat *seat;
|
||||
|
||||
display_wayland->seat_version = MIN (version, 7);
|
||||
display_wayland->seat_version = MIN (version, 8);
|
||||
seat = wl_registry_bind (display_wayland->wl_registry,
|
||||
id, &wl_seat_interface,
|
||||
display_wayland->seat_version);
|
||||
|
@ -1729,6 +1729,7 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
&xev->valuators, &delta_x, &delta_y))
|
||||
{
|
||||
GdkModifierType state;
|
||||
GdkScrollDirection direction;
|
||||
|
||||
GDK_DISPLAY_NOTE (display, EVENTS,
|
||||
g_message ("smooth scroll: \n\tdevice: %u\n\tsource device: %u\n\twindow %ld\n\tdeltas: %f %f",
|
||||
@ -1737,21 +1738,19 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
|
||||
state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
|
||||
|
||||
if (delta_x > 0)
|
||||
direction = GDK_SCROLL_RIGHT;
|
||||
else if (delta_x < 0)
|
||||
direction = GDK_SCROLL_LEFT;
|
||||
else if (delta_y > 0)
|
||||
direction = GDK_SCROLL_DOWN;
|
||||
else
|
||||
direction = GDK_SCROLL_UP;
|
||||
|
||||
if (gdk_device_get_source (source_device) != GDK_SOURCE_TOUCHPAD &&
|
||||
((delta_x == 0.0 && ABS (delta_y) == 1.0) ||
|
||||
(ABS (delta_x) == 1.0 && delta_y == 0.0)))
|
||||
{
|
||||
GdkScrollDirection direction;
|
||||
|
||||
if (delta_x > 0)
|
||||
direction = GDK_SCROLL_RIGHT;
|
||||
else if (delta_x < 0)
|
||||
direction = GDK_SCROLL_LEFT;
|
||||
else if (delta_y > 0)
|
||||
direction = GDK_SCROLL_DOWN;
|
||||
else
|
||||
direction = GDK_SCROLL_UP;
|
||||
|
||||
event = gdk_scroll_event_new_discrete (surface,
|
||||
device,
|
||||
NULL,
|
||||
@ -1759,6 +1758,17 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
|
||||
state,
|
||||
direction);
|
||||
}
|
||||
else if (gdk_device_get_source (source_device) == GDK_SOURCE_MOUSE)
|
||||
{
|
||||
event = gdk_scroll_event_new_value120 (surface,
|
||||
device,
|
||||
NULL,
|
||||
xev->time,
|
||||
state,
|
||||
direction,
|
||||
delta_x * 120.0,
|
||||
delta_y * 120.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
event = gdk_scroll_event_new (surface,
|
||||
|
@ -85,6 +85,8 @@ struct _GtkEventControllerScroll
|
||||
/* For discrete event coalescing */
|
||||
double cur_dx;
|
||||
double cur_dy;
|
||||
double last_cur_dx;
|
||||
double last_cur_dy;
|
||||
|
||||
GdkScrollUnit cur_unit;
|
||||
|
||||
@ -337,6 +339,17 @@ gtk_event_controller_scroll_handle_hold_event (GtkEventController *controller,
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
should_reset_discrete_acc (double current_delta,
|
||||
double last_delta)
|
||||
{
|
||||
if (last_delta == 0)
|
||||
return TRUE;
|
||||
|
||||
return (current_delta < 0 && last_delta > 0) ||
|
||||
(current_delta > 0 && last_delta < 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_event_controller_scroll_handle_event (GtkEventController *controller,
|
||||
GdkEvent *event,
|
||||
@ -416,30 +429,51 @@ gtk_event_controller_scroll_handle_event (GtkEventController *controller,
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case GDK_SCROLL_UP:
|
||||
dy -= 1;
|
||||
break;
|
||||
case GDK_SCROLL_DOWN:
|
||||
dy += 1;
|
||||
break;
|
||||
case GDK_SCROLL_LEFT:
|
||||
dx -= 1;
|
||||
break;
|
||||
case GDK_SCROLL_RIGHT:
|
||||
dx += 1;
|
||||
break;
|
||||
case GDK_SCROLL_SMOOTH:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
gdk_scroll_event_get_deltas (event, &dx, &dy);
|
||||
|
||||
if ((scroll->flags & GTK_EVENT_CONTROLLER_SCROLL_VERTICAL) == 0)
|
||||
dy = 0;
|
||||
if ((scroll->flags & GTK_EVENT_CONTROLLER_SCROLL_HORIZONTAL) == 0)
|
||||
dx = 0;
|
||||
|
||||
if (scroll->flags & GTK_EVENT_CONTROLLER_SCROLL_DISCRETE)
|
||||
{
|
||||
int steps;
|
||||
|
||||
if (dx != 0)
|
||||
{
|
||||
if (should_reset_discrete_acc (dx, scroll->last_cur_dx))
|
||||
scroll->cur_dx = 0;
|
||||
|
||||
scroll->last_cur_dx = dx;
|
||||
}
|
||||
|
||||
if (dy != 0)
|
||||
{
|
||||
if (should_reset_discrete_acc (dy, scroll->last_cur_dy))
|
||||
scroll->cur_dy = 0;
|
||||
|
||||
scroll->last_cur_dy = dy;
|
||||
}
|
||||
|
||||
scroll->cur_dx += dx;
|
||||
scroll->cur_dy += dy;
|
||||
dx = dy = 0;
|
||||
|
||||
if (ABS (scroll->cur_dx) >= 1)
|
||||
{
|
||||
steps = trunc (scroll->cur_dx);
|
||||
scroll->cur_dx -= steps;
|
||||
dx = steps;
|
||||
}
|
||||
|
||||
if (ABS (scroll->cur_dy) >= 1)
|
||||
{
|
||||
steps = trunc (scroll->cur_dy);
|
||||
scroll->cur_dy -= steps;
|
||||
dy = steps;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scroll->cur_unit = scroll_unit;
|
||||
|
@ -18,7 +18,7 @@ cairo_req = '>= 1.14.0'
|
||||
gdk_pixbuf_req = '>= 2.30.0'
|
||||
introspection_req = '>= 1.39.0'
|
||||
wayland_proto_req = '>= 1.25'
|
||||
wayland_req = '>= 1.20.0'
|
||||
wayland_req = '>= 1.21.0'
|
||||
graphene_req = '>= 1.9.1'
|
||||
epoxy_req = '>= 1.4'
|
||||
cloudproviders_req = '>= 0.3.1'
|
||||
|
Loading…
Reference in New Issue
Block a user