gesture: Add gtk_gesture_[sg]et_window()
This can be used to restrict a gesture to an specific GdkWindow, all events will be checked to happen on/within that window.
This commit is contained in:
parent
7f787e1d3b
commit
25ece22013
121
gtk/gtkgesture.c
121
gtk/gtkgesture.c
@ -29,6 +29,7 @@ typedef struct _PointData PointData;
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_N_POINTS = 1,
|
PROP_N_POINTS = 1,
|
||||||
|
PROP_WINDOW
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -52,6 +53,7 @@ struct _GtkGesturePrivate
|
|||||||
{
|
{
|
||||||
GHashTable *points;
|
GHashTable *points;
|
||||||
GdkEventSequence *last_sequence;
|
GdkEventSequence *last_sequence;
|
||||||
|
GdkWindow *user_window;
|
||||||
GdkWindow *window;
|
GdkWindow *window;
|
||||||
GdkDevice *device;
|
GdkDevice *device;
|
||||||
guint n_points;
|
guint n_points;
|
||||||
@ -77,6 +79,8 @@ gtk_gesture_get_property (GObject *object,
|
|||||||
case PROP_N_POINTS:
|
case PROP_N_POINTS:
|
||||||
g_value_set_uint (value, priv->n_points);
|
g_value_set_uint (value, priv->n_points);
|
||||||
break;
|
break;
|
||||||
|
case PROP_WINDOW:
|
||||||
|
g_value_set_object (value, priv->user_window);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
@ -96,6 +100,9 @@ gtk_gesture_set_property (GObject *object,
|
|||||||
case PROP_N_POINTS:
|
case PROP_N_POINTS:
|
||||||
priv->n_points = g_value_get_uint (value);
|
priv->n_points = g_value_get_uint (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_WINDOW:
|
||||||
|
gtk_gesture_set_window (GTK_GESTURE (object),
|
||||||
|
g_value_get_object (value));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
@ -199,12 +206,36 @@ _gtk_gesture_check_recognized (GtkGesture *gesture,
|
|||||||
return priv->recognized;
|
return priv->recognized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Finds the first window pertaining to the controller's widget */
|
||||||
|
static GdkWindow *
|
||||||
|
_find_widget_window (GtkGesture *gesture,
|
||||||
|
GdkWindow *window)
|
||||||
|
{
|
||||||
|
GtkWidget *widget, *window_widget;
|
||||||
|
|
||||||
|
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
|
||||||
|
|
||||||
|
while (window)
|
||||||
|
{
|
||||||
|
gdk_window_get_user_data (window, (gpointer*) &window_widget);
|
||||||
|
|
||||||
|
if (window_widget == widget ||
|
||||||
|
gtk_widget_get_window (widget) == window)
|
||||||
|
return window;
|
||||||
|
|
||||||
|
window = gdk_window_get_effective_parent (window);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_gtk_gesture_update_point (GtkGesture *gesture,
|
_gtk_gesture_update_point (GtkGesture *gesture,
|
||||||
const GdkEvent *event,
|
const GdkEvent *event,
|
||||||
gboolean add)
|
gboolean add)
|
||||||
{
|
{
|
||||||
GdkEventSequence *sequence;
|
GdkEventSequence *sequence;
|
||||||
|
GdkWindow *widget_window;
|
||||||
GtkGesturePrivate *priv;
|
GtkGesturePrivate *priv;
|
||||||
GdkDevice *device;
|
GdkDevice *device;
|
||||||
PointData *data;
|
PointData *data;
|
||||||
@ -219,8 +250,21 @@ _gtk_gesture_update_point (GtkGesture *gesture,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
priv = gtk_gesture_get_instance_private (gesture);
|
priv = gtk_gesture_get_instance_private (gesture);
|
||||||
|
widget_window = _find_widget_window (gesture, event->any.window);
|
||||||
|
|
||||||
if (priv->device && priv->device != device)
|
if (add)
|
||||||
|
{
|
||||||
|
/* If the event happens with the wrong device, or
|
||||||
|
* on the wrong window, ignore.
|
||||||
|
*/
|
||||||
|
if (priv->device && priv->device != device)
|
||||||
|
return FALSE;
|
||||||
|
if (priv->window && priv->window != widget_window)
|
||||||
|
return FALSE;
|
||||||
|
if (priv->user_window && priv->user_window != widget_window)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else if (!priv->device || !priv->window)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
sequence = gdk_event_get_event_sequence (event);
|
sequence = gdk_event_get_event_sequence (event);
|
||||||
@ -233,7 +277,7 @@ _gtk_gesture_update_point (GtkGesture *gesture,
|
|||||||
|
|
||||||
if (g_hash_table_size (priv->points) == 0)
|
if (g_hash_table_size (priv->points) == 0)
|
||||||
{
|
{
|
||||||
priv->window = event->any.window;
|
priv->window = widget_window;
|
||||||
priv->device = device;
|
priv->device = device;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,10 +329,6 @@ gtk_gesture_handle_event (GtkEventController *controller,
|
|||||||
priv->last_sequence = sequence;
|
priv->last_sequence = sequence;
|
||||||
was_recognized = gtk_gesture_is_recognized (gesture);
|
was_recognized = gtk_gesture_is_recognized (gesture);
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (event->any.window != priv->window)
|
|
||||||
return FALSE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (event->type)
|
switch (event->type)
|
||||||
{
|
{
|
||||||
@ -362,6 +402,13 @@ gtk_gesture_class_init (GtkGestureClass *klass)
|
|||||||
1, G_MAXUINT, 1,
|
1, G_MAXUINT, 1,
|
||||||
GTK_PARAM_READWRITE |
|
GTK_PARAM_READWRITE |
|
||||||
G_PARAM_CONSTRUCT_ONLY));
|
G_PARAM_CONSTRUCT_ONLY));
|
||||||
|
g_object_class_install_property (object_class,
|
||||||
|
PROP_WINDOW,
|
||||||
|
g_param_spec_boolean ("window",
|
||||||
|
P_("GdkWindow to receive events about"),
|
||||||
|
P_("GdkWindow to receive events about"),
|
||||||
|
TRUE,
|
||||||
|
GTK_PARAM_READWRITE));
|
||||||
|
|
||||||
signals[CHECK] =
|
signals[CHECK] =
|
||||||
g_signal_new ("check",
|
g_signal_new ("check",
|
||||||
@ -936,6 +983,68 @@ gtk_gesture_cancel_sequence (GtkGesture *gesture,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_gesture_get_window:
|
||||||
|
* @gesture: a #GtkGesture
|
||||||
|
*
|
||||||
|
* Returns the user-defined window that receives the events
|
||||||
|
* handled by @gesture. See gtk_gesture_set_window() for more
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* Returns: the user defined window, or %NULL if none.
|
||||||
|
*
|
||||||
|
* Since: 3.14
|
||||||
|
**/
|
||||||
|
GdkWindow *
|
||||||
|
gtk_gesture_get_window (GtkGesture *gesture)
|
||||||
|
{
|
||||||
|
GtkGesturePrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GTK_IS_GESTURE (gesture), NULL);
|
||||||
|
|
||||||
|
priv = gtk_gesture_get_instance_private (gesture);
|
||||||
|
|
||||||
|
return priv->user_window;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gtk_gesture_set_window:
|
||||||
|
* @gesture: a #GtkGesture
|
||||||
|
* @window: (allow-none): a #GdkWindow, or %NULL
|
||||||
|
*
|
||||||
|
* Sets a specific window to receive events about, so @gesture
|
||||||
|
* will effectively handle only events targeting @window, or
|
||||||
|
* a child of it. @window must pertain to gtk_event_controller_get_widget().
|
||||||
|
*
|
||||||
|
* Since: 3.14
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
gtk_gesture_set_window (GtkGesture *gesture,
|
||||||
|
GdkWindow *window)
|
||||||
|
{
|
||||||
|
GtkGesturePrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (GTK_IS_GESTURE (gesture));
|
||||||
|
g_return_if_fail (!window || GDK_IS_WINDOW (window));
|
||||||
|
|
||||||
|
priv = gtk_gesture_get_instance_private (gesture);
|
||||||
|
|
||||||
|
if (window)
|
||||||
|
{
|
||||||
|
GtkWidget *window_widget;
|
||||||
|
|
||||||
|
gdk_window_get_user_data (window, (gpointer*) &window_widget);
|
||||||
|
g_return_if_fail (window_widget !=
|
||||||
|
gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->user_window == window)
|
||||||
|
return;
|
||||||
|
|
||||||
|
priv->user_window = window;
|
||||||
|
g_object_notify (G_OBJECT (gesture), "window");
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
_gtk_gesture_handled_sequence_press (GtkGesture *gesture,
|
_gtk_gesture_handled_sequence_press (GtkGesture *gesture,
|
||||||
GdkEventSequence *sequence)
|
GdkEventSequence *sequence)
|
||||||
|
@ -126,6 +126,13 @@ gboolean gtk_gesture_is_recognized (GtkGesture *gesture);
|
|||||||
GDK_AVAILABLE_IN_3_14
|
GDK_AVAILABLE_IN_3_14
|
||||||
gboolean gtk_gesture_check (GtkGesture *gesture);
|
gboolean gtk_gesture_check (GtkGesture *gesture);
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_3_14
|
||||||
|
GdkWindow * gtk_gesture_get_window (GtkGesture *gesture);
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_3_14
|
||||||
|
void gtk_gesture_set_window (GtkGesture *gesture,
|
||||||
|
GdkWindow *window);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GTK_GESTURE_H__ */
|
#endif /* __GTK_GESTURE_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user