[Uim] Focus and cursor position shift handlings (bug #7729)

YAMAMOTO Kengo / YamaKen yamaken at bp.iij4u.or.jp
Fri Nov 17 11:17:02 EET 2006


At Fri, 17 Nov 2006 16:31:51 +0900,
ek.kato at gmail.com wrote:
> On 11/17/06, YAMAMOTO Kengo / YamaKen <yamaken at bp.iij4u.or.jp> wrote:
> > Did you mean that any pressed() signal of button instances are
> > needed to be connected to QApplication::fixFocusInputContext()?
> 
> No.  I just meant calling QApplication::fixInputContext() from
> QButton::mousePressEven().
> Forget about pressed() signal...
> 
> > And it seems that fixFocusInputContext() is a typo of
> > fixInputContext(). Right?
> 
> I use the name from a hint of QApplication::focusWidget() in
> qapplication.c.  Maybe I should use fixFocusedInputContext().  But
> fixInputContext() is fine.

I see. The name fixFocusedInputContext() is more appropriate
than mine.

> > > In GTK+, how about adding gtk_widget_fix_input_context(widget) in
> > > GtkWidget and call this from gtk_button_button_press() in GtkButton.
> > >
> > > --- gtkwidget.c.orig    2006-11-16 03:37:53.000000000 +0900
> > > +++ gtkwidget.c 2006-11-16 03:39:57.000000000 +0900
> > > @@ -8057,5 +8057,23 @@
> > >    g_object_notify (G_OBJECT (widget), "no-show-all");
> > >  }
> > >
> > > +void
> > > +gtk_widget_fix_input_context (GtkWidget *widget)
> > > +{
> > > +  GtkWidget *toplevel, *focus_widget;;
> > > +
> > > +  g_return_if_fail (GTK_IS_WIDGET (widget));
> > > +
> > > +  toplevel = gtk_widget_get_toplevel (widget);
> > > +
> > > +  if (GTK_WIDGET_TOPLEVEL (toplevel)) {
> > > +    focus_widget = GTK_WINDOW (toplevel)->focus_widget;
> > > +    if (focus_widget) {
> > > +      g_signal_emit (focus_widget, widget_signals[FOCUS_OUT_EVENT], 0);
> > > +      g_signal_emit (focus_widget, widget_signals[FOCUS_IN_EVENT], 0);
> > > +    }
> > > +  }
> > > +}
> >
> > The gtk_widget_fix_input_context() interface seems good. But I
> > want to keep widget-level focus untouched. How about following
> > change? It is supposed that gtk_editable_set_position() calls
> > gtk_im_context_focus_{out,in}() as the workaround on setting
> > same position. This workaround does not affect widget-level
> > focus and does not break the GTK+ ABI.
> 
> As GtkTextview doesn't inherit GtkEditable we can't use this.  Since
> only GtkEntry and GtkTextView have GtkIMContext in GTK+, following
> code should work (but seem hack).

Oops, sorry. You're right. But I think that the responsibility
violation of your code should be avoided even if it's a
workaround hack. I prefer keeping im_context private to text
widgets, as described in gtk_entry_init(). And I also want to
keep full-implementability of user text widgets that use
im_context possible.

# Although I recently suggested a code fragment which touches
# im_context directly to explain my concepts. Sorry, it was only
# a concept and inappropriate for actual implementation.

static void
gtk_entry_init (GtkEntry *entry)
{
  ...
  /* This object is completely private. No external entity can gain a reference
   * to it; so we create it here and destroy it in finalize().
   */
  entry->im_context = gtk_im_multicontext_new ();
  ...
}

How about using move_cursor signal with zero move to notify text
widgets the event?

> --- gtkwidget.c.orig    2006-09-09 14:07:07.000000000 +0900
> +++ gtkwidget.c 2006-11-17 16:24:51.000000000 +0900
> @@ -52,6 +52,9 @@
>  #include "gtkaccessible.h"
>  #include "gtktooltips.h"
>  #include "gtkinvisible.h"
> +#include "gtktextview.h"
> +#include "gtkentry.h"
> +#include "gtkimcontext.h"
>  #include "gtkalias.h"
> 
>  #define WIDGET_CLASS(w)         GTK_WIDGET_GET_CLASS (w)
> @@ -8057,5 +8060,42 @@
>    g_object_notify (G_OBJECT (widget), "no-show-all");
>  }
> 
> +/**
> + * gtk_widget_fix_input_context:
> + * @widget: a #GtkWidget
> + *
> + * Interrupt input context and fix or reset the existing preedit string.
> + *
> + * This is mostly for use in pressing toolbutton in a application,
> + * see #GtkButton.
> + **/
> +
> +void
> +gtk_widget_fix_input_context (GtkWidget *widget)
> +{
> +  GtkWidget *toplevel, *focus_widget;;
> +  GtkIMContext *im_context = NULL;
> +
> +  g_return_if_fail (GTK_IS_WIDGET (widget));
> +
> +  toplevel = gtk_widget_get_toplevel (widget);
> +
> +  if (GTK_WIDGET_TOPLEVEL (toplevel)) {
> +    focus_widget = GTK_WINDOW (toplevel)->focus_widget;
> +    if (focus_widget) {
> +      if (GTK_IS_TEXT_VIEW(focus_widget))
> +       im_context = GTK_TEXT_VIEW(focus_widget)->im_context;
> +      if (GTK_IS_ENTRY(focus_widget))
> +       im_context = GTK_ENTRY(focus_widget)->im_context;
> +
> +    }
> +  }
> +
> +  if (im_context) {
> +    gtk_im_context_focus_out (im_context);
> +    gtk_im_context_focus_in (im_context);
> +  }
> +}

------------------------------------------------
YAMAMOTO Kengo / YamaKen  yamaken at bp.iij4u.or.jp
FAMILY   Given / Nick



More information about the uim mailing list