gtk-a-higuti-990523-0.patch

This patch is made against gtk+-1.2.2.


PHENOMENON:

Sometimes, an editable widget which has input focus, doesn't have input
context focus. This makes us impossible to input Japanese text on the
editable widget. This phenomenon occurs frequently when we call
gtk_widget_grab_focus() explicitly.


HOW TO REPRODUCE:

1. Run fvwm2 with the ClickToFocus setting.
2. Run an input method server (e.g. kinput2).
3. Run the test program.
4. Two file selection dialogs will be appeared. Y has input focus, but
you can't activate XIM with it.

WHAT IS HAPPANING:

This phenomenon can be summarized as follows.

1. At first, gtk_widget_show_all(x) is called. Because x->selection_entry
has focus (cf. gtk_file_selection_init), gdk_im_begin(x->selection_entry)
is called.  Therefore x->selection_entry has ICFocus at this moment.

2. gtk_widget_show_all(y) is called. Because y->selection_entry has focus,
gdk_im_begin(y->selection_entry) is called. y->selection_entry gets ICFocus,
and x->selection_entry loses ICFocus.

3. In gtk_main(), we get the following events.
 (1) FocusIn event for x.
    This event doesn't cause a call to gtk_entry_focus_in(x->selection_entry)
    because x->selection_entry already has focus (cf.
    gtk_window_focus_in_event).
 (2) FocusOut event for x.
    This cuases a call to gtk_entry_focus_out(x->selection_entry), which
    calls gdk_im_end(). y->selection_entry (NOT x!) loses ICFocus.
 (3) FocusIn event for y.
    This event doesn't cause a call to gtk_entry_focus_in(y->selection_entry)
    because y->selection_entry already has focus. Though y->selection_entry
    has focus, it doesn't have ICFocus.


HOW TO FIX IT:

I think there are two ways to fix it.
(1) Make gdk_im_end() have an argument of type GdkIC *.
(2) Make gtk_window_focus_in_event() call gtk_*_focus_in(B) even if
B has input focus.

I think (1) is a bit better, but not suitable for gtk+-1.2. So I send a
patch according to (2).


TEST PROGRAM:

#include <gtk/gtk.h>
int main(int argc, char *argv[])
{
	GtkWidget *x, *y;
	gtk_set_locale();
	gtk_init(&argc, &argv);
	x = gtk_file_selection_new("X");
	y = gtk_file_selection_new("Y");
	gtk_widget_show_all(x);
	gtk_widget_show_all(y);
	gtk_main();
	return 0;
}