Merge branch 'wip/carlosg/event-final-cleanup' into 'master'

Wip/carlosg/event final cleanup

See merge request GNOME/gtk!279
This commit is contained in:
Carlos Garnacho 2018-07-30 11:25:24 +00:00
commit efa42a6932
21 changed files with 591 additions and 1127 deletions

View File

@ -87,14 +87,14 @@ find_toplevel_at_pointer (GdkDisplay *display)
return widget ? gtk_widget_get_toplevel (widget) : NULL;
}
static gboolean
release_event_cb (GtkWidget *widget,
GdkEvent *event,
gboolean *clicked)
static void
released_cb (GtkGestureMultiPress *gesture,
guint n_press,
gdouble x,
gdouble y,
gboolean *clicked)
{
if (gdk_event_get_event_type (event) == GDK_BUTTON_RELEASE)
*clicked = TRUE;
return TRUE;
*clicked = TRUE;
}
/* Asks the user to click on a window, then waits for them click
@ -132,10 +132,12 @@ query_for_toplevel (GdkDisplay *display,
GDK_SEAT_CAPABILITY_ALL_POINTING,
FALSE, cursor, NULL, NULL, NULL) == GDK_GRAB_SUCCESS)
{
GtkGesture *gesture = gtk_gesture_multi_press_new ();
gboolean clicked = FALSE;
g_signal_connect (popup, "event",
G_CALLBACK (release_event_cb), &clicked);
g_signal_connect (gesture, "released",
G_CALLBACK (released_cb), &clicked);
gtk_widget_add_controller (popup, GTK_EVENT_CONTROLLER (gesture));
/* Process events until clicked is set by our button release event handler.
* We pass in may_block=TRUE since we want to wait if there
@ -144,6 +146,8 @@ query_for_toplevel (GdkDisplay *display,
while (!clicked)
g_main_context_iteration (NULL, TRUE);
gdk_seat_ungrab (gdk_device_get_seat (device));
toplevel = find_toplevel_at_pointer (display);
if (toplevel == popup)
toplevel = NULL;

View File

@ -161,7 +161,6 @@
<file>editable_cells.c</file>
<file>entry_buffer.c</file>
<file>entry_completion.c</file>
<file>event_axes.c</file>
<file>expander.c</file>
<file>filtermodel.c</file>
<file>fishbowl.c</file>

View File

@ -1,666 +0,0 @@
/* Touch and Drawing Tablets
*
* Demonstrates advanced handling of event information from exotic
* input devices.
*
* On one hand, this snippet demonstrates management of drawing tablets,
* those contain additional information for the pointer other than
* X/Y coordinates. Tablet pads events are mapped to actions, which
* are both defined and interpreted by the application.
*
* Input axes are dependent on hardware devices, on linux/unix you
* can see the device axes through xinput list <device>. Each time
* a different hardware device is used to move the pointer, the
* master device will be updated to match the axes it provides,
* these changes can be tracked through GdkDevice::changed, or
* checking gdk_event_get_source_device().
*
* On the other hand, this demo handles basic multitouch events,
* each event coming from an specific touchpoint will contain a
* GdkEventSequence that's unique for its lifetime, so multiple
* touchpoints can be tracked.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
typedef struct {
GdkDevice *last_source;
GdkDeviceTool *last_tool;
gdouble *axes;
GdkRGBA color;
gdouble x;
gdouble y;
} AxesInfo;
typedef struct {
GHashTable *pointer_info; /* GdkDevice -> AxesInfo */
GHashTable *touch_info; /* GdkEventSequence -> AxesInfo */
} EventData;
const gchar *colors[] = {
"black",
"orchid",
"fuchsia",
"indigo",
"thistle",
"sienna",
"azure",
"plum",
"lime",
"navy",
"maroon",
"burlywood"
};
static GtkPadActionEntry pad_actions[] = {
{ GTK_PAD_ACTION_BUTTON, 1, -1, N_("Nuclear strike"), "pad.nuke" },
{ GTK_PAD_ACTION_BUTTON, 2, -1, N_("Release siberian methane reserves"), "pad.heat" },
{ GTK_PAD_ACTION_BUTTON, 3, -1, N_("Release solar flare"), "pad.fry" },
{ GTK_PAD_ACTION_BUTTON, 4, -1, N_("De-stabilize Oort cloud"), "pad.fall" },
{ GTK_PAD_ACTION_BUTTON, 5, -1, N_("Ignite WR-104"), "pad.burst" },
{ GTK_PAD_ACTION_BUTTON, 6, -1, N_("Lart whoever asks about this button"), "pad.lart" },
{ GTK_PAD_ACTION_RING, -1, -1, N_("Earth axial tilt"), "pad.tilt" },
{ GTK_PAD_ACTION_STRIP, -1, -1, N_("Extent of weak nuclear force"), "pad.dissolve" },
};
static const gchar *pad_action_results[] = {
"",
"",
"",
"",
"",
"💫",
"",
""
};
static guint cur_color = 0;
static guint pad_action_timeout_id = 0;
static AxesInfo *
axes_info_new (void)
{
AxesInfo *info;
info = g_new0 (AxesInfo, 1);
gdk_rgba_parse (&info->color, colors[cur_color]);
cur_color = (cur_color + 1) % G_N_ELEMENTS (colors);
return info;
}
static EventData *
event_data_new (void)
{
EventData *data;
data = g_new0 (EventData, 1);
data->pointer_info = g_hash_table_new_full (NULL, NULL, NULL,
(GDestroyNotify) g_free);
data->touch_info = g_hash_table_new_full (NULL, NULL, NULL,
(GDestroyNotify) g_free);
return data;
}
static void
event_data_free (EventData *data)
{
g_hash_table_destroy (data->pointer_info);
g_hash_table_destroy (data->touch_info);
g_free (data);
}
static void
update_axes_from_event (GdkEvent *event,
EventData *data)
{
GdkDevice *device, *source_device;
GdkEventSequence *sequence;
GdkDeviceTool *tool;
GdkEventType type;
gdouble x, y;
AxesInfo *info;
device = gdk_event_get_device (event);
source_device = gdk_event_get_source_device (event);
sequence = gdk_event_get_event_sequence (event);
tool = gdk_event_get_device_tool (event);
type = gdk_event_get_event_type (event);
if (type == GDK_TOUCH_END ||
type == GDK_TOUCH_CANCEL)
{
g_hash_table_remove (data->touch_info, sequence);
return;
}
else if (type == GDK_LEAVE_NOTIFY)
{
g_hash_table_remove (data->pointer_info, device);
return;
}
if (!source_device)
return;
if (!sequence)
{
info = g_hash_table_lookup (data->pointer_info, device);
if (!info)
{
info = axes_info_new ();
g_hash_table_insert (data->pointer_info, device, info);
}
}
else
{
info = g_hash_table_lookup (data->touch_info, sequence);
if (!info)
{
info = axes_info_new ();
g_hash_table_insert (data->touch_info, sequence, info);
}
}
if (info->last_source != source_device)
info->last_source = source_device;
if (info->last_tool != tool)
info->last_tool = tool;
g_clear_pointer (&info->axes, g_free);
if (type == GDK_TOUCH_BEGIN ||
type == GDK_TOUCH_UPDATE)
{
gboolean emulating_pointer;
gdk_event_get_touch_emulating_pointer (event, &emulating_pointer);
if (sequence && emulating_pointer)
g_hash_table_remove (data->pointer_info, device);
}
if (type == GDK_MOTION_NOTIFY ||
type == GDK_BUTTON_PRESS ||
type == GDK_BUTTON_RELEASE)
{
gdouble *axes;
guint n_axes;
gdk_event_get_axes (event, &axes, &n_axes);
info->axes = g_memdup (axes, sizeof (double) * n_axes);
}
if (gdk_event_get_coords (event, &x, &y))
{
info->x = x;
info->y = y;
}
}
static gboolean
event_cb (GtkWidget *widget,
GdkEvent *event,
gpointer user_data)
{
update_axes_from_event (event, user_data);
gtk_widget_queue_draw (widget);
return FALSE;
}
static void
render_arrow (cairo_t *cr,
gdouble x_diff,
gdouble y_diff,
const gchar *label)
{
cairo_save (cr);
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_new_path (cr);
cairo_move_to (cr, 0, 0);
cairo_line_to (cr, x_diff, y_diff);
cairo_stroke (cr);
cairo_move_to (cr, x_diff, y_diff);
cairo_show_text (cr, label);
cairo_restore (cr);
}
static void
draw_axes_info (cairo_t *cr,
AxesInfo *info,
int width,
int height)
{
gdouble pressure, tilt_x, tilt_y, distance, wheel, rotation, slider;
GdkAxisFlags axes = gdk_device_get_axes (info->last_source);
cairo_save (cr);
cairo_set_line_width (cr, 1);
gdk_cairo_set_source_rgba (cr, &info->color);
cairo_move_to (cr, 0, info->y);
cairo_line_to (cr, width, info->y);
cairo_move_to (cr, info->x, 0);
cairo_line_to (cr, info->x, height);
cairo_stroke (cr);
cairo_translate (cr, info->x, info->y);
if (!info->axes)
{
cairo_restore (cr);
return;
}
if (axes & GDK_AXIS_FLAG_PRESSURE)
{
cairo_pattern_t *pattern;
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_PRESSURE,
&pressure);
pattern = cairo_pattern_create_radial (0, 0, 0, 0, 0, 100);
cairo_pattern_add_color_stop_rgba (pattern, pressure, 1, 0, 0, pressure);
cairo_pattern_add_color_stop_rgba (pattern, 1, 0, 0, 1, 0);
cairo_set_source (cr, pattern);
cairo_arc (cr, 0, 0, 100, 0, 2 * G_PI);
cairo_fill (cr);
cairo_pattern_destroy (pattern);
}
if (axes & GDK_AXIS_FLAG_XTILT &&
axes & GDK_AXIS_FLAG_YTILT)
{
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_XTILT,
&tilt_x);
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_YTILT,
&tilt_y);
render_arrow (cr, tilt_x * 100, tilt_y * 100, "Tilt");
}
if (axes & GDK_AXIS_FLAG_DISTANCE)
{
double dashes[] = { 5.0, 5.0 };
cairo_text_extents_t extents;
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_DISTANCE,
&distance);
cairo_save (cr);
cairo_move_to (cr, distance * 100, 0);
cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
cairo_set_dash (cr, dashes, 2, 0.0);
cairo_arc (cr, 0, 0, distance * 100, 0, 2 * G_PI);
cairo_stroke (cr);
cairo_move_to (cr, 0, -distance * 100);
cairo_text_extents (cr, "Distance", &extents);
cairo_rel_move_to (cr, -extents.width / 2, 0);
cairo_show_text (cr, "Distance");
cairo_move_to (cr, 0, 0);
cairo_restore (cr);
}
if (axes & GDK_AXIS_FLAG_WHEEL)
{
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_WHEEL,
&wheel);
cairo_save (cr);
cairo_set_line_width (cr, 10);
cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
cairo_new_sub_path (cr);
cairo_arc (cr, 0, 0, 100, 0, wheel * 2 * G_PI);
cairo_stroke (cr);
cairo_restore (cr);
}
if (axes & GDK_AXIS_FLAG_ROTATION)
{
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_ROTATION,
&rotation);
rotation *= 2 * G_PI;
cairo_save (cr);
cairo_rotate (cr, - G_PI / 2);
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
cairo_set_line_width (cr, 5);
cairo_new_sub_path (cr);
cairo_arc (cr, 0, 0, 100, 0, rotation);
cairo_stroke (cr);
cairo_restore (cr);
}
if (axes & GDK_AXIS_FLAG_SLIDER)
{
cairo_pattern_t *pattern, *mask;
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_SLIDER,
&slider);
cairo_save (cr);
cairo_move_to (cr, 0, -10);
cairo_rel_line_to (cr, 0, -50);
cairo_rel_line_to (cr, 10, 0);
cairo_rel_line_to (cr, -5, 50);
cairo_close_path (cr);
cairo_clip_preserve (cr);
pattern = cairo_pattern_create_linear (0, -10, 0, -60);
cairo_pattern_add_color_stop_rgb (pattern, 0, 0, 1, 0);
cairo_pattern_add_color_stop_rgb (pattern, 1, 1, 0, 0);
cairo_set_source (cr, pattern);
cairo_pattern_destroy (pattern);
mask = cairo_pattern_create_linear (0, -10, 0, -60);
cairo_pattern_add_color_stop_rgba (mask, 0, 0, 0, 0, 1);
cairo_pattern_add_color_stop_rgba (mask, slider, 0, 0, 0, 1);
cairo_pattern_add_color_stop_rgba (mask, slider, 0, 0, 0, 0);
cairo_pattern_add_color_stop_rgba (mask, 1, 0, 0, 0, 0);
cairo_mask (cr, mask);
cairo_pattern_destroy (mask);
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_stroke (cr);
cairo_restore (cr);
}
cairo_restore (cr);
}
static const gchar *
tool_type_to_string (GdkDeviceToolType tool_type)
{
switch (tool_type)
{
case GDK_DEVICE_TOOL_TYPE_PEN:
return "Pen";
case GDK_DEVICE_TOOL_TYPE_ERASER:
return "Eraser";
case GDK_DEVICE_TOOL_TYPE_BRUSH:
return "Brush";
case GDK_DEVICE_TOOL_TYPE_PENCIL:
return "Pencil";
case GDK_DEVICE_TOOL_TYPE_AIRBRUSH:
return "Airbrush";
case GDK_DEVICE_TOOL_TYPE_MOUSE:
return "Mouse";
case GDK_DEVICE_TOOL_TYPE_LENS:
return "Lens cursor";
case GDK_DEVICE_TOOL_TYPE_UNKNOWN:
default:
return "Unknown";
}
}
static void
draw_device_info (GtkWidget *widget,
cairo_t *cr,
GdkEventSequence *sequence,
gint *y,
AxesInfo *info)
{
PangoLayout *layout;
GString *string;
gint height;
cairo_save (cr);
string = g_string_new (NULL);
g_string_append_printf (string, "Source: %s",
gdk_device_get_name (info->last_source));
if (sequence)
g_string_append_printf (string, "\nSequence: %d",
GPOINTER_TO_UINT (sequence));
if (info->last_tool)
{
const gchar *tool_type;
guint64 serial;
tool_type = tool_type_to_string (gdk_device_tool_get_tool_type (info->last_tool));
serial = gdk_device_tool_get_serial (info->last_tool);
g_string_append_printf (string, "\nTool: %s", tool_type);
if (serial != 0)
g_string_append_printf (string, ", Serial: %" G_GINT64_MODIFIER "x", serial);
}
cairo_move_to (cr, 10, *y);
layout = gtk_widget_create_pango_layout (widget, string->str);
pango_cairo_show_layout (cr, layout);
cairo_stroke (cr);
pango_layout_get_pixel_size (layout, NULL, &height);
gdk_cairo_set_source_rgba (cr, &info->color);
cairo_set_line_width (cr, 10);
cairo_move_to (cr, 0, *y);
*y = *y + height;
cairo_line_to (cr, 0, *y);
cairo_stroke (cr);
cairo_restore (cr);
g_object_unref (layout);
g_string_free (string, TRUE);
}
static void
draw_cb (GtkDrawingArea *da,
cairo_t *cr,
int width,
int height,
gpointer user_data)
{
GtkWidget *widget = GTK_WIDGET (da);
EventData *data = user_data;
AxesInfo *info;
GHashTableIter iter;
gpointer key, value;
gint y = 0;
/* Draw Abs info */
g_hash_table_iter_init (&iter, data->pointer_info);
while (g_hash_table_iter_next (&iter, NULL, &value))
{
info = value;
draw_axes_info (cr, info, width, height);
}
g_hash_table_iter_init (&iter, data->touch_info);
while (g_hash_table_iter_next (&iter, NULL, &value))
{
info = value;
draw_axes_info (cr, info, width, height);
}
/* Draw name, color legend and misc data */
g_hash_table_iter_init (&iter, data->pointer_info);
while (g_hash_table_iter_next (&iter, NULL, &value))
{
info = value;
draw_device_info (widget, cr, NULL, &y, info);
}
g_hash_table_iter_init (&iter, data->touch_info);
while (g_hash_table_iter_next (&iter, &key, &value))
{
info = value;
draw_device_info (widget, cr, key, &y, info);
}
}
static void
update_label_text (GtkWidget *label,
const gchar *text)
{
gchar *markup = NULL;
if (text)
markup = g_strdup_printf ("<span font='48.0'>%s</span>", text);
gtk_label_set_markup (GTK_LABEL (label), markup);
g_free (markup);
}
static gboolean
reset_label_text_timeout_cb (gpointer user_data)
{
GtkWidget *label = user_data;
update_label_text (label, NULL);
pad_action_timeout_id = 0;
return G_SOURCE_REMOVE;
}
static void
update_label_and_timeout (GtkWidget *label,
const gchar *text)
{
if (pad_action_timeout_id)
g_source_remove (pad_action_timeout_id);
update_label_text (label, text);
pad_action_timeout_id = g_timeout_add (200, reset_label_text_timeout_cb, label);
}
static void
on_action_activate (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GtkWidget *label = user_data;
const gchar *result;
gchar *str;
result = g_object_get_data (G_OBJECT (action), "action-result");
if (!parameter)
update_label_and_timeout (label, result);
else
{
str = g_strdup_printf ("%s %.2f", result, g_variant_get_double (parameter));
update_label_and_timeout (label, str);
g_free (str);
}
}
static void
init_pad_controller (GtkWidget *window,
GtkWidget *label)
{
GtkPadController *pad_controller;
GSimpleActionGroup *action_group;
GSimpleAction *action;
gint i;
action_group = g_simple_action_group_new ();
pad_controller = gtk_pad_controller_new (G_ACTION_GROUP (action_group),
NULL);
for (i = 0; i < G_N_ELEMENTS (pad_actions); i++)
{
if (pad_actions[i].type == GTK_PAD_ACTION_BUTTON)
{
action = g_simple_action_new (pad_actions[i].action_name, NULL);
}
else
{
action = g_simple_action_new_stateful (pad_actions[i].action_name,
G_VARIANT_TYPE_DOUBLE, NULL);
}
g_signal_connect (action, "activate",
G_CALLBACK (on_action_activate), label);
g_object_set_data (G_OBJECT (action), "action-result",
(gpointer) pad_action_results[i]);
g_action_map_add_action (G_ACTION_MAP (action_group), G_ACTION (action));
g_object_unref (action);
}
gtk_pad_controller_set_action_entries (pad_controller, pad_actions,
G_N_ELEMENTS (pad_actions));
gtk_widget_add_controller (window, GTK_EVENT_CONTROLLER (pad_controller));
g_object_unref (action_group);
}
GtkWidget *
do_event_axes (GtkWidget *toplevel)
{
static GtkWidget *window = NULL;
EventData *event_data;
GtkWidget *label;
GtkWidget *overlay;
GtkWidget *da;
if (!window)
{
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Touch and Drawing Tablets");
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
gtk_widget_set_support_multidevice (window, TRUE);
event_data = event_data_new ();
g_object_set_data_full (G_OBJECT (window), "gtk-demo-event-data",
event_data, (GDestroyNotify) event_data_free);
da = gtk_drawing_area_new ();
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 400);
gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (da), 400);
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), draw_cb, event_data, NULL);
gtk_widget_set_can_focus (da, TRUE);
gtk_widget_grab_focus (da);
g_signal_connect (da, "event",
G_CALLBACK (event_cb), event_data);
label = gtk_label_new ("");
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_valign (label, GTK_ALIGN_START);
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
overlay = gtk_overlay_new ();
gtk_container_add (GTK_CONTAINER (window), overlay);
gtk_container_add (GTK_CONTAINER (overlay), da);
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), label);
init_pad_controller (da, label);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
return window;
}

View File

@ -135,55 +135,42 @@ static void set_cursor_if_appropriate (GtkTextView *text_view,
gint x,
gint y);
/* Links can also be activated by clicking or tapping.
*/
static gboolean
event_cb (GtkWidget *text_view,
GdkEvent *ev)
static void
released_cb (GtkGestureMultiPress *gesture,
guint n_press,
gdouble x,
gdouble y,
GtkWidget *text_view)
{
GtkTextIter start, end, iter;
GtkTextBuffer *buffer;
gdouble ex, ey;
int x, y;
GdkEventType type;
int tx, ty;
type = gdk_event_get_event_type (ev);
if (gtk_gesture_single_get_button (GTK_GESTURE_SINGLE (gesture)) > 1)
return;
gdk_event_get_coords (ev, &ex, &ey);
gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
GTK_TEXT_WINDOW_WIDGET,
ex, ey, &x, &y);
if (type == GDK_BUTTON_RELEASE)
{
guint button;
gdk_event_get_button (ev, &button);
if (button != GDK_BUTTON_PRIMARY)
return FALSE;
}
else if (type == GDK_MOTION_NOTIFY)
{
set_cursor_if_appropriate (GTK_TEXT_VIEW (text_view), x, y);
return FALSE;
}
else if (type == GDK_TOUCH_END)
{
}
else
return FALSE;
x, y, &tx, &ty);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
/* we shouldn't follow a link if the user has selected something */
gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end))
return FALSE;
return;
if (gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (text_view), &iter, x, y))
follow_if_link (text_view, &iter);
}
return TRUE;
static void
motion_cb (GtkEventControllerMotion *controller,
gdouble x,
gdouble y,
GtkTextView *text_view)
{
set_cursor_if_appropriate (text_view, x, y);
}
static gboolean hovering_over_link = FALSE;
@ -259,8 +246,16 @@ do_hypertext (GtkWidget *do_widget)
controller = gtk_event_controller_key_new ();
g_signal_connect (controller, "key-pressed", G_CALLBACK (key_pressed), view);
gtk_widget_add_controller (view, controller);
g_signal_connect (view, "event",
G_CALLBACK (event_cb), NULL);
controller = GTK_EVENT_CONTROLLER (gtk_gesture_multi_press_new ());
g_signal_connect (controller, "released",
G_CALLBACK (released_cb), view);
gtk_widget_add_controller (view, controller);
controller = gtk_event_controller_motion_new ();
g_signal_connect (controller, "motion",
G_CALLBACK (motion_cb), view);
gtk_widget_add_controller (view, controller);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));

View File

@ -22,7 +22,6 @@ demos = files([
'editable_cells.c',
'entry_buffer.c',
'entry_completion.c',
'event_axes.c',
'expander.c',
'filtermodel.c',
'fishbowl.c',

View File

@ -3,14 +3,24 @@
* Demonstrates practical handling of drawing tablets in a real world
* usecase.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
enum {
COLOR_SET,
N_SIGNALS
};
static guint area_signals[N_SIGNALS] = { 0, };
typedef struct
{
GtkWidget parent_instance;
cairo_surface_t *surface;
cairo_t *cr;
GdkRGBA draw_color;
GtkPadController *pad_controller;
gdouble brush_size;
} DrawingArea;
typedef struct
@ -18,8 +28,30 @@ typedef struct
GtkWidgetClass parent_class;
} DrawingAreaClass;
static GtkPadActionEntry pad_actions[] = {
{ GTK_PAD_ACTION_BUTTON, 1, -1, N_("Black"), "pad.black" },
{ GTK_PAD_ACTION_BUTTON, 2, -1, N_("Pink"), "pad.pink" },
{ GTK_PAD_ACTION_BUTTON, 3, -1, N_("Green"), "pad.green" },
{ GTK_PAD_ACTION_BUTTON, 4, -1, N_("Red"), "pad.red" },
{ GTK_PAD_ACTION_BUTTON, 5, -1, N_("Purple"), "pad.purple" },
{ GTK_PAD_ACTION_BUTTON, 6, -1, N_("Orange"), "pad.orange" },
{ GTK_PAD_ACTION_STRIP, -1, -1, N_("Brush size"), "pad.brush_size" },
};
static const gchar *pad_colors[] = {
"black",
"pink",
"green",
"red",
"purple",
"orange"
};
G_DEFINE_TYPE (DrawingArea, drawing_area, GTK_TYPE_WIDGET)
static void drawing_area_set_color (DrawingArea *area,
GdkRGBA *color);
static void
drawing_area_ensure_surface (DrawingArea *area,
gint width,
@ -115,6 +147,82 @@ drawing_area_snapshot (GtkWidget *widget,
cairo_destroy (cr);
}
static void
on_pad_button_activate (GSimpleAction *action,
GVariant *parameter,
DrawingArea *area)
{
const gchar *color = g_object_get_data (G_OBJECT (action), "color");
GdkRGBA rgba;
gdk_rgba_parse (&rgba, color);
drawing_area_set_color (area, &rgba);
}
static void
on_pad_knob_change (GSimpleAction *action,
GVariant *parameter,
DrawingArea *area)
{
gdouble value = g_variant_get_double (parameter);
area->brush_size = value;
}
static void
drawing_area_hierarchy_changed (GtkWidget *widget,
GtkWidget *previous_toplevel)
{
DrawingArea *area = (DrawingArea *) widget;
GSimpleActionGroup *action_group;
GSimpleAction *action;
GtkWidget *toplevel;
gint i;
if (previous_toplevel && area->pad_controller)
{
gtk_widget_remove_controller (previous_toplevel,
GTK_EVENT_CONTROLLER (area->pad_controller));
area->pad_controller = NULL;
}
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (area));
if (!GTK_IS_WINDOW (toplevel))
return;
action_group = g_simple_action_group_new ();
area->pad_controller = gtk_pad_controller_new (G_ACTION_GROUP (action_group),
NULL);
for (i = 0; i < G_N_ELEMENTS (pad_actions); i++)
{
if (pad_actions[i].type == GTK_PAD_ACTION_BUTTON)
{
action = g_simple_action_new (pad_actions[i].action_name, NULL);
g_object_set_data (G_OBJECT (action), "color",
(gpointer) pad_colors[i]);
g_signal_connect (action, "activate",
G_CALLBACK (on_pad_button_activate), area);
}
else
{
action = g_simple_action_new_stateful (pad_actions[i].action_name,
G_VARIANT_TYPE_DOUBLE, NULL);
g_signal_connect (action, "activate",
G_CALLBACK (on_pad_knob_change), area);
}
g_action_map_add_action (G_ACTION_MAP (action_group), G_ACTION (action));
g_object_unref (action);
}
gtk_pad_controller_set_action_entries (area->pad_controller, pad_actions,
G_N_ELEMENTS (pad_actions));
gtk_widget_add_controller (toplevel,
GTK_EVENT_CONTROLLER (area->pad_controller));
}
static void
drawing_area_class_init (DrawingAreaClass *klass)
{
@ -124,6 +232,14 @@ drawing_area_class_init (DrawingAreaClass *klass)
widget_class->snapshot = drawing_area_snapshot;
widget_class->map = drawing_area_map;
widget_class->unmap = drawing_area_unmap;
widget_class->hierarchy_changed = drawing_area_hierarchy_changed;
area_signals[COLOR_SET] =
g_signal_new ("color-set",
G_TYPE_FROM_CLASS (widget_class),
G_SIGNAL_RUN_FIRST,
0, NULL, NULL, NULL,
G_TYPE_NONE, 1, GDK_TYPE_RGBA);
}
static void
@ -135,12 +251,12 @@ drawing_area_apply_stroke (DrawingArea *area,
{
if (gdk_device_tool_get_tool_type (tool) == GDK_DEVICE_TOOL_TYPE_ERASER)
{
cairo_set_line_width (area->cr, 10 * pressure);
cairo_set_line_width (area->cr, 10 * pressure * area->brush_size);
cairo_set_operator (area->cr, CAIRO_OPERATOR_DEST_OUT);
}
else
{
cairo_set_line_width (area->cr, 4 * pressure);
cairo_set_line_width (area->cr, 4 * pressure * area->brush_size);
cairo_set_operator (area->cr, CAIRO_OPERATOR_SATURATE);
}
@ -148,8 +264,6 @@ drawing_area_apply_stroke (DrawingArea *area,
area->draw_color.green, area->draw_color.blue,
area->draw_color.alpha * pressure);
//cairo_set_source_rgba (area->cr, 0, 0, 0, pressure);
cairo_line_to (area->cr, x, y);
cairo_stroke (area->cr);
cairo_move_to (area->cr, x, y);
@ -225,11 +339,15 @@ drawing_area_new (void)
return g_object_new (drawing_area_get_type (), NULL);
}
void
static void
drawing_area_set_color (DrawingArea *area,
GdkRGBA *color)
{
if (gdk_rgba_equal (&area->draw_color, color))
return;
area->draw_color = *color;
g_signal_emit (area, area_signals[COLOR_SET], 0, &area->draw_color);
}
static void
@ -242,6 +360,14 @@ color_button_color_set (GtkColorButton *button,
drawing_area_set_color (draw_area, &color);
}
static void
drawing_area_color_set (DrawingArea *area,
GdkRGBA *color,
GtkColorButton *button)
{
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (button), color);
}
GtkWidget *
do_paint (GtkWidget *toplevel)
{
@ -263,6 +389,8 @@ do_paint (GtkWidget *toplevel)
colorbutton = gtk_color_button_new ();
g_signal_connect (colorbutton, "color-set",
G_CALLBACK (color_button_color_set), draw_area);
g_signal_connect (draw_area, "color-set",
G_CALLBACK (drawing_area_color_set), colorbutton);
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (colorbutton),
&(GdkRGBA) { 0, 0, 0, 1 });

View File

@ -26,17 +26,6 @@ changed_cb (GtkEditable *editable)
g_message ("changed: %s", text);
}
static gboolean
window_event_cb (GtkWidget *widget,
GdkEvent *event,
GtkSearchBar *bar)
{
if (gdk_event_get_event_type (event) == GDK_KEY_PRESS)
return gtk_search_bar_handle_event (bar, event);
return GDK_EVENT_PROPAGATE;
}
static void
search_changed (GtkSearchEntry *entry,
GtkLabel *label)
@ -102,7 +91,7 @@ do_search_entry2 (GtkWidget *do_widget)
gtk_box_pack_start (GTK_BOX (vbox), searchbar);
/* Hook the search bar to key presses */
g_signal_connect (window, "event", G_CALLBACK (window_event_cb), searchbar);
gtk_search_bar_set_key_capture_widget (GTK_SEARCH_BAR (searchbar), window);
/* Help */
label = gtk_label_new ("Start Typing to search");

View File

@ -39,6 +39,7 @@
#include "gtktogglebutton.h"
#include "gtktreemenu.h"
#include "gtktypebuiltins.h"
#include "gtkeventcontrollerkey.h"
#include "a11y/gtkcomboboxaccessible.h"
@ -275,9 +276,11 @@ static void gtk_combo_box_menu_activate (GtkWidget *menu,
const gchar *path,
GtkComboBox *combo_box);
static void gtk_combo_box_update_sensitivity (GtkComboBox *combo_box);
static gboolean gtk_combo_box_menu_event (GtkWidget *widget,
GdkEvent *event,
gpointer data);
static gboolean gtk_combo_box_menu_key (GtkEventControllerKey *key,
guint keyval,
guint keycode,
GdkModifierType modifiers,
GtkComboBox *combo_box);
static void gtk_combo_box_menu_popup (GtkComboBox *combo_box);
/* cell layout */
@ -843,7 +846,7 @@ gtk_combo_box_class_init (GtkComboBoxClass *klass)
gtk_widget_class_bind_template_child_internal_private (widget_class, GtkComboBox, popup_widget);
gtk_widget_class_bind_template_callback (widget_class, gtk_combo_box_button_toggled);
gtk_widget_class_bind_template_callback (widget_class, gtk_combo_box_menu_activate);
gtk_widget_class_bind_template_callback (widget_class, gtk_combo_box_menu_event);
gtk_widget_class_bind_template_callback (widget_class, gtk_combo_box_menu_key);
gtk_widget_class_bind_template_callback (widget_class, gtk_combo_box_menu_show);
gtk_widget_class_bind_template_callback (widget_class, gtk_combo_box_menu_hide);
@ -1931,21 +1934,26 @@ gtk_combo_box_model_row_changed (GtkTreeModel *model,
}
static gboolean
gtk_combo_box_menu_event (GtkWidget *widget,
GdkEvent *event,
gpointer data)
gtk_combo_box_menu_key (GtkEventControllerKey *key,
guint keyval,
guint keycode,
GdkModifierType modifiers,
GtkComboBox *combo_box)
{
GtkComboBox *combo_box = GTK_COMBO_BOX (data);
GtkWidget *widget;
GdkEvent *event;
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (key));
event = gtk_get_current_event ();
if (!gtk_bindings_activate_event (G_OBJECT (widget), (GdkEventKey *)event))
{
/* The menu hasn't managed the
* event, forward it to the combobox
*/
return gtk_bindings_activate_event (G_OBJECT (combo_box), (GdkEventKey *)event);
gtk_event_controller_key_forward (key, GTK_WIDGET (combo_box));
}
return GDK_EVENT_PROPAGATE;
g_object_unref (event);
return TRUE;
}
/*
@ -2726,19 +2734,12 @@ gtk_combo_box_dispose (GObject* object)
}
static gboolean
gtk_cell_editable_event (GtkWidget *widget,
GdkEvent *event,
gpointer data)
gtk_cell_editable_key_pressed (GtkEventControllerKey *key,
guint keyval,
guint keycode,
GdkModifierType modifiers,
GtkComboBox *combo_box)
{
GtkComboBox *combo_box = GTK_COMBO_BOX (data);
guint keyval;
if (gdk_event_get_event_type (event) != GDK_KEY_PRESS)
return GDK_EVENT_PROPAGATE;
if (!gdk_event_get_keyval (event, &keyval))
return GDK_EVENT_PROPAGATE;
if (keyval == GDK_KEY_Escape)
{
g_object_set (combo_box,
@ -2768,25 +2769,25 @@ gtk_combo_box_start_editing (GtkCellEditable *cell_editable,
{
GtkComboBox *combo_box = GTK_COMBO_BOX (cell_editable);
GtkComboBoxPrivate *priv = gtk_combo_box_get_instance_private (combo_box);
GtkEventController *controller;
GtkWidget *child;
priv->is_cell_renderer = TRUE;
controller = gtk_event_controller_key_new ();
g_signal_connect_object (controller, "key-pressed",
G_CALLBACK (gtk_cell_editable_key_pressed),
cell_editable, 0);
if (priv->cell_view)
{
g_signal_connect_object (priv->button, "event",
G_CALLBACK (gtk_cell_editable_event),
cell_editable, 0);
gtk_widget_add_controller (priv->button, controller);
gtk_widget_grab_focus (priv->button);
}
else
{
child = gtk_bin_get_child (GTK_BIN (combo_box));
g_signal_connect_object (child, "event",
G_CALLBACK (gtk_cell_editable_event),
cell_editable, 0);
gtk_widget_add_controller (child, controller);
gtk_widget_grab_focus (child);
gtk_widget_set_can_focus (priv->button, FALSE);

View File

@ -4412,18 +4412,13 @@ gtk_cell_editable_entry_activated (GtkEntry *entry, gpointer data)
}
static gboolean
gtk_cell_editable_event (GtkEntry *entry,
GdkEvent *event,
gpointer data)
gtk_cell_editable_entry_key_pressed (GtkEventControllerKey *key,
guint keyval,
guint keycode,
GdkModifierType modifiers,
GtkEntry *entry)
{
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
guint keyval;
if (gdk_event_get_event_type (event) != GDK_KEY_PRESS)
return GDK_EVENT_PROPAGATE;
if (!gdk_event_get_keyval (event, &keyval))
return GDK_EVENT_PROPAGATE;
if (keyval == GDK_KEY_Escape)
{
@ -4452,8 +4447,10 @@ gtk_entry_start_editing (GtkCellEditable *cell_editable,
{
g_signal_connect (cell_editable, "activate",
G_CALLBACK (gtk_cell_editable_entry_activated), NULL);
g_signal_connect (cell_editable, "event",
G_CALLBACK (gtk_cell_editable_event), NULL);
g_signal_connect (gtk_entry_get_key_controller (GTK_ENTRY (cell_editable)),
"key-pressed",
G_CALLBACK (gtk_cell_editable_entry_key_pressed),
cell_editable);
}
static void

View File

@ -1052,17 +1052,16 @@ indicator_set_over (Indicator *indicator,
}
static gboolean
event_close_to_indicator (GtkScrolledWindow *sw,
Indicator *indicator,
GdkEvent *event)
coords_close_to_indicator (GtkScrolledWindow *sw,
Indicator *indicator,
gdouble x,
gdouble y)
{
GtkScrolledWindowPrivate *priv = gtk_scrolled_window_get_instance_private (sw);
graphene_rect_t indicator_bounds;
gdouble x, y;
gint distance;
gtk_widget_compute_bounds (indicator->scrollbar, GTK_WIDGET (sw), &indicator_bounds);
gdk_event_get_coords (event, &x, &y);
if (indicator->over)
distance = INDICATOR_FAR_DISTANCE;
@ -1099,25 +1098,18 @@ enable_over_timeout_cb (gpointer user_data)
static gboolean
check_update_scrollbar_proximity (GtkScrolledWindow *sw,
Indicator *indicator,
GdkEvent *event)
GtkWidget *target,
gdouble x,
gdouble y)
{
GtkScrolledWindowPrivate *priv = gtk_scrolled_window_get_instance_private (sw);
gboolean indicator_close, on_scrollbar, on_other_scrollbar;
GtkWidget *event_target;
GtkWidget *event_target_ancestor;
GdkEventType event_type;
event_target = gtk_get_event_target (event);
event_target_ancestor = gtk_widget_get_ancestor (event_target, GTK_TYPE_SCROLLBAR);
event_type = gdk_event_get_event_type (event);
indicator_close = event_close_to_indicator (sw, indicator, event);
on_scrollbar = (event_target_ancestor == indicator->scrollbar &&
event_type != GDK_LEAVE_NOTIFY);
indicator_close = coords_close_to_indicator (sw, indicator, x, y);
on_scrollbar = (target == indicator->scrollbar);
on_other_scrollbar = (!on_scrollbar &&
event_type != GDK_LEAVE_NOTIFY &&
(event_target_ancestor == priv->hindicator.scrollbar ||
event_target_ancestor == priv->vindicator.scrollbar));
(target == priv->hindicator.scrollbar ||
target == priv->vindicator.scrollbar));
if (indicator->over_timeout_id)
{
@ -1173,85 +1165,66 @@ captured_event_cb (GtkWidget *widget,
GdkEvent *event)
{
GtkScrolledWindow *sw = GTK_SCROLLED_WINDOW (widget);
GtkScrolledWindowPrivate *priv = gtk_scrolled_window_get_instance_private (sw);
GdkInputSource input_source;
GdkDevice *source_device;
GtkWidget *event_target;
GtkWidget *event_target_ancestor;
gboolean on_scrollbar;
GdkEventType event_type;
guint state;
GdkCrossingMode mode;
source_device = gdk_event_get_source_device (event);
event_type = gdk_event_get_event_type (event);
if (event_type == GDK_SCROLL)
{
gtk_scrolled_window_cancel_deceleration (sw);
return GDK_EVENT_PROPAGATE;
}
if (!priv->use_indicators)
return GDK_EVENT_PROPAGATE;
if (event_type != GDK_MOTION_NOTIFY &&
event_type != GDK_LEAVE_NOTIFY)
return GDK_EVENT_PROPAGATE;
input_source = gdk_device_get_source (source_device);
if (input_source == GDK_SOURCE_KEYBOARD ||
input_source == GDK_SOURCE_TOUCHSCREEN)
return GDK_EVENT_PROPAGATE;
event_target = gtk_get_event_target (event);
event_target_ancestor = gtk_widget_get_ancestor (event_target, GTK_TYPE_SCROLLBAR);
on_scrollbar = (event_target_ancestor == priv->hindicator.scrollbar ||
event_target_ancestor == priv->vindicator.scrollbar);
gdk_event_get_crossing_mode (event, &mode);
if (event_type == GDK_MOTION_NOTIFY)
{
if (priv->hscrollbar_visible)
indicator_start_fade (&priv->hindicator, 1.0);
if (priv->vscrollbar_visible)
indicator_start_fade (&priv->vindicator, 1.0);
gdk_event_get_state (event, &state);
if (!on_scrollbar &&
(state &
(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) != 0)
{
indicator_set_over (&priv->hindicator, FALSE);
indicator_set_over (&priv->vindicator, FALSE);
}
else if (input_source == GDK_SOURCE_PEN ||
input_source == GDK_SOURCE_ERASER ||
input_source == GDK_SOURCE_TRACKPOINT)
{
indicator_set_over (&priv->hindicator, TRUE);
indicator_set_over (&priv->vindicator, TRUE);
}
else
{
if (!check_update_scrollbar_proximity (sw, &priv->vindicator, event))
check_update_scrollbar_proximity (sw, &priv->hindicator, event);
else
indicator_set_over (&priv->hindicator, FALSE);
}
}
else if (event_type == GDK_LEAVE_NOTIFY && on_scrollbar &&
mode == GDK_CROSSING_UNGRAB)
{
check_update_scrollbar_proximity (sw, &priv->vindicator, event);
check_update_scrollbar_proximity (sw, &priv->hindicator, event);
}
if (gdk_event_get_event_type (event) == GDK_SCROLL)
gtk_scrolled_window_cancel_deceleration (sw);
return GDK_EVENT_PROPAGATE;
}
static void
captured_motion (GtkScrolledWindow *sw,
gdouble x,
gdouble y)
{
GtkScrolledWindowPrivate *priv = gtk_scrolled_window_get_instance_private (sw);
GdkDevice *source_device;
GdkInputSource input_source;
GdkModifierType state;
GdkEvent *event;
if (!priv->use_indicators)
return;
event = gtk_get_current_event ();
source_device = gdk_event_get_source_device (event);
input_source = gdk_device_get_source (source_device);
if (priv->hscrollbar_visible)
indicator_start_fade (&priv->hindicator, 1.0);
if (priv->vscrollbar_visible)
indicator_start_fade (&priv->vindicator, 1.0);
gdk_event_get_state (event, &state);
if (!gtk_get_event_target_with_type (event, GTK_TYPE_SCROLLBAR) &&
(state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) != 0)
{
indicator_set_over (&priv->hindicator, FALSE);
indicator_set_over (&priv->vindicator, FALSE);
}
else if (input_source == GDK_SOURCE_PEN ||
input_source == GDK_SOURCE_ERASER ||
input_source == GDK_SOURCE_TRACKPOINT)
{
indicator_set_over (&priv->hindicator, TRUE);
indicator_set_over (&priv->vindicator, TRUE);
}
else
{
GtkWidget *target;
target = gtk_get_event_target_with_type (event, GTK_TYPE_SCROLLBAR);
if (!check_update_scrollbar_proximity (sw, &priv->vindicator, target, x, y))
check_update_scrollbar_proximity (sw, &priv->hindicator, target, x, y);
else
indicator_set_over (&priv->hindicator, FALSE);
}
g_object_unref (event);
}
static gboolean
start_scroll_deceleration_cb (gpointer user_data)
{
@ -1978,6 +1951,12 @@ gtk_scrolled_window_init (GtkScrolledWindow *scrolled_window)
_gtk_widget_set_captured_event_handler (widget, captured_event_cb);
controller = gtk_event_controller_motion_new ();
gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_CAPTURE);
g_signal_connect_swapped (controller, "motion",
G_CALLBACK (captured_motion), scrolled_window);
gtk_widget_add_controller (widget, controller);
widget_node = gtk_widget_get_css_node (widget);
for (i = 0; i < 4; i++)
{

View File

@ -34,6 +34,7 @@
#include "gtkdragdest.h"
#include "gtkdragsource.h"
#include "gtkentryprivate.h"
#include "gtkeventcontrollerkey.h"
#include "gtkeventcontrollermotion.h"
#include "gtkeventcontrollerscroll.h"
#include "gtkframe.h"
@ -599,8 +600,19 @@ static void gtk_tree_view_snapshot (GtkWidget *widget,
static void gtk_tree_view_set_focus_child (GtkContainer *container,
GtkWidget *child);
static gboolean gtk_tree_view_event (GtkWidget *widget,
GdkEvent *event);
static gboolean gtk_tree_view_key_controller_key_pressed (GtkEventControllerKey *key,
guint keyval,
guint keycode,
GdkModifierType state,
GtkTreeView *tree_view);
static void gtk_tree_view_key_controller_key_released (GtkEventControllerKey *key,
guint keyval,
guint keycode,
GdkModifierType state,
GtkTreeView *tree_view);
static void gtk_tree_view_key_controller_focus_out (GtkEventControllerKey *key,
GtkTreeView *tree_view);
static gint gtk_tree_view_focus (GtkWidget *widget,
GtkDirectionType direction);
static void gtk_tree_view_grab_focus (GtkWidget *widget);
@ -803,9 +815,11 @@ static void gtk_tree_view_search_scroll_event (GtkWidget *entry
gdouble dx,
gdouble dy,
GtkTreeView *tree_view);
static gboolean gtk_tree_view_search_event (GtkWidget *entry,
GdkEvent *event,
GtkTreeView *tree_view);
static gboolean gtk_tree_view_search_key_pressed (GtkEventControllerKey *key,
guint keyval,
guint keycode,
GdkModifierType state,
GtkTreeView *tree_view);
static gboolean gtk_tree_view_search_move (GtkWidget *window,
GtkTreeView *tree_view,
gboolean up);
@ -960,7 +974,6 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
widget_class->measure = gtk_tree_view_measure;
widget_class->size_allocate = gtk_tree_view_size_allocate;
widget_class->snapshot = gtk_tree_view_snapshot;
widget_class->event = gtk_tree_view_event;
widget_class->drag_begin = gtk_tree_view_drag_begin;
widget_class->drag_end = gtk_tree_view_drag_end;
widget_class->drag_data_get = gtk_tree_view_drag_data_get;
@ -1744,6 +1757,15 @@ gtk_tree_view_init (GtkTreeView *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);
controller = gtk_event_controller_key_new ();
g_signal_connect (controller, "key-pressed",
G_CALLBACK (gtk_tree_view_key_controller_key_pressed), tree_view);
g_signal_connect (controller, "key-released",
G_CALLBACK (gtk_tree_view_key_controller_key_released), tree_view);
g_signal_connect (controller, "focus-out",
G_CALLBACK (gtk_tree_view_key_controller_focus_out), tree_view);
gtk_widget_add_controller (GTK_WIDGET (tree_view), controller);
}
@ -2086,8 +2108,8 @@ gtk_tree_view_destroy (GtkWidget *widget)
g_signal_handlers_disconnect_by_func (tree_view->priv->search_entry,
G_CALLBACK (gtk_tree_view_search_init),
tree_view);
g_signal_handlers_disconnect_by_func (tree_view->priv->search_entry,
G_CALLBACK (gtk_tree_view_search_event),
g_signal_handlers_disconnect_by_func (gtk_entry_get_key_controller (GTK_ENTRY (tree_view->priv->search_entry)),
G_CALLBACK (gtk_tree_view_search_key_pressed),
tree_view);
g_object_unref (tree_view->priv->search_entry);
@ -5169,16 +5191,15 @@ no_popup (void)
}
static gboolean
gtk_tree_view_key_press (GtkWidget *widget,
GdkEventKey *event)
gtk_tree_view_key_controller_key_pressed (GtkEventControllerKey *key,
guint keyval,
guint keycode,
GdkModifierType state,
GtkTreeView *tree_view)
{
GtkTreeView *tree_view = (GtkTreeView *) widget;
GtkWidget *button;
guint keyval, state;
if (!gdk_event_get_keyval ((GdkEvent *) event, &keyval) ||
!gdk_event_get_state ((GdkEvent *) event, &state))
return GDK_EVENT_PROPAGATE;
GtkWidget *widget = GTK_WIDGET (tree_view);
GtkWidget *button;
GdkEvent *event;
if (tree_view->priv->rubber_band_status)
{
@ -5298,13 +5319,16 @@ gtk_tree_view_key_press (GtkWidget *widget,
}
}
/* Chain up to the parent class. It handles the keybindings. */
if (GTK_WIDGET_CLASS (gtk_tree_view_parent_class)->event)
/* Handle the keybindings. */
event = gtk_get_current_event ();
if (gtk_bindings_activate_event (G_OBJECT (widget), (GdkEventKey *)event))
{
if (GTK_WIDGET_CLASS (gtk_tree_view_parent_class)->event (widget, (GdkEvent *)event))
return TRUE;
g_object_unref (event);
return TRUE;
}
g_object_unref (event);
if (tree_view->priv->search_entry_avoid_unhandled_binding)
{
tree_view->priv->search_entry_avoid_unhandled_binding = FALSE;
@ -5329,17 +5353,14 @@ gtk_tree_view_key_press (GtkWidget *widget,
search_window = tree_view->priv->search_window;
if (!gtk_widget_is_visible (search_window))
{
GtkIMContext *im_context =
_gtk_entry_get_im_context (GTK_ENTRY (tree_view->priv->search_entry));
tree_view->priv->imcontext_changed = FALSE;
gtk_im_context_filter_keypress (im_context, event);
gtk_event_controller_key_forward (key, tree_view->priv->search_entry);
if (tree_view->priv->imcontext_changed)
{
GdkDevice *device;
device = gdk_event_get_device ((GdkEvent *) event);
device = gtk_get_current_event_device ();
if (gtk_tree_view_real_start_interactive_search (tree_view,
device,
FALSE))
@ -5356,23 +5377,15 @@ gtk_tree_view_key_press (GtkWidget *widget,
}
else
{
GdkEvent *new_event;
gulong popup_menu_id;
new_event = gdk_event_copy ((GdkEvent *) event);
g_object_unref (((GdkEventKey *) new_event)->any.surface);
((GdkEventKey *) new_event)->any.surface =
g_object_ref (gtk_widget_get_surface (search_window));
gtk_widget_realize (search_window);
popup_menu_id = g_signal_connect (tree_view->priv->search_entry,
"popup-menu", G_CALLBACK (no_popup),
NULL);
/* Because we keep the focus on the treeview, we need to forward the
* key events to the entry, when it is visible. */
gtk_widget_event (search_window, new_event);
g_object_unref (new_event);
gtk_event_controller_key_forward (key, search_window);
g_signal_handler_disconnect (tree_view->priv->search_entry,
popup_menu_id);
@ -5382,20 +5395,22 @@ gtk_tree_view_key_press (GtkWidget *widget,
return FALSE;
}
static gboolean
gtk_tree_view_key_release (GtkWidget *widget,
GdkEventKey *event)
static void
gtk_tree_view_key_controller_key_released (GtkEventControllerKey *key,
guint keyval,
guint keycode,
GdkModifierType state,
GtkTreeView *tree_view)
{
GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
GdkEvent *event;
if (tree_view->priv->rubber_band_status)
return GDK_EVENT_STOP;
return;
/* Chain up to the parent class. It handles the keybindings. */
if (GTK_WIDGET_CLASS (gtk_tree_view_parent_class)->event)
return GTK_WIDGET_CLASS (gtk_tree_view_parent_class)->event (widget, (GdkEvent *)event);
return GDK_EVENT_PROPAGATE;
/* Handle the keybindings. */
event = gtk_get_current_event ();
gtk_bindings_activate_event (G_OBJECT (tree_view), (GdkEventKey *)event);
g_object_unref (event);
}
static void
@ -5440,41 +5455,18 @@ gtk_tree_view_motion_controller_leave (GtkEventControllerMotion *controller,
-1000, -1000); /* coords not possibly over an arrow */
}
static gboolean
gtk_tree_view_event (GtkWidget *widget,
GdkEvent *event)
static void
gtk_tree_view_key_controller_focus_out (GtkEventControllerKey *key,
GtkTreeView *tree_view)
{
GtkTreeView *tree_view;
gtk_widget_queue_draw (GTK_WIDGET (tree_view));
tree_view = GTK_TREE_VIEW (widget);
if (gdk_event_get_event_type (event) == GDK_KEY_PRESS)
return gtk_tree_view_key_press (widget, (GdkEventKey *)event);
else if (gdk_event_get_event_type (event) == GDK_KEY_RELEASE)
return gtk_tree_view_key_release (widget, (GdkEventKey *)event);
else if (gdk_event_get_event_type (event) == GDK_FOCUS_CHANGE)
{
gboolean focus_in;
gdk_event_get_focus_in (event, &focus_in);
if (!focus_in)
{
gtk_widget_queue_draw (widget);
/* destroy interactive search dialog */
if (tree_view->priv->search_window)
gtk_tree_view_search_window_hide (tree_view->priv->search_window, tree_view,
gdk_event_get_device ((GdkEvent *) event));
}
return GDK_EVENT_PROPAGATE;
}
return GDK_EVENT_PROPAGATE;
/* destroy interactive search dialog */
if (tree_view->priv->search_window)
gtk_tree_view_search_window_hide (tree_view->priv->search_window, tree_view,
gtk_get_current_event_device ());
}
/* Incremental Reflow
*/
@ -10200,9 +10192,12 @@ gtk_tree_view_ensure_interactive_directory (GtkTreeView *tree_view)
gtk_window_set_transient_for (GTK_WINDOW (tree_view->priv->search_window),
GTK_WINDOW (toplevel));
g_signal_connect (tree_view->priv->search_window, "event",
G_CALLBACK (gtk_tree_view_search_event),
controller = gtk_event_controller_key_new ();
g_signal_connect (controller, "key-pressed",
G_CALLBACK (gtk_tree_view_search_key_pressed),
tree_view);
gtk_widget_add_controller (tree_view->priv->search_window, controller);
gesture = gtk_gesture_multi_press_new ();
g_signal_connect (gesture, "pressed",
G_CALLBACK (gtk_tree_view_search_pressed_cb), tree_view);
@ -13661,8 +13656,9 @@ gtk_tree_view_set_search_entry (GtkTreeView *tree_view,
tree_view->priv->search_entry_changed_id);
tree_view->priv->search_entry_changed_id = 0;
}
g_signal_handlers_disconnect_by_func (tree_view->priv->search_entry,
G_CALLBACK (gtk_tree_view_search_event),
g_signal_handlers_disconnect_by_func (gtk_entry_get_key_controller (GTK_ENTRY (tree_view->priv->search_entry)),
G_CALLBACK (gtk_tree_view_search_key_pressed),
tree_view);
g_object_unref (tree_view->priv->search_entry);
@ -13684,12 +13680,13 @@ gtk_tree_view_set_search_entry (GtkTreeView *tree_view,
G_CALLBACK (gtk_tree_view_search_init),
tree_view);
}
g_signal_connect (tree_view->priv->search_entry, "event",
G_CALLBACK (gtk_tree_view_search_event),
tree_view);
gtk_tree_view_search_init (tree_view->priv->search_entry, tree_view);
g_signal_connect (gtk_entry_get_key_controller (GTK_ENTRY (tree_view->priv->search_entry)),
"key-pressed",
G_CALLBACK (gtk_tree_view_search_key_pressed),
tree_view);
gtk_tree_view_search_init (tree_view->priv->search_entry, tree_view);
}
else
{
@ -13946,30 +13943,25 @@ gtk_tree_view_search_scroll_event (GtkWidget *widget,
}
static gboolean
gtk_tree_view_search_event (GtkWidget *widget,
GdkEvent *event,
GtkTreeView *tree_view)
gtk_tree_view_search_key_pressed (GtkEventControllerKey *key,
guint keyval,
guint keycode,
GdkModifierType state,
GtkTreeView *tree_view)
{
GtkWidget *widget = tree_view->priv->search_window;
GdkModifierType default_accel;
gboolean retval = FALSE;
guint keyval, state;
gboolean retval = FALSE;
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), FALSE);
if (gdk_event_get_event_type (event) != GDK_KEY_PRESS)
return GDK_EVENT_PROPAGATE;
if (!gdk_event_get_keyval (event, &keyval) ||
!gdk_event_get_state (event, &state))
return GDK_EVENT_PROPAGATE;
/* close window and cancel the search */
if (!tree_view->priv->search_custom_entry_set
&& gtk_tree_view_search_key_cancels_search (keyval))
{
gtk_tree_view_search_window_hide (widget, tree_view,
gdk_event_get_device (event));
gtk_get_current_event_device ());
return TRUE;
}
@ -14024,6 +14016,9 @@ gtk_tree_view_search_event (GtkWidget *widget,
g_source_set_name_by_id (tree_view->priv->typeselect_flush_timeout, "[gtk+] gtk_tree_view_search_entry_flush_timeout");
}
if (!retval)
gtk_event_controller_key_forward (key, tree_view->priv->search_entry);
return retval;
}

View File

@ -43,6 +43,7 @@
#include "gtkcssstylepropertyprivate.h"
#include "gtkdragdest.h"
#include "gtkeventcontrollerkey.h"
#include "gtkeventcontrollermotion.h"
#include "gtkgesturedrag.h"
#include "gtkgesturemultipress.h"
#include "gtkgestureprivate.h"
@ -1833,12 +1834,12 @@ edge_under_coordinates (GtkWindow *window,
return TRUE;
}
static gboolean
captured_event_cb (GtkWidget *widget,
GdkEvent *event)
static void
gtk_window_capture_motion (GtkWidget *widget,
gdouble x,
gdouble y)
{
GdkCursor *cursor = NULL;
gdouble x, y;
gint i;
const gchar *cursor_names[8] = {
"nw-resize", "n-resize", "ne-resize",
@ -1846,11 +1847,6 @@ captured_event_cb (GtkWidget *widget,
"sw-resize", "s-resize", "se-resize"
};
if (gdk_event_get_event_type (event) != GDK_MOTION_NOTIFY)
return GDK_EVENT_PROPAGATE;
if (!gdk_event_get_coords (event, &x, &y))
return GDK_EVENT_PROPAGATE;
for (i = 0; i < 8; i++)
{
if (edge_under_coordinates (GTK_WINDOW (widget), x, y, i))
@ -1864,8 +1860,6 @@ captured_event_cb (GtkWidget *widget,
if (cursor)
g_object_unref (cursor);
return GDK_EVENT_PROPAGATE;
}
static void
@ -1875,6 +1869,7 @@ gtk_window_init (GtkWindow *window)
GtkWidget *widget;
GtkCssNode *widget_node;
GdkSeat *seat;
GtkEventController *motion_controller;
#ifdef GDK_WINDOWING_X11
GdkContentFormats *targets;
#endif
@ -1951,7 +1946,12 @@ gtk_window_init (GtkWindow *window)
g_signal_connect (seat, "device-removed",
G_CALLBACK (device_removed_cb), window);
_gtk_widget_set_captured_event_handler (widget, captured_event_cb);
motion_controller = gtk_event_controller_motion_new ();
gtk_event_controller_set_propagation_phase (motion_controller,
GTK_PHASE_CAPTURE);
g_signal_connect_swapped (motion_controller, "motion",
G_CALLBACK (gtk_window_capture_motion), window);
gtk_widget_add_controller (widget, motion_controller);
priv->key_controller = gtk_event_controller_key_new ();
g_signal_connect_swapped (priv->key_controller, "focus-in",

View File

@ -33,7 +33,9 @@
#include "gtkmain.h"
#include "gtkinvisible.h"
#include "gtkwidgetprivate.h"
#include "gtkgesturemultipress.h"
#include "gtkeventcontrollermotion.h"
#include "gtkeventcontrollerkey.h"
static gboolean
inspector_contains (GtkWidget *widget,
@ -247,45 +249,71 @@ reemphasize_window (GtkWidget *window)
gdk_surface_raise (gtk_widget_get_surface (window));
}
static gboolean
property_query_event (GtkWidget *widget,
GdkEvent *event,
gpointer data)
static void
property_query_pressed (GtkGestureMultiPress *gesture,
guint n_press,
gdouble x,
gdouble y,
GtkInspectorWindow *iw)
{
GtkInspectorWindow *iw = (GtkInspectorWindow *)data;
GdkEventType event_type = gdk_event_get_event_type (event);
GdkEvent *event;
if (event_type == GDK_BUTTON_RELEASE)
gtk_grab_remove (iw->invisible);
if (iw->grab_seat)
{
g_signal_handlers_disconnect_by_func (widget, property_query_event, data);
gtk_grab_remove (widget);
if (iw->grabbed)
gdk_seat_ungrab (gdk_event_get_seat (event));
gdk_seat_ungrab (iw->grab_seat);
iw->grab_seat = NULL;
}
reemphasize_window (GTK_WIDGET (iw));
event = gtk_get_current_event ();
on_inspect_widget (iw->invisible, event, iw);
g_object_unref (event);
gtk_widget_destroy (iw->invisible);
iw->invisible = NULL;
}
static void
property_query_motion (GtkEventControllerMotion *controller,
gdouble x,
gdouble y,
GtkInspectorWindow *iw)
{
GdkEvent *event;
event = gtk_get_current_event ();
on_highlight_widget (iw->invisible, event, iw);
g_object_unref (event);
}
static gboolean
property_query_key (GtkEventControllerKey *key,
guint keyval,
guint keycode,
GdkModifierType modifiers,
GtkInspectorWindow *iw)
{
if (keyval == GDK_KEY_Escape)
{
gtk_grab_remove (iw->invisible);
if (iw->grab_seat)
{
gdk_seat_ungrab (iw->grab_seat);
iw->grab_seat = NULL;
}
reemphasize_window (GTK_WIDGET (iw));
on_inspect_widget (widget, event, data);
}
else if (event_type == GDK_MOTION_NOTIFY)
{
on_highlight_widget (widget, event, data);
}
else if (event_type == GDK_KEY_PRESS)
{
guint keyval;
clear_flash (iw);
if (gdk_event_get_keyval (event, &keyval) && keyval == GDK_KEY_Escape)
{
g_signal_handlers_disconnect_by_func (widget, property_query_event, data);
gtk_grab_remove (widget);
if (iw->grabbed)
gdk_seat_ungrab (gdk_event_get_seat (event));
reemphasize_window (GTK_WIDGET (iw));
gtk_widget_destroy (iw->invisible);
iw->invisible = NULL;
clear_flash (iw);
}
return TRUE;
}
return TRUE;
return FALSE;
}
static void
@ -304,6 +332,8 @@ gtk_inspector_on_inspect (GtkWidget *button,
GdkDisplay *display;
GdkCursor *cursor;
GdkGrabStatus status;
GtkEventController *controller;
GdkSeat *seat;
if (!iw->invisible)
{
@ -314,14 +344,29 @@ gtk_inspector_on_inspect (GtkWidget *button,
display = gdk_display_get_default ();
cursor = gdk_cursor_new_from_name ("crosshair", NULL);
status = gdk_seat_grab (gdk_display_get_default_seat (display),
seat = gdk_display_get_default_seat (display);
status = gdk_seat_grab (seat,
gtk_widget_get_surface (iw->invisible),
GDK_SEAT_CAPABILITY_ALL_POINTING, TRUE,
cursor, NULL, prepare_inspect_func, NULL);
g_object_unref (cursor);
iw->grabbed = status == GDK_GRAB_SUCCESS;
if (status == GDK_GRAB_SUCCESS)
iw->grab_seat = seat;
g_signal_connect (iw->invisible, "event", G_CALLBACK (property_query_event), iw);
controller = GTK_EVENT_CONTROLLER (gtk_gesture_multi_press_new ());
g_signal_connect (controller, "pressed",
G_CALLBACK (property_query_pressed), iw);
gtk_widget_add_controller (iw->invisible, controller);
controller = GTK_EVENT_CONTROLLER (gtk_event_controller_motion_new ());
g_signal_connect (controller, "motion",
G_CALLBACK (property_query_motion), iw);
gtk_widget_add_controller (iw->invisible, controller);
controller = GTK_EVENT_CONTROLLER (gtk_event_controller_key_new ());
g_signal_connect (controller, "key-pressed",
G_CALLBACK (property_query_key), iw);
gtk_widget_add_controller (iw->invisible, controller);
gtk_grab_add (GTK_WIDGET (iw->invisible));
deemphasize_window (GTK_WIDGET (iw));

View File

@ -77,7 +77,7 @@ typedef struct
GList *extra_pages;
gboolean grabbed;
GdkSeat *grab_seat;
GtkInspectorOverlay *flash_overlay;
gint flash_count;

View File

@ -34,8 +34,13 @@
<object class="GtkTreeMenu" id="popup_widget">
<property name="cell-area">area</property>
<signal name="menu-activate" handler="gtk_combo_box_menu_activate" swapped="no"/>
<signal name="event" handler="gtk_combo_box_menu_event" swapped="no"/>
<signal name="show" handler="gtk_combo_box_menu_show" swapped="no"/>
<signal name="hide" handler="gtk_combo_box_menu_hide" swapped="no"/>
<child>
<object class="GtkEventControllerKey">
<signal name="key-pressed" handler="gtk_combo_box_menu_key" swapped="no"/>
<signal name="key-released" handler="gtk_combo_box_menu_key" swapped="no"/>
</object>
</child>
</object>
</interface>

View File

@ -4,24 +4,18 @@
GtkAdjustment *adjustment;
int cursor_x, cursor_y;
static gboolean
event_cb (GtkWidget *window,
GdkEvent *event)
static void
motion_cb (GtkEventControllerMotion *motion,
gdouble x,
gdouble y,
GtkWidget *widget)
{
if (gdk_event_get_event_type (event) == GDK_MOTION_NOTIFY &&
gdk_event_get_surface (event) == gtk_widget_get_surface (window))
{
gdouble x, y;
float processing_ms = gtk_adjustment_get_value (adjustment);
g_usleep (processing_ms * 1000);
float processing_ms = gtk_adjustment_get_value (adjustment);
g_usleep (processing_ms * 1000);
gdk_event_get_coords ((GdkEvent *)event, &x, &y);
cursor_x = x;
cursor_y = y;
gtk_widget_queue_draw (window);
}
return GDK_EVENT_PROPAGATE;
cursor_x = x;
cursor_y = y;
gtk_widget_queue_draw (widget);
}
static void
@ -48,6 +42,7 @@ main (int argc, char **argv)
GtkWidget *label;
GtkWidget *scale;
GtkWidget *da;
GtkEventController *controller;
gtk_init ();
@ -69,9 +64,12 @@ main (int argc, char **argv)
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), on_draw, NULL, NULL);
gtk_widget_set_vexpand (da, TRUE);
gtk_box_pack_end (GTK_BOX (vbox), da);
g_signal_connect (window, "event",
G_CALLBACK (event_cb), NULL);
controller = gtk_event_controller_motion_new ();
g_signal_connect (controller, "motion",
G_CALLBACK (motion_cb), da);
gtk_widget_add_controller (da, controller);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_main_quit), NULL);

View File

@ -31,17 +31,15 @@ test_widget (const gchar *label, const gchar *color)
static GtkOrientation o;
static gboolean
toggle_orientation (GtkWidget *window, GdkEvent *event, GtkGrid *grid)
static void
toggle_orientation (GtkGestureMultiPress *gesture,
guint n_press,
gdouble x,
gdouble y,
GtkGrid *grid)
{
if (gdk_event_get_event_type (event) == GDK_BUTTON_PRESS)
{
o = 1 - o;
gtk_orientable_set_orientation (GTK_ORIENTABLE (grid), o);
}
return GDK_EVENT_PROPAGATE;
o = 1 - o;
gtk_orientable_set_orientation (GTK_ORIENTABLE (grid), o);
}
static void
@ -50,12 +48,16 @@ simple_grid (void)
GtkWidget *window;
GtkWidget *grid;
GtkWidget *test1, *test2, *test3, *test4, *test5, *test6;
GtkGesture *gesture;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Orientation");
grid = gtk_grid_new ();
gtk_container_add (GTK_CONTAINER (window), grid);
g_signal_connect (window, "event", G_CALLBACK (toggle_orientation), grid);
gesture = gtk_gesture_multi_press_new ();
g_signal_connect (gesture, "pressed", G_CALLBACK (toggle_orientation), grid);
gtk_widget_add_controller (window, GTK_EVENT_CONTROLLER (gesture));
gtk_grid_set_column_spacing (GTK_GRID (grid), 5);
gtk_grid_set_row_spacing (GTK_GRID (grid), 5);

View File

@ -329,34 +329,13 @@ item_cb (GtkWidget *menuitem,
}
static void
do_popup_menu (GtkWidget *icon_list,
GdkEvent *event)
do_popup_menu (GtkWidget *icon_list,
GtkTreePath *path)
{
GtkIconView *icon_view = GTK_ICON_VIEW (icon_list);
GtkWidget *menu;
GtkWidget *menuitem;
GtkTreePath *path = NULL;
guint button, event_time;
ItemData *data;
GList *list;
if (event)
{
double x, y;
gdk_event_get_coords (event, &x, &y);
path = gtk_icon_view_get_path_at_pos (icon_view, x, y);
}
else
{
list = gtk_icon_view_get_selected_items (icon_view);
if (list)
{
path = (GtkTreePath*)list->data;
g_list_free_full (list, (GDestroyNotify) gtk_tree_path_free);
}
}
if (!path)
return;
@ -373,40 +352,41 @@ do_popup_menu (GtkWidget *icon_list,
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
g_signal_connect (menuitem, "activate", G_CALLBACK (item_cb), data);
if (event)
{
gdk_event_get_button (event, &button);
event_time = gdk_event_get_time (event);
}
else
{
button = 0;
event_time = gtk_get_current_event_time ();
}
gtk_menu_popup_at_pointer (GTK_MENU (menu), event);
gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL);
}
static gboolean
event_handler (GtkWidget *widget,
GdkEvent *event)
static void
press_handler (GtkGestureMultiPress *gesture,
guint n_press,
gdouble x,
gdouble y,
GtkWidget *widget)
{
/* Ignore double-clicks and triple-clicks */
if (gdk_event_triggers_context_menu (event) &&
gdk_event_get_event_type (event) == GDK_BUTTON_PRESS)
{
do_popup_menu (widget, event);
return TRUE;
}
GtkTreePath *path = NULL;
return FALSE;
/* Ignore double-clicks and triple-clicks */
if (n_press > 1)
return;
path = gtk_icon_view_get_path_at_pos (GTK_ICON_VIEW (widget), x, y);
do_popup_menu (widget, path);
}
static gboolean
popup_menu_handler (GtkWidget *widget)
{
do_popup_menu (widget, NULL);
GtkTreePath *path = NULL;
GList *list;
list = gtk_icon_view_get_selected_items (GTK_ICON_VIEW (widget));
if (list)
{
path = (GtkTreePath*)list->data;
g_list_free_full (list, (GDestroyNotify) gtk_tree_path_free);
}
do_popup_menu (widget, path);
return TRUE;
}
@ -425,6 +405,7 @@ main (gint argc, gchar **argv)
GtkCellRenderer *cell;
GtkTreeViewColumn *tvc;
GdkContentFormats *targets;
GtkGesture *gesture;
#ifdef GTK_SRCDIR
g_chdir (GTK_SRCDIR);
@ -453,8 +434,13 @@ main (gint argc, gchar **argv)
tvc = gtk_tree_view_column_new ();
gtk_tree_view_append_column (GTK_TREE_VIEW (tv), tvc);
g_signal_connect_after (icon_list, "event",
G_CALLBACK (event_handler), NULL);
gesture = gtk_gesture_multi_press_new ();
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture),
GDK_BUTTON_SECONDARY);
g_signal_connect (gesture, "pressed",
G_CALLBACK (press_handler), icon_list);
gtk_widget_add_controller (icon_list, GTK_EVENT_CONTROLLER (gesture));
g_signal_connect (icon_list, "selection_changed",
G_CALLBACK (selection_changed), NULL);
g_signal_connect (icon_list, "popup_menu",

View File

@ -52,18 +52,19 @@ clicked_icon (GtkTreeView *tv,
return FALSE;
}
static gboolean
release_event (GtkTreeView *tv,
GdkEvent *event)
static void
release_event (GtkGestureMultiPress *gesture,
guint n_press,
gdouble x,
gdouble y,
GtkTreeView *tv)
{
GtkTreePath *path;
gdouble x, y;
gint tx, ty;
if (gdk_event_get_event_type (event) != GDK_BUTTON_RELEASE)
return TRUE;
gtk_tree_view_convert_widget_to_tree_coords (tv, x, y, &tx, &ty);
gdk_event_get_coords (event, &x, &y);
if (clicked_icon (tv, x, y, &path))
if (clicked_icon (tv, tx, ty, &path))
{
GtkTreeModel *model;
GtkTreeIter iter;
@ -76,11 +77,7 @@ release_event (GtkTreeView *tv,
g_print ("text was: %s\n", text);
g_free (text);
gtk_tree_path_free (path);
return TRUE;
}
return FALSE;
}
int main (int argc, char *argv[])
@ -92,6 +89,7 @@ int main (int argc, char *argv[])
GtkCellRenderer *cell;
GtkTreeStore *store;
GtkTreeIter iter;
GtkGesture *gesture;
gtk_init ();
@ -131,8 +129,12 @@ int main (int argc, char *argv[])
gtk_tree_view_set_model (GTK_TREE_VIEW (tv), GTK_TREE_MODEL (store));
g_signal_connect (tv, "event",
G_CALLBACK (release_event), NULL);
gesture = gtk_gesture_multi_press_new ();
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
GTK_PHASE_CAPTURE);
g_signal_connect (gesture, "released",
G_CALLBACK (release_event), tv);
gtk_widget_add_controller (tv, GTK_EVENT_CONTROLLER (gesture));
gtk_widget_show (window);

View File

@ -199,24 +199,18 @@ gtk_focus_widget_snapshot (GtkWidget *widget, GtkSnapshot *snapshot)
}
}
static gboolean
gtk_focus_widget_event (GtkWidget *widget,
GdkEvent *event)
static void
motion_cb (GtkEventControllerMotion *controller,
gdouble x,
gdouble y,
GtkWidget *widget)
{
GtkFocusWidget *self = GTK_FOCUS_WIDGET (widget);
double x, y;
if (gdk_event_get_event_type (event) == GDK_MOTION_NOTIFY)
{
gdk_event_get_coords ((GdkEvent *)event, &x, &y);
self->mouse_x = x;
self->mouse_y = y;
self->mouse_x = x;
self->mouse_y = y;
gtk_widget_queue_draw (widget);
}
return GDK_EVENT_PROPAGATE;
gtk_widget_queue_draw (widget);
}
static void
@ -235,6 +229,8 @@ gtk_focus_widget_finalize (GObject *object)
static void
gtk_focus_widget_init (GtkFocusWidget *self)
{
GtkEventController *controller;
gtk_widget_set_has_surface (GTK_WIDGET (self), FALSE);
self->child1 = gtk_button_new_with_label ("1");
@ -248,6 +244,11 @@ gtk_focus_widget_init (GtkFocusWidget *self)
self->mouse_x = G_MININT;
self->mouse_y = G_MININT;
controller = gtk_event_controller_motion_new ();
g_signal_connect (controller, "motion",
G_CALLBACK (motion_cb), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
}
static void
@ -261,7 +262,6 @@ gtk_focus_widget_class_init (GtkFocusWidgetClass *klass)
widget_class->snapshot = gtk_focus_widget_snapshot;
widget_class->measure = gtk_focus_widget_measure;
widget_class->size_allocate = gtk_focus_widget_size_allocate;
widget_class->event = gtk_focus_widget_event;
gtk_widget_class_set_css_name (widget_class, "focuswidget");
}

View File

@ -40,11 +40,9 @@ on_draw (GtkDrawingArea *da,
}
static gboolean
on_keypress (GtkWidget *widget,
GdkEvent *event)
on_keypress (GtkEventControllerKey *key)
{
if (gdk_event_get_event_type (event) == GDK_KEY_PRESS)
gtk_main_quit ();
gtk_main_quit ();
return GDK_EVENT_PROPAGATE;
}
@ -58,7 +56,11 @@ test_default_size (void)
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
if (interactive)
g_signal_connect (window, "event", G_CALLBACK (on_keypress), NULL);
{
GtkEventController *controller = gtk_event_controller_key_new ();
g_signal_connect (controller, "key-pressed", G_CALLBACK (on_keypress), window);
gtk_widget_add_controller (window, controller);
}
da = gtk_drawing_area_new ();
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), on_draw, NULL, NULL);
@ -135,7 +137,11 @@ test_resize (void)
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
if (interactive)
g_signal_connect (window, "event", G_CALLBACK (on_keypress), NULL);
{
GtkEventController *controller = gtk_event_controller_key_new ();
g_signal_connect (controller, "key-pressed", G_CALLBACK (on_keypress), window);
gtk_widget_add_controller (window, controller);
}
da = gtk_drawing_area_new ();
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), on_draw, NULL, NULL);