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 @@
+--- gtk+-2.6.4/gtk/gtkwidget.c 2005-02-24 18:44:02.000000000 +0200
++++ gtk+-2.6.4/gtk/gtkwidget.c 2005-04-06 16:19:38.386702696 +0300
+@@ -28,6 +28,8 @@
+ #include <stdarg.h>
+ #include <string.h>
+ #include <locale.h>
++#include <stdlib.h>
++#include <x11/gdkx.h>
+ #include "gtkalias.h"
+ #include "gtkcontainer.h"
+ #include "gtkaccelmap.h"
+@@ -44,6 +46,11 @@
+ #include "gtkwindow.h"
+ #include "gtkbindings.h"
+ #include "gtkprivate.h"
++#include "gtktreeview.h"
++#include "gtkentry.h"
++#include "gtktextview.h"
++#include "gtkimcontext.h"
++#include "gtkmenu.h"
+ #include "gdk/gdk.h"
+ #include "gdk/gdkprivate.h" /* Used in gtk_reset_shapes_recurse to avoid copy */
+ #include <gobject/gvaluecollector.h>
+@@ -53,11 +60,30 @@
+ #include "gtkaccessible.h"
+ #include "gtktooltips.h"
+ #include "gtkinvisible.h"
++#include "gtkscrollbar.h" /* Following are needed for special focus changes */
++#include "gtktoolbar.h"
++#include "gtkmenu.h"
++#include "gtkmenuitem.h"
++#include "gtktogglebutton.h"
++#include "gtkcomboboxentry.h"
++#include "gtktogglebutton.h"
++#include "gtkcomboboxentry.h"
+
+ #define WIDGET_CLASS(w) GTK_WIDGET_GET_CLASS (w)
+ #define INIT_PATH_SIZE (512)
+
++#define GTK_TAP_THRESHOLD 30
++#define GTK_TAP_MENU_THRESHOLD 20
++#define GTK_TAP_AND_HOLD_TIMER_COUNTER 11
++#define GTK_TAP_AND_HOLD_TIMER_INTERVAL 100
+
++typedef struct _GtkWidgetPrivate GtkWidgetPrivate;
++
++#define GTK_WIDGET_GET_PRIVATE(obj) ( G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
++ GTK_TYPE_WIDGET, GtkWidgetPrivate) )
++
++#define TAP_AND_HOLD_ANIMATION 1
++
+ enum {
+ SHOW,
+ HIDE,
+@@ -120,6 +146,9 @@
+ ACCEL_CLOSURES_CHANGED,
+ SCREEN_CHANGED,
+ CAN_ACTIVATE_ACCEL,
++ INSENSITIVE_PRESS,
++ TAP_AND_HOLD,
++ TAP_AND_HOLD_SETUP,
+ LAST_SIGNAL
+ };
+
+@@ -142,7 +171,8 @@
+ PROP_STYLE,
+ PROP_EVENTS,
+ PROP_EXTENSION_EVENTS,
+- PROP_NO_SHOW_ALL
++ PROP_NO_SHOW_ALL,
++ PROP_TAP_AND_HOLD
+ };
+
+ typedef struct _GtkStateData GtkStateData;
+@@ -155,7 +185,50 @@
+ guint use_forall : 1;
+ };
+
++struct _GtkWidgetPrivate
++{
++ GtkWidget *menu;
++ guint timer_id;
++
++ GtkStateType stype;
++ GtkStateType type_on_press;
++ GdkEvent *fake_event;
++ GtkMenuPositionFunc func;
++ gint x, y;
++ gint timer_counter;
++ gint run_press : 1;
++ gint button_pressed : 1;
++ gint signals_connected : 1;
++ GtkWidgetTapAndHoldFlags flags;
++ gboolean state_set;
++ guint interval;
++
++#ifdef TAP_AND_HOLD_ANIMATION
++ GdkPixbufAnimation *anim;
++ GdkPixbufAnimationIter *iter;
++ guint width, height;
++#endif
++};
++
+
++/* --- Tap And Hold --- */
++static gboolean gtk_widget_tap_and_hold_button_press_with_events( GtkWidget *widget,
++ GdkEvent *event, GtkWidgetPrivate *priv );
++static gboolean gtk_widget_tap_and_hold_button_release_with_events( GtkWidget *widget,
++ GdkEvent *event, GtkWidgetPrivate *priv );
++static gboolean gtk_widget_tap_and_hold_leave_notify_with_events( GtkWidget *widget,
++ GdkEvent *event, GtkWidgetPrivate *priv );
++static gboolean gtk_widget_tap_and_hold_timeout_with_events( GtkWidget *widget );
++static gboolean gtk_widget_tap_and_hold_timeout( GtkWidget *widget );
++static gboolean gtk_widget_tap_and_hold_button_press( GtkWidget *widget,
++ GdkEvent *event, GtkWidgetPrivate *priv );
++static gboolean gtk_widget_tap_and_hold_button_release( GtkWidget *widget,
++ GdkEvent *event, GtkWidgetPrivate *priv );
++static gboolean gtk_widget_tap_and_hold_leave_notify( GtkWidget *widget,
++ GdkEvent *event, GtkWidgetPrivate *priv );
++static void gtk_widget_tap_and_hold_setup_real( GtkWidget *widget,
++ GtkWidget *menu, GtkCallback func, GtkWidgetTapAndHoldFlags flags );
++static void gtk_widget_real_tap_and_hold(GtkWidget *widget);
+ /* --- prototypes --- */
+ static void gtk_widget_class_init (GtkWidgetClass *klass);
+ static void gtk_widget_init (GtkWidget *widget);
+@@ -228,6 +301,13 @@
+ gint width,
+ gint height);
+
++/*Hildon focus handling*/
++static void gtk_widget_set_focus_handling( GtkWidget *widget, gboolean state );
++
++static gboolean gtk_widget_enter_notify_event( GtkWidget *widget, GdkEventCrossing *event );
++static gboolean gtk_widget_leave_notify_event( GtkWidget *widget, GdkEventCrossing *event );
++static gint gtk_widget_button_release_event( GtkWidget *widget, GdkEventButton *event );
++static gint gtk_widget_button_press_event( GtkWidget *widget, GdkEventButton *event );
+
+ /* --- variables --- */
+ static gpointer parent_class = NULL;
+@@ -239,6 +319,9 @@
+ static GtkTextDirection gtk_default_direction = GTK_TEXT_DIR_LTR;
+ static GParamSpecPool *style_property_spec_pool = NULL;
+
++static gboolean on_same_widget = FALSE; /*Hildon focus handling*/
++static gboolean mouse_pressed = FALSE; /*Hildon focus handling*/
++
+ static GQuark quark_property_parser = 0;
+ static GQuark quark_aux_info = 0;
+ static GQuark quark_accel_path = 0;
+@@ -396,6 +479,9 @@
+ klass->drag_data_received = NULL;
+ klass->screen_changed = NULL;
+ klass->can_activate_accel = gtk_widget_real_can_activate_accel;
++ klass->tap_and_hold_setup = gtk_widget_tap_and_hold_setup_real;
++ klass->insensitive_press = NULL;
++ klass->tap_and_hold = gtk_widget_real_tap_and_hold;
+
+ klass->show_help = gtk_widget_real_show_help;
+
+@@ -404,6 +490,18 @@
+
+ klass->no_expose_event = NULL;
+
++ g_type_class_add_private( klass, sizeof(GtkWidgetPrivate) );
++
++ g_object_class_install_property (gobject_class,
++ PROP_TAP_AND_HOLD,
++ g_param_spec_int ("tap_and_hold_state",
++ P_("Tap and hold State type"),
++ P_("Sets the state to be used to the tap and hold functionality. The default is GTK_STATE_NORMAL"),
++ 0,
++ 4, /*4 == Last state in GTK+-2.0*/
++ GTK_STATE_NORMAL,
++ G_PARAM_READWRITE));
++
+ g_object_class_install_property (gobject_class,
+ PROP_NAME,
+ g_param_spec_string ("name",
+@@ -1389,6 +1487,31 @@
+ _gtk_marshal_BOOLEAN__UINT,
+ G_TYPE_BOOLEAN, 1, G_TYPE_UINT);
+
++ widget_signals[INSENSITIVE_PRESS] =
++ g_signal_new ("insensitive_press",
++ G_TYPE_FROM_CLASS (gobject_class),
++ G_SIGNAL_RUN_FIRST,
++ G_STRUCT_OFFSET (GtkWidgetClass, insensitive_press),
++ NULL, NULL,
++ _gtk_marshal_VOID__VOID,
++ G_TYPE_NONE, 0);
++
++ widget_signals[TAP_AND_HOLD] =
++ g_signal_new("tap-and-hold", G_TYPE_FROM_CLASS(gobject_class),
++ G_SIGNAL_RUN_LAST,
++ G_STRUCT_OFFSET(GtkWidgetClass, tap_and_hold),
++ NULL, NULL,
++ _gtk_marshal_VOID__VOID,
++ G_TYPE_NONE, 0);
++
++ widget_signals[TAP_AND_HOLD_SETUP] =
++ g_signal_new("tap-and-hold-setup", G_TYPE_FROM_CLASS(gobject_class),
++ G_SIGNAL_RUN_LAST,
++ G_STRUCT_OFFSET(GtkWidgetClass, tap_and_hold_setup),
++ NULL, NULL, /*FIXME -- OBJECT_POINTER_FLAGS*/
++ _gtk_marshal_VOID__OBJECT_UINT_FLAGS,
++ G_TYPE_NONE, 3, G_TYPE_OBJECT, G_TYPE_POINTER, G_TYPE_UINT);
++
+ binding_set = gtk_binding_set_by_class (klass);
+ gtk_binding_entry_add_signal (binding_set, GDK_F10, GDK_SHIFT_MASK,
+ "popup_menu", 0);
+@@ -1418,7 +1541,12 @@
+ P_("Whether to draw the focus indicator inside widgets"),
+ TRUE,
+ G_PARAM_READABLE));
+-
++ gtk_widget_class_install_style_property (klass,
++ g_param_spec_boolean ("hildon-focus-handling",
++ P_("Hildon focus handling"),
++ P_("Whether the widget is using the hildon like focus handling or not"),
++ FALSE,
++ G_PARAM_READABLE));
+ gtk_widget_class_install_style_property (klass,
+ g_param_spec_int ("focus-line-width",
+ P_("Focus linewidth"),
+@@ -1543,6 +1671,8 @@
+ case PROP_NO_SHOW_ALL:
+ gtk_widget_set_no_show_all (widget, g_value_get_boolean (value));
+ break;
++ case PROP_TAP_AND_HOLD:
++ GTK_WIDGET_GET_PRIVATE(widget)->type_on_press = g_value_get_int(value);
+ default:
+ break;
+ }
+@@ -1637,16 +1767,45 @@
+ case PROP_NO_SHOW_ALL:
+ g_value_set_boolean (value, gtk_widget_get_no_show_all (widget));
+ break;
++ case PROP_TAP_AND_HOLD:
++ g_value_set_int (value,
++ (int)GTK_WIDGET_GET_PRIVATE(widget)->type_on_press);
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+ }
+
++static void gtk_widget_set_focus_handling( GtkWidget *widget, gboolean state )
++{
++ GtkWidgetPrivate *priv;
++ priv = GTK_WIDGET_GET_PRIVATE (widget);
++
++ if( state && GTK_WIDGET_CAN_FOCUS(widget) )
++ {
++ if (!priv->state_set)
++ {
++ g_signal_connect( G_OBJECT(widget), "button-press-event",
++ G_CALLBACK(gtk_widget_button_press_event), NULL );
++ g_signal_connect( G_OBJECT(widget), "button-release-event",
++ G_CALLBACK(gtk_widget_button_release_event), NULL );
++ g_signal_connect( G_OBJECT(widget), "enter-notify-event",
++ G_CALLBACK(gtk_widget_enter_notify_event), NULL );
++ g_signal_connect( G_OBJECT(widget), "leave-notify-event",
++ G_CALLBACK(gtk_widget_leave_notify_event), NULL );
++ priv->state_set = TRUE;
++ }
++ }
++}
++
+ static void
+ gtk_widget_init (GtkWidget *widget)
+ {
++ GtkWidgetPrivate *priv;
+ GTK_PRIVATE_FLAGS (widget) = PRIVATE_GTK_CHILD_VISIBLE;
++
++ priv = GTK_WIDGET_GET_PRIVATE(widget);
++
+ widget->state = GTK_STATE_NORMAL;
+ widget->saved_state = GTK_STATE_NORMAL;
+ widget->name = NULL;
+@@ -1659,6 +1818,18 @@
+ widget->window = NULL;
+ widget->parent = NULL;
+
++ priv->fake_event = NULL;
++ priv->timer_id = 0;
++ priv->menu = NULL;
++ priv->run_press = TRUE;
++ priv->signals_connected = FALSE;
++ priv->x = priv->y = 0;
++ priv->func = NULL;
++ priv->timer_counter = 0;
++ priv->flags = 0x0;
++ priv->state_set = FALSE;
++ priv->interval = GTK_TAP_AND_HOLD_TIMER_INTERVAL;
++
+ GTK_WIDGET_SET_FLAGS (widget,
+ GTK_SENSITIVE |
+ GTK_PARENT_SENSITIVE |
+@@ -1670,6 +1841,7 @@
+ GTK_PRIVATE_SET_FLAG (widget, GTK_ALLOC_NEEDED);
+
+ widget->style = gtk_widget_get_default_style ();
++
+ g_object_ref (widget->style);
+ }
+
+@@ -2153,6 +2325,7 @@
+
+ if ((GTK_WIDGET_FLAGS (widget) & GTK_NO_SHOW_ALL) != 0)
+ return;
++
+
+ class = GTK_WIDGET_GET_CLASS (widget);
+
+@@ -3400,6 +3573,127 @@
+ return FALSE;
+ }
+
++/**
++ * gtk_widget_button_press_event
++ * @widget: a #GtkWidget
++ * @event: a #GtkEventKey
++ *
++**/
++static gboolean gtk_widget_button_press_event(GtkWidget *widget, GdkEventButton *event )
++{
++ if( !mouse_pressed /*&& !GTK_IS_TREE_VIEW(widget) && !GTK_IS_ENTRY(widget)*/ )
++ {
++ GtkWidget *toplevel;
++ toplevel = gtk_widget_get_toplevel (widget);
++ if (GTK_IS_WINDOW (toplevel))
++ {
++ mouse_pressed = TRUE;
++
++ if( /*!gtk_window_get_prev_focus_widget(GTK_WINDOW(toplevel)) &&*/
++ GTK_IS_WIDGET(GTK_WINDOW(toplevel)->focus_widget) )
++ gtk_window_set_prev_focus_widget( GTK_WINDOW(toplevel),
++ GTK_WINDOW(toplevel)->focus_widget );
++ }
++ }
++ return FALSE;
++}
++
++/**
++ * gtk_widget_button_release_event
++ * @widget: a #GtkWidget
++ * @event: a #GtkEventKey
++ *
++**/
++static gboolean gtk_widget_button_release_event(GtkWidget *widget, GdkEventButton *event )
++{
++ if( mouse_pressed /*&& !GTK_IS_ENTRY(widget)*/ )
++ {
++ GtkWidget *toplevel;
++ GtkWidget *event_widget;
++ event_widget = gtk_get_event_widget( (GdkEvent*) event );
++ toplevel = gtk_widget_get_toplevel (widget);
++
++ mouse_pressed = FALSE;
++ on_same_widget = TRUE;
++
++ if (GTK_IS_WINDOW (toplevel))
++ {
++ if( !on_same_widget && GTK_IS_WIDGET(GTK_WINDOW(toplevel)->focus_widget) )
++ gtk_window_set_prev_focus_widget( GTK_WINDOW(toplevel), GTK_WINDOW(toplevel)->focus_widget );
++ else
++ gtk_window_set_prev_focus_widget( GTK_WINDOW(toplevel), event_widget );
++ }
++ }
++ return FALSE;
++}
++
++/**
++ * gtk_widget_enter_notify_event
++ * @widget: a #GtkWidget
++ * @event: a #GtkEventCrossing
++ *
++**/
++static gboolean gtk_widget_enter_notify_event( GtkWidget *widget, GdkEventCrossing *event )
++{
++ GtkWidget *toplevel;
++ GtkWidget *event_widget;
++ /*if( GTK_IS_ENTRY(widget) )
++ return FALSE;*/
++
++ toplevel = gtk_widget_get_toplevel (widget);
++ event_widget = gtk_get_event_widget ( (GdkEvent*) event );
++
++ if(mouse_pressed && !on_same_widget && gtk_window_get_prev_focus_widget( GTK_WINDOW(toplevel) ) == event_widget)
++ {
++/* GtkWidget *temp;*/
++ on_same_widget = TRUE;
++
++/* temp = gtk_window_get_prev_focus_widget( GTK_WINDOW(toplevel) );*/
++ if( GTK_IS_WIDGET(GTK_WINDOW(toplevel)->focus_widget) )
++ {
++ gtk_window_set_prev_focus_widget( GTK_WINDOW(toplevel), GTK_WINDOW(toplevel)->focus_widget );
++ if( GTK_WIDGET_CAN_FOCUS(event_widget) )
++ gtk_widget_grab_focus( event_widget );
++ else
++ gtk_widget_activate( event_widget );
++ }
++ }
++ return FALSE;
++}
++
++
++/**
++ * gtk_widget_leave_notify_event
++ * @widget: a #GtkWidget
++ * @event: a #GtkEventCrossing
++ *
++**/
++static gboolean gtk_widget_leave_notify_event( GtkWidget *widget, GdkEventCrossing *event )
++{
++ if( mouse_pressed && on_same_widget /*&& !GTK_IS_ENTRY(widget)*/ )
++ {
++ GtkWidget *event_widget;
++ GtkWidget *toplevel;
++ GtkWidget *temp;
++ toplevel = gtk_widget_get_toplevel( widget );
++ event_widget = gtk_get_event_widget( (GdkEvent*) event );
++ on_same_widget = FALSE;
++
++ temp = gtk_window_get_prev_focus_widget( GTK_WINDOW(toplevel) );
++ if( GTK_IS_WIDGET(temp) &&
++ gtk_window_has_toplevel_focus(GTK_WINDOW(toplevel)) )
++ {
++ gtk_window_set_prev_focus_widget( GTK_WINDOW(toplevel), event_widget );
++ if( GTK_WIDGET_CAN_FOCUS(temp) )
++ gtk_widget_grab_focus( temp );
++ else
++ gtk_widget_activate( temp );
++ }
++ }
++ return FALSE;
++}
++
++
+ #define WIDGET_REALIZED_FOR_EVENT(widget, event) \
+ (event->type == GDK_FOCUS_CHANGE || GTK_WIDGET_REALIZED(widget))
+
+@@ -3947,11 +4241,14 @@
+ static void
+ gtk_widget_real_grab_focus (GtkWidget *focus_widget)
+ {
+- if (GTK_WIDGET_CAN_FOCUS (focus_widget))
++ if (GTK_WIDGET_CAN_FOCUS (focus_widget) &&
++ GTK_WIDGET_VISIBLE (focus_widget))
+ {
++ static GtkIMContext *last_context = NULL;
+ GtkWidget *toplevel;
+ GtkWidget *widget;
+-
++ GtkIMContext *context;
++
+ /* clear the current focus setting, break if the current widget
+ * is the focus widget's parent, since containers above that will
+ * be set by the next loop.
+@@ -3972,6 +4269,53 @@
+
+ return;
+ }
++
++ /* Focus change stuff (previously in modified im context) */
++ if (GTK_IS_ENTRY (widget))
++ context = GTK_ENTRY (widget)->im_context;
++ else if (GTK_IS_TEXT_VIEW (widget))
++ context = GTK_TEXT_VIEW (widget)->im_context;
++ else
++ context = NULL;
++
++ if (context || last_context)
++ {
++ gboolean is_combo, is_inside_toolbar;
++ GtkWidget *parent;
++
++ parent = gtk_widget_get_parent (focus_widget);
++ is_combo = GTK_IS_TOGGLE_BUTTON (focus_widget) &&
++ (GTK_IS_COMBO_BOX_ENTRY (parent) ||
++ GTK_IS_COMBO_BOX (parent));
++ is_inside_toolbar =
++ gtk_widget_get_ancestor (focus_widget,
++ GTK_TYPE_TOOLBAR) != NULL;
++
++ if (focus_widget == NULL ||
++ !GTK_IS_ENTRY (focus_widget) &&
++ !GTK_IS_TEXT_VIEW (focus_widget) &&
++ !GTK_IS_SCROLLBAR (focus_widget) &&
++ !GTK_IS_MENU_ITEM (focus_widget) &&
++ !GTK_IS_MENU (focus_widget) &&
++ !is_inside_toolbar &&
++ !is_combo)
++ {
++ /* we can't hide IM without IM context. it's possible to move
++ * focus to widget which doesn't have IM context, but which
++ * doesn't want IM to be hidden either. So, we have this
++ * static last_context variable which is used... */
++ gtk_im_context_hide (context != NULL
++ ? context : last_context);
++ }
++
++ if (context)
++ {
++ if (last_context != NULL)
++ g_object_unref (last_context);
++ last_context = context;
++ g_object_ref (last_context);
++ }
++ }
+
+ if (widget)
+ {
+@@ -4462,9 +4806,13 @@
+ {
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+- if (!GTK_WIDGET_USER_STYLE (widget) &&
+- !GTK_WIDGET_RC_STYLE (widget))
++ if (!GTK_WIDGET_USER_STYLE (widget) && !GTK_WIDGET_RC_STYLE (widget))
++ {
++ gboolean hfh = FALSE;
+ gtk_widget_reset_rc_style (widget);
++ gtk_widget_style_get( widget, "hildon-focus-handling", &hfh, NULL );
++ gtk_widget_set_focus_handling( widget, hfh );
++ }
+ }
+
+ /* Look up the RC style for this widget, unsetting any user style that
+@@ -6396,7 +6744,7 @@
+
+ if (!GTK_WIDGET_DIRECTION_SET (widget))
+ gtk_widget_emit_direction_changed (widget, old_dir);
+-
++
+ if (GTK_IS_CONTAINER (widget))
+ gtk_container_forall (GTK_CONTAINER (widget),
+ gtk_widget_set_default_direction_recurse,
+@@ -6405,6 +6753,13 @@
+ g_object_unref (widget);
+ }
+
++/* Non static */
++void gtk_widget_set_direction_recursive(GtkWidget * widget, GtkTextDirection dir )
++{
++ gtk_widget_set_default_direction_recurse( widget, GUINT_TO_POINTER(dir) );
++}
++
++
+ /**
+ * gtk_widget_set_default_direction:
+ * @dir: the new default direction. This cannot be
+@@ -6422,7 +6777,7 @@
+ {
+ GList *toplevels, *tmp_list;
+ GtkTextDirection old_dir = gtk_default_direction;
+-
++
+ gtk_default_direction = dir;
+
+ tmp_list = toplevels = gtk_window_list_toplevels ();
+@@ -6497,6 +6852,7 @@
+ gtk_widget_finalize (GObject *object)
+ {
+ GtkWidget *widget = GTK_WIDGET (object);
++ GtkWidgetPrivate *priv = GTK_WIDGET_GET_PRIVATE(object);
+ GtkWidgetAuxInfo *aux_info;
+ gint *events;
+ GdkExtensionMode *mode;
+@@ -6507,6 +6863,12 @@
+ g_object_unref (widget->style);
+ widget->style = NULL;
+
++ if (priv->timer_id)
++ {
++ g_source_remove (priv->timer_id);
++ priv->timer_id = 0;
++ }
++
+ if (widget->name)
+ g_free (widget->name);
+
+@@ -6526,6 +6888,12 @@
+ if (accessible)
+ g_object_unref (accessible);
+
++ if (GTK_IS_MENU(priv->menu))
++ gtk_widget_destroy (priv->menu);
++
++ if (priv->fake_event)
++ gdk_event_free (priv->fake_event);
++
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+ }
+
+@@ -7577,3 +7945,450 @@
+
+ g_object_notify (G_OBJECT (widget), "no_show_all");
+ }
++
++void gtk_widget_insensitive_press ( GtkWidget *widget )
++{
++ g_return_if_fail (GTK_IS_WIDGET (widget));
++
++ g_signal_emit(widget, widget_signals[INSENSITIVE_PRESS], 0);
++}
++
++/*Tap And Hold*/
++
++#ifdef TAP_AND_HOLD_ANIMATION
++static void
++init_tap_and_hold_animation( GtkWidgetPrivate *priv )
++{
++ GTimeVal time;
++ if( priv->anim )
++ {
++ g_get_current_time( &time );
++ priv->iter = gdk_pixbuf_animation_get_iter( priv->anim, &time );
++ priv->interval = gdk_pixbuf_animation_iter_get_delay_time( priv->iter );
++ }
++}
++
++static void
++timeout_tap_and_hold_animation( GtkWidgetPrivate *priv )
++{
++ GdkScreen *screen;
++ GdkPixbuf *pic;
++ GdkCursor *cursor;
++ GTimeVal time;
++
++ if( priv->anim )
++ {
++ screen = gdk_screen_get_default();
++ g_get_current_time( &time );
++
++ pic = gdk_pixbuf_animation_iter_get_pixbuf( priv->iter );
++ cursor = gdk_cursor_new_from_pixbuf( gdk_display_get_default(), pic,
++ priv->width, priv->height );
++
++ gdk_window_set_cursor( priv->fake_event->button.window, cursor );
++
++ gdk_pixbuf_animation_iter_advance( priv->iter, &time );
++ }
++}
++
++static void
++stop_tap_and_hold_animation( GtkWidgetPrivate *priv )
++{
++ if( priv->anim )
++ {
++ gdk_window_set_cursor( priv->fake_event->button.window, NULL );
++ }
++}
++
++
++#endif
++
++void tap_and_hold_remove_timer( GtkWidgetPrivate *priv )
++{
++ if (priv->timer_id)
++ {
++ g_source_remove (priv->timer_id);
++ priv->timer_id = 0;
++ #ifdef TAP_AND_HOLD_ANIMATION
++ stop_tap_and_hold_animation( priv );
++ #endif
++ }
++}
++
++/**
++ * gtk_widget_tap_and_hold_setup:
++ *
++ * @widget : A @GtkWidget
++ * @menu : A @GtkWidget
++ * @func : A @GtkCallback
++ * @flags : A @GtkWidgetTapAndHoldFlags
++ *
++ * Setups the tap and hold functionality to the @widget.
++ * The @menu is shown when the functionality is activated.
++ * If the @menu is wanted to be positioned in a different way than the
++ * gtk+ default, the menuposition @func can be passed as a third parameter.
++ * Fourth parameter, @flags are explaned with detail in the documentation.
++ */
++void gtk_widget_tap_and_hold_setup (GtkWidget *widget, GtkWidget *menu,
++ GtkCallback func, GtkWidgetTapAndHoldFlags flags)
++{
++ /*GtkWidgetClass *klass = GTK_WIDGET_GET_CLASS(widget);*/
++ g_return_if_fail( GTK_IS_WIDGET(widget));
++ g_return_if_fail(menu == NULL || GTK_IS_MENU(menu));
++ g_signal_emit( widget, widget_signals[TAP_AND_HOLD_SETUP], 0, menu, func,
++ flags );
++}
++
++static void gtk_widget_tap_and_hold_setup_real (GtkWidget *widget,
++ GtkWidget *menu, GtkCallback func, GtkWidgetTapAndHoldFlags flags)
++{
++ #ifdef TAP_AND_HOLD_ANIMATION
++ GtkStyle *style = NULL;
++ GError *error = NULL;
++ #endif
++ GtkWidgetPrivate *priv;
++ g_return_if_fail (GTK_IS_WIDGET(widget));
++ g_return_if_fail (menu == NULL || GTK_IS_MENU(menu));
++ priv = GTK_WIDGET_GET_PRIVATE (widget);
++
++ if (priv->signals_connected)
++ return;
++
++ _gtk_menu_enable_context_menu_behavior (menu);
++
++ priv->menu = menu;
++ priv->func = (GtkMenuPositionFunc)func;
++ priv->signals_connected = TRUE;
++ priv->timer_counter = 0;
++ priv->flags = flags;
++
++ if (flags & GTK_TAP_AND_HOLD_PASS_PRESS)
++ {
++ g_signal_connect( widget, "button-press-event",
++ G_CALLBACK(gtk_widget_tap_and_hold_button_press_with_events), priv );
++ g_signal_connect( widget, "button-release-event",
++ G_CALLBACK(gtk_widget_tap_and_hold_button_release_with_events), priv );
++ g_signal_connect( widget, "leave-notify-event",
++ G_CALLBACK(gtk_widget_tap_and_hold_leave_notify_with_events), priv );
++ }
++ else
++ {
++ g_signal_connect( widget, "button-press-event",
++ G_CALLBACK(gtk_widget_tap_and_hold_button_press), priv );
++ g_signal_connect( widget, "button-release-event",
++ G_CALLBACK(gtk_widget_tap_and_hold_button_release), priv );
++ g_signal_connect( widget, "leave-notify-event",
++ G_CALLBACK(gtk_widget_tap_and_hold_leave_notify), priv );
++ }
++
++#ifdef TAP_AND_HOLD_ANIMATION
++ priv->anim = NULL;
++ style = gtk_rc_get_style_by_paths(gtk_settings_get_default(),
++ "gtk-tap-and-hold-animation",
++ NULL, G_TYPE_NONE);
++
++ if( style )
++ {
++
++ priv->anim = gdk_pixbuf_animation_new_from_file(
++ (gchar*)style->rc_style->bg_pixmap_name[0], &error );
++
++ priv->width = gdk_pixbuf_animation_get_width( priv->anim )/2;
++ priv->height = gdk_pixbuf_animation_get_height( priv->anim )/2;
++ }
++#endif
++}
++
++static void gtk_widget_real_tap_and_hold(GtkWidget *widget)
++{
++ GtkWidgetPrivate *priv = GTK_WIDGET_GET_PRIVATE (widget);
++
++ if (GTK_IS_MENU(priv->menu))
++ gtk_menu_popup( GTK_MENU(priv->menu), NULL, NULL,
++ (GtkMenuPositionFunc)priv->func,
++ widget, 1, gdk_x11_get_server_time(widget->window) );
++}
++
++static gboolean gtk_widget_tap_and_hold_timeout (GtkWidget *widget)
++{
++ GtkWidgetPrivate *priv= GTK_WIDGET_GET_PRIVATE(widget);
++ gboolean return_value;
++ gint x = 0, y = 0;
++
++ #ifdef TAP_AND_HOLD_ANIMATION
++ timeout_tap_and_hold_animation( priv );
++ #endif
++
++ if( priv->timer_counter )
++ priv->timer_counter--;
++ else
++ priv->timer_id = 0;
++
++ gdk_display_get_pointer( gdk_x11_lookup_xdisplay(
++ GDK_WINDOW_XDISPLAY(priv->fake_event->button.window) ),
++ NULL, &x, &y, NULL );
++
++ if ((abs(x - priv->x) > GTK_TAP_THRESHOLD) ||
++ (abs(y - priv->y) > GTK_TAP_THRESHOLD))
++ {
++ if (priv->stype != priv->type_on_press)
++ gtk_widget_set_state( widget, priv->stype );
++ priv->timer_counter = 0;
++ priv->timer_id = 0;
++ priv->x = priv->y = 0;
++ priv->run_press = FALSE;
++ g_signal_emit_by_name (G_OBJECT(widget), "button-press-event",
++ priv->fake_event, &return_value);
++ return FALSE;
++ }
++ if (!priv->timer_id)
++ {
++ if (priv->stype != priv->type_on_press)
++ gtk_widget_set_state( widget, priv->stype );
++ #ifdef TAP_AND_HOLD_ANIMATION
++ stop_tap_and_hold_animation( priv );
++ #endif
++ g_signal_emit(widget, widget_signals[TAP_AND_HOLD], 0);
++ priv->x = x;
++ priv->y = y;
++ return FALSE;
++ }
++ return TRUE;
++}
++
++static gboolean gtk_widget_tap_and_hold_button_press (GtkWidget *widget,
++ GdkEvent *event, GtkWidgetPrivate *priv)
++{
++ if (!priv->run_press || event->button.button != 1)
++ {
++ priv->run_press = TRUE;
++ return FALSE;
++ }
++
++ if (event->button.type == GDK_2BUTTON_PRESS)
++ return FALSE;
++
++ if (priv->fake_event)
++ gdk_event_free (priv->fake_event);
++ priv->fake_event = gdk_event_copy(event);
++
++ if (!priv->timer_id)
++ {
++ priv->stype = GTK_WIDGET_STATE(widget);
++ if (priv->stype != priv->type_on_press)
++ gtk_widget_set_state( widget, priv->type_on_press );
++ gdk_display_get_pointer(
++ gdk_x11_lookup_xdisplay( GDK_WINDOW_XDISPLAY(event->button.window) ),
++ NULL, &priv->x, &priv->y, NULL );
++ priv->timer_counter = GTK_TAP_AND_HOLD_TIMER_COUNTER;
++
++ #ifdef TAP_AND_HOLD_ANIMATION
++ init_tap_and_hold_animation( priv );
++ #endif
++ priv->timer_id = g_timeout_add( priv->interval,
++ (GSourceFunc)gtk_widget_tap_and_hold_timeout, widget );
++ }
++return TRUE;
++}
++
++static gboolean gtk_widget_tap_and_hold_button_release (GtkWidget *widget,
++ GdkEvent *event, GtkWidgetPrivate *priv)
++{
++ gboolean return_value;
++
++ if (!priv->run_press || event->button.button != 1 || !priv->timer_id ||
++ event->button.type == GDK_2BUTTON_PRESS)
++ return FALSE;
++
++ g_source_remove (priv->timer_id);
++ priv->timer_id = 0;
++ priv->x = priv->y = priv->timer_counter = 0;
++ if (priv->stype != priv->type_on_press)
++ gtk_widget_set_state (widget, priv->stype);
++
++ #ifdef TAP_AND_HOLD_ANIMATION
++ stop_tap_and_hold_animation( priv );
++ #endif
++
++ if (priv->flags & GTK_TAP_AND_HOLD_NO_SIGNALS)
++ return FALSE;
++
++ priv->run_press = FALSE;
++
++ g_signal_emit_by_name (G_OBJECT(widget), "button-press-event",
++ priv->fake_event, &return_value);
++
++return FALSE;
++}
++
++static gboolean gtk_widget_tap_and_hold_leave_notify (GtkWidget *widget,
++ GdkEvent *event, GtkWidgetPrivate *priv)
++{
++ gboolean return_value;
++ if (!priv->timer_id)
++ return FALSE;
++
++ g_source_remove (priv->timer_id);
++ priv->timer_id = 0;
++ priv->x = priv->y = priv->timer_counter = 0;
++ if (priv->stype != priv->type_on_press)
++ gtk_widget_set_state (widget, priv->stype);
++
++ #ifdef TAP_AND_HOLD_ANIMATION
++ stop_tap_and_hold_animation( priv );
++ #endif
++ priv->run_press = FALSE;
++ g_signal_emit_by_name (G_OBJECT(widget), "button-press-event",
++ priv->fake_event, &return_value);
++
++return FALSE;
++}
++
++static gboolean
++gtk_widget_tap_and_hold_timeout_with_events (GtkWidget *widget)
++{
++ gint x, y;
++ GtkWidgetPrivate *priv= GTK_WIDGET_GET_PRIVATE(widget);
++
++ g_return_val_if_fail (priv->fake_event, FALSE);
++
++ #ifdef TAP_AND_HOLD_ANIMATION
++ timeout_tap_and_hold_animation( priv );
++ #endif
++
++ gdk_display_get_pointer( gdk_x11_lookup_xdisplay(
++ GDK_WINDOW_XDISPLAY(priv->fake_event->button.window) ),
++ NULL, &x, &y, NULL );
++
++ if( priv->timer_counter )
++ {
++ priv->timer_counter--;
++ if ((abs(x - priv->x) > GTK_TAP_THRESHOLD) ||
++ (abs(y - priv->y) > GTK_TAP_THRESHOLD))
++ {
++ #ifdef TAP_AND_HOLD_ANIMATION
++ stop_tap_and_hold_animation( priv );
++ #endif
++ tap_and_hold_remove_timer( priv );
++ }
++ return TRUE;
++ }
++
++ if (!((abs(x - priv->x) > GTK_TAP_THRESHOLD) ||
++ (abs(y - priv->y) > GTK_TAP_THRESHOLD)))
++ {
++ gboolean return_value;
++ priv->fake_event->button.type = GDK_BUTTON_RELEASE;
++ priv->fake_event->button.x = x;
++ priv->fake_event->button.y = y;
++ g_signal_emit_by_name (G_OBJECT(widget), "button-release-event",
++ priv->fake_event, &return_value);
++ #ifdef TAP_AND_HOLD_ANIMATION
++ stop_tap_and_hold_animation( priv );
++ #endif
++ g_signal_emit(widget, widget_signals[TAP_AND_HOLD], 0);
++ priv->timer_id = 0;
++ priv->x = x;
++ priv->y = y;
++ gdk_event_free(priv->fake_event);
++ priv->fake_event = NULL;
++ }
++
++
++ if (priv->timer_id)
++ {
++ g_source_remove (priv->timer_id);
++ priv->timer_id = 0;
++ }
++
++ return FALSE;
++}
++
++static gboolean gtk_widget_tap_and_hold_button_press_with_events(
++ GtkWidget *widget, GdkEvent *event, GtkWidgetPrivate *priv)
++{
++ if( priv->timer_id || event->button.type == GDK_2BUTTON_PRESS)
++ return FALSE;
++
++ if (priv->fake_event)
++ gdk_event_free (priv->fake_event);
++ priv->fake_event = gdk_event_copy (event);
++
++ gdk_display_get_pointer(
++ gdk_x11_lookup_xdisplay(GDK_WINDOW_XDISPLAY(event->button.window)),
++ NULL, &priv->x, &priv->y, NULL);
++ #ifdef TAP_AND_HOLD_ANIMATION
++ init_tap_and_hold_animation( priv );
++ #endif
++ priv->timer_counter = GTK_TAP_AND_HOLD_TIMER_COUNTER;
++ priv->timer_id = g_timeout_add(priv->interval,
++ (GSourceFunc)gtk_widget_tap_and_hold_timeout_with_events,
++ widget);
++ return FALSE;
++}
++
++static gboolean gtk_widget_tap_and_hold_button_release_with_events(
++ GtkWidget *widget, GdkEvent *event, GtkWidgetPrivate *priv)
++{
++ tap_and_hold_remove_timer( priv );
++ return FALSE;
++}
++
++static gboolean gtk_widget_tap_and_hold_leave_notify_with_events(
++ GtkWidget *widget, GdkEvent *event, GtkWidgetPrivate *priv)
++{
++ tap_and_hold_remove_timer( priv );
++ return FALSE;
++}
++
++/**
++ * gtk_widget_tap_and_hold_menu_position_top:
++ * @menu: a #GtkMenu
++ * @x: x cordinate to be returned
++ * @y: y cordinate to be returned
++ * @push_in: If going off screen, push it pack on the screen
++ * @widget: a #GtkWidget
++ *
++ * Pre-made menu positioning function.
++ * It positiones the @menu over the @widget.
++ *
++ **/
++void gtk_widget_tap_and_hold_menu_position_top( GtkWidget *menu,
++ gint *x, gint *y, gboolean *push_in, GtkWidget *widget )
++{
++ /*
++ * This function positiones the menu above widgets.
++ * This is a modified version of the position function
++ * gtk_combo_box_position_over.
++ */
++ GtkWidget *topw;
++ GtkRequisition requisition;
++ gint screen_width = 0;
++ gint menu_xpos = 0;
++ gint menu_ypos = 0;
++ gint w_xpos = 0, w_ypos = 0;
++
++ gtk_widget_size_request( menu, &requisition );
++
++ topw = gtk_widget_get_toplevel(widget);
++ gdk_window_get_origin( topw->window, &w_xpos, &w_ypos );
++
++ menu_xpos += widget->allocation.x + w_xpos;
++ menu_ypos += widget->allocation.y + w_ypos - requisition.height;
++
++ if( gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL )
++ menu_xpos = menu_xpos + widget->allocation.width - requisition.width;
++
++ screen_width = gdk_screen_get_width( gtk_widget_get_screen(widget) );
++
++ if( menu_xpos < w_xpos )
++ menu_xpos = w_xpos;
++ else if( (menu_xpos + requisition.width) > screen_width )
++ menu_xpos -= ( (menu_xpos + requisition.width) - screen_width );
++ if( menu_ypos < w_ypos )
++ menu_ypos = w_ypos;
++
++ *x = menu_xpos;
++ *y = menu_ypos;
++ *push_in = TRUE;
++}