summaryrefslogtreecommitdiffstats
path: root/meta/packages/gtk+/gtk+-2.6.4-1.osso7/gtkwidget.c.diff
diff options
context:
space:
mode:
Diffstat (limited to 'meta/packages/gtk+/gtk+-2.6.4-1.osso7/gtkwidget.c.diff')
-rw-r--r--meta/packages/gtk+/gtk+-2.6.4-1.osso7/gtkwidget.c.diff1046
1 files changed, 1046 insertions, 0 deletions
diff --git a/meta/packages/gtk+/gtk+-2.6.4-1.osso7/gtkwidget.c.diff b/meta/packages/gtk+/gtk+-2.6.4-1.osso7/gtkwidget.c.diff
new file mode 100644
index 0000000000..ecef0041eb
--- /dev/null
+++ b/meta/packages/gtk+/gtk+-2.6.4-1.osso7/gtkwidget.c.diff
@@ -0,0 +1,1046 @@
1--- gtk+-2.6.4/gtk/gtkwidget.c 2005-02-24 18:44:02.000000000 +0200
2+++ gtk+-2.6.4/gtk/gtkwidget.c 2005-04-06 16:19:38.386702696 +0300
3@@ -28,6 +28,8 @@
4 #include <stdarg.h>
5 #include <string.h>
6 #include <locale.h>
7+#include <stdlib.h>
8+#include <x11/gdkx.h>
9 #include "gtkalias.h"
10 #include "gtkcontainer.h"
11 #include "gtkaccelmap.h"
12@@ -44,6 +46,11 @@
13 #include "gtkwindow.h"
14 #include "gtkbindings.h"
15 #include "gtkprivate.h"
16+#include "gtktreeview.h"
17+#include "gtkentry.h"
18+#include "gtktextview.h"
19+#include "gtkimcontext.h"
20+#include "gtkmenu.h"
21 #include "gdk/gdk.h"
22 #include "gdk/gdkprivate.h" /* Used in gtk_reset_shapes_recurse to avoid copy */
23 #include <gobject/gvaluecollector.h>
24@@ -53,11 +60,30 @@
25 #include "gtkaccessible.h"
26 #include "gtktooltips.h"
27 #include "gtkinvisible.h"
28+#include "gtkscrollbar.h" /* Following are needed for special focus changes */
29+#include "gtktoolbar.h"
30+#include "gtkmenu.h"
31+#include "gtkmenuitem.h"
32+#include "gtktogglebutton.h"
33+#include "gtkcomboboxentry.h"
34+#include "gtktogglebutton.h"
35+#include "gtkcomboboxentry.h"
36
37 #define WIDGET_CLASS(w) GTK_WIDGET_GET_CLASS (w)
38 #define INIT_PATH_SIZE (512)
39
40+#define GTK_TAP_THRESHOLD 30
41+#define GTK_TAP_MENU_THRESHOLD 20
42+#define GTK_TAP_AND_HOLD_TIMER_COUNTER 11
43+#define GTK_TAP_AND_HOLD_TIMER_INTERVAL 100
44
45+typedef struct _GtkWidgetPrivate GtkWidgetPrivate;
46+
47+#define GTK_WIDGET_GET_PRIVATE(obj) ( G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
48+ GTK_TYPE_WIDGET, GtkWidgetPrivate) )
49+
50+#define TAP_AND_HOLD_ANIMATION 1
51+
52 enum {
53 SHOW,
54 HIDE,
55@@ -120,6 +146,9 @@
56 ACCEL_CLOSURES_CHANGED,
57 SCREEN_CHANGED,
58 CAN_ACTIVATE_ACCEL,
59+ INSENSITIVE_PRESS,
60+ TAP_AND_HOLD,
61+ TAP_AND_HOLD_SETUP,
62 LAST_SIGNAL
63 };
64
65@@ -142,7 +171,8 @@
66 PROP_STYLE,
67 PROP_EVENTS,
68 PROP_EXTENSION_EVENTS,
69- PROP_NO_SHOW_ALL
70+ PROP_NO_SHOW_ALL,
71+ PROP_TAP_AND_HOLD
72 };
73
74 typedef struct _GtkStateData GtkStateData;
75@@ -155,7 +185,50 @@
76 guint use_forall : 1;
77 };
78
79+struct _GtkWidgetPrivate
80+{
81+ GtkWidget *menu;
82+ guint timer_id;
83+
84+ GtkStateType stype;
85+ GtkStateType type_on_press;
86+ GdkEvent *fake_event;
87+ GtkMenuPositionFunc func;
88+ gint x, y;
89+ gint timer_counter;
90+ gint run_press : 1;
91+ gint button_pressed : 1;
92+ gint signals_connected : 1;
93+ GtkWidgetTapAndHoldFlags flags;
94+ gboolean state_set;
95+ guint interval;
96+
97+#ifdef TAP_AND_HOLD_ANIMATION
98+ GdkPixbufAnimation *anim;
99+ GdkPixbufAnimationIter *iter;
100+ guint width, height;
101+#endif
102+};
103+
104
105+/* --- Tap And Hold --- */
106+static gboolean gtk_widget_tap_and_hold_button_press_with_events( GtkWidget *widget,
107+ GdkEvent *event, GtkWidgetPrivate *priv );
108+static gboolean gtk_widget_tap_and_hold_button_release_with_events( GtkWidget *widget,
109+ GdkEvent *event, GtkWidgetPrivate *priv );
110+static gboolean gtk_widget_tap_and_hold_leave_notify_with_events( GtkWidget *widget,
111+ GdkEvent *event, GtkWidgetPrivate *priv );
112+static gboolean gtk_widget_tap_and_hold_timeout_with_events( GtkWidget *widget );
113+static gboolean gtk_widget_tap_and_hold_timeout( GtkWidget *widget );
114+static gboolean gtk_widget_tap_and_hold_button_press( GtkWidget *widget,
115+ GdkEvent *event, GtkWidgetPrivate *priv );
116+static gboolean gtk_widget_tap_and_hold_button_release( GtkWidget *widget,
117+ GdkEvent *event, GtkWidgetPrivate *priv );
118+static gboolean gtk_widget_tap_and_hold_leave_notify( GtkWidget *widget,
119+ GdkEvent *event, GtkWidgetPrivate *priv );
120+static void gtk_widget_tap_and_hold_setup_real( GtkWidget *widget,
121+ GtkWidget *menu, GtkCallback func, GtkWidgetTapAndHoldFlags flags );
122+static void gtk_widget_real_tap_and_hold(GtkWidget *widget);
123 /* --- prototypes --- */
124 static void gtk_widget_class_init (GtkWidgetClass *klass);
125 static void gtk_widget_init (GtkWidget *widget);
126@@ -228,6 +301,13 @@
127 gint width,
128 gint height);
129
130+/*Hildon focus handling*/
131+static void gtk_widget_set_focus_handling( GtkWidget *widget, gboolean state );
132+
133+static gboolean gtk_widget_enter_notify_event( GtkWidget *widget, GdkEventCrossing *event );
134+static gboolean gtk_widget_leave_notify_event( GtkWidget *widget, GdkEventCrossing *event );
135+static gint gtk_widget_button_release_event( GtkWidget *widget, GdkEventButton *event );
136+static gint gtk_widget_button_press_event( GtkWidget *widget, GdkEventButton *event );
137
138 /* --- variables --- */
139 static gpointer parent_class = NULL;
140@@ -239,6 +319,9 @@
141 static GtkTextDirection gtk_default_direction = GTK_TEXT_DIR_LTR;
142 static GParamSpecPool *style_property_spec_pool = NULL;
143
144+static gboolean on_same_widget = FALSE; /*Hildon focus handling*/
145+static gboolean mouse_pressed = FALSE; /*Hildon focus handling*/
146+
147 static GQuark quark_property_parser = 0;
148 static GQuark quark_aux_info = 0;
149 static GQuark quark_accel_path = 0;
150@@ -396,6 +479,9 @@
151 klass->drag_data_received = NULL;
152 klass->screen_changed = NULL;
153 klass->can_activate_accel = gtk_widget_real_can_activate_accel;
154+ klass->tap_and_hold_setup = gtk_widget_tap_and_hold_setup_real;
155+ klass->insensitive_press = NULL;
156+ klass->tap_and_hold = gtk_widget_real_tap_and_hold;
157
158 klass->show_help = gtk_widget_real_show_help;
159
160@@ -404,6 +490,18 @@
161
162 klass->no_expose_event = NULL;
163
164+ g_type_class_add_private( klass, sizeof(GtkWidgetPrivate) );
165+
166+ g_object_class_install_property (gobject_class,
167+ PROP_TAP_AND_HOLD,
168+ g_param_spec_int ("tap_and_hold_state",
169+ P_("Tap and hold State type"),
170+ P_("Sets the state to be used to the tap and hold functionality. The default is GTK_STATE_NORMAL"),
171+ 0,
172+ 4, /*4 == Last state in GTK+-2.0*/
173+ GTK_STATE_NORMAL,
174+ G_PARAM_READWRITE));
175+
176 g_object_class_install_property (gobject_class,
177 PROP_NAME,
178 g_param_spec_string ("name",
179@@ -1389,6 +1487,31 @@
180 _gtk_marshal_BOOLEAN__UINT,
181 G_TYPE_BOOLEAN, 1, G_TYPE_UINT);
182
183+ widget_signals[INSENSITIVE_PRESS] =
184+ g_signal_new ("insensitive_press",
185+ G_TYPE_FROM_CLASS (gobject_class),
186+ G_SIGNAL_RUN_FIRST,
187+ G_STRUCT_OFFSET (GtkWidgetClass, insensitive_press),
188+ NULL, NULL,
189+ _gtk_marshal_VOID__VOID,
190+ G_TYPE_NONE, 0);
191+
192+ widget_signals[TAP_AND_HOLD] =
193+ g_signal_new("tap-and-hold", G_TYPE_FROM_CLASS(gobject_class),
194+ G_SIGNAL_RUN_LAST,
195+ G_STRUCT_OFFSET(GtkWidgetClass, tap_and_hold),
196+ NULL, NULL,
197+ _gtk_marshal_VOID__VOID,
198+ G_TYPE_NONE, 0);
199+
200+ widget_signals[TAP_AND_HOLD_SETUP] =
201+ g_signal_new("tap-and-hold-setup", G_TYPE_FROM_CLASS(gobject_class),
202+ G_SIGNAL_RUN_LAST,
203+ G_STRUCT_OFFSET(GtkWidgetClass, tap_and_hold_setup),
204+ NULL, NULL, /*FIXME -- OBJECT_POINTER_FLAGS*/
205+ _gtk_marshal_VOID__OBJECT_UINT_FLAGS,
206+ G_TYPE_NONE, 3, G_TYPE_OBJECT, G_TYPE_POINTER, G_TYPE_UINT);
207+
208 binding_set = gtk_binding_set_by_class (klass);
209 gtk_binding_entry_add_signal (binding_set, GDK_F10, GDK_SHIFT_MASK,
210 "popup_menu", 0);
211@@ -1418,7 +1541,12 @@
212 P_("Whether to draw the focus indicator inside widgets"),
213 TRUE,
214 G_PARAM_READABLE));
215-
216+ gtk_widget_class_install_style_property (klass,
217+ g_param_spec_boolean ("hildon-focus-handling",
218+ P_("Hildon focus handling"),
219+ P_("Whether the widget is using the hildon like focus handling or not"),
220+ FALSE,
221+ G_PARAM_READABLE));
222 gtk_widget_class_install_style_property (klass,
223 g_param_spec_int ("focus-line-width",
224 P_("Focus linewidth"),
225@@ -1543,6 +1671,8 @@
226 case PROP_NO_SHOW_ALL:
227 gtk_widget_set_no_show_all (widget, g_value_get_boolean (value));
228 break;
229+ case PROP_TAP_AND_HOLD:
230+ GTK_WIDGET_GET_PRIVATE(widget)->type_on_press = g_value_get_int(value);
231 default:
232 break;
233 }
234@@ -1637,16 +1767,45 @@
235 case PROP_NO_SHOW_ALL:
236 g_value_set_boolean (value, gtk_widget_get_no_show_all (widget));
237 break;
238+ case PROP_TAP_AND_HOLD:
239+ g_value_set_int (value,
240+ (int)GTK_WIDGET_GET_PRIVATE(widget)->type_on_press);
241 default:
242 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
243 break;
244 }
245 }
246
247+static void gtk_widget_set_focus_handling( GtkWidget *widget, gboolean state )
248+{
249+ GtkWidgetPrivate *priv;
250+ priv = GTK_WIDGET_GET_PRIVATE (widget);
251+
252+ if( state && GTK_WIDGET_CAN_FOCUS(widget) )
253+ {
254+ if (!priv->state_set)
255+ {
256+ g_signal_connect( G_OBJECT(widget), "button-press-event",
257+ G_CALLBACK(gtk_widget_button_press_event), NULL );
258+ g_signal_connect( G_OBJECT(widget), "button-release-event",
259+ G_CALLBACK(gtk_widget_button_release_event), NULL );
260+ g_signal_connect( G_OBJECT(widget), "enter-notify-event",
261+ G_CALLBACK(gtk_widget_enter_notify_event), NULL );
262+ g_signal_connect( G_OBJECT(widget), "leave-notify-event",
263+ G_CALLBACK(gtk_widget_leave_notify_event), NULL );
264+ priv->state_set = TRUE;
265+ }
266+ }
267+}
268+
269 static void
270 gtk_widget_init (GtkWidget *widget)
271 {
272+ GtkWidgetPrivate *priv;
273 GTK_PRIVATE_FLAGS (widget) = PRIVATE_GTK_CHILD_VISIBLE;
274+
275+ priv = GTK_WIDGET_GET_PRIVATE(widget);
276+
277 widget->state = GTK_STATE_NORMAL;
278 widget->saved_state = GTK_STATE_NORMAL;
279 widget->name = NULL;
280@@ -1659,6 +1818,18 @@
281 widget->window = NULL;
282 widget->parent = NULL;
283
284+ priv->fake_event = NULL;
285+ priv->timer_id = 0;
286+ priv->menu = NULL;
287+ priv->run_press = TRUE;
288+ priv->signals_connected = FALSE;
289+ priv->x = priv->y = 0;
290+ priv->func = NULL;
291+ priv->timer_counter = 0;
292+ priv->flags = 0x0;
293+ priv->state_set = FALSE;
294+ priv->interval = GTK_TAP_AND_HOLD_TIMER_INTERVAL;
295+
296 GTK_WIDGET_SET_FLAGS (widget,
297 GTK_SENSITIVE |
298 GTK_PARENT_SENSITIVE |
299@@ -1670,6 +1841,7 @@
300 GTK_PRIVATE_SET_FLAG (widget, GTK_ALLOC_NEEDED);
301
302 widget->style = gtk_widget_get_default_style ();
303+
304 g_object_ref (widget->style);
305 }
306
307@@ -2153,6 +2325,7 @@
308
309 if ((GTK_WIDGET_FLAGS (widget) & GTK_NO_SHOW_ALL) != 0)
310 return;
311+
312
313 class = GTK_WIDGET_GET_CLASS (widget);
314
315@@ -3400,6 +3573,127 @@
316 return FALSE;
317 }
318
319+/**
320+ * gtk_widget_button_press_event
321+ * @widget: a #GtkWidget
322+ * @event: a #GtkEventKey
323+ *
324+**/
325+static gboolean gtk_widget_button_press_event(GtkWidget *widget, GdkEventButton *event )
326+{
327+ if( !mouse_pressed /*&& !GTK_IS_TREE_VIEW(widget) && !GTK_IS_ENTRY(widget)*/ )
328+ {
329+ GtkWidget *toplevel;
330+ toplevel = gtk_widget_get_toplevel (widget);
331+ if (GTK_IS_WINDOW (toplevel))
332+ {
333+ mouse_pressed = TRUE;
334+
335+ if( /*!gtk_window_get_prev_focus_widget(GTK_WINDOW(toplevel)) &&*/
336+ GTK_IS_WIDGET(GTK_WINDOW(toplevel)->focus_widget) )
337+ gtk_window_set_prev_focus_widget( GTK_WINDOW(toplevel),
338+ GTK_WINDOW(toplevel)->focus_widget );
339+ }
340+ }
341+ return FALSE;
342+}
343+
344+/**
345+ * gtk_widget_button_release_event
346+ * @widget: a #GtkWidget
347+ * @event: a #GtkEventKey
348+ *
349+**/
350+static gboolean gtk_widget_button_release_event(GtkWidget *widget, GdkEventButton *event )
351+{
352+ if( mouse_pressed /*&& !GTK_IS_ENTRY(widget)*/ )
353+ {
354+ GtkWidget *toplevel;
355+ GtkWidget *event_widget;
356+ event_widget = gtk_get_event_widget( (GdkEvent*) event );
357+ toplevel = gtk_widget_get_toplevel (widget);
358+
359+ mouse_pressed = FALSE;
360+ on_same_widget = TRUE;
361+
362+ if (GTK_IS_WINDOW (toplevel))
363+ {
364+ if( !on_same_widget && GTK_IS_WIDGET(GTK_WINDOW(toplevel)->focus_widget) )
365+ gtk_window_set_prev_focus_widget( GTK_WINDOW(toplevel), GTK_WINDOW(toplevel)->focus_widget );
366+ else
367+ gtk_window_set_prev_focus_widget( GTK_WINDOW(toplevel), event_widget );
368+ }
369+ }
370+ return FALSE;
371+}
372+
373+/**
374+ * gtk_widget_enter_notify_event
375+ * @widget: a #GtkWidget
376+ * @event: a #GtkEventCrossing
377+ *
378+**/
379+static gboolean gtk_widget_enter_notify_event( GtkWidget *widget, GdkEventCrossing *event )
380+{
381+ GtkWidget *toplevel;
382+ GtkWidget *event_widget;
383+ /*if( GTK_IS_ENTRY(widget) )
384+ return FALSE;*/
385+
386+ toplevel = gtk_widget_get_toplevel (widget);
387+ event_widget = gtk_get_event_widget ( (GdkEvent*) event );
388+
389+ if(mouse_pressed && !on_same_widget && gtk_window_get_prev_focus_widget( GTK_WINDOW(toplevel) ) == event_widget)
390+ {
391+/* GtkWidget *temp;*/
392+ on_same_widget = TRUE;
393+
394+/* temp = gtk_window_get_prev_focus_widget( GTK_WINDOW(toplevel) );*/
395+ if( GTK_IS_WIDGET(GTK_WINDOW(toplevel)->focus_widget) )
396+ {
397+ gtk_window_set_prev_focus_widget( GTK_WINDOW(toplevel), GTK_WINDOW(toplevel)->focus_widget );
398+ if( GTK_WIDGET_CAN_FOCUS(event_widget) )
399+ gtk_widget_grab_focus( event_widget );
400+ else
401+ gtk_widget_activate( event_widget );
402+ }
403+ }
404+ return FALSE;
405+}
406+
407+
408+/**
409+ * gtk_widget_leave_notify_event
410+ * @widget: a #GtkWidget
411+ * @event: a #GtkEventCrossing
412+ *
413+**/
414+static gboolean gtk_widget_leave_notify_event( GtkWidget *widget, GdkEventCrossing *event )
415+{
416+ if( mouse_pressed && on_same_widget /*&& !GTK_IS_ENTRY(widget)*/ )
417+ {
418+ GtkWidget *event_widget;
419+ GtkWidget *toplevel;
420+ GtkWidget *temp;
421+ toplevel = gtk_widget_get_toplevel( widget );
422+ event_widget = gtk_get_event_widget( (GdkEvent*) event );
423+ on_same_widget = FALSE;
424+
425+ temp = gtk_window_get_prev_focus_widget( GTK_WINDOW(toplevel) );
426+ if( GTK_IS_WIDGET(temp) &&
427+ gtk_window_has_toplevel_focus(GTK_WINDOW(toplevel)) )
428+ {
429+ gtk_window_set_prev_focus_widget( GTK_WINDOW(toplevel), event_widget );
430+ if( GTK_WIDGET_CAN_FOCUS(temp) )
431+ gtk_widget_grab_focus( temp );
432+ else
433+ gtk_widget_activate( temp );
434+ }
435+ }
436+ return FALSE;
437+}
438+
439+
440 #define WIDGET_REALIZED_FOR_EVENT(widget, event) \
441 (event->type == GDK_FOCUS_CHANGE || GTK_WIDGET_REALIZED(widget))
442
443@@ -3947,11 +4241,14 @@
444 static void
445 gtk_widget_real_grab_focus (GtkWidget *focus_widget)
446 {
447- if (GTK_WIDGET_CAN_FOCUS (focus_widget))
448+ if (GTK_WIDGET_CAN_FOCUS (focus_widget) &&
449+ GTK_WIDGET_VISIBLE (focus_widget))
450 {
451+ static GtkIMContext *last_context = NULL;
452 GtkWidget *toplevel;
453 GtkWidget *widget;
454-
455+ GtkIMContext *context;
456+
457 /* clear the current focus setting, break if the current widget
458 * is the focus widget's parent, since containers above that will
459 * be set by the next loop.
460@@ -3972,6 +4269,53 @@
461
462 return;
463 }
464+
465+ /* Focus change stuff (previously in modified im context) */
466+ if (GTK_IS_ENTRY (widget))
467+ context = GTK_ENTRY (widget)->im_context;
468+ else if (GTK_IS_TEXT_VIEW (widget))
469+ context = GTK_TEXT_VIEW (widget)->im_context;
470+ else
471+ context = NULL;
472+
473+ if (context || last_context)
474+ {
475+ gboolean is_combo, is_inside_toolbar;
476+ GtkWidget *parent;
477+
478+ parent = gtk_widget_get_parent (focus_widget);
479+ is_combo = GTK_IS_TOGGLE_BUTTON (focus_widget) &&
480+ (GTK_IS_COMBO_BOX_ENTRY (parent) ||
481+ GTK_IS_COMBO_BOX (parent));
482+ is_inside_toolbar =
483+ gtk_widget_get_ancestor (focus_widget,
484+ GTK_TYPE_TOOLBAR) != NULL;
485+
486+ if (focus_widget == NULL ||
487+ !GTK_IS_ENTRY (focus_widget) &&
488+ !GTK_IS_TEXT_VIEW (focus_widget) &&
489+ !GTK_IS_SCROLLBAR (focus_widget) &&
490+ !GTK_IS_MENU_ITEM (focus_widget) &&
491+ !GTK_IS_MENU (focus_widget) &&
492+ !is_inside_toolbar &&
493+ !is_combo)
494+ {
495+ /* we can't hide IM without IM context. it's possible to move
496+ * focus to widget which doesn't have IM context, but which
497+ * doesn't want IM to be hidden either. So, we have this
498+ * static last_context variable which is used... */
499+ gtk_im_context_hide (context != NULL
500+ ? context : last_context);
501+ }
502+
503+ if (context)
504+ {
505+ if (last_context != NULL)
506+ g_object_unref (last_context);
507+ last_context = context;
508+ g_object_ref (last_context);
509+ }
510+ }
511
512 if (widget)
513 {
514@@ -4462,9 +4806,13 @@
515 {
516 g_return_if_fail (GTK_IS_WIDGET (widget));
517
518- if (!GTK_WIDGET_USER_STYLE (widget) &&
519- !GTK_WIDGET_RC_STYLE (widget))
520+ if (!GTK_WIDGET_USER_STYLE (widget) && !GTK_WIDGET_RC_STYLE (widget))
521+ {
522+ gboolean hfh = FALSE;
523 gtk_widget_reset_rc_style (widget);
524+ gtk_widget_style_get( widget, "hildon-focus-handling", &hfh, NULL );
525+ gtk_widget_set_focus_handling( widget, hfh );
526+ }
527 }
528
529 /* Look up the RC style for this widget, unsetting any user style that
530@@ -6396,7 +6744,7 @@
531
532 if (!GTK_WIDGET_DIRECTION_SET (widget))
533 gtk_widget_emit_direction_changed (widget, old_dir);
534-
535+
536 if (GTK_IS_CONTAINER (widget))
537 gtk_container_forall (GTK_CONTAINER (widget),
538 gtk_widget_set_default_direction_recurse,
539@@ -6405,6 +6753,13 @@
540 g_object_unref (widget);
541 }
542
543+/* Non static */
544+void gtk_widget_set_direction_recursive(GtkWidget * widget, GtkTextDirection dir )
545+{
546+ gtk_widget_set_default_direction_recurse( widget, GUINT_TO_POINTER(dir) );
547+}
548+
549+
550 /**
551 * gtk_widget_set_default_direction:
552 * @dir: the new default direction. This cannot be
553@@ -6422,7 +6777,7 @@
554 {
555 GList *toplevels, *tmp_list;
556 GtkTextDirection old_dir = gtk_default_direction;
557-
558+
559 gtk_default_direction = dir;
560
561 tmp_list = toplevels = gtk_window_list_toplevels ();
562@@ -6497,6 +6852,7 @@
563 gtk_widget_finalize (GObject *object)
564 {
565 GtkWidget *widget = GTK_WIDGET (object);
566+ GtkWidgetPrivate *priv = GTK_WIDGET_GET_PRIVATE(object);
567 GtkWidgetAuxInfo *aux_info;
568 gint *events;
569 GdkExtensionMode *mode;
570@@ -6507,6 +6863,12 @@
571 g_object_unref (widget->style);
572 widget->style = NULL;
573
574+ if (priv->timer_id)
575+ {
576+ g_source_remove (priv->timer_id);
577+ priv->timer_id = 0;
578+ }
579+
580 if (widget->name)
581 g_free (widget->name);
582
583@@ -6526,6 +6888,12 @@
584 if (accessible)
585 g_object_unref (accessible);
586
587+ if (GTK_IS_MENU(priv->menu))
588+ gtk_widget_destroy (priv->menu);
589+
590+ if (priv->fake_event)
591+ gdk_event_free (priv->fake_event);
592+
593 G_OBJECT_CLASS (parent_class)->finalize (object);
594 }
595
596@@ -7577,3 +7945,450 @@
597
598 g_object_notify (G_OBJECT (widget), "no_show_all");
599 }
600+
601+void gtk_widget_insensitive_press ( GtkWidget *widget )
602+{
603+ g_return_if_fail (GTK_IS_WIDGET (widget));
604+
605+ g_signal_emit(widget, widget_signals[INSENSITIVE_PRESS], 0);
606+}
607+
608+/*Tap And Hold*/
609+
610+#ifdef TAP_AND_HOLD_ANIMATION
611+static void
612+init_tap_and_hold_animation( GtkWidgetPrivate *priv )
613+{
614+ GTimeVal time;
615+ if( priv->anim )
616+ {
617+ g_get_current_time( &time );
618+ priv->iter = gdk_pixbuf_animation_get_iter( priv->anim, &time );
619+ priv->interval = gdk_pixbuf_animation_iter_get_delay_time( priv->iter );
620+ }
621+}
622+
623+static void
624+timeout_tap_and_hold_animation( GtkWidgetPrivate *priv )
625+{
626+ GdkScreen *screen;
627+ GdkPixbuf *pic;
628+ GdkCursor *cursor;
629+ GTimeVal time;
630+
631+ if( priv->anim )
632+ {
633+ screen = gdk_screen_get_default();
634+ g_get_current_time( &time );
635+
636+ pic = gdk_pixbuf_animation_iter_get_pixbuf( priv->iter );
637+ cursor = gdk_cursor_new_from_pixbuf( gdk_display_get_default(), pic,
638+ priv->width, priv->height );
639+
640+ gdk_window_set_cursor( priv->fake_event->button.window, cursor );
641+
642+ gdk_pixbuf_animation_iter_advance( priv->iter, &time );
643+ }
644+}
645+
646+static void
647+stop_tap_and_hold_animation( GtkWidgetPrivate *priv )
648+{
649+ if( priv->anim )
650+ {
651+ gdk_window_set_cursor( priv->fake_event->button.window, NULL );
652+ }
653+}
654+
655+
656+#endif
657+
658+void tap_and_hold_remove_timer( GtkWidgetPrivate *priv )
659+{
660+ if (priv->timer_id)
661+ {
662+ g_source_remove (priv->timer_id);
663+ priv->timer_id = 0;
664+ #ifdef TAP_AND_HOLD_ANIMATION
665+ stop_tap_and_hold_animation( priv );
666+ #endif
667+ }
668+}
669+
670+/**
671+ * gtk_widget_tap_and_hold_setup:
672+ *
673+ * @widget : A @GtkWidget
674+ * @menu : A @GtkWidget
675+ * @func : A @GtkCallback
676+ * @flags : A @GtkWidgetTapAndHoldFlags
677+ *
678+ * Setups the tap and hold functionality to the @widget.
679+ * The @menu is shown when the functionality is activated.
680+ * If the @menu is wanted to be positioned in a different way than the
681+ * gtk+ default, the menuposition @func can be passed as a third parameter.
682+ * Fourth parameter, @flags are explaned with detail in the documentation.
683+ */
684+void gtk_widget_tap_and_hold_setup (GtkWidget *widget, GtkWidget *menu,
685+ GtkCallback func, GtkWidgetTapAndHoldFlags flags)
686+{
687+ /*GtkWidgetClass *klass = GTK_WIDGET_GET_CLASS(widget);*/
688+ g_return_if_fail( GTK_IS_WIDGET(widget));
689+ g_return_if_fail(menu == NULL || GTK_IS_MENU(menu));
690+ g_signal_emit( widget, widget_signals[TAP_AND_HOLD_SETUP], 0, menu, func,
691+ flags );
692+}
693+
694+static void gtk_widget_tap_and_hold_setup_real (GtkWidget *widget,
695+ GtkWidget *menu, GtkCallback func, GtkWidgetTapAndHoldFlags flags)
696+{
697+ #ifdef TAP_AND_HOLD_ANIMATION
698+ GtkStyle *style = NULL;
699+ GError *error = NULL;
700+ #endif
701+ GtkWidgetPrivate *priv;
702+ g_return_if_fail (GTK_IS_WIDGET(widget));
703+ g_return_if_fail (menu == NULL || GTK_IS_MENU(menu));
704+ priv = GTK_WIDGET_GET_PRIVATE (widget);
705+
706+ if (priv->signals_connected)
707+ return;
708+
709+ _gtk_menu_enable_context_menu_behavior (menu);
710+
711+ priv->menu = menu;
712+ priv->func = (GtkMenuPositionFunc)func;
713+ priv->signals_connected = TRUE;
714+ priv->timer_counter = 0;
715+ priv->flags = flags;
716+
717+ if (flags & GTK_TAP_AND_HOLD_PASS_PRESS)
718+ {
719+ g_signal_connect( widget, "button-press-event",
720+ G_CALLBACK(gtk_widget_tap_and_hold_button_press_with_events), priv );
721+ g_signal_connect( widget, "button-release-event",
722+ G_CALLBACK(gtk_widget_tap_and_hold_button_release_with_events), priv );
723+ g_signal_connect( widget, "leave-notify-event",
724+ G_CALLBACK(gtk_widget_tap_and_hold_leave_notify_with_events), priv );
725+ }
726+ else
727+ {
728+ g_signal_connect( widget, "button-press-event",
729+ G_CALLBACK(gtk_widget_tap_and_hold_button_press), priv );
730+ g_signal_connect( widget, "button-release-event",
731+ G_CALLBACK(gtk_widget_tap_and_hold_button_release), priv );
732+ g_signal_connect( widget, "leave-notify-event",
733+ G_CALLBACK(gtk_widget_tap_and_hold_leave_notify), priv );
734+ }
735+
736+#ifdef TAP_AND_HOLD_ANIMATION
737+ priv->anim = NULL;
738+ style = gtk_rc_get_style_by_paths(gtk_settings_get_default(),
739+ "gtk-tap-and-hold-animation",
740+ NULL, G_TYPE_NONE);
741+
742+ if( style )
743+ {
744+
745+ priv->anim = gdk_pixbuf_animation_new_from_file(
746+ (gchar*)style->rc_style->bg_pixmap_name[0], &error );
747+
748+ priv->width = gdk_pixbuf_animation_get_width( priv->anim )/2;
749+ priv->height = gdk_pixbuf_animation_get_height( priv->anim )/2;
750+ }
751+#endif
752+}
753+
754+static void gtk_widget_real_tap_and_hold(GtkWidget *widget)
755+{
756+ GtkWidgetPrivate *priv = GTK_WIDGET_GET_PRIVATE (widget);
757+
758+ if (GTK_IS_MENU(priv->menu))
759+ gtk_menu_popup( GTK_MENU(priv->menu), NULL, NULL,
760+ (GtkMenuPositionFunc)priv->func,
761+ widget, 1, gdk_x11_get_server_time(widget->window) );
762+}
763+
764+static gboolean gtk_widget_tap_and_hold_timeout (GtkWidget *widget)
765+{
766+ GtkWidgetPrivate *priv= GTK_WIDGET_GET_PRIVATE(widget);
767+ gboolean return_value;
768+ gint x = 0, y = 0;
769+
770+ #ifdef TAP_AND_HOLD_ANIMATION
771+ timeout_tap_and_hold_animation( priv );
772+ #endif
773+
774+ if( priv->timer_counter )
775+ priv->timer_counter--;
776+ else
777+ priv->timer_id = 0;
778+
779+ gdk_display_get_pointer( gdk_x11_lookup_xdisplay(
780+ GDK_WINDOW_XDISPLAY(priv->fake_event->button.window) ),
781+ NULL, &x, &y, NULL );
782+
783+ if ((abs(x - priv->x) > GTK_TAP_THRESHOLD) ||
784+ (abs(y - priv->y) > GTK_TAP_THRESHOLD))
785+ {
786+ if (priv->stype != priv->type_on_press)
787+ gtk_widget_set_state( widget, priv->stype );
788+ priv->timer_counter = 0;
789+ priv->timer_id = 0;
790+ priv->x = priv->y = 0;
791+ priv->run_press = FALSE;
792+ g_signal_emit_by_name (G_OBJECT(widget), "button-press-event",
793+ priv->fake_event, &return_value);
794+ return FALSE;
795+ }
796+ if (!priv->timer_id)
797+ {
798+ if (priv->stype != priv->type_on_press)
799+ gtk_widget_set_state( widget, priv->stype );
800+ #ifdef TAP_AND_HOLD_ANIMATION
801+ stop_tap_and_hold_animation( priv );
802+ #endif
803+ g_signal_emit(widget, widget_signals[TAP_AND_HOLD], 0);
804+ priv->x = x;
805+ priv->y = y;
806+ return FALSE;
807+ }
808+ return TRUE;
809+}
810+
811+static gboolean gtk_widget_tap_and_hold_button_press (GtkWidget *widget,
812+ GdkEvent *event, GtkWidgetPrivate *priv)
813+{
814+ if (!priv->run_press || event->button.button != 1)
815+ {
816+ priv->run_press = TRUE;
817+ return FALSE;
818+ }
819+
820+ if (event->button.type == GDK_2BUTTON_PRESS)
821+ return FALSE;
822+
823+ if (priv->fake_event)
824+ gdk_event_free (priv->fake_event);
825+ priv->fake_event = gdk_event_copy(event);
826+
827+ if (!priv->timer_id)
828+ {
829+ priv->stype = GTK_WIDGET_STATE(widget);
830+ if (priv->stype != priv->type_on_press)
831+ gtk_widget_set_state( widget, priv->type_on_press );
832+ gdk_display_get_pointer(
833+ gdk_x11_lookup_xdisplay( GDK_WINDOW_XDISPLAY(event->button.window) ),
834+ NULL, &priv->x, &priv->y, NULL );
835+ priv->timer_counter = GTK_TAP_AND_HOLD_TIMER_COUNTER;
836+
837+ #ifdef TAP_AND_HOLD_ANIMATION
838+ init_tap_and_hold_animation( priv );
839+ #endif
840+ priv->timer_id = g_timeout_add( priv->interval,
841+ (GSourceFunc)gtk_widget_tap_and_hold_timeout, widget );
842+ }
843+return TRUE;
844+}
845+
846+static gboolean gtk_widget_tap_and_hold_button_release (GtkWidget *widget,
847+ GdkEvent *event, GtkWidgetPrivate *priv)
848+{
849+ gboolean return_value;
850+
851+ if (!priv->run_press || event->button.button != 1 || !priv->timer_id ||
852+ event->button.type == GDK_2BUTTON_PRESS)
853+ return FALSE;
854+
855+ g_source_remove (priv->timer_id);
856+ priv->timer_id = 0;
857+ priv->x = priv->y = priv->timer_counter = 0;
858+ if (priv->stype != priv->type_on_press)
859+ gtk_widget_set_state (widget, priv->stype);
860+
861+ #ifdef TAP_AND_HOLD_ANIMATION
862+ stop_tap_and_hold_animation( priv );
863+ #endif
864+
865+ if (priv->flags & GTK_TAP_AND_HOLD_NO_SIGNALS)
866+ return FALSE;
867+
868+ priv->run_press = FALSE;
869+
870+ g_signal_emit_by_name (G_OBJECT(widget), "button-press-event",
871+ priv->fake_event, &return_value);
872+
873+return FALSE;
874+}
875+
876+static gboolean gtk_widget_tap_and_hold_leave_notify (GtkWidget *widget,
877+ GdkEvent *event, GtkWidgetPrivate *priv)
878+{
879+ gboolean return_value;
880+ if (!priv->timer_id)
881+ return FALSE;
882+
883+ g_source_remove (priv->timer_id);
884+ priv->timer_id = 0;
885+ priv->x = priv->y = priv->timer_counter = 0;
886+ if (priv->stype != priv->type_on_press)
887+ gtk_widget_set_state (widget, priv->stype);
888+
889+ #ifdef TAP_AND_HOLD_ANIMATION
890+ stop_tap_and_hold_animation( priv );
891+ #endif
892+ priv->run_press = FALSE;
893+ g_signal_emit_by_name (G_OBJECT(widget), "button-press-event",
894+ priv->fake_event, &return_value);
895+
896+return FALSE;
897+}
898+
899+static gboolean
900+gtk_widget_tap_and_hold_timeout_with_events (GtkWidget *widget)
901+{
902+ gint x, y;
903+ GtkWidgetPrivate *priv= GTK_WIDGET_GET_PRIVATE(widget);
904+
905+ g_return_val_if_fail (priv->fake_event, FALSE);
906+
907+ #ifdef TAP_AND_HOLD_ANIMATION
908+ timeout_tap_and_hold_animation( priv );
909+ #endif
910+
911+ gdk_display_get_pointer( gdk_x11_lookup_xdisplay(
912+ GDK_WINDOW_XDISPLAY(priv->fake_event->button.window) ),
913+ NULL, &x, &y, NULL );
914+
915+ if( priv->timer_counter )
916+ {
917+ priv->timer_counter--;
918+ if ((abs(x - priv->x) > GTK_TAP_THRESHOLD) ||
919+ (abs(y - priv->y) > GTK_TAP_THRESHOLD))
920+ {
921+ #ifdef TAP_AND_HOLD_ANIMATION
922+ stop_tap_and_hold_animation( priv );
923+ #endif
924+ tap_and_hold_remove_timer( priv );
925+ }
926+ return TRUE;
927+ }
928+
929+ if (!((abs(x - priv->x) > GTK_TAP_THRESHOLD) ||
930+ (abs(y - priv->y) > GTK_TAP_THRESHOLD)))
931+ {
932+ gboolean return_value;
933+ priv->fake_event->button.type = GDK_BUTTON_RELEASE;
934+ priv->fake_event->button.x = x;
935+ priv->fake_event->button.y = y;
936+ g_signal_emit_by_name (G_OBJECT(widget), "button-release-event",
937+ priv->fake_event, &return_value);
938+ #ifdef TAP_AND_HOLD_ANIMATION
939+ stop_tap_and_hold_animation( priv );
940+ #endif
941+ g_signal_emit(widget, widget_signals[TAP_AND_HOLD], 0);
942+ priv->timer_id = 0;
943+ priv->x = x;
944+ priv->y = y;
945+ gdk_event_free(priv->fake_event);
946+ priv->fake_event = NULL;
947+ }
948+
949+
950+ if (priv->timer_id)
951+ {
952+ g_source_remove (priv->timer_id);
953+ priv->timer_id = 0;
954+ }
955+
956+ return FALSE;
957+}
958+
959+static gboolean gtk_widget_tap_and_hold_button_press_with_events(
960+ GtkWidget *widget, GdkEvent *event, GtkWidgetPrivate *priv)
961+{
962+ if( priv->timer_id || event->button.type == GDK_2BUTTON_PRESS)
963+ return FALSE;
964+
965+ if (priv->fake_event)
966+ gdk_event_free (priv->fake_event);
967+ priv->fake_event = gdk_event_copy (event);
968+
969+ gdk_display_get_pointer(
970+ gdk_x11_lookup_xdisplay(GDK_WINDOW_XDISPLAY(event->button.window)),
971+ NULL, &priv->x, &priv->y, NULL);
972+ #ifdef TAP_AND_HOLD_ANIMATION
973+ init_tap_and_hold_animation( priv );
974+ #endif
975+ priv->timer_counter = GTK_TAP_AND_HOLD_TIMER_COUNTER;
976+ priv->timer_id = g_timeout_add(priv->interval,
977+ (GSourceFunc)gtk_widget_tap_and_hold_timeout_with_events,
978+ widget);
979+ return FALSE;
980+}
981+
982+static gboolean gtk_widget_tap_and_hold_button_release_with_events(
983+ GtkWidget *widget, GdkEvent *event, GtkWidgetPrivate *priv)
984+{
985+ tap_and_hold_remove_timer( priv );
986+ return FALSE;
987+}
988+
989+static gboolean gtk_widget_tap_and_hold_leave_notify_with_events(
990+ GtkWidget *widget, GdkEvent *event, GtkWidgetPrivate *priv)
991+{
992+ tap_and_hold_remove_timer( priv );
993+ return FALSE;
994+}
995+
996+/**
997+ * gtk_widget_tap_and_hold_menu_position_top:
998+ * @menu: a #GtkMenu
999+ * @x: x cordinate to be returned
1000+ * @y: y cordinate to be returned
1001+ * @push_in: If going off screen, push it pack on the screen
1002+ * @widget: a #GtkWidget
1003+ *
1004+ * Pre-made menu positioning function.
1005+ * It positiones the @menu over the @widget.
1006+ *
1007+ **/
1008+void gtk_widget_tap_and_hold_menu_position_top( GtkWidget *menu,
1009+ gint *x, gint *y, gboolean *push_in, GtkWidget *widget )
1010+{
1011+ /*
1012+ * This function positiones the menu above widgets.
1013+ * This is a modified version of the position function
1014+ * gtk_combo_box_position_over.
1015+ */
1016+ GtkWidget *topw;
1017+ GtkRequisition requisition;
1018+ gint screen_width = 0;
1019+ gint menu_xpos = 0;
1020+ gint menu_ypos = 0;
1021+ gint w_xpos = 0, w_ypos = 0;
1022+
1023+ gtk_widget_size_request( menu, &requisition );
1024+
1025+ topw = gtk_widget_get_toplevel(widget);
1026+ gdk_window_get_origin( topw->window, &w_xpos, &w_ypos );
1027+
1028+ menu_xpos += widget->allocation.x + w_xpos;
1029+ menu_ypos += widget->allocation.y + w_ypos - requisition.height;
1030+
1031+ if( gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL )
1032+ menu_xpos = menu_xpos + widget->allocation.width - requisition.width;
1033+
1034+ screen_width = gdk_screen_get_width( gtk_widget_get_screen(widget) );
1035+
1036+ if( menu_xpos < w_xpos )
1037+ menu_xpos = w_xpos;
1038+ else if( (menu_xpos + requisition.width) > screen_width )
1039+ menu_xpos -= ( (menu_xpos + requisition.width) - screen_width );
1040+ if( menu_ypos < w_ypos )
1041+ menu_ypos = w_ypos;
1042+
1043+ *x = menu_xpos;
1044+ *y = menu_ypos;
1045+ *push_in = TRUE;
1046+}