Ticket #4134: 0003-OSK-im-osk-position.patch

File 0003-OSK-im-osk-position.patch, 13.1 KB (added by garnacho, 12 years ago)

last iteration of the gtk+ patch, meant to work on webkit too

  • gtk/gtkimcontext.c

    From 1117a90cdee4352bdbf123ec5e0517002758b4f3 Mon Sep 17 00:00:00 2001
    From: Carlos Garnacho <carlos@lanedo.com>
    Date: Wed, 19 Sep 2012 15:37:01 +0200
    Subject: [PATCH] OSK: im-osk-position
    
    Patch based on: http://git.gnome.org/browse/gtk+/log/?h=wip/im-osk-position
    ---
     gtk/gtkimcontext.c      | 46 +++++++++++++++++++++++++++++-
     gtk/gtkimmulticontext.c | 20 +++++++++++++
     gtk/gtkscrolledwindow.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++-
     gtk/gtkwidget.c         | 72 ++++++++++++++++++++++++++++++++++++++++++++++
     gtk/gtkwidget.h         |  6 ++++
     5 files changed, 218 insertions(+), 2 deletions(-)
    
    diff --git a/gtk/gtkimcontext.c b/gtk/gtkimcontext.c
    index f0f351f..645795b 100644
    a b enum { 
    105105  COMMIT,
    106106  RETRIEVE_SURROUNDING,
    107107  DELETE_SURROUNDING,
     108  CLEAR_AREA,
    108109  LAST_SIGNAL
    109110};
    110111
    typedef struct _GtkIMContextPrivate GtkIMContextPrivate; 
    121122struct _GtkIMContextPrivate {
    122123  GtkInputPurpose purpose;
    123124  GtkInputHints hints;
     125  guint clear_area_signal_id;
    124126};
    125127
    126128static void     gtk_im_context_real_get_preedit_string (GtkIMContext   *context,
    gtk_im_context_class_init (GtkIMContextClass *klass) 
    327329                  G_TYPE_INT,
    328330                  G_TYPE_INT);
    329331
     332  im_context_signals[CLEAR_AREA] =
     333      g_signal_new (I_("clear-area"),
     334                    G_TYPE_FROM_CLASS (klass),
     335                    G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
     336                    0, NULL, NULL,
     337                    _gtk_marshal_VOID__BOXED_BOXED,
     338                    G_TYPE_NONE, 2,
     339                    GDK_TYPE_RECTANGLE, GDK_TYPE_RECTANGLE);
     340
    330341  properties[PROP_INPUT_PURPOSE] =
    331342    g_param_spec_enum ("input-purpose",
    332343                         P_("Purpose"),
    gtk_im_context_real_get_surrounding (GtkIMContext *context, 
    438449  return result;
    439450}
    440451
     452static void
     453_gtk_im_context_clear_area (GtkIMContext          *context,
     454                            cairo_rectangle_int_t *clear_area,
     455                            cairo_rectangle_int_t *cursor_rect,
     456                            GtkWidget             *widget)
     457{
     458  gtk_widget_unset_clear_area (widget, TRUE);
     459
     460  if (clear_area->width != 0 && clear_area->height != 0)
     461    gtk_widget_request_clear_area (widget, clear_area, cursor_rect);
     462}
     463
    441464/**
    442465 * gtk_im_context_set_client_window:
    443466 * @context: a #GtkIMContext
    gtk_im_context_set_client_window (GtkIMContext *context, 
    454477                                  GdkWindow    *window)
    455478{
    456479  GtkIMContextClass *klass;
    457  
     480  GtkIMContextPrivate *priv;
     481
    458482  g_return_if_fail (GTK_IS_IM_CONTEXT (context));
    459483
    460484  klass = GTK_IM_CONTEXT_GET_CLASS (context);
    461485  if (klass->set_client_window)
    462486    klass->set_client_window (context, window);
     487
     488  priv = G_TYPE_INSTANCE_GET_PRIVATE (context, GTK_TYPE_IM_CONTEXT, GtkIMContextPrivate);
     489
     490  if (priv->clear_area_signal_id)
     491    {
     492      g_signal_handler_disconnect (context, priv->clear_area_signal_id);
     493      priv->clear_area_signal_id = 0;
     494    }
     495
     496  if (window)
     497    {
     498      gpointer window_data;
     499
     500      gdk_window_get_user_data (window, &window_data);
     501
     502      if (GTK_IS_WIDGET (window_data))
     503        priv->clear_area_signal_id = g_signal_connect (context, "clear-area",
     504                                                       G_CALLBACK (_gtk_im_context_clear_area),
     505                                                       window_data);
     506    }
    463507}
    464508
    465509/**
  • gtk/gtkimmulticontext.c

    diff --git a/gtk/gtkimmulticontext.c b/gtk/gtkimmulticontext.c
    index 712d5ca..69fba46 100644
    a b static gboolean gtk_im_multicontext_delete_surrounding_cb (GtkIMContext * 
    102102                                                             gint               n_chars,
    103103                                                             GtkIMMulticontext *multicontext);
    104104
     105static void     gtk_im_multicontext_clear_area_cb           (GtkIMContext      *slave,
     106                                                             GdkRectangle      *osk_rect,
     107                                                             GdkRectangle      *cursor_rect,
     108                                                             GtkIMMulticontext *multicontext);
     109
    105110static void propagate_purpose (GtkIMMulticontext *context);
    106111
    107112static const gchar *global_context_id = NULL;
    gtk_im_multicontext_set_slave (GtkIMMulticontext *multicontext, 
    197202      g_signal_handlers_disconnect_by_func (priv->slave,
    198203                                            gtk_im_multicontext_commit_cb,
    199204                                            multicontext);
     205      g_signal_handlers_disconnect_by_func (priv->slave,
     206                                            gtk_im_multicontext_clear_area_cb,
     207                                            multicontext);
    200208
    201209      g_object_unref (priv->slave);
    202210      priv->slave = NULL;
    gtk_im_multicontext_set_slave (GtkIMMulticontext *multicontext, 
    231239      g_signal_connect (priv->slave, "delete-surrounding",
    232240                        G_CALLBACK (gtk_im_multicontext_delete_surrounding_cb),
    233241                        multicontext);
     242      g_signal_connect (priv->slave, "clear-area",
     243                        G_CALLBACK (gtk_im_multicontext_clear_area_cb),
     244                        multicontext);
    234245
    235246      if (!priv->use_preedit)   /* Default is TRUE */
    236247        gtk_im_context_set_use_preedit (slave, FALSE);
    gtk_im_multicontext_delete_surrounding_cb (GtkIMContext *slave, 
    553564}
    554565
    555566static void
     567gtk_im_multicontext_clear_area_cb (GtkIMContext      *slave,
     568                                   GdkRectangle      *osk_rect,
     569                                   GdkRectangle      *cursor_rect,
     570                                   GtkIMMulticontext *multicontext)
     571{
     572  g_signal_emit_by_name (multicontext, "clear-area", osk_rect, cursor_rect);
     573}
     574
     575static void
    556576activate_cb (GtkWidget         *menuitem,
    557577             GtkIMMulticontext *context)
    558578{
  • gtk/gtkscrolledwindow.c

    diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
    index a18c4cf..3595456 100644
    a b struct _GtkScrolledWindowPrivate 
    175175
    176176  gdouble                unclamped_hadj_value;
    177177  gdouble                unclamped_vadj_value;
     178  gdouble                clear_area_dy;
    178179};
    179180
    180181typedef struct
    static gboolean _gtk_scrolled_window_set_adjustment_value (GtkScrolledWindo 
    287288                                                                gboolean           allow_overshooting,
    288289                                                                gboolean           snap_to_border);
    289290
     291static gboolean gtk_scrolled_window_request_clear_area (GtkWidget             *widget,
     292                                                        cairo_rectangle_int_t *clear_area,
     293                                                        cairo_rectangle_int_t *cursor_area,
     294                                                        gpointer               user_data);
     295static gboolean gtk_scrolled_window_unset_clear_area   (GtkWidget             *widget,
     296                                                         gboolean               snap_back,
     297                                                        gpointer               user_data);
     298
    290299static guint signals[LAST_SIGNAL] = {0};
    291300
    292301G_DEFINE_TYPE (GtkScrolledWindow, gtk_scrolled_window, GTK_TYPE_BIN)
    gtk_scrolled_window_init (GtkScrolledWindow *scrolled_window) 
    599608  gtk_scrolled_window_update_real_placement (scrolled_window);
    600609  priv->min_content_width = -1;
    601610  priv->min_content_height = -1;
     611  priv->clear_area_dy = 0;
    602612
    603613  gtk_scrolled_window_set_kinetic_scrolling (scrolled_window, TRUE);
    604614  gtk_scrolled_window_set_capture_button_press (scrolled_window, TRUE);
     615
     616  g_signal_connect (scrolled_window, "request-clear-area",
     617                    G_CALLBACK (gtk_scrolled_window_request_clear_area),
     618                    NULL);
     619  g_signal_connect (scrolled_window, "unset-clear-area",
     620                    G_CALLBACK (gtk_scrolled_window_unset_clear_area),
     621                    NULL);
    605622}
    606623
    607624/**
    _gtk_scrolled_window_set_adjustment_value (GtkScrolledWindow *scrolled_window, 
    23632380  if (adjustment == gtk_range_get_adjustment (GTK_RANGE (priv->hscrollbar)))
    23642381    prev_value = &priv->unclamped_hadj_value;
    23652382  else if (adjustment == gtk_range_get_adjustment (GTK_RANGE (priv->vscrollbar)))
    2366     prev_value = &priv->unclamped_vadj_value;
     2383    {
     2384      if (!snap_to_border)
     2385          upper += priv->clear_area_dy;
     2386      prev_value = &priv->unclamped_vadj_value;
     2387    }
    23672388  else
    23682389    return FALSE;
    23692390
    gtk_scrolled_window_grab_notify (GtkWidget *widget, 
    34943515    }
    34953516}
    34963517
     3518static gboolean
     3519gtk_scrolled_window_request_clear_area (GtkWidget             *widget,
     3520                                        cairo_rectangle_int_t *cursor_area,
     3521                                        cairo_rectangle_int_t *clear_area,
     3522                                        gpointer               user_data)
     3523{
     3524  GtkScrolledWindowPrivate *priv;
     3525  GtkAdjustment *adjustment;
     3526  gdouble value;
     3527
     3528  priv = GTK_SCROLLED_WINDOW (widget)->priv;
     3529  adjustment = gtk_range_get_adjustment (GTK_RANGE (priv->vscrollbar));
     3530  value = priv->unclamped_vadj_value;
     3531
     3532  priv->clear_area_dy = cursor_area->y + cursor_area->height - clear_area->y;
     3533  value = priv->unclamped_vadj_value + priv->clear_area_dy;
     3534  _gtk_scrolled_window_set_adjustment_value (GTK_SCROLLED_WINDOW (widget),
     3535                                             adjustment, value,
     3536                                             FALSE, FALSE);
     3537
     3538  return TRUE;
     3539}
     3540
     3541static gboolean
     3542gtk_scrolled_window_unset_clear_area (GtkWidget *widget,
     3543                                      gboolean   snap_back,
     3544                                      gpointer   user_data)
     3545{
     3546  GtkScrolledWindowPrivate *priv;
     3547
     3548  priv = GTK_SCROLLED_WINDOW (widget)->priv;
     3549
     3550  if (priv->clear_area_dy != 0)
     3551    {
     3552      if (snap_back)
     3553        {
     3554          GtkAdjustment *adjustment;
     3555          gdouble value;
     3556
     3557          adjustment = gtk_range_get_adjustment (GTK_RANGE (priv->vscrollbar));
     3558          value = priv->unclamped_vadj_value - priv->clear_area_dy;
     3559          _gtk_scrolled_window_set_adjustment_value (GTK_SCROLLED_WINDOW (widget),
     3560                                                     adjustment, value,
     3561                                                     FALSE, FALSE);
     3562        }
     3563
     3564      priv->clear_area_dy = 0;
     3565      return TRUE;
     3566    }
     3567
     3568  return FALSE;
     3569}
     3570
    34973571/**
    34983572 * gtk_scrolled_window_get_min_content_width:
    34993573 * @scrolled_window: a #GtkScrolledWindow
  • gtk/gtkwidget.c

    diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
    index 58ad57a..9c480a1 100644
    a b enum { 
    484484  DRAG_FAILED,
    485485  STYLE_UPDATED,
    486486  TOUCH_EVENT,
     487  REQUEST_CLEAR_AREA,
     488  UNSET_CLEAR_AREA,
    487489  LAST_SIGNAL
    488490};
    489491
    gtk_widget_class_init (GtkWidgetClass *klass) 
    31183120                  _gtk_marshal_BOOLEAN__UINT,
    31193121                  G_TYPE_BOOLEAN, 1, G_TYPE_UINT);
    31203122
     3123  widget_signals[REQUEST_CLEAR_AREA] =
     3124    g_signal_new (I_("request-clear-area"),
     3125                  G_TYPE_FROM_CLASS (klass),
     3126                  G_SIGNAL_RUN_LAST, 0,
     3127                  g_signal_accumulator_true_handled, NULL,
     3128                  _gtk_marshal_BOOLEAN__BOXED_BOXED,
     3129                  G_TYPE_BOOLEAN, 2,
     3130                  CAIRO_GOBJECT_TYPE_RECTANGLE_INT,
     3131                  CAIRO_GOBJECT_TYPE_RECTANGLE_INT);
     3132  widget_signals[UNSET_CLEAR_AREA] =
     3133    g_signal_new (I_("unset-clear-area"),
     3134                  G_TYPE_FROM_CLASS (klass),
     3135                  G_SIGNAL_RUN_LAST, 0,
     3136                  g_signal_accumulator_true_handled, NULL,
     3137                  _gtk_marshal_BOOLEAN__BOOLEAN,
     3138                  G_TYPE_BOOLEAN, 1, G_TYPE_BOOLEAN);
     3139
    31213140  binding_set = gtk_binding_set_by_class (klass);
    31223141  gtk_binding_entry_add_signal (binding_set, GDK_KEY_F10, GDK_SHIFT_MASK,
    31233142                                "popup-menu", 0);
    gtk_widget_insert_action_group (GtkWidget *widget, 
    1413714156  else
    1413814157    g_action_muxer_remove (muxer, name);
    1413914158}
     14159
     14160gboolean
     14161gtk_widget_request_clear_area (GtkWidget             *widget,
     14162                               cairo_rectangle_int_t *clear_area,
     14163                               cairo_rectangle_int_t *cursor_position)
     14164{
     14165  gboolean handled = FALSE;
     14166  GtkWidget *cur;
     14167
     14168  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
     14169  g_return_val_if_fail (cursor_position != NULL, FALSE);
     14170  g_return_val_if_fail (clear_area != NULL, FALSE);
     14171
     14172  if (cursor_position->x < clear_area->x - cursor_position->width ||
     14173      cursor_position->x >= clear_area->x + clear_area->width ||
     14174      cursor_position->y < clear_area->y - cursor_position->height ||
     14175      cursor_position->y >= clear_area->y + clear_area->height)
     14176    return FALSE;
     14177
     14178  cur = widget;
     14179
     14180  while (!handled && cur)
     14181    {
     14182      g_signal_emit (cur, widget_signals[REQUEST_CLEAR_AREA], 0,
     14183                     clear_area, cursor_position, &handled);
     14184
     14185      if (!handled)
     14186        cur = gtk_widget_get_parent (cur);
     14187    }
     14188
     14189  return handled;
     14190}
     14191
     14192gboolean
     14193gtk_widget_unset_clear_area (GtkWidget *widget,
     14194                             gboolean   snap_back)
     14195{
     14196  gboolean handled = FALSE;
     14197  GtkWidget *cur;
     14198
     14199  cur = widget;
     14200
     14201  while (!handled && cur)
     14202    {
     14203      g_signal_emit (cur, widget_signals[UNSET_CLEAR_AREA], 0,
     14204                     snap_back, &handled);
     14205
     14206      if (!handled)
     14207        cur = gtk_widget_get_parent (cur);
     14208    }
     14209
     14210  return handled;
     14211}
  • gtk/gtkwidget.h

    diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
    index c178478..ce4f4dc 100644
    a b GDK_AVAILABLE_IN_3_4 
    886886GdkModifierType   gtk_widget_get_modifier_mask (GtkWidget         *widget,
    887887                                                GdkModifierIntent  intent);
    888888
     889gboolean gtk_widget_request_clear_area (GtkWidget             *widget,
     890                                        cairo_rectangle_int_t *clear_area,
     891                                        cairo_rectangle_int_t *cursor_position);
     892gboolean gtk_widget_unset_clear_area   (GtkWidget             *widget,
     893                                        gboolean               snap_back);
     894
    889895GDK_AVAILABLE_IN_3_6
    890896void                    gtk_widget_insert_action_group                  (GtkWidget    *widget,
    891897                                                                         const gchar  *name,