Compare commits

...

16 Commits

Author SHA1 Message Date
Carlos Garnacho
3c53063e2f viewport: set GDK_SMOOTH_SCROLL_MASK
This is so smooth scroll events are send/handled by the
parent GtkScrolledWindow if any.
2012-02-18 18:07:45 +01:00
Carlos Garnacho
7e08f94c9a treeview: set GDK_SMOOTH_SCROLL_MASK
This is so smooth scroll events are send/handled by the
parent GtkScrolledWindow if any.
2012-02-18 18:07:45 +01:00
Carlos Garnacho
f549b02a09 textview: set GDK_SMOOTH_SCROLL_MASK
This is so smooth scroll events are send/handled by the
parent GtkScrolledWindow if any.
2012-02-18 18:07:44 +01:00
Carlos Garnacho
08111aea4c layout: set GDK_SMOOTH_SCROLL_MASK
This is so smooth scroll events are send/handled by the
parent GtkScrolledWindow if any.
2012-02-18 18:07:44 +01:00
Carlos Garnacho
975a3424e7 iconview: set GDK_SMOOTH_SCROLL_MASK
This is so smooth scroll events are send/handled by the
parent GtkScrolledWindow if any.
2012-02-18 18:07:44 +01:00
Michael Natterer
00eab88efc gtk: Implement smooth scrolling in scrolledwindow/range
If delta_x/y information is provided in scroll events, use it
to modify the underlying adjustment in steps proportional to
the deltas provided.

If the child widget of a scrolledwindow doesn't set
GDK_SMOOTH_SCROLL_MASK, regular scroll events will be dispatched,
and still handled by these 2 widgets.
2012-02-18 18:07:44 +01:00
Carlos Garnacho
dd498d825f devicemanager,xi2: Implement smooth scrolling
XInput >= 2.1 allows for implementing smooth scrolling,
reporting the different scrolling axes as valuators.
Any change in those will be reported as GdkEventScroll
events with delta_x/y information.

the older kind of scroll events is still handled, and
emulated in devices able to provide smooth scrolling,
setting _gdk_event_set_pointer_emulated() in that case.
2012-02-18 18:07:44 +01:00
Carlos Garnacho
88a1d2584a devicemanager,x11: Initialize event->scroll.delta_x/y to 0 on core events 2012-02-18 18:07:44 +01:00
Michael Natterer
acad37d372 quartz: Implement smooth scrolling
nsevent scrollingDeltaX/Y (available on OSX >= Lion) is used to
provide the smooth scrolling values. In any case, old fashioned
events are still sent, setting _gdk_event_set_pointer_emulated()
if the event contains both smooth and non-smooth values.
2012-02-18 18:07:44 +01:00
Carlos Garnacho
c5ae193124 gdk: update csw event mask filter to handle smooth scroll
Events of type GDK_SCROLL will be received if the client side window
event mask has either GDK_SCROLL_MASK or GDK_SMOOTH_SCROLL_MASK.

GDK_BUTTON_PRESS_MASK has been removed from type_masks[GDK_SCROLL]
as that bit is often set for other-than-scrolling purposes, and
yet have the window receive scroll events. In GTK+, this forces
non-smooth events bubbling, even if the widgets above want smooth
events, and legitimately set GDK_[SMOOTH_]SCROLL_MASK.
2012-02-18 18:07:44 +01:00
Carlos Garnacho
535e6c5c6e gdk: Filter out either smooth or non-smooth event depending on the evmask
If a device provides both smooth and non-smooth events, the latter will be
flagged with _gdk_event_set_pointer_emulated() so the client side window
receives one or the other. If a device is only able to deliver non-smooth
events, those will be sent, so both direction/deltas may need to be handled.
2012-02-18 18:07:44 +01:00
Carlos Garnacho
251f318ff8 gdk: Add GDK_SMOOTH_SCROLL_MASK
By setting this event, a GdkWindow will receive scroll events
that provide delta values.
2012-02-18 18:07:44 +01:00
Michael Natterer
811019f261 gdk: transfer event->scroll.delta_x/y through csw 2012-02-18 18:07:44 +01:00
Carlos Garnacho
aeaa762b7e gdk: deal with GDK_SMOOTH_SCROLL events as not having a direction
gdk_event_get_scroll_direction() will return FALSE on these, so
gdk_event_get_scroll_deltas() has to be used to retrieve dx/dy
2012-02-18 18:07:44 +01:00
Michael Natterer
992cfb285c gdk: Add delta_x/y to scroll events
gdk_event_get_scroll_deltas() can be used to retrieve those
values on smooth scroll events.
2012-02-18 18:07:44 +01:00
Carlos Garnacho
c7327d2bc5 gdk: Add GDK_SCROLL_SMOOTH to GdkScrollDirection
This value will be used for smooth scroll events, as they'll
express the scrolling direction in terms of dx/dy.
2012-02-18 18:07:44 +01:00
17 changed files with 462 additions and 53 deletions

View File

@@ -467,6 +467,8 @@ gdk_event_new (GdkEventType type)
new_event->scroll.y = 0.;
new_event->scroll.x_root = 0.;
new_event->scroll.y_root = 0.;
new_event->scroll.delta_x = 0.;
new_event->scroll.delta_y = 0.;
break;
case GDK_ENTER_NOTIFY:
case GDK_LEAVE_NOTIFY:
@@ -1206,7 +1208,10 @@ gdk_event_get_scroll_direction (const GdkEvent *event,
switch (event->type)
{
case GDK_SCROLL:
dir = event->scroll.direction;
if (event->scroll.direction == GDK_SCROLL_SMOOTH)
fetched = FALSE;
else
dir = event->scroll.direction;
break;
default:
fetched = FALSE;
@@ -1219,6 +1224,52 @@ gdk_event_get_scroll_direction (const GdkEvent *event,
return fetched;
}
/**
* gdk_event_get_scroll_deltas:
* @event: a #GdkEvent
* @delta_x: return location for X delta
* @delta_y: return location for Y delta
*
* Retrieves the scroll deltas from a #GdkEvent
*
* Returns: %TRUE if the event contains smooth scroll information
*
* Since: 3.4
**/
gboolean
gdk_event_get_scroll_deltas (const GdkEvent *event,
gdouble *delta_x,
gdouble *delta_y)
{
gboolean fetched = TRUE;
gdouble dx = 0.0;
gdouble dy = 0.0;
switch (event->type)
{
case GDK_SCROLL:
if (event->scroll.direction == GDK_SCROLL_SMOOTH)
{
dx = event->scroll.delta_x;
dy = event->scroll.delta_y;
}
else
fetched = FALSE;
break;
default:
fetched = FALSE;
break;
}
if (delta_x)
*delta_x = dx;
if (delta_y)
*delta_y = dy;
return fetched;
}
/**
* gdk_event_get_axis:
* @event: a #GdkEvent

View File

@@ -354,6 +354,8 @@ typedef enum
* @GDK_SCROLL_DOWN: the window is scrolled down.
* @GDK_SCROLL_LEFT: the window is scrolled to the left.
* @GDK_SCROLL_RIGHT: the window is scrolled to the right.
* @GDK_SCROLL_SMOOTH: the scrolling is determined by the delta values
* in #GdkEventScroll. See gdk_event_get_scroll_deltas().
*
* Specifies the direction for #GdkEventScroll.
*/
@@ -362,7 +364,8 @@ typedef enum
GDK_SCROLL_UP,
GDK_SCROLL_DOWN,
GDK_SCROLL_LEFT,
GDK_SCROLL_RIGHT
GDK_SCROLL_RIGHT,
GDK_SCROLL_SMOOTH
} GdkScrollDirection;
/**
@@ -776,6 +779,8 @@ struct _GdkEventScroll
GdkScrollDirection direction;
GdkDevice *device;
gdouble x_root, y_root;
gdouble delta_x;
gdouble delta_y;
};
/**
@@ -1215,6 +1220,10 @@ gboolean gdk_event_get_keycode (const GdkEvent *event,
guint16 *keycode);
gboolean gdk_event_get_scroll_direction (const GdkEvent *event,
GdkScrollDirection *direction);
gboolean gdk_event_get_scroll_deltas (const GdkEvent *event,
gdouble *delta_x,
gdouble *delta_y);
gboolean gdk_event_get_axis (const GdkEvent *event,
GdkAxisUse axis_use,
gdouble *value);

View File

@@ -351,6 +351,7 @@ typedef enum
* child windows
* @GDK_SCROLL_MASK: receive scroll events
* @GDK_TOUCH_MASK: receive (multi)touch events
* @GDK_SMOOTH_SCROLL_MASK: receive smooth scrolling events
* @GDK_ALL_EVENTS_MASK: the combination of all the above event masks.
*
* A set of bit-flags to indicate which events a window is to receive.
@@ -398,7 +399,8 @@ typedef enum
GDK_SUBSTRUCTURE_MASK = 1 << 20,
GDK_SCROLL_MASK = 1 << 21,
GDK_TOUCH_MASK = 1 << 22,
GDK_ALL_EVENTS_MASK = 0x3FFFFF
GDK_SMOOTH_SCROLL_MASK = 1 << 23,
GDK_ALL_EVENTS_MASK = 0x7FFFFF
} GdkEventMask;
/**

View File

@@ -8145,7 +8145,7 @@ static const guint type_masks[] = {
GDK_ALL_EVENTS_MASK, /* GDK_CLIENT_EVENT = 28 */
GDK_VISIBILITY_NOTIFY_MASK, /* GDK_VISIBILITY_NOTIFY = 29 */
GDK_EXPOSURE_MASK, /* GDK_NO_EXPOSE = 30 */
GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK,/* GDK_SCROLL= 31 */
GDK_SCROLL_MASK | GDK_SMOOTH_SCROLL_MASK,/* GDK_SCROLL= 31 */
0, /* GDK_WINDOW_STATE = 32 */
0, /* GDK_SETTING = 33 */
0, /* GDK_OWNER_CHANGE = 34 */
@@ -9888,6 +9888,13 @@ proxy_button_event (GdkEvent *source_event,
state, time_, source_event,
serial, FALSE);
}
else if (type == GDK_SCROLL &&
(((evmask & GDK_SMOOTH_SCROLL_MASK) == 0 &&
source_event->scroll.direction == GDK_SCROLL_SMOOTH) ||
((evmask & GDK_SMOOTH_SCROLL_MASK) != 0 &&
source_event->scroll.direction != GDK_SCROLL_SMOOTH &&
_gdk_event_get_pointer_emulated (source_event))))
return FALSE;
event = _gdk_make_event (event_win, type, source_event, FALSE);
@@ -9942,6 +9949,8 @@ proxy_button_event (GdkEvent *source_event,
event->scroll.y_root = source_event->scroll.y_root;
event->scroll.state = state;
event->scroll.device = source_event->scroll.device;
event->scroll.delta_x = source_event->scroll.delta_x;
event->scroll.delta_y = source_event->scroll.delta_y;
gdk_event_set_source_device (event, source_device);
break;

View File

@@ -870,6 +870,8 @@ fill_scroll_event (GdkWindow *window,
gint y,
gint x_root,
gint y_root,
gdouble delta_x,
gdouble delta_y,
GdkScrollDirection direction)
{
NSPoint point;
@@ -886,6 +888,8 @@ fill_scroll_event (GdkWindow *window,
event->scroll.state = get_keyboard_modifiers_from_ns_event (nsevent);
event->scroll.direction = direction;
event->scroll.device = _gdk_display->core_pointer;
event->scroll.delta_x = delta_x;
event->scroll.delta_y = delta_y;
}
static void
@@ -1320,28 +1324,64 @@ gdk_event_translate (GdkEvent *event,
case NSScrollWheel:
{
float dx = [nsevent deltaX];
float dy = [nsevent deltaY];
GdkScrollDirection direction;
GdkScrollDirection direction;
float dx;
float dy;
if (dy != 0)
if (gdk_quartz_osx_version() >= GDK_OSX_LION &&
[nsevent hasPreciseScrollingDeltas])
{
dx = [nsevent scrollingDeltaX];
dy = [nsevent scrollingDeltaY];
direction = GDK_SCROLL_SMOOTH;
fill_scroll_event (window, event, nsevent, x, y, x_root, y_root,
-dx, -dy, direction);
/* Fall through for scroll buttons emulation */
}
dx = [nsevent deltaX];
dy = [nsevent deltaY];
if (dy != 0.0)
{
if (dy < 0.0)
direction = GDK_SCROLL_DOWN;
else
direction = GDK_SCROLL_UP;
fill_scroll_event (window, event, nsevent, x, y, x_root, y_root, direction);
dy = fabs (dy);
dx = 0.0;
}
if (dx != 0)
else if (dx != 0.0)
{
if (dx < 0.0)
direction = GDK_SCROLL_RIGHT;
else
direction = GDK_SCROLL_LEFT;
fill_scroll_event (window, event, nsevent, x, y, x_root, y_root, direction);
dx = fabs (dx);
dy = 0.0;
}
if (dx != 0.0 || dy != 0.0)
{
if ([nsevent hasPreciseScrollingDeltas])
{
GdkEvent *emulated_event;
emulated_event = gdk_event_new (GDK_SCROLL);
_gdk_event_set_pointer_emulated (emulated_event, TRUE);
fill_scroll_event (window, emulated_event, nsevent,
x, y, x_root, y_root,
dx, dy, direction);
append_event (emulated_event, TRUE);
}
else
fill_scroll_event (window, event, nsevent,
x, y, x_root, y_root,
dx, dy, direction);
}
}
break;

View File

@@ -35,11 +35,21 @@
#endif
typedef struct _ScrollValuator ScrollValuator;
struct _ScrollValuator
{
guint n_valuator : 4;
guint direction : 4;
gdouble last_value;
};
struct _GdkX11DeviceXI2
{
GdkDevice parent_instance;
gint device_id;
GArray *scroll_valuators;
};
struct _GdkX11DeviceXI2Class
@@ -51,6 +61,7 @@ G_DEFINE_TYPE (GdkX11DeviceXI2, gdk_x11_device_xi2, GDK_TYPE_DEVICE)
#ifdef XINPUT_2
static void gdk_x11_device_xi2_finalize (GObject *object);
static void gdk_x11_device_xi2_get_property (GObject *object,
guint prop_id,
GValue *value,
@@ -112,6 +123,7 @@ gdk_x11_device_xi2_class_init (GdkX11DeviceXI2Class *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GdkDeviceClass *device_class = GDK_DEVICE_CLASS (klass);
object_class->finalize = gdk_x11_device_xi2_finalize;
object_class->get_property = gdk_x11_device_xi2_get_property;
object_class->set_property = gdk_x11_device_xi2_set_property;
@@ -136,6 +148,17 @@ gdk_x11_device_xi2_class_init (GdkX11DeviceXI2Class *klass)
static void
gdk_x11_device_xi2_init (GdkX11DeviceXI2 *device)
{
device->scroll_valuators = g_array_new (FALSE, FALSE, sizeof (ScrollValuator));
}
static void
gdk_x11_device_xi2_finalize (GObject *object)
{
GdkX11DeviceXI2 *device = GDK_X11_DEVICE_XI2 (object);
g_array_free (device->scroll_valuators, TRUE);
G_OBJECT_CLASS (gdk_x11_device_xi2_parent_class)->finalize (object);
}
static void
@@ -779,6 +802,82 @@ _gdk_x11_device_xi2_translate_state (XIModifierState *mods_state,
return state;
}
void
_gdk_x11_device_xi2_add_scroll_valuator (GdkX11DeviceXI2 *device,
guint n_valuator,
GdkScrollDirection direction,
gdouble current_value)
{
ScrollValuator scroll;
g_return_if_fail (GDK_IS_X11_DEVICE_XI2 (device));
g_return_if_fail (n_valuator < gdk_device_get_n_axes (GDK_DEVICE (device)));
scroll.n_valuator = n_valuator;
scroll.direction = direction;
scroll.last_value = current_value;
g_array_append_val (device->scroll_valuators, scroll);
}
gboolean
_gdk_x11_device_xi2_is_scroll_valuator (GdkX11DeviceXI2 *device,
guint n_valuator,
GdkScrollDirection *direction)
{
guint i;
g_return_val_if_fail (GDK_IS_X11_DEVICE_XI2 (device), FALSE);
g_return_val_if_fail (n_valuator < gdk_device_get_n_axes (GDK_DEVICE (device)), FALSE);
for (i = 0; i < device->scroll_valuators->len; i++)
{
ScrollValuator *scroll;
scroll = &g_array_index (device->scroll_valuators, ScrollValuator, i);
if (scroll->n_valuator == n_valuator)
{
if (*direction)
*direction = scroll->direction;
return TRUE;
}
}
return FALSE;
}
gdouble
_gdk_x11_device_xi2_get_scroll_delta (GdkX11DeviceXI2 *device,
guint n_valuator,
gdouble valuator_value)
{
guint i;
g_return_val_if_fail (GDK_IS_X11_DEVICE_XI2 (device), 0);
g_return_val_if_fail (n_valuator < gdk_device_get_n_axes (GDK_DEVICE (device)), 0);
for (i = 0; i < device->scroll_valuators->len; i++)
{
ScrollValuator *scroll;
scroll = &g_array_index (device->scroll_valuators, ScrollValuator, i);
if (scroll->n_valuator == n_valuator)
{
gdouble delta;
delta = valuator_value - scroll->last_value;
scroll->last_value = valuator_value;
return delta;
}
}
return 0;
}
gint
_gdk_x11_device_xi2_get_id (GdkX11DeviceXI2 *device)
{

View File

@@ -471,6 +471,9 @@ gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator,
event->scroll.state = (GdkModifierType) xevent->xbutton.state;
event->scroll.device = device_manager->core_pointer;
event->scroll.delta_x = 0;
event->scroll.delta_y = 0;
if (!set_screen_from_root (display, event, xevent->xbutton.root))
{
return_val = FALSE;

View File

@@ -243,6 +243,32 @@ translate_device_classes (GdkDisplay *display,
valuator_info->resolution);
}
break;
#ifdef XINPUT_2_2
case XIScrollClass:
{
XIScrollClassInfo *scroll_info = (XIScrollClassInfo *) class_info;
XIValuatorClassInfo *scroll_valuator_info = NULL;
GdkScrollDirection direction;
gint j;
for (j = 0; j < n_classes; j++)
{
if (classes[j]->type == XIValuatorClass &&
((XIValuatorClassInfo *) classes[j])->number == scroll_info->number)
scroll_valuator_info = (XIValuatorClassInfo *) classes[j];
}
if (scroll_info->scroll_type == XIScrollTypeVertical)
direction = GDK_SCROLL_DOWN;
else
direction = GDK_SCROLL_RIGHT;
_gdk_x11_device_xi2_add_scroll_valuator (GDK_X11_DEVICE_XI2 (device),
scroll_info->number,
direction,
scroll_valuator_info->value);
}
#endif /* XINPUT_2_2 */
default:
/* Ignore */
break;
@@ -1008,6 +1034,47 @@ gdk_x11_device_manager_xi2_translate_core_event (GdkEventTranslator *translator,
return TRUE;
}
static gboolean
scroll_valuators_changed (GdkX11DeviceXI2 *device,
XIValuatorState *valuators,
gdouble *dx,
gdouble *dy)
{
gdouble has_scroll_valuators = FALSE;
GdkScrollDirection direction;
guint n_axes, i, n_val;
gdouble *vals;
n_axes = gdk_device_get_n_axes (GDK_DEVICE (device));
vals = valuators->values;
*dx = *dy = 0;
n_val = 0;
for (i = 0; i < MIN (valuators->mask_len * 8, n_axes); i++)
{
if (!XIMaskIsSet (valuators->mask, i))
continue;
if (_gdk_x11_device_xi2_is_scroll_valuator (device, i, &direction))
{
gdouble delta;
has_scroll_valuators = TRUE;
delta = _gdk_x11_device_xi2_get_scroll_delta (device, i, vals[n_val]);
if (direction == GDK_SCROLL_UP ||
direction == GDK_SCROLL_DOWN)
*dy = delta;
else
*dx = delta;
}
n_val++;
}
return has_scroll_valuators;
}
static gboolean
gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
GdkDisplay *display,
@@ -1139,6 +1206,8 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
event->scroll.y = (gdouble) xev->event_y;
event->scroll.x_root = (gdouble) xev->root_x;
event->scroll.y_root = (gdouble) xev->root_y;
event->scroll.delta_x = 0;
event->scroll.delta_y = 0;
event->scroll.device = g_hash_table_lookup (device_manager->id_table,
GUINT_TO_POINTER (xev->deviceid));
@@ -1148,6 +1217,9 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
gdk_event_set_source_device (event, source_device);
event->scroll.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
if (xev->flags & XIPointerEmulated)
_gdk_event_set_pointer_emulated (event, TRUE);
}
else
{
@@ -1230,6 +1302,34 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
{
XIDeviceEvent *xev = (XIDeviceEvent *) ev;
GdkDevice *source_device;
gdouble delta_x, delta_y;
source_device = g_hash_table_lookup (device_manager->id_table,
GUINT_TO_POINTER (xev->sourceid));
if (scroll_valuators_changed (GDK_X11_DEVICE_XI2 (source_device),
&xev->valuators, &delta_x, &delta_y))
{
event->scroll.type = GDK_SCROLL;
event->scroll.direction = GDK_SCROLL_SMOOTH;
event->scroll.window = window;
event->scroll.time = xev->time;
event->scroll.x = (gdouble) xev->event_x;
event->scroll.y = (gdouble) xev->event_y;
event->scroll.x_root = (gdouble) xev->root_x;
event->scroll.y_root = (gdouble) xev->root_y;
event->scroll.delta_x = delta_x;
event->scroll.delta_y = delta_y;
event->scroll.device = g_hash_table_lookup (device_manager->id_table,
GUINT_TO_POINTER (xev->deviceid));
gdk_event_set_source_device (event, source_device);
event->scroll.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
break;
}
if (ev->evtype == XI_Motion)
{
@@ -1255,8 +1355,6 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
event->motion.device = g_hash_table_lookup (device_manager->id_table,
GINT_TO_POINTER (xev->deviceid));
source_device = g_hash_table_lookup (device_manager->id_table,
GUINT_TO_POINTER (xev->sourceid));
gdk_event_set_source_device (event, source_device);
event->motion.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);

View File

@@ -257,6 +257,16 @@ gint _gdk_x11_device_xi2_get_id (GdkX11DeviceXI2 *device);
GdkDevice * _gdk_x11_device_manager_xi2_lookup (GdkX11DeviceManagerXI2 *device_manager_xi2,
gint device_id);
void _gdk_x11_device_xi2_add_scroll_valuator (GdkX11DeviceXI2 *device,
guint n_valuator,
GdkScrollDirection direction,
gdouble current_value);
gboolean _gdk_x11_device_xi2_is_scroll_valuator (GdkX11DeviceXI2 *device,
guint n_valuator,
GdkScrollDirection *direction);
gdouble _gdk_x11_device_xi2_get_scroll_delta (GdkX11DeviceXI2 *device,
guint n_valuator,
gdouble valuator_value);
#endif

View File

@@ -1285,12 +1285,13 @@ gtk_icon_view_realize (GtkWidget *widget)
attributes.width = MAX (icon_view->priv->width, allocation.width);
attributes.height = MAX (icon_view->priv->height, allocation.height);
attributes.event_mask = (GDK_EXPOSURE_MASK |
GDK_SCROLL_MASK |
GDK_POINTER_MOTION_MASK |
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_KEY_PRESS_MASK |
GDK_KEY_RELEASE_MASK) |
GDK_SCROLL_MASK |
GDK_SMOOTH_SCROLL_MASK |
GDK_POINTER_MOTION_MASK |
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_KEY_PRESS_MASK |
GDK_KEY_RELEASE_MASK) |
gtk_widget_get_events (widget);
icon_view->priv->bin_window = gdk_window_new (window,

View File

@@ -894,7 +894,8 @@ gtk_layout_realize (GtkWidget *widget)
attributes.y = - gtk_adjustment_get_value (priv->vadjustment);
attributes.width = MAX (priv->width, allocation.width);
attributes.height = MAX (priv->height, allocation.height);
attributes.event_mask = GDK_EXPOSURE_MASK | GDK_SCROLL_MASK |
attributes.event_mask = GDK_EXPOSURE_MASK | GDK_SCROLL_MASK |
GDK_SMOOTH_SCROLL_MASK |
gtk_widget_get_events (widget);
priv->bin_window = gdk_window_new (window,

View File

@@ -1730,9 +1730,11 @@ gtk_range_realize (GtkWidget *widget)
attributes.wclass = GDK_INPUT_ONLY;
attributes.event_mask = gtk_widget_get_events (widget);
attributes.event_mask |= (GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_ENTER_NOTIFY_MASK |
GDK_LEAVE_NOTIFY_MASK |
GDK_BUTTON_RELEASE_MASK |
GDK_SCROLL_MASK |
GDK_SMOOTH_SCROLL_MASK |
GDK_ENTER_NOTIFY_MASK |
GDK_LEAVE_NOTIFY_MASK |
GDK_POINTER_MOTION_MASK |
GDK_POINTER_MOTION_HINT_MASK);
@@ -2786,7 +2788,7 @@ gtk_range_button_release (GtkWidget *widget,
/**
* _gtk_range_get_wheel_delta:
* @range: a #GtkRange
* @direction: A #GdkScrollDirection
* @event: A #GdkEventScroll
*
* Returns a good step value for the mouse wheel.
*
@@ -2795,28 +2797,58 @@ gtk_range_button_release (GtkWidget *widget,
* Since: 2.4
**/
gdouble
_gtk_range_get_wheel_delta (GtkRange *range,
GdkScrollDirection direction)
_gtk_range_get_wheel_delta (GtkRange *range,
GdkEventScroll *event)
{
GtkRangePrivate *priv = range->priv;
GtkAdjustment *adjustment = priv->adjustment;
gdouble dx, dy;
gdouble delta;
gdouble page_size;
if (GTK_IS_SCROLLBAR (range))
delta = pow (gtk_adjustment_get_page_size (adjustment), 2.0 / 3.0);
page_size = gtk_adjustment_get_page_size (adjustment);
if (gdk_event_get_scroll_deltas ((GdkEvent *) event, &dx, &dy))
{
GtkAllocation allocation;
gtk_widget_get_allocation (GTK_WIDGET (range), &allocation);
if (gtk_orientable_get_orientation (GTK_ORIENTABLE (range)) == GTK_ORIENTATION_HORIZONTAL)
{
if (GTK_IS_SCROLLBAR (range) && page_size > 0)
delta = dx * page_size / allocation.width;
else
delta = dx * (gtk_adjustment_get_upper (adjustment) -
gtk_adjustment_get_lower (adjustment)) / allocation.width;
}
else
{
if (GTK_IS_SCROLLBAR (range) && page_size > 0)
delta = dy * page_size / allocation.height;
else
delta = dy * (gtk_adjustment_get_upper (adjustment) -
gtk_adjustment_get_lower (adjustment)) / allocation.height;
}
}
else
delta = gtk_adjustment_get_step_increment (adjustment) * 2;
if (direction == GDK_SCROLL_UP ||
direction == GDK_SCROLL_LEFT)
delta = - delta;
{
if (GTK_IS_SCROLLBAR (range))
delta = pow (page_size, 2.0 / 3.0);
else
delta = gtk_adjustment_get_page_increment (adjustment) * 2;
if (event->direction == GDK_SCROLL_UP ||
event->direction == GDK_SCROLL_LEFT)
delta = - delta;
}
if (priv->inverted)
delta = - delta;
return delta;
}
static gboolean
gtk_range_scroll_event (GtkWidget *widget,
GdkEventScroll *event)
@@ -2829,7 +2861,7 @@ gtk_range_scroll_event (GtkWidget *widget,
gdouble delta;
gboolean handled;
delta = _gtk_range_get_wheel_delta (range, event->direction);
delta = _gtk_range_get_wheel_delta (range, event);
g_signal_emit (range, signals[CHANGE_VALUE], 0,
GTK_SCROLL_JUMP, gtk_adjustment_get_value (priv->adjustment) + delta,

View File

@@ -148,8 +148,8 @@ void gtk_range_set_round_digits (GtkRange *range
gint gtk_range_get_round_digits (GtkRange *range);
/* internal API */
gdouble _gtk_range_get_wheel_delta (GtkRange *range,
GdkScrollDirection direction);
gdouble _gtk_range_get_wheel_delta (GtkRange *range,
GdkEventScroll *event);
void _gtk_range_set_has_origin (GtkRange *range,
gboolean has_origin);
gboolean _gtk_range_get_has_origin (GtkRange *range);

View File

@@ -2165,7 +2165,9 @@ gtk_scrolled_window_scroll_event (GtkWidget *widget,
{
GtkScrolledWindowPrivate *priv;
GtkScrolledWindow *scrolled_window;
GtkWidget *range;
gboolean handled = FALSE;
gdouble delta_x;
gdouble delta_y;
g_return_val_if_fail (GTK_IS_SCROLLED_WINDOW (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
@@ -2173,23 +2175,72 @@ gtk_scrolled_window_scroll_event (GtkWidget *widget,
scrolled_window = GTK_SCROLLED_WINDOW (widget);
priv = scrolled_window->priv;
if (event->direction == GDK_SCROLL_UP || event->direction == GDK_SCROLL_DOWN)
range = priv->vscrollbar;
else
range = priv->hscrollbar;
if (range && gtk_widget_get_visible (range))
if (gdk_event_get_scroll_deltas ((GdkEvent *) event, &delta_x, &delta_y))
{
GtkAdjustment *adjustment = gtk_range_get_adjustment (GTK_RANGE (range));
gdouble delta;
if (delta_x != 0.0 && priv->hscrollbar &&
gtk_widget_get_visible (priv->hscrollbar))
{
GtkAdjustment *adj;
gdouble new_value;
delta = _gtk_range_get_wheel_delta (GTK_RANGE (range), event->direction);
gtk_adjustment_set_value (adjustment, gtk_adjustment_get_value (adjustment) + delta);
adj = gtk_range_get_adjustment (GTK_RANGE (priv->hscrollbar));
return TRUE;
new_value = CLAMP (gtk_adjustment_get_value (adj) + delta_x,
gtk_adjustment_get_lower (adj),
gtk_adjustment_get_upper (adj) -
gtk_adjustment_get_page_size (adj));
gtk_adjustment_set_value (adj, new_value);
handled = TRUE;
}
if (delta_y != 0.0 && priv->vscrollbar &&
gtk_widget_get_visible (priv->vscrollbar))
{
GtkAdjustment *adj;
gdouble new_value;
adj = gtk_range_get_adjustment (GTK_RANGE (priv->vscrollbar));
new_value = CLAMP (gtk_adjustment_get_value (adj) + delta_y,
gtk_adjustment_get_lower (adj),
gtk_adjustment_get_upper (adj) -
gtk_adjustment_get_page_size (adj));
gtk_adjustment_set_value (adj, new_value);
handled = TRUE;
}
}
else
{
GtkWidget *range;
if (event->direction == GDK_SCROLL_UP || event->direction == GDK_SCROLL_DOWN)
range = priv->vscrollbar;
else
range = priv->hscrollbar;
if (range && gtk_widget_get_visible (range))
{
GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (range));
gdouble delta, new_value;
delta = _gtk_range_get_wheel_delta (GTK_RANGE (range), event);
new_value = CLAMP (gtk_adjustment_get_value (adj) + delta,
gtk_adjustment_get_lower (adj),
gtk_adjustment_get_upper (adj) -
gtk_adjustment_get_page_size (adj));
gtk_adjustment_set_value (adj, new_value);
handled = TRUE;
}
}
return FALSE;
return handled;
}
static gboolean

View File

@@ -8482,6 +8482,7 @@ text_window_realize (GtkTextWindow *win,
attributes.height = win->allocation.height;
attributes.event_mask = (GDK_EXPOSURE_MASK |
GDK_SCROLL_MASK |
GDK_SMOOTH_SCROLL_MASK |
GDK_KEY_PRESS_MASK |
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |

View File

@@ -2239,6 +2239,7 @@ gtk_tree_view_realize (GtkWidget *widget)
attributes.height = allocation.height;
attributes.event_mask = (GDK_EXPOSURE_MASK |
GDK_SCROLL_MASK |
GDK_SMOOTH_SCROLL_MASK |
GDK_POINTER_MOTION_MASK |
GDK_ENTER_NOTIFY_MASK |
GDK_LEAVE_NOTIFY_MASK |

View File

@@ -684,7 +684,8 @@ gtk_viewport_realize (GtkWidget *widget)
event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
/* We select on button_press_mask so that button 4-5 scrolls are trapped.
*/
attributes.event_mask = event_mask | GDK_BUTTON_PRESS_MASK;
attributes.event_mask = event_mask |
GDK_BUTTON_PRESS_MASK | GDK_SCROLL_MASK | GDK_SMOOTH_SCROLL_MASK;
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;