forked from AuroraMiddleware/gtk
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:
commit
efa42a6932
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
}
|
@ -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));
|
||||
|
||||
|
@ -22,7 +22,6 @@ demos = files([
|
||||
'editable_cells.c',
|
||||
'entry_buffer.c',
|
||||
'entry_completion.c',
|
||||
'event_axes.c',
|
||||
'expander.c',
|
||||
'filtermodel.c',
|
||||
'fishbowl.c',
|
||||
|
@ -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 });
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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++)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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));
|
||||
|
@ -77,7 +77,7 @@ typedef struct
|
||||
|
||||
GList *extra_pages;
|
||||
|
||||
gboolean grabbed;
|
||||
GdkSeat *grab_seat;
|
||||
|
||||
GtkInspectorOverlay *flash_overlay;
|
||||
gint flash_count;
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user