mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-29 06:51:10 +00:00
Make crossing events handled the same way
This commit is contained in:
parent
23c67f8c67
commit
e3158a1bfb
@ -105,6 +105,7 @@ gtk_event_controller_filter_event_default (GtkEventController *self,
|
||||
}
|
||||
|
||||
target = GTK_WIDGET (gdk_event_get_related_target (event));
|
||||
|
||||
if (target)
|
||||
{
|
||||
native2 = GTK_WIDGET (gtk_widget_get_native (target));
|
||||
@ -320,8 +321,8 @@ gtk_event_controller_handle_event (GtkEventController *controller,
|
||||
* gtk_event_controller_handle_crossing:
|
||||
* @controller: a #GtkEventController
|
||||
* @crossing: a #GtkCrossingData
|
||||
* @x: event position in widget coordinates
|
||||
* @y: event position in widget coordinates
|
||||
* @x: translated event coordinates
|
||||
* @y: translated event coordinates
|
||||
*
|
||||
* Feeds a crossing event into @controller, so it can be interpreted
|
||||
* and the controller actions triggered.
|
||||
|
@ -64,8 +64,6 @@ struct _GtkCrossingData {
|
||||
GtkWidget *new_target;
|
||||
};
|
||||
|
||||
#define GTK_TYPE_CROSSING_DATA (gtk_crossing_data_get_type ())
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gtk_crossing_data_get_type (void) G_GNUC_CONST;
|
||||
|
||||
|
@ -475,13 +475,13 @@ gtk_event_controller_key_forward (GtkEventControllerKey *controller,
|
||||
gtk_widget_realize (widget);
|
||||
|
||||
if (gtk_widget_run_controllers (widget, controller->current_event, 0, 0,
|
||||
GTK_PHASE_CAPTURE))
|
||||
GTK_PHASE_CAPTURE))
|
||||
return TRUE;
|
||||
if (gtk_widget_run_controllers (widget, controller->current_event, 0, 0,
|
||||
GTK_PHASE_TARGET))
|
||||
GTK_PHASE_TARGET))
|
||||
return TRUE;
|
||||
if (gtk_widget_run_controllers (widget, controller->current_event, 0, 0,
|
||||
GTK_PHASE_BUBBLE))
|
||||
GTK_PHASE_BUBBLE))
|
||||
return TRUE;
|
||||
|
||||
if (gtk_bindings_activate_event (G_OBJECT (widget), (GdkEventKey *)controller->current_event))
|
||||
|
@ -42,6 +42,7 @@ struct _GtkEventControllerMotion
|
||||
GtkEventController parent_instance;
|
||||
|
||||
const GdkEvent *current_event;
|
||||
const GtkCrossingData *current_crossing;
|
||||
|
||||
guint is_pointer : 1;
|
||||
guint contains_pointer : 1;
|
||||
@ -53,9 +54,8 @@ struct _GtkEventControllerMotionClass
|
||||
};
|
||||
|
||||
enum {
|
||||
ENTER,
|
||||
LEAVE,
|
||||
MOTION,
|
||||
POINTER_CHANGE,
|
||||
N_SIGNALS
|
||||
};
|
||||
|
||||
@ -71,34 +71,39 @@ static guint signals[N_SIGNALS] = { 0 };
|
||||
|
||||
G_DEFINE_TYPE (GtkEventControllerMotion, gtk_event_controller_motion, GTK_TYPE_EVENT_CONTROLLER)
|
||||
|
||||
static void
|
||||
update_pointer_focus (GtkEventControllerMotion *motion,
|
||||
gboolean enter,
|
||||
GdkNotifyType detail)
|
||||
static gboolean
|
||||
gtk_event_controller_motion_handle_event (GtkEventController *controller,
|
||||
const GdkEvent *event,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
gboolean is_pointer;
|
||||
gboolean contains_pointer;
|
||||
GtkEventControllerClass *parent_class;
|
||||
GdkEventType type;
|
||||
|
||||
switch (detail)
|
||||
type = gdk_event_get_event_type (event);
|
||||
if (type == GDK_MOTION_NOTIFY)
|
||||
g_signal_emit (controller, signals[MOTION], 0, x, y);
|
||||
|
||||
parent_class = GTK_EVENT_CONTROLLER_CLASS (gtk_event_controller_motion_parent_class);
|
||||
|
||||
return parent_class->handle_event (controller, event, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
update_pointer_focus (GtkEventController *controller,
|
||||
const GtkCrossingData *crossing)
|
||||
{
|
||||
GtkEventControllerMotion *motion = GTK_EVENT_CONTROLLER_MOTION (controller);
|
||||
GtkWidget *widget = gtk_event_controller_get_widget (controller);
|
||||
gboolean is_pointer = FALSE;
|
||||
gboolean contains_pointer = FALSE;
|
||||
|
||||
if (crossing->direction == GTK_CROSSING_IN)
|
||||
{
|
||||
case GDK_NOTIFY_VIRTUAL:
|
||||
case GDK_NOTIFY_NONLINEAR_VIRTUAL:
|
||||
is_pointer = FALSE;
|
||||
contains_pointer = enter;
|
||||
break;
|
||||
case GDK_NOTIFY_ANCESTOR:
|
||||
case GDK_NOTIFY_NONLINEAR:
|
||||
is_pointer = enter;
|
||||
contains_pointer = enter;
|
||||
break;
|
||||
case GDK_NOTIFY_INFERIOR:
|
||||
is_pointer = enter;
|
||||
contains_pointer = TRUE;
|
||||
break;
|
||||
case GDK_NOTIFY_UNKNOWN:
|
||||
default:
|
||||
g_warning ("Unknown crossing detail");
|
||||
return;
|
||||
if (crossing->new_target == widget)
|
||||
is_pointer = TRUE;
|
||||
if (crossing->new_target != NULL)
|
||||
contains_pointer = TRUE;
|
||||
}
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (motion));
|
||||
@ -115,57 +120,28 @@ update_pointer_focus (GtkEventControllerMotion *motion,
|
||||
g_object_thaw_notify (G_OBJECT (motion));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_event_controller_motion_handle_event (GtkEventController *controller,
|
||||
const GdkEvent *event,
|
||||
double x,
|
||||
double y)
|
||||
static void
|
||||
gtk_event_controller_motion_handle_crossing (GtkEventController *controller,
|
||||
const GtkCrossingData *crossing,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
GtkEventControllerMotion *motion = GTK_EVENT_CONTROLLER_MOTION (controller);
|
||||
GtkEventControllerClass *parent_class;
|
||||
GdkEventType type;
|
||||
|
||||
type = gdk_event_get_event_type (event);
|
||||
if (type == GDK_ENTER_NOTIFY)
|
||||
{
|
||||
GdkCrossingMode mode;
|
||||
GdkNotifyType detail;
|
||||
if (crossing->type != GTK_CROSSING_POINTER)
|
||||
return;
|
||||
|
||||
gdk_event_get_crossing_mode (event, &mode);
|
||||
gdk_event_get_crossing_detail (event, &detail);
|
||||
motion->current_crossing = crossing;
|
||||
|
||||
update_pointer_focus (motion, TRUE, detail);
|
||||
update_pointer_focus (controller, crossing);
|
||||
|
||||
motion->current_event = event;
|
||||
g_signal_emit (controller, signals[POINTER_CHANGE], 0,
|
||||
crossing->direction,
|
||||
x,
|
||||
y,
|
||||
crossing->mode);
|
||||
|
||||
g_signal_emit (controller, signals[ENTER], 0, x, y, mode, detail);
|
||||
|
||||
motion->current_event = NULL;
|
||||
}
|
||||
else if (type == GDK_LEAVE_NOTIFY)
|
||||
{
|
||||
GdkCrossingMode mode;
|
||||
GdkNotifyType detail;
|
||||
|
||||
gdk_event_get_crossing_mode (event, &mode);
|
||||
gdk_event_get_crossing_detail (event, &detail);
|
||||
|
||||
update_pointer_focus (motion, FALSE, detail);
|
||||
|
||||
motion->current_event = event;
|
||||
|
||||
g_signal_emit (controller, signals[LEAVE], 0, mode, detail);
|
||||
|
||||
motion->current_event = NULL;
|
||||
}
|
||||
else if (type == GDK_MOTION_NOTIFY)
|
||||
{
|
||||
g_signal_emit (controller, signals[MOTION], 0, x, y);
|
||||
}
|
||||
|
||||
parent_class = GTK_EVENT_CONTROLLER_CLASS (gtk_event_controller_motion_parent_class);
|
||||
|
||||
return parent_class->handle_event (controller, event, x, y);
|
||||
motion->current_crossing = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -200,6 +176,7 @@ gtk_event_controller_motion_class_init (GtkEventControllerMotionClass *klass)
|
||||
object_class->get_property = gtk_event_controller_motion_get_property;
|
||||
|
||||
controller_class->handle_event = gtk_event_controller_motion_handle_event;
|
||||
controller_class->handle_crossing = gtk_event_controller_motion_handle_crossing;
|
||||
|
||||
/**
|
||||
* GtkEventControllerMotion:is-pointer:
|
||||
@ -239,52 +216,33 @@ gtk_event_controller_motion_class_init (GtkEventControllerMotionClass *klass)
|
||||
g_object_class_install_properties (object_class, NUM_PROPERTIES, props);
|
||||
|
||||
/**
|
||||
* GtkEventControllerMotion::enter:
|
||||
* @controller: The object that received the signal
|
||||
* @x: the x coordinate
|
||||
* @y: the y coordinate
|
||||
* @crossing_mode: the crossing mode of this event
|
||||
* @notify_type: the kind of crossing event
|
||||
* GtkEventControllerMotion::pointer-change:
|
||||
* @controller: the object which received the signal
|
||||
* @direction: the direction of this crossing event
|
||||
* @x: coordinates of pointer location
|
||||
* @y: coordinates of pointer location
|
||||
* @mode: crossing mode
|
||||
*
|
||||
* Signals that the pointer has entered the widget.
|
||||
* This signal is emitted whenever the pointer focus changes
|
||||
* from or to a widget that is a descendant of the widget to
|
||||
* which @controller is attached.
|
||||
*
|
||||
* Handlers for this signal can use
|
||||
* gtk_event_controller_motion_get_pointer_origin() and
|
||||
* gtk_event_controller_motion_get_pointer_target() to find
|
||||
* the old and new pointer locations.
|
||||
*/
|
||||
signals[ENTER] =
|
||||
g_signal_new (I_("enter"),
|
||||
signals[POINTER_CHANGE] =
|
||||
g_signal_new (I_("pointer-change"),
|
||||
GTK_TYPE_EVENT_CONTROLLER_MOTION,
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL,
|
||||
_gtk_marshal_VOID__DOUBLE_DOUBLE_ENUM_ENUM,
|
||||
G_TYPE_NONE,
|
||||
4,
|
||||
NULL,
|
||||
G_TYPE_NONE, 4,
|
||||
GTK_TYPE_CROSSING_DIRECTION,
|
||||
G_TYPE_DOUBLE,
|
||||
G_TYPE_DOUBLE,
|
||||
GDK_TYPE_CROSSING_MODE,
|
||||
GDK_TYPE_NOTIFY_TYPE);
|
||||
g_signal_set_va_marshaller (signals[ENTER],
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
_gtk_marshal_VOID__DOUBLE_DOUBLE_ENUM_ENUMv);
|
||||
|
||||
/**
|
||||
* GtkEventControllerMotion::leave:
|
||||
* @controller: The object that received the signal
|
||||
* @crossing_mode: the crossing mode of this event
|
||||
* @notify_type: the kind of crossing event
|
||||
*
|
||||
* Signals that pointer has left the widget.
|
||||
*/
|
||||
signals[LEAVE] =
|
||||
g_signal_new (I_("leave"),
|
||||
GTK_TYPE_EVENT_CONTROLLER_MOTION,
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0, NULL, NULL,
|
||||
_gtk_marshal_VOID__ENUM_ENUM,
|
||||
G_TYPE_NONE,
|
||||
2,
|
||||
GDK_TYPE_CROSSING_MODE,
|
||||
GDK_TYPE_NOTIFY_TYPE);
|
||||
g_signal_set_va_marshaller (signals[LEAVE],
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
_gtk_marshal_VOID__ENUM_ENUMv);
|
||||
GDK_TYPE_CROSSING_MODE);
|
||||
|
||||
/**
|
||||
* GtkEventControllerMotion::motion:
|
||||
@ -332,25 +290,17 @@ gtk_event_controller_motion_new (void)
|
||||
* Returns the widget that contained the pointer before.
|
||||
*
|
||||
* This function can only be used in handlers for the
|
||||
* #GtkEventControllerMotion::enter and
|
||||
* #GtkEventControllerMotion::leave signals.
|
||||
* #GtkEventControllerMotion::pointer-change signal.
|
||||
*
|
||||
* Returns: (transfer none): the previous pointer focus
|
||||
*/
|
||||
GtkWidget *
|
||||
gtk_event_controller_motion_get_pointer_origin (GtkEventControllerMotion *controller)
|
||||
{
|
||||
GtkWidget *origin;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER_MOTION (controller), NULL);
|
||||
g_return_val_if_fail (controller->current_event != NULL, NULL);
|
||||
g_return_val_if_fail (controller->current_crossing != NULL, NULL);
|
||||
|
||||
if (gdk_event_get_event_type (controller->current_event) == GDK_ENTER_NOTIFY)
|
||||
origin = (GtkWidget *)gdk_event_get_related_target (controller->current_event);
|
||||
else
|
||||
origin = (GtkWidget *)gdk_event_get_target (controller->current_event);
|
||||
|
||||
return origin;
|
||||
return controller->current_crossing->old_target;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -360,8 +310,7 @@ gtk_event_controller_motion_get_pointer_origin (GtkEventControllerMotion *contro
|
||||
* Returns the widget that will contain the pointer afterwards.
|
||||
*
|
||||
* This function can only be used in handlers for the
|
||||
* #GtkEventControllerMotion::enter and
|
||||
* #GtkEventControllerMotion::leave signals.
|
||||
* #GtkEventControllerMotion::pointer-change signal.
|
||||
*
|
||||
* Returns: (transfer none): the next pointer focus
|
||||
*/
|
||||
@ -369,12 +318,9 @@ GtkWidget *
|
||||
gtk_event_controller_motion_get_pointer_target (GtkEventControllerMotion *controller)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER_MOTION (controller), NULL);
|
||||
g_return_val_if_fail (controller->current_event != NULL, NULL);
|
||||
g_return_val_if_fail (controller->current_crossing != NULL, NULL);
|
||||
|
||||
if (gdk_event_get_event_type (controller->current_event) == GDK_ENTER_NOTIFY)
|
||||
return (GtkWidget *)gdk_event_get_target (controller->current_event);
|
||||
else
|
||||
return (GtkWidget *)gdk_event_get_related_target (controller->current_event);
|
||||
return controller->current_crossing->new_target;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -166,10 +166,12 @@ static void gtk_icon_view_motion (GtkEventControl
|
||||
double x,
|
||||
double y,
|
||||
gpointer user_data);
|
||||
static void gtk_icon_view_leave (GtkEventController *controller,
|
||||
GdkCrossingMode mode,
|
||||
GdkNotifyType detail,
|
||||
gpointer user_data);
|
||||
static void gtk_icon_view_pointer (GtkEventController *controller,
|
||||
GtkCrossingDirection direction,
|
||||
double x,
|
||||
double y,
|
||||
GdkCrossingMode mode,
|
||||
gpointer user_data);
|
||||
static void gtk_icon_view_button_press (GtkGestureClick *gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
@ -965,7 +967,7 @@ gtk_icon_view_init (GtkIconView *icon_view)
|
||||
gtk_widget_add_controller (GTK_WIDGET (icon_view), GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
controller = gtk_event_controller_motion_new ();
|
||||
g_signal_connect (controller, "leave", G_CALLBACK (gtk_icon_view_leave),
|
||||
g_signal_connect (controller, "pointer-change", G_CALLBACK (gtk_icon_view_pointer),
|
||||
icon_view);
|
||||
g_signal_connect (controller, "motion", G_CALLBACK (gtk_icon_view_motion),
|
||||
icon_view);
|
||||
@ -1881,21 +1883,26 @@ gtk_icon_view_motion (GtkEventController *controller,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_view_leave (GtkEventController *controller,
|
||||
GdkCrossingMode mode,
|
||||
GdkNotifyType detail,
|
||||
gpointer user_data)
|
||||
gtk_icon_view_pointer (GtkEventController *controller,
|
||||
GtkCrossingDirection direction,
|
||||
double x,
|
||||
double y,
|
||||
GdkCrossingMode mode,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkIconView *icon_view;
|
||||
GtkIconViewPrivate *priv;
|
||||
|
||||
icon_view = GTK_ICON_VIEW (user_data);
|
||||
priv = icon_view->priv;
|
||||
|
||||
if (priv->last_prelight)
|
||||
if (direction == GTK_CROSSING_OUT)
|
||||
{
|
||||
gtk_icon_view_queue_draw_item (icon_view, priv->last_prelight);
|
||||
priv->last_prelight = NULL;
|
||||
icon_view = GTK_ICON_VIEW (user_data);
|
||||
priv = icon_view->priv;
|
||||
|
||||
if (priv->last_prelight)
|
||||
{
|
||||
gtk_icon_view_queue_draw_item (icon_view, priv->last_prelight);
|
||||
priv->last_prelight = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -448,9 +448,11 @@ static void gtk_label_motion (GtkEventControllerMotion *controller,
|
||||
double x,
|
||||
double y,
|
||||
gpointer data);
|
||||
static void gtk_label_leave (GtkEventControllerMotion *controller,
|
||||
static void gtk_label_pointer (GtkEventControllerMotion *controller,
|
||||
GtkCrossingDirection direction,
|
||||
double x,
|
||||
double y,
|
||||
GdkCrossingMode mode,
|
||||
GdkNotifyType detail,
|
||||
gpointer data);
|
||||
|
||||
static gboolean gtk_label_grab_focus (GtkWidget *widget);
|
||||
@ -4857,19 +4859,24 @@ gtk_label_motion (GtkEventControllerMotion *controller,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_leave (GtkEventControllerMotion *controller,
|
||||
GdkCrossingMode mode,
|
||||
GdkNotifyType detail,
|
||||
gpointer data)
|
||||
gtk_label_pointer (GtkEventControllerMotion *controller,
|
||||
GtkCrossingDirection direction,
|
||||
double x,
|
||||
double y,
|
||||
GdkCrossingMode mode,
|
||||
gpointer data)
|
||||
{
|
||||
GtkLabel *label = GTK_LABEL (data);
|
||||
GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
|
||||
|
||||
if (priv->select_info)
|
||||
if (direction == GTK_CROSSING_OUT)
|
||||
{
|
||||
priv->select_info->active_link = NULL;
|
||||
gtk_label_update_cursor (label);
|
||||
gtk_widget_queue_draw (GTK_WIDGET (label));
|
||||
if (priv->select_info)
|
||||
{
|
||||
priv->select_info->active_link = NULL;
|
||||
gtk_label_update_cursor (label);
|
||||
gtk_widget_queue_draw (GTK_WIDGET (label));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5015,8 +5022,8 @@ gtk_label_ensure_select_info (GtkLabel *label)
|
||||
priv->select_info->motion_controller = gtk_event_controller_motion_new ();
|
||||
g_signal_connect (priv->select_info->motion_controller, "motion",
|
||||
G_CALLBACK (gtk_label_motion), label);
|
||||
g_signal_connect (priv->select_info->motion_controller, "leave",
|
||||
G_CALLBACK (gtk_label_leave), label);
|
||||
g_signal_connect (priv->select_info->motion_controller, "pointer-change",
|
||||
G_CALLBACK (gtk_label_pointer), label);
|
||||
gtk_widget_add_controller (GTK_WIDGET (label), priv->select_info->motion_controller);
|
||||
|
||||
priv->select_info->provider = g_object_new (GTK_TYPE_LABEL_CONTENT, NULL);
|
||||
|
245
gtk/gtkmain.c
245
gtk/gtkmain.c
@ -1258,144 +1258,33 @@ check_event_in_child_popover (GtkWidget *event_widget,
|
||||
return (popover_parent == grab_widget || gtk_widget_is_ancestor (popover_parent, grab_widget));
|
||||
}
|
||||
|
||||
static GdkNotifyType
|
||||
get_virtual_notify_type (GdkNotifyType notify_type)
|
||||
{
|
||||
switch (notify_type)
|
||||
{
|
||||
case GDK_NOTIFY_ANCESTOR:
|
||||
case GDK_NOTIFY_INFERIOR:
|
||||
return GDK_NOTIFY_VIRTUAL;
|
||||
case GDK_NOTIFY_NONLINEAR:
|
||||
return GDK_NOTIFY_NONLINEAR_VIRTUAL;
|
||||
case GDK_NOTIFY_VIRTUAL:
|
||||
case GDK_NOTIFY_NONLINEAR_VIRTUAL:
|
||||
case GDK_NOTIFY_UNKNOWN:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return GDK_NOTIFY_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine from crossing mode details whether the ultimate
|
||||
* target is us or a descendant. Keep this code in sync with
|
||||
* gtkeventcontrollerkey.c:update_focus
|
||||
*/
|
||||
static gboolean
|
||||
is_or_contains (gboolean enter,
|
||||
GdkNotifyType detail)
|
||||
translate_event_coordinates (GdkEvent *event,
|
||||
double *x,
|
||||
double *y,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
gboolean is = FALSE;
|
||||
gboolean contains = FALSE;
|
||||
GtkWidget *event_widget;
|
||||
graphene_point_t p;
|
||||
double event_x, event_y;
|
||||
|
||||
switch (detail)
|
||||
{
|
||||
case GDK_NOTIFY_VIRTUAL:
|
||||
case GDK_NOTIFY_NONLINEAR_VIRTUAL:
|
||||
is = FALSE;
|
||||
contains = enter;
|
||||
break;
|
||||
case GDK_NOTIFY_ANCESTOR:
|
||||
case GDK_NOTIFY_NONLINEAR:
|
||||
is = enter;
|
||||
contains = FALSE;
|
||||
break;
|
||||
case GDK_NOTIFY_INFERIOR:
|
||||
is = enter;
|
||||
contains = !enter;
|
||||
break;
|
||||
case GDK_NOTIFY_UNKNOWN:
|
||||
default:
|
||||
g_warning ("Unknown focus change detail");
|
||||
break;
|
||||
}
|
||||
*x = *y = 0;
|
||||
|
||||
return is || contains;
|
||||
}
|
||||
if (!gdk_event_get_coords (event, &event_x, &event_y))
|
||||
return FALSE;
|
||||
|
||||
static void
|
||||
synth_crossing (GtkWidget *widget,
|
||||
GtkWidget *toplevel,
|
||||
gboolean enter,
|
||||
GtkWidget *target,
|
||||
GtkWidget *related_target,
|
||||
GdkEvent *source,
|
||||
GdkNotifyType notify_type,
|
||||
GdkCrossingMode crossing_mode)
|
||||
{
|
||||
GdkSurface *surface;
|
||||
GdkDevice *device;
|
||||
GdkDevice *source_device;
|
||||
GdkEvent *event;
|
||||
GtkStateFlags flags;
|
||||
event_widget = gtk_get_event_widget (event);
|
||||
|
||||
surface = gtk_native_get_surface (gtk_widget_get_native (toplevel));
|
||||
device = gdk_event_get_device (source);
|
||||
source_device = gdk_event_get_source_device (source);
|
||||
if (!gtk_widget_compute_point (event_widget,
|
||||
widget,
|
||||
&GRAPHENE_POINT_INIT (event_x, event_y),
|
||||
&p))
|
||||
return FALSE;
|
||||
|
||||
if (gdk_event_get_event_type (source) == GDK_FOCUS_CHANGE)
|
||||
{
|
||||
event = gdk_event_focus_new (surface, device, source_device, enter);
|
||||
*x = p.x;
|
||||
*y = p.y;
|
||||
|
||||
flags = GTK_STATE_FLAG_FOCUSED;
|
||||
if (!GTK_IS_WINDOW (toplevel) || gtk_window_get_focus_visible (GTK_WINDOW (toplevel)))
|
||||
flags |= GTK_STATE_FLAG_FOCUS_VISIBLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
double x, y;
|
||||
|
||||
gdk_event_get_coords (source, &x, &y);
|
||||
event = gdk_event_crossing_new (enter ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY,
|
||||
surface,
|
||||
device,
|
||||
source_device,
|
||||
GDK_CURRENT_TIME,
|
||||
0,
|
||||
x, y,
|
||||
crossing_mode,
|
||||
notify_type);
|
||||
|
||||
flags = GTK_STATE_FLAG_PRELIGHT;
|
||||
}
|
||||
|
||||
gdk_event_set_target (event, G_OBJECT (target));
|
||||
gdk_event_set_related_target (event, G_OBJECT (related_target));
|
||||
|
||||
event->any.surface = gtk_native_get_surface (gtk_widget_get_native (toplevel));
|
||||
if (event->any.surface)
|
||||
g_object_ref (event->any.surface);
|
||||
|
||||
if (is_or_contains (enter, notify_type))
|
||||
gtk_widget_set_state_flags (widget, flags, FALSE);
|
||||
else
|
||||
gtk_widget_unset_state_flags (widget, flags);
|
||||
|
||||
if (gdk_event_get_event_type (source) == GDK_FOCUS_CHANGE)
|
||||
{
|
||||
/* maintain focus chain */
|
||||
if (enter || notify_type == GDK_NOTIFY_INFERIOR)
|
||||
{
|
||||
GtkWidget *parent = gtk_widget_get_parent (widget);
|
||||
if (parent)
|
||||
gtk_widget_set_focus_child (parent, widget);
|
||||
}
|
||||
else if (!enter && notify_type != GDK_NOTIFY_INFERIOR)
|
||||
{
|
||||
GtkWidget *parent = gtk_widget_get_parent (widget);
|
||||
if (parent)
|
||||
gtk_widget_set_focus_child (parent, NULL);
|
||||
}
|
||||
|
||||
/* maintain widget state */
|
||||
if (notify_type == GDK_NOTIFY_ANCESTOR ||
|
||||
notify_type == GDK_NOTIFY_INFERIOR ||
|
||||
notify_type == GDK_NOTIFY_NONLINEAR)
|
||||
gtk_widget_set_has_focus (widget, enter);
|
||||
}
|
||||
|
||||
gtk_widget_event (widget, event);
|
||||
gdk_event_unref (event);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1405,72 +1294,48 @@ gtk_synthesize_crossing_events (GtkRoot *toplevel,
|
||||
GdkEvent *event,
|
||||
GdkCrossingMode mode)
|
||||
{
|
||||
GtkWidget *ancestor = NULL, *widget;
|
||||
GdkNotifyType enter_type, leave_type, notify_type;
|
||||
GtkCrossingData crossing;
|
||||
GtkWidget *widget;
|
||||
GList *list, *l;
|
||||
double x, y;
|
||||
|
||||
if (old_target && new_target)
|
||||
ancestor = gtk_widget_common_ancestor (old_target, new_target);
|
||||
crossing.type = GTK_CROSSING_POINTER;
|
||||
crossing.mode = mode;
|
||||
crossing.old_target = old_target;
|
||||
crossing.new_target = new_target;
|
||||
|
||||
if (ancestor == old_target)
|
||||
crossing.direction = GTK_CROSSING_OUT;
|
||||
|
||||
widget = old_target;
|
||||
while (widget)
|
||||
{
|
||||
leave_type = GDK_NOTIFY_INFERIOR;
|
||||
enter_type = GDK_NOTIFY_ANCESTOR;
|
||||
}
|
||||
else if (ancestor == new_target)
|
||||
{
|
||||
leave_type = GDK_NOTIFY_ANCESTOR;
|
||||
enter_type = GDK_NOTIFY_INFERIOR;
|
||||
}
|
||||
else
|
||||
enter_type = leave_type = GDK_NOTIFY_NONLINEAR;
|
||||
|
||||
if (old_target)
|
||||
{
|
||||
widget = old_target;
|
||||
|
||||
while (widget)
|
||||
{
|
||||
notify_type = (widget == old_target) ?
|
||||
leave_type : get_virtual_notify_type (leave_type);
|
||||
|
||||
if (widget != ancestor || widget == old_target)
|
||||
synth_crossing (widget, GTK_WIDGET (toplevel), FALSE,
|
||||
old_target, new_target, event, notify_type, mode);
|
||||
if (widget == ancestor || widget == GTK_WIDGET (toplevel))
|
||||
break;
|
||||
widget = gtk_widget_get_parent (widget);
|
||||
}
|
||||
translate_event_coordinates (event, &x, &y, widget);
|
||||
gtk_widget_handle_crossing (widget, &crossing, x, y);
|
||||
gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_PRELIGHT);
|
||||
widget = gtk_widget_get_parent (widget);
|
||||
}
|
||||
|
||||
if (new_target)
|
||||
list = NULL;
|
||||
widget = new_target;
|
||||
while (widget)
|
||||
{
|
||||
GSList *widgets = NULL;
|
||||
|
||||
widget = new_target;
|
||||
|
||||
while (widget)
|
||||
{
|
||||
widgets = g_slist_prepend (widgets, widget);
|
||||
if (widget == ancestor || widget == GTK_WIDGET (toplevel))
|
||||
break;
|
||||
widget = gtk_widget_get_parent (widget);
|
||||
}
|
||||
|
||||
while (widgets)
|
||||
{
|
||||
widget = widgets->data;
|
||||
widgets = g_slist_delete_link (widgets, widgets);
|
||||
notify_type = (widget == new_target) ?
|
||||
enter_type : get_virtual_notify_type (enter_type);
|
||||
|
||||
if (widget != ancestor || widget == new_target)
|
||||
synth_crossing (widget, GTK_WIDGET (toplevel), TRUE,
|
||||
new_target, old_target, event, notify_type, mode);
|
||||
}
|
||||
list = g_list_prepend (list, widget);
|
||||
widget = gtk_widget_get_parent (widget);
|
||||
}
|
||||
|
||||
crossing.direction = GTK_CROSSING_IN;
|
||||
|
||||
for (l = list; l; l = l->next)
|
||||
{
|
||||
widget = l->data;
|
||||
translate_event_coordinates (event, &x, &y, widget);
|
||||
gtk_widget_handle_crossing (widget, &crossing, x, y);
|
||||
gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_PRELIGHT, FALSE);
|
||||
}
|
||||
|
||||
g_list_free (list);
|
||||
}
|
||||
|
||||
|
||||
static GtkWidget *
|
||||
update_pointer_focus_state (GtkWindow *toplevel,
|
||||
GdkEvent *event,
|
||||
@ -1671,8 +1536,8 @@ handle_pointing_event (GdkEvent *event)
|
||||
new_target = gtk_widget_pick (GTK_WIDGET (native), x, y, GTK_PICK_DEFAULT);
|
||||
if (new_target == NULL)
|
||||
new_target = GTK_WIDGET (toplevel);
|
||||
gtk_synthesize_crossing_events (GTK_ROOT (toplevel), target, new_target, event,
|
||||
GDK_CROSSING_UNGRAB);
|
||||
gtk_synthesize_crossing_events (GTK_ROOT (toplevel), target, new_target,
|
||||
event, GDK_CROSSING_UNGRAB);
|
||||
gtk_window_maybe_update_cursor (toplevel, NULL, device);
|
||||
}
|
||||
|
||||
@ -1899,7 +1764,7 @@ gtk_main_do_event (GdkEvent *event)
|
||||
break;
|
||||
}
|
||||
|
||||
_gtk_tooltip_handle_event (event);
|
||||
_gtk_tooltip_handle_event (target_widget, event);
|
||||
|
||||
cleanup:
|
||||
tmp_list = current_events;
|
||||
|
@ -1311,26 +1311,32 @@ stop_open (GtkModelButton *button)
|
||||
}
|
||||
|
||||
static void
|
||||
enter_cb (GtkEventController *controller,
|
||||
double x,
|
||||
double y,
|
||||
GdkCrossingMode mode,
|
||||
GdkNotifyType type,
|
||||
gpointer data)
|
||||
pointer_change_cb (GtkEventController *controller,
|
||||
GtkCrossingDirection direction,
|
||||
double x,
|
||||
double y,
|
||||
GdkCrossingMode mode,
|
||||
gpointer data)
|
||||
{
|
||||
GtkModelButton *button = data;
|
||||
GtkWidget *target;
|
||||
GtkWidget *popover;
|
||||
|
||||
target = gtk_event_controller_get_widget (controller);
|
||||
popover = gtk_widget_get_ancestor (target, GTK_TYPE_POPOVER_MENU);
|
||||
|
||||
if (popover && gtk_event_controller_motion_contains_pointer (GTK_EVENT_CONTROLLER_MOTION (controller)))
|
||||
if (direction == GTK_CROSSING_IN)
|
||||
{
|
||||
if (gtk_popover_menu_get_open_submenu (GTK_POPOVER_MENU (popover)) != NULL)
|
||||
start_open (GTK_MODEL_BUTTON (target));
|
||||
else
|
||||
open_submenu (target);
|
||||
target = gtk_event_controller_get_widget (controller);
|
||||
popover = gtk_widget_get_ancestor (target, GTK_TYPE_POPOVER_MENU);
|
||||
|
||||
if (popover && gtk_event_controller_motion_contains_pointer (GTK_EVENT_CONTROLLER_MOTION (controller)))
|
||||
{
|
||||
if (gtk_popover_menu_get_open_submenu (GTK_POPOVER_MENU (popover)) != NULL)
|
||||
start_open (GTK_MODEL_BUTTON (target));
|
||||
else
|
||||
open_submenu (target);
|
||||
}
|
||||
}
|
||||
else
|
||||
stop_open (button);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1342,22 +1348,6 @@ motion_cb (GtkEventController *controller,
|
||||
start_open (GTK_MODEL_BUTTON (data));
|
||||
}
|
||||
|
||||
static void
|
||||
leave_cb (GtkEventController *controller,
|
||||
GdkCrossingMode mode,
|
||||
GdkNotifyType type,
|
||||
gpointer data)
|
||||
{
|
||||
GtkPopoverMenu *popover;
|
||||
|
||||
popover = (GtkPopoverMenu*)gtk_widget_get_ancestor (GTK_WIDGET (data), GTK_TYPE_POPOVER_MENU);
|
||||
|
||||
stop_open (GTK_MODEL_BUTTON (data));
|
||||
|
||||
if (popover)
|
||||
gtk_popover_menu_set_active_item (popover, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
focus_change_cb (GtkEventController *controller,
|
||||
GtkCrossingDirection direction,
|
||||
@ -1396,9 +1386,8 @@ gtk_model_button_init (GtkModelButton *self)
|
||||
gtk_widget_add_css_class (GTK_WIDGET (self), "flat");
|
||||
|
||||
controller = gtk_event_controller_motion_new ();
|
||||
g_signal_connect (controller, "enter", G_CALLBACK (enter_cb), self);
|
||||
g_signal_connect (controller, "pointer-change", G_CALLBACK (pointer_change_cb), self);
|
||||
g_signal_connect (controller, "motion", G_CALLBACK (motion_cb), self);
|
||||
g_signal_connect (controller, "leave", G_CALLBACK (leave_cb), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), controller);
|
||||
|
||||
controller = gtk_event_controller_key_new ();
|
||||
|
@ -186,17 +186,22 @@ focus_change (GtkEventController *controller,
|
||||
}
|
||||
|
||||
static void
|
||||
leave_cb (GtkEventController *controller,
|
||||
GdkCrossingMode mode,
|
||||
GdkNotifyType type,
|
||||
gpointer data)
|
||||
pointer_cb (GtkEventController *controller,
|
||||
GtkCrossingDirection direction,
|
||||
double x,
|
||||
double y,
|
||||
GdkCrossingMode mode,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *target;
|
||||
|
||||
target = gtk_event_controller_get_widget (controller);
|
||||
if (direction == GTK_CROSSING_OUT)
|
||||
{
|
||||
target = gtk_event_controller_get_widget (controller);
|
||||
|
||||
if (!gtk_event_controller_motion_contains_pointer (GTK_EVENT_CONTROLLER_MOTION (controller)))
|
||||
gtk_popover_menu_set_active_item (GTK_POPOVER_MENU (target), NULL);
|
||||
if (!gtk_event_controller_motion_contains_pointer (GTK_EVENT_CONTROLLER_MOTION (controller)))
|
||||
gtk_popover_menu_set_active_item (GTK_POPOVER_MENU (target), NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -220,7 +225,7 @@ gtk_popover_menu_init (GtkPopoverMenu *popover)
|
||||
gtk_widget_add_controller (GTK_WIDGET (popover), controller);
|
||||
|
||||
controller = gtk_event_controller_motion_new ();
|
||||
g_signal_connect (controller, "leave", G_CALLBACK (leave_cb), popover);
|
||||
g_signal_connect (controller, "pointer-change", G_CALLBACK (pointer_cb), popover);
|
||||
gtk_widget_add_controller (GTK_WIDGET (popover), controller);
|
||||
}
|
||||
|
||||
|
@ -166,39 +166,43 @@ clicked_cb (GtkGesture *gesture,
|
||||
}
|
||||
|
||||
static void
|
||||
enter_cb (GtkEventController *controller,
|
||||
double x,
|
||||
double y,
|
||||
GdkCrossingMode mode,
|
||||
GdkNotifyType type,
|
||||
gpointer data)
|
||||
item_pointer_change_cb (GtkEventController *controller,
|
||||
GtkCrossingDirection direction,
|
||||
double x,
|
||||
double y,
|
||||
GdkCrossingMode mode,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *target;
|
||||
GtkPopoverMenuBar *bar;
|
||||
|
||||
target = gtk_event_controller_get_widget (controller);
|
||||
|
||||
bar = GTK_POPOVER_MENU_BAR (gtk_widget_get_ancestor (target, GTK_TYPE_POPOVER_MENU_BAR));
|
||||
|
||||
set_active_item (bar, GTK_POPOVER_MENU_BAR_ITEM (target), FALSE);
|
||||
if (direction == GTK_CROSSING_IN)
|
||||
set_active_item (bar, GTK_POPOVER_MENU_BAR_ITEM (target), FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
leave_cb (GtkEventController *controller,
|
||||
GdkCrossingMode mode,
|
||||
GdkNotifyType type,
|
||||
gpointer data)
|
||||
bar_pointer_change_cb (GtkEventController *controller,
|
||||
GtkCrossingDirection direction,
|
||||
double x,
|
||||
double y,
|
||||
GdkCrossingMode mode,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *target;
|
||||
GtkPopoverMenuBar *bar;
|
||||
|
||||
target = gtk_event_controller_get_widget (controller);
|
||||
|
||||
bar = GTK_POPOVER_MENU_BAR (gtk_widget_get_ancestor (target, GTK_TYPE_POPOVER_MENU_BAR));
|
||||
|
||||
if (bar->active_item &&
|
||||
!gtk_widget_get_mapped (GTK_WIDGET (bar->active_item->popover)))
|
||||
set_active_item (bar, NULL, FALSE);
|
||||
if (direction == GTK_CROSSING_OUT)
|
||||
{
|
||||
if (bar->active_item &&
|
||||
!gtk_widget_get_mapped (GTK_WIDGET (bar->active_item->popover)))
|
||||
set_active_item (bar, NULL, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -261,7 +265,7 @@ gtk_popover_menu_bar_item_init (GtkPopoverMenuBarItem *item)
|
||||
|
||||
controller = gtk_event_controller_motion_new ();
|
||||
gtk_event_controller_set_propagation_limit (controller, GTK_LIMIT_NONE);
|
||||
g_signal_connect (controller, "enter", G_CALLBACK (enter_cb), NULL);
|
||||
g_signal_connect (controller, "pointer-change", G_CALLBACK (item_pointer_change_cb), NULL);
|
||||
gtk_widget_add_controller (GTK_WIDGET (item), controller);
|
||||
}
|
||||
|
||||
@ -613,7 +617,7 @@ gtk_popover_menu_bar_init (GtkPopoverMenuBar *bar)
|
||||
|
||||
controller = gtk_event_controller_motion_new ();
|
||||
gtk_event_controller_set_propagation_limit (controller, GTK_LIMIT_NONE);
|
||||
g_signal_connect (controller, "leave", G_CALLBACK (leave_cb), NULL);
|
||||
g_signal_connect (controller, "pointer-change", G_CALLBACK (bar_pointer_change_cb), NULL);
|
||||
gtk_widget_add_controller (GTK_WIDGET (bar), controller);
|
||||
}
|
||||
|
||||
|
@ -444,17 +444,22 @@ add_tab_bindings (GtkBindingSet *binding_set,
|
||||
}
|
||||
|
||||
static void
|
||||
motion_controller_leave (GtkEventController *controller,
|
||||
GdkCrossingMode mode,
|
||||
GdkNotifyType detail,
|
||||
GtkScrolledWindow *scrolled_window)
|
||||
motion_controller_pointer (GtkEventController *controller,
|
||||
GtkCrossingDirection direction,
|
||||
double x,
|
||||
double y,
|
||||
GdkCrossingMode mode,
|
||||
GtkScrolledWindow *scrolled_window)
|
||||
{
|
||||
GtkScrolledWindowPrivate *priv = gtk_scrolled_window_get_instance_private (scrolled_window);
|
||||
|
||||
if (priv->use_indicators)
|
||||
if (direction == GTK_CROSSING_OUT)
|
||||
{
|
||||
indicator_set_over (&priv->hindicator, FALSE);
|
||||
indicator_set_over (&priv->vindicator, FALSE);
|
||||
if (priv->use_indicators)
|
||||
{
|
||||
indicator_set_over (&priv->hindicator, FALSE);
|
||||
indicator_set_over (&priv->vindicator, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2020,8 +2025,8 @@ gtk_scrolled_window_init (GtkScrolledWindow *scrolled_window)
|
||||
gtk_widget_add_controller (widget, controller);
|
||||
|
||||
controller = gtk_event_controller_motion_new ();
|
||||
g_signal_connect (controller, "leave",
|
||||
G_CALLBACK (motion_controller_leave), scrolled_window);
|
||||
g_signal_connect (controller, "pointer-change",
|
||||
G_CALLBACK (motion_controller_pointer), scrolled_window);
|
||||
gtk_widget_add_controller (widget, controller);
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkaccessible.h"
|
||||
#include "gtknative.h"
|
||||
#include "gdk/gdkeventsprivate.h"
|
||||
|
||||
/**
|
||||
* SECTION:gtktooltip
|
||||
@ -875,10 +874,10 @@ tooltips_enabled (GdkEvent *event)
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_tooltip_handle_event (GdkEvent *event)
|
||||
_gtk_tooltip_handle_event (GtkWidget *target,
|
||||
GdkEvent *event)
|
||||
{
|
||||
GdkEventType event_type;
|
||||
GtkWidget *target;
|
||||
GdkSurface *surface;
|
||||
gdouble dx, dy;
|
||||
|
||||
@ -888,7 +887,6 @@ _gtk_tooltip_handle_event (GdkEvent *event)
|
||||
event_type = gdk_event_get_event_type (event);
|
||||
surface = gdk_event_get_surface (event);
|
||||
gdk_event_get_coords (event, &dx, &dy);
|
||||
target = GTK_WIDGET (gdk_event_get_target (event));
|
||||
|
||||
gtk_tooltip_handle_event_internal (event_type, surface, target, dx, dy);
|
||||
}
|
||||
|
@ -31,7 +31,8 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void _gtk_tooltip_handle_event (GdkEvent *event);
|
||||
void _gtk_tooltip_handle_event (GtkWidget *target,
|
||||
GdkEvent *event);
|
||||
void _gtk_tooltip_hide (GtkWidget *widget);
|
||||
void gtk_tooltip_trigger_tooltip_query (GtkWidget *widget);
|
||||
|
||||
|
@ -619,30 +619,23 @@ item_activated_cb (GtkGesture *gesture,
|
||||
}
|
||||
|
||||
static void
|
||||
enter_cb (GtkEventController *controller,
|
||||
double x,
|
||||
double y,
|
||||
GdkCrossingMode mode,
|
||||
GdkNotifyType type,
|
||||
GtkTreePopover *popover)
|
||||
pointer_change_cb (GtkEventController *controller,
|
||||
GtkCrossingDirection direction,
|
||||
double x,
|
||||
double y,
|
||||
GdkCrossingMode mode,
|
||||
GtkTreePopover *popover)
|
||||
{
|
||||
GtkWidget *item;
|
||||
item = gtk_event_controller_get_widget (controller);
|
||||
|
||||
if (gtk_event_controller_motion_contains_pointer (GTK_EVENT_CONTROLLER_MOTION (controller)))
|
||||
if (direction == GTK_CROSSING_IN)
|
||||
{
|
||||
gtk_tree_popover_set_active_item (popover, item);
|
||||
if (gtk_event_controller_motion_contains_pointer (GTK_EVENT_CONTROLLER_MOTION (controller)))
|
||||
gtk_tree_popover_set_active_item (popover, item);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
leave_cb (GtkEventController *controller,
|
||||
GdkCrossingMode mode,
|
||||
GdkNotifyType type,
|
||||
GtkTreePopover *popover)
|
||||
{
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
gtk_tree_popover_create_item (GtkTreePopover *popover,
|
||||
GtkTreePath *path,
|
||||
@ -700,8 +693,7 @@ gtk_tree_popover_create_item (GtkTreePopover *popover,
|
||||
gtk_widget_add_controller (item, GTK_EVENT_CONTROLLER (controller));
|
||||
|
||||
controller = gtk_event_controller_motion_new ();
|
||||
g_signal_connect (controller, "enter", G_CALLBACK (enter_cb), popover);
|
||||
g_signal_connect (controller, "leave", G_CALLBACK (leave_cb), popover);
|
||||
g_signal_connect (controller, "pointer-change", G_CALLBACK (pointer_change_cb), popover);
|
||||
gtk_widget_add_controller (item, controller);
|
||||
|
||||
g_object_set_data (G_OBJECT (item), "is-header", GINT_TO_POINTER (header_item));
|
||||
|
@ -970,15 +970,11 @@ static void gtk_tree_view_drag_gesture_end (GtkGestureDrag *ges
|
||||
gdouble offset_x,
|
||||
gdouble offset_y,
|
||||
GtkTreeView *tree_view);
|
||||
static void gtk_tree_view_motion_controller_enter (GtkEventControllerMotion *controller,
|
||||
static void gtk_tree_view_motion_controller_pointer (GtkEventControllerMotion *controller,
|
||||
GtkCrossingDirection direction,
|
||||
double x,
|
||||
double y,
|
||||
GdkCrossingMode mode,
|
||||
GdkNotifyType detail,
|
||||
GtkTreeView *tree_view);
|
||||
static void gtk_tree_view_motion_controller_leave (GtkEventControllerMotion *controller,
|
||||
GdkCrossingMode mode,
|
||||
GdkNotifyType detail,
|
||||
GtkTreeView *tree_view);
|
||||
static void gtk_tree_view_motion_controller_motion (GtkEventControllerMotion *controller,
|
||||
double x,
|
||||
@ -1825,10 +1821,8 @@ gtk_tree_view_init (GtkTreeView *tree_view)
|
||||
gtk_widget_add_controller (GTK_WIDGET (tree_view), GTK_EVENT_CONTROLLER (tree_view->column_drag_gesture));
|
||||
|
||||
controller = gtk_event_controller_motion_new ();
|
||||
g_signal_connect (controller, "enter",
|
||||
G_CALLBACK (gtk_tree_view_motion_controller_enter), tree_view);
|
||||
g_signal_connect (controller, "leave",
|
||||
G_CALLBACK (gtk_tree_view_motion_controller_leave), tree_view);
|
||||
g_signal_connect (controller, "pointer-change",
|
||||
G_CALLBACK (gtk_tree_view_motion_controller_pointer), tree_view);
|
||||
g_signal_connect (controller, "motion",
|
||||
G_CALLBACK (gtk_tree_view_motion_controller_motion), tree_view);
|
||||
gtk_widget_add_controller (GTK_WIDGET (tree_view), controller);
|
||||
@ -5500,48 +5494,46 @@ gtk_tree_view_key_controller_key_released (GtkEventControllerKey *key,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_tree_view_motion_controller_enter (GtkEventControllerMotion *controller,
|
||||
double x,
|
||||
double y,
|
||||
GdkCrossingMode mode,
|
||||
GdkNotifyType detail,
|
||||
GtkTreeView *tree_view)
|
||||
gtk_tree_view_motion_controller_pointer (GtkEventControllerMotion *controller,
|
||||
GtkCrossingDirection direction,
|
||||
double x,
|
||||
double y,
|
||||
GdkCrossingMode mode,
|
||||
GtkTreeView *tree_view)
|
||||
{
|
||||
GtkTreeRBTree *tree;
|
||||
GtkTreeRBNode *node;
|
||||
gint new_y;
|
||||
|
||||
if (direction == GTK_CROSSING_IN)
|
||||
{
|
||||
if (tree_view->tree == NULL)
|
||||
return;
|
||||
|
||||
if (tree_view->tree == NULL)
|
||||
return;
|
||||
/* find the node internally */
|
||||
new_y = TREE_WINDOW_Y_TO_RBTREE_Y(tree_view, y);
|
||||
if (new_y < 0)
|
||||
new_y = 0;
|
||||
gtk_tree_rbtree_find_offset (tree_view->tree, new_y, &tree, &node);
|
||||
|
||||
/* find the node internally */
|
||||
new_y = TREE_WINDOW_Y_TO_RBTREE_Y(tree_view, y);
|
||||
if (new_y < 0)
|
||||
new_y = 0;
|
||||
gtk_tree_rbtree_find_offset (tree_view->tree, new_y, &tree, &node);
|
||||
tree_view->event_last_x = x;
|
||||
tree_view->event_last_y = y;
|
||||
|
||||
tree_view->event_last_x = x;
|
||||
tree_view->event_last_y = y;
|
||||
if ((tree_view->button_pressed_node == NULL) ||
|
||||
(tree_view->button_pressed_node == node))
|
||||
prelight_or_select (tree_view, tree, node, x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tree_view->prelight_node)
|
||||
gtk_widget_queue_draw (GTK_WIDGET (tree_view));
|
||||
|
||||
if ((tree_view->button_pressed_node == NULL) ||
|
||||
(tree_view->button_pressed_node == node))
|
||||
prelight_or_select (tree_view, tree, node, x, y);
|
||||
}
|
||||
tree_view->event_last_x = -10000;
|
||||
tree_view->event_last_y = -10000;
|
||||
|
||||
static void
|
||||
gtk_tree_view_motion_controller_leave (GtkEventControllerMotion *controller,
|
||||
GdkCrossingMode mode,
|
||||
GdkNotifyType detail,
|
||||
GtkTreeView *tree_view)
|
||||
{
|
||||
if (tree_view->prelight_node)
|
||||
gtk_widget_queue_draw (GTK_WIDGET (tree_view));
|
||||
|
||||
tree_view->event_last_x = -10000;
|
||||
tree_view->event_last_y = -10000;
|
||||
|
||||
if (!gtk_event_controller_motion_contains_pointer (GTK_EVENT_CONTROLLER_MOTION (controller)))
|
||||
prelight_or_select (tree_view, NULL, NULL, -1000, -1000); /* not possibly over an arrow */
|
||||
if (!gtk_event_controller_motion_contains_pointer (GTK_EVENT_CONTROLLER_MOTION (controller)))
|
||||
prelight_or_select (tree_view, NULL, NULL, -1000, -1000); /* not possibly over an arrow */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -4793,7 +4793,7 @@ gtk_widget_event (GtkWidget *widget,
|
||||
|
||||
gboolean
|
||||
gtk_widget_run_controllers (GtkWidget *widget,
|
||||
const GdkEvent *event,
|
||||
const GdkEvent *event,
|
||||
double x,
|
||||
double y,
|
||||
GtkPropagationPhase phase)
|
||||
@ -4878,6 +4878,7 @@ translate_event_coordinates (GdkEvent *event,
|
||||
double *x,
|
||||
double *y,
|
||||
GtkWidget *widget);
|
||||
|
||||
gboolean
|
||||
_gtk_widget_captured_event (GtkWidget *widget,
|
||||
GdkEvent *event)
|
||||
@ -4891,7 +4892,6 @@ _gtk_widget_captured_event (GtkWidget *widget,
|
||||
if (!event_surface_is_still_viewable (event))
|
||||
return TRUE;
|
||||
|
||||
x = y = 0;
|
||||
translate_event_coordinates (event, &x, &y, widget);
|
||||
|
||||
return_val = gtk_widget_run_controllers (widget, event, x, y, GTK_PHASE_CAPTURE);
|
||||
@ -4984,7 +4984,6 @@ gtk_widget_event_internal (GtkWidget *widget,
|
||||
if (!_gtk_widget_get_mapped (widget))
|
||||
return FALSE;
|
||||
|
||||
x = y = 0;
|
||||
translate_event_coordinates (event, &x, &y, widget);
|
||||
|
||||
if (widget == GTK_WIDGET (gdk_event_get_target (event)))
|
||||
@ -7968,38 +7967,6 @@ _gtk_widget_list_devices (GtkWidget *widget)
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
synth_crossing (GtkWidget *widget,
|
||||
GdkEventType type,
|
||||
GdkSurface *surface,
|
||||
GdkDevice *device,
|
||||
GdkCrossingMode mode,
|
||||
GdkNotifyType detail)
|
||||
{
|
||||
GdkEvent *event;
|
||||
double x, y;
|
||||
GdkModifierType state;
|
||||
|
||||
gdk_surface_get_device_position (surface, device, &x, &y, &state);
|
||||
event = gdk_event_crossing_new (type,
|
||||
surface,
|
||||
device,
|
||||
device,
|
||||
GDK_CURRENT_TIME,
|
||||
state,
|
||||
x, y,
|
||||
mode,
|
||||
detail);
|
||||
|
||||
if (!widget)
|
||||
widget = gtk_get_event_widget (event);
|
||||
|
||||
if (widget)
|
||||
gtk_widget_event_internal (widget, event);
|
||||
|
||||
gdk_event_unref (event);
|
||||
}
|
||||
|
||||
/*
|
||||
* _gtk_widget_synthesize_crossing:
|
||||
* @from: the #GtkWidget the virtual pointer is leaving.
|
||||
@ -8015,46 +7982,37 @@ _gtk_widget_synthesize_crossing (GtkWidget *from,
|
||||
GdkCrossingMode mode)
|
||||
{
|
||||
GdkSurface *from_surface = NULL, *to_surface = NULL;
|
||||
GtkCrossingData crossing;
|
||||
double x, y;
|
||||
|
||||
g_return_if_fail (from != NULL || to != NULL);
|
||||
|
||||
if (from != NULL)
|
||||
{
|
||||
from_surface = _gtk_widget_get_device_surface (from, device);
|
||||
crossing.type = GTK_CROSSING_POINTER;
|
||||
crossing.old_target = from;
|
||||
crossing.new_target = to;
|
||||
crossing.mode = mode;
|
||||
|
||||
if (from)
|
||||
{
|
||||
crossing.direction = GTK_CROSSING_OUT;
|
||||
|
||||
from_surface = _gtk_widget_get_device_surface (from, device);
|
||||
if (!from_surface)
|
||||
from_surface = from->priv->surface;
|
||||
|
||||
gdk_surface_get_device_position (from_surface, device, &x, &y, NULL);
|
||||
gtk_widget_handle_crossing (from, &crossing, x, y);
|
||||
}
|
||||
|
||||
if (to != NULL)
|
||||
if (to)
|
||||
{
|
||||
to_surface = _gtk_widget_get_device_surface (to, device);
|
||||
|
||||
if (!to_surface)
|
||||
to_surface = to->priv->surface;
|
||||
}
|
||||
|
||||
if (from_surface == NULL && to_surface == NULL)
|
||||
;
|
||||
else if (from_surface != NULL && to_surface == NULL)
|
||||
{
|
||||
synth_crossing (from, GDK_LEAVE_NOTIFY, from_surface,
|
||||
device, mode, GDK_NOTIFY_ANCESTOR);
|
||||
}
|
||||
else if (from_surface == NULL && to_surface != NULL)
|
||||
{
|
||||
synth_crossing (to, GDK_ENTER_NOTIFY, to_surface,
|
||||
device, mode, GDK_NOTIFY_ANCESTOR);
|
||||
}
|
||||
else if (from_surface == to_surface)
|
||||
;
|
||||
else
|
||||
{
|
||||
synth_crossing (from, GDK_LEAVE_NOTIFY, from_surface,
|
||||
device, mode, GDK_NOTIFY_NONLINEAR);
|
||||
|
||||
synth_crossing (to, GDK_ENTER_NOTIFY, to_surface,
|
||||
device, mode, GDK_NOTIFY_NONLINEAR);
|
||||
crossing.direction = GTK_CROSSING_IN;
|
||||
gdk_surface_get_device_position (to_surface, device, &x, &y, NULL);
|
||||
gtk_widget_handle_crossing (to, &crossing, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -400,7 +400,6 @@ gboolean gtk_widget_mnemonic_activate (GtkWidget *widget,
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_widget_event (GtkWidget *widget,
|
||||
GdkEvent *event);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_widget_activate (GtkWidget *widget);
|
||||
|
||||
|
@ -262,7 +262,7 @@ GList * _gtk_widget_list_devices (GtkWidget *widget);
|
||||
void gtk_synthesize_crossing_events (GtkRoot *toplevel,
|
||||
GtkWidget *from,
|
||||
GtkWidget *to,
|
||||
GdkEvent *event,
|
||||
GdkEvent *source,
|
||||
GdkCrossingMode mode);
|
||||
|
||||
void _gtk_widget_synthesize_crossing (GtkWidget *from,
|
||||
|
@ -6030,7 +6030,7 @@ gtk_window_propagate_key_event (GtkWindow *window,
|
||||
|
||||
if (gtk_widget_is_sensitive (focus))
|
||||
{
|
||||
handled = gtk_widget_event (focus, (GdkEvent*) event);
|
||||
handled = gtk_widget_event (focus, (GdkEvent *)event);
|
||||
if (handled)
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user