Forum > GTK
Synedit at UIM input method module.
parcel:
I try to solve problem asian word inputing in synedit control, but there is a lot of problem.
Most of them caused by 'key-press-evnent' handler.
I have use UIM input method module in linux mint 17 64bit.
synedit with candidate window will not work, key press raised in widget.
--- Code: ---unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, SynEdit, Forms, Controls, Graphics, Dialogs,
StdCtrls;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Memo1: TMemo;
SynEdit1: TSynEdit;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
uses glib2, gdk2, gtk2, Gtk2Globals, pango;
{$R *.lfm}
var
ntext:PGtkIMContext;
ipos:Integer;
preeditstr:string;
procedure preeditstart(context:PGtkIMContext; Data:Pointer); cdecl;
begin
Inc(ipos);
Form1.Memo1.Lines.Add(IntToStr(ipos)+' preedit-start');
end;
procedure preeditchanged(context:PGtkIMContext; Data:Pointer); cdecl;
var
str:Pgchar;
pangoattr:PPangoAttrList;
pos:pgint;
begin
Form1.Memo1.Lines.Add(IntToStr(ipos)+' preedit-changed');
gtk_im_context_get_preedit_string(context,@str,pangoattr,nil);
preeditstr:=str;
g_free(str);
pango_attr_list_unref(pangoattr);
Form1.Memo1.Lines.Add(IntToStr(ipos)+' '+preeditstr);
im_context_string:=preeditstr;
end;
procedure preeditend(context:PGtkIMContext; Data:Pointer); cdecl;
begin
Form1.Memo1.Lines.Add(IntToStr(ipos)+' preedit-end');
preeditstr:='';
end;
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
begin
gtk_im_context_reset(im_context);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
ipos:=0;
g_signal_connect(G_OBJECT(im_context),'preedit-start',G_CALLBACK(@preeditstart),nil);
g_signal_connect(G_OBJECT(im_context),'preedit-changed',G_CALLBACK(@preeditchanged),nil);
g_signal_connect(G_OBJECT(im_context),'preedit-end',G_CALLBACK(@preeditend),nil);
end;
end.
--- End code ---
with above source, composition string out successfully in synedit.
What is the best way of skipping candidate window key(hanja candidate window) code in synedit control's widget?
Martin_fr:
Can you point me to documentation for those functions?
I am not sure, if gtk should send key down events to synedit, if the pre-compose win is open, that may need to be fixed in the LCL widgetset code.
'key-press-evnent' is in lcl-gtk. I'll see if I can get the maintainer to join us here. (I only do SynEdit, but not gtk)
Otherwise it would need some checks in synedit (hardcoded in KeyDown/Press)
Once you have the composition, look at unit LazSynIMM (windows)
It shows how to insert the text.
procedure LazSynImeFull.WMImeComposition(var Msg: TMessage);
zeljko:
@parcel, what version of lazarus do you use ?
parcel:
I'm also newbie in gtk. :-[
I did check gtk2proc.inc 'key-press-event' signal but 'commit' not work property.
'preedit' signals match windows IME-compositon messages. I can get input from above code, but it's insert all between-composition characters.
widgetset GTK 'key-press-event' signal handler break apart input method composition, and only alphabet character appears.
I guess it's not synedit problem.
parcel:
--- Quote from: zeljko on June 18, 2014, 03:23:46 pm ---@parcel, what version of lazarus do you use ?
--- End quote ---
It is svn trunk version.
I made small patch.
it works but composition window is not shown.
and not work with breaking composition mode by mouse click.
and candidate window is not work.
--- Code: ---Index: lcl/interfaces/gtk2/gtk2globals.pp
===================================================================
--- lcl/interfaces/gtk2/gtk2globals.pp (revision 45577)
+++ lcl/interfaces/gtk2/gtk2globals.pp (working copy)
@@ -75,6 +75,7 @@
im_context: PGtkIMContext = nil;
im_context_widget: PGtkWidget = nil;
im_context_string: string = '';
+ im_context_use: Boolean = False; //DW
procedure ResetDefaultIMContext;
@@ -421,6 +422,7 @@
end;
im_context_widget:=nil;
im_context_string:='';
+ im_context_use:=False; //DW
end;
procedure AddCharsetEncoding(CharSet: Byte; CharSetReg, CharSetCod: CharSetStr;
Index: lcl/interfaces/gtk2/gtk2proc.inc
===================================================================
--- lcl/interfaces/gtk2/gtk2proc.inc (revision 45577)
+++ lcl/interfaces/gtk2/gtk2proc.inc (working copy)
@@ -1990,7 +1990,8 @@
end;
Exit;
end;
- Result := (AEvent^.Length > 0) or (GetSpecialChar <> #0);
+ //DW
+ Result := ((not im_context_use) and (AEvent^.Length > 0)) or (GetSpecialChar <> #0);
end;
function KeyAlreadyHandledByGtk: boolean;
Index: lcl/interfaces/gtk2/gtk2widgetset.inc
===================================================================
--- lcl/interfaces/gtk2/gtk2widgetset.inc (revision 45577)
+++ lcl/interfaces/gtk2/gtk2widgetset.inc (working copy)
@@ -221,6 +221,32 @@
im_context_string:=Str;
end;
+//DW
+procedure gtk_predit_start_cb({%H-}context: PGtkIMContext; {%H-}Data: Pointer); cdecl;
+begin
+ im_context_use:=True;
+end;
+
+procedure gtk_predit_end_cb({%H-}context: PGtkIMContext; {%H-}Data: Pointer); cdecl;
+var
+ WinControl:TCustomControl;
+ chutf8:TUTF8Char;
+begin
+ im_context_use:=False;
+ { at preedit ending, "commit => preedit-end => commit => keypress"
+ it send last composition character to keyboard event.
+ }
+ if (im_context_widget<>nil) and (im_context_string<>'') and
+ gtk_widget_is_focus(im_context_widget) and
+ (GetNearestLCLObject(im_context_widget) is TCustomControl) then
+ begin
+ WinControl:=GetNearestLCLObject(im_context_widget) as TCustomControl;
+ chutf8:=UTF8Copy(im_context_string,1,1);
+ WinControl.IntfUTF8KeyPress(chutf8,1,False);
+ im_context_string:='';
+ end;
+end;
+
{$IfNDef GTK2_2}
procedure gtkTreeSelectionCountSelectedRows({%H-}model : PGtkTreeModel; {%H-}path : PGtkTreePath;
{%H-}iter : PGtkTreeIter; data : PGint); cdecl;
@@ -985,6 +1011,11 @@
im_context:=gtk_im_multicontext_new;
g_signal_connect (G_OBJECT (im_context), 'commit',
G_CALLBACK (@gtk_commit_cb), nil);
+ //DW
+ g_signal_connect (G_OBJECT (im_context), 'preedit-start',
+ G_CALLBACK (@gtk_predit_start_cb), nil);
+ g_signal_connect (G_OBJECT (im_context), 'preedit-end',
+ G_CALLBACK (@gtk_predit_end_cb), nil);
{$IFDEF HASX}
if IsNoTransientWM then
begin
--- End code ---
Navigation
[0] Message Index
[#] Next page