Forum > GTK

Synedit at UIM input method module.

(1/3) > >>

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

Go to full version