Input method menu patch
Yukihiro Nakai <[email protected]> Thu, 11 Mar 2004 19:41:58 +0900
| Newsgroups | gmane.comp.graphics.sodipodi |
|---|---|
| Organization | Red Hat North Asia |
| Message-ID | <[email protected]> |
Hi, Users can change input methods (GTK+ immodules) with the right click menu in the normal GTK+ editable widgets, and this feature is very useful when you want to switch to another input method or input other languages on an application. The attached patch brings you a happy switching of input methods. I've put a screenshot: http://bonobo.gnome.gr.jp/~nakai/tmp/immenu.png Thank you. -- Nakai
sodipodi-CVS-immenu.diff
(application/octet-stream, 9.2 KB)
Index: ChangeLog =================================================================== RCS file: /cvs/gnome/sodipodi/ChangeLog,v retrieving revision 1.753 diff -u -r1.753 ChangeLog --- ChangeLog 29 Feb 2004 18:10:19 -0000 1.753 +++ ChangeLog 11 Mar 2004 10:28:18 -0000 @@ -1,3 +1,9 @@ +2004-03-11 Yukihiro Nakai <[email protected]> + + * src/desktop.h,src/desktop.c,src/interface.c,src/text-context.h, + src/text-context.c: Move GtkIMContext to desktop.h to add + input method menus to right click menu. + 2004-02-29 Lauris Kaplinski <[email protected]> * src/sp-item.c (sp_item_set): Parse visibility Index: src/desktop.c =================================================================== RCS file: /cvs/gnome/sodipodi/src/desktop.c,v retrieving revision 1.124 diff -u -r1.124 desktop.c --- src/desktop.c 29 Feb 2004 18:10:20 -0000 1.124 +++ src/desktop.c 11 Mar 2004 10:28:18 -0000 @@ -180,6 +180,7 @@ nr_matrix_d_set_scale (NR_MATRIX_D_FROM_DOUBLE (desktop->doc2dt), 0.8, -0.8); desktop->guides_active = FALSE; + desktop->imc = gtk_im_multicontext_new(); } static void @@ -210,6 +211,8 @@ dt->selection = NULL; } + g_object_unref (dt->imc); + G_OBJECT_CLASS (parent_class)->dispose (object); } Index: src/desktop.h =================================================================== RCS file: /cvs/gnome/sodipodi/src/desktop.h,v retrieving revision 1.50 diff -u -r1.50 desktop.h --- src/desktop.h 29 Feb 2004 18:10:21 -0000 1.50 +++ src/desktop.h 11 Mar 2004 10:28:18 -0000 @@ -28,6 +28,7 @@ #include "helper/units.h" #include "forward.h" #include "view.h" +#include <gtk/gtkimcontext.h> struct _SPDesktop { SPView view; @@ -62,6 +63,9 @@ gdouble guidesnap; /* fixme: This has to be implemented in different way */ guint guides_active : 1; + + /* Input Methods */ + GtkIMContext *imc; }; struct _SPDesktopClass { Index: src/interface.c =================================================================== RCS file: /cvs/gnome/sodipodi/src/interface.c,v retrieving revision 1.75 diff -u -r1.75 interface.c --- src/interface.c 29 Feb 2004 18:10:21 -0000 1.75 +++ src/interface.c 11 Mar 2004 10:28:19 -0000 @@ -482,6 +482,15 @@ sp_ui_menu_append (menu, verbs, FALSE); } +static void +sp_ui_inputmethod_menu (GtkMenu *menu, SPDocument *doc) +{ + static const unsigned int verbs[] = { + SP_VERB_LAST + }; + sp_ui_menu_append (menu, verbs, FALSE); +} + /* Menus */ static void @@ -617,6 +626,13 @@ sp_ui_dialog_menu (GTK_MENU (sm), NULL); gtk_widget_show (sm); gtk_menu_item_set_submenu (GTK_MENU_ITEM (i), sm); + /* Input Methods */ + i = sp_ui_menu_append_item (GTK_MENU (m), NULL, _("Input Methods"), NULL, NULL); + sm = gtk_menu_new (); + gtk_im_multicontext_append_menuitems (GTK_IM_MULTICONTEXT (dt->imc), + GTK_MENU_SHELL (sm)); + gtk_widget_show (sm); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (i), sm); /* Modules submenu */ sm = sp_modules_menu_new (); if (sm) { Index: src/text-context.c =================================================================== RCS file: /cvs/gnome/sodipodi/src/text-context.c,v retrieving revision 1.60 diff -u -r1.60 text-context.c --- src/text-context.c 16 Feb 2004 17:08:23 -0000 1.60 +++ src/text-context.c 11 Mar 2004 10:28:19 -0000 @@ -113,8 +113,6 @@ ec->hot_x = 0; ec->hot_y = 0; - tc->imc = NULL; - tc->text = NULL; tc->pdoc.x = 0.0; tc->pdoc.y = 0.0; @@ -128,6 +126,8 @@ tc->show = FALSE; tc->phase = 0; + tc->sigid_commit = 0; + tc->sigid_preedit = 0; tc->preedit_string = NULL; } @@ -160,19 +160,20 @@ tc->timeout = gtk_timeout_add (250, (GtkFunction) sp_text_context_timeout, ec); - tc->imc = gtk_im_multicontext_new(); - if (tc->imc) { + gtk_im_context_reset (desktop->imc); + + if (desktop->imc) { GtkWidget *canvas; canvas = GTK_WIDGET (SP_DT_CANVAS (desktop)); - gtk_im_context_set_use_preedit (tc->imc, TRUE); - gtk_im_context_set_client_window (tc->imc, canvas->window); + gtk_im_context_set_use_preedit (desktop->imc, TRUE); + gtk_im_context_set_client_window (desktop->imc, canvas->window); g_signal_connect (G_OBJECT (canvas), "focus_in_event", G_CALLBACK (sptc_focus_in), tc); g_signal_connect (G_OBJECT (canvas), "focus_out_event", G_CALLBACK (sptc_focus_out), tc); - g_signal_connect (G_OBJECT (tc->imc), "commit", G_CALLBACK (sptc_commit), tc); - g_signal_connect (G_OBJECT (tc->imc), "preedit_changed", G_CALLBACK (sptc_preedit_changed), tc); + tc->sigid_commit = g_signal_connect (G_OBJECT (desktop->imc), "commit", G_CALLBACK (sptc_commit), tc); + tc->sigid_preedit = g_signal_connect (G_OBJECT (desktop->imc), "preedit_changed", G_CALLBACK (sptc_preedit_changed), tc); if (GTK_WIDGET_HAS_FOCUS (canvas)) { sptc_focus_in (canvas, NULL, tc); @@ -193,15 +194,23 @@ sp_text_context_finish (SPEventContext *ec) { SPTextContext *tc; + SPDesktop *desktop; + tc = SP_TEXT_CONTEXT (ec); + desktop = ec->desktop; sp_text_context_forget_text (SP_TEXT_CONTEXT (ec)); - if (tc->imc) { - g_object_unref (G_OBJECT (tc->imc)); - tc->imc = NULL; + if( tc->sigid_commit > 0 ) { + g_signal_handler_disconnect (desktop->imc, tc->sigid_commit); + tc->sigid_commit = 0; + } + + if( tc->sigid_preedit > 0 ) { + g_signal_handler_disconnect (desktop->imc, tc->sigid_preedit); + tc->sigid_preedit = 0; } - + if (tc->timeout) { gtk_timeout_remove (tc->timeout); tc->timeout = 0; @@ -305,6 +314,7 @@ { SPTextContext *tc; SPStyle *style; + SPDesktop* desktop = ec->desktop; tc = SP_TEXT_CONTEXT (ec); @@ -329,7 +339,7 @@ } break; case GDK_KEY_PRESS: - if (!tc->unimode && tc->imc && gtk_im_context_filter_keypress (tc->imc, (GdkEventKey*)event)) { + if (!tc->unimode && desktop->imc && gtk_im_context_filter_keypress (desktop->imc, (GdkEventKey*)event)) { return TRUE; } /* fixme: This is a quick bug fix to avoid to enter infinite loop @@ -338,7 +348,7 @@ * gtk_im_context_filter_keypress twice for single event. * The fundamental problem is at sp_desktop_new, it is bad idea to * connect sp_desktop_root_handler to acetate and main canvas (Oka) */ - if (!tc->unimode && tc->imc && + if (!tc->unimode && desktop->imc && ((event->key.keyval == GDK_Shift_L) || (event->key.keyval == GDK_Shift_R))) { return TRUE; @@ -364,8 +374,8 @@ tc->unimode = TRUE; tc->unipos = 0; } - if (tc->imc) { - gtk_im_context_reset (tc->imc); + if (desktop->imc) { + gtk_im_context_reset (desktop->imc); } return TRUE; default: @@ -452,7 +462,7 @@ } break; case GDK_KEY_RELEASE: - if (!tc->unimode && tc->imc && gtk_im_context_filter_keypress (tc->imc, (GdkEventKey*)event)) { + if (!tc->unimode && desktop->imc && gtk_im_context_filter_keypress (desktop->imc, (GdkEventKey*)event)) { return TRUE; } break; @@ -499,6 +509,7 @@ sp_text_context_update_cursor (SPTextContext *tc) { GdkRectangle im_cursor = { 0, 0, 1, 1 }; + SPDesktop *desktop = SP_EVENT_CONTEXT (tc)->desktop; if (tc->text) { ArtPoint p0, p1, d0, d1; @@ -525,8 +536,8 @@ tc->show = FALSE; } - if (tc->imc) { - gtk_im_context_set_cursor_location (tc->imc, &im_cursor); + if (desktop->imc) { + gtk_im_context_set_cursor_location (desktop->imc, &im_cursor); } } @@ -568,14 +579,34 @@ gint sptc_focus_in (GtkWidget *widget, GdkEventFocus *event, SPTextContext *tc) { - gtk_im_context_focus_in (tc->imc); + SPDesktop *desktop = SP_EVENT_CONTEXT (tc)->desktop; + + if( tc->sigid_commit == 0 ) { + tc->sigid_commit = g_signal_connect (desktop->imc, "commit", G_CALLBACK(sptc_commit), tc); + } + if( tc->sigid_preedit == 0 ) { + tc->sigid_preedit = g_signal_connect (desktop->imc, "preedit_changed", G_CALLBACK(sptc_preedit_changed), tc); + } + gtk_im_context_focus_in (desktop->imc); + return FALSE; } gint sptc_focus_out (GtkWidget *widget, GdkEventFocus *event, SPTextContext *tc) { - gtk_im_context_focus_out (tc->imc); + SPDesktop *desktop = SP_EVENT_CONTEXT (tc)->desktop; + + gtk_im_context_focus_out (desktop->imc); + if( tc->sigid_commit > 0 ) { + g_signal_handler_disconnect (desktop->imc, tc->sigid_commit); + tc->sigid_commit = 0; + } + if( tc->sigid_preedit > 0 ) { + g_signal_handler_disconnect (desktop->imc, tc->sigid_preedit); + tc->sigid_preedit = 0; + } + return FALSE; } @@ -595,10 +626,11 @@ sptc_preedit_changed (GtkIMContext *imc, SPTextContext *tc) { gint cursor_pos; + SPDesktop *desktop = SP_EVENT_CONTEXT (tc)->desktop; sp_text_context_preedit_reset (tc); - gtk_im_context_get_preedit_string (tc->imc, + gtk_im_context_get_preedit_string (desktop->imc, &tc->preedit_string, NULL, &cursor_pos); if( tc->preedit_string != NULL ) { Index: src/text-context.h =================================================================== RCS file: /cvs/gnome/sodipodi/src/text-context.h,v retrieving revision 1.18 diff -u -r1.18 text-context.h --- src/text-context.h 17 Aug 2003 20:39:25 -0000 1.18 +++ src/text-context.h 11 Mar 2004 10:28:19 -0000 @@ -29,8 +29,6 @@ struct _SPTextContext { SPEventContext event_context; - GtkIMContext *imc; - SPItem *text; /* Text item position in root coordinates */ @@ -48,6 +46,10 @@ guint show : 1; guint phase : 1; + /* Signal Handlers for Input Methods */ + gulong sigid_commit; + gulong sigid_preedit; + /* Preedit String */ gchar* preedit_string; };