You've already forked CEF4Delphi
mirror of
https://github.com/salvadordf/CEF4Delphi.git
synced 2025-09-30 21:28:55 +02:00
Fixed IME in GTK3 for Lazarus
Only for browsers in OSR mode.
This commit is contained in:
@@ -207,6 +207,12 @@ type
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
function ConnectSignals: boolean;
|
function ConnectSignals: boolean;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
{$IFDEF LCLGTK3}
|
||||||
|
/// <summary>
|
||||||
|
/// This is just a workaround for the missing implementation of SendMessage in GTK3. Don't use!
|
||||||
|
/// </summary>
|
||||||
|
procedure SendMessage(var aMessage : TMessage);
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the scanline size.
|
/// Returns the scanline size.
|
||||||
@@ -675,6 +681,15 @@ begin
|
|||||||
end;
|
end;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
|
{$IFDEF LCLGTK3}
|
||||||
|
// This is just a workaround for the missing implementation of SendMessage in GTK3.
|
||||||
|
procedure TBufferPanel.SendMessage(var aMessage : TMessage);
|
||||||
|
begin
|
||||||
|
if (aMessage.Msg = LM_IM_COMPOSITION) and Focused then
|
||||||
|
WMIMEComposition(aMessage);
|
||||||
|
end;
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
procedure TBufferPanel.CreateIMEHandler;
|
procedure TBufferPanel.CreateIMEHandler;
|
||||||
begin
|
begin
|
||||||
{$IFDEF MSWINDOWS}
|
{$IFDEF MSWINDOWS}
|
||||||
@@ -1162,7 +1177,7 @@ procedure TBufferPanel.WMIMEComposition(var aMessage : TMessage);
|
|||||||
var
|
var
|
||||||
TempText : ustring;
|
TempText : ustring;
|
||||||
TempCommit : string;
|
TempCommit : string;
|
||||||
begin
|
begin
|
||||||
case aMessage.WPARAM of
|
case aMessage.WPARAM of
|
||||||
GTK_IM_FLAG_START :
|
GTK_IM_FLAG_START :
|
||||||
if assigned(FOnIMEPreEditStart) then
|
if assigned(FOnIMEPreEditStart) then
|
||||||
|
@@ -25,11 +25,11 @@ type
|
|||||||
public
|
public
|
||||||
constructor Create(aPanel : TCustomPanel);
|
constructor Create(aPanel : TCustomPanel);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure CreateContext;
|
function CreateContext : boolean;
|
||||||
procedure DestroyContext;
|
procedure DestroyContext;
|
||||||
procedure SetClientWindow;
|
procedure SetClientWindow;
|
||||||
procedure ResetClientWindow;
|
procedure ResetClientWindow;
|
||||||
procedure ConnectSignals;
|
function ConnectSignals : boolean;
|
||||||
procedure Focus;
|
procedure Focus;
|
||||||
procedure Blur;
|
procedure Blur;
|
||||||
procedure Reset;
|
procedure Reset;
|
||||||
@@ -51,7 +51,29 @@ implementation
|
|||||||
uses
|
uses
|
||||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}pango,{$ENDIF}
|
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}pango,{$ENDIF}
|
||||||
{$IFDEF FPC}LCLType, LCLIntf, LMessages,{$ENDIF}
|
{$IFDEF FPC}LCLType, LCLIntf, LMessages,{$ENDIF}
|
||||||
SysUtils;
|
{$IFDEF LCLGTK3}uCEFBufferPanel,{$ENDIF}
|
||||||
|
SysUtils, uCEFMiscFunctions;
|
||||||
|
|
||||||
|
{$IFDEF LCLGTK3}
|
||||||
|
// This is just a workaround for the missing implementation of SendMessage in GTK3.
|
||||||
|
function SendMessage(HandleWnd: HWND; Msg: Cardinal; wParam: WParam; lParam: LParam): LResult;
|
||||||
|
var
|
||||||
|
LMessage : TLMessage;
|
||||||
|
LPanel : TBufferPanel;
|
||||||
|
begin
|
||||||
|
LMessage.Msg := Msg;
|
||||||
|
LMessage.WParam := WParam;
|
||||||
|
LMessage.LParam := LParam;
|
||||||
|
LMessage.Result := 0;
|
||||||
|
|
||||||
|
LPanel := TBufferPanel(HandleWnd);
|
||||||
|
|
||||||
|
if (LPanel <> nil) then
|
||||||
|
LPanel.SendMessage(LMessage);
|
||||||
|
|
||||||
|
Result := LMessage.Result;
|
||||||
|
end;
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||||
procedure gtk_commit_cb({%H-}context: PGtkIMContext; const Str: Pgchar; {%H-}Data: Pointer); cdecl;
|
procedure gtk_commit_cb({%H-}context: PGtkIMContext; const Str: Pgchar; {%H-}Data: Pointer); cdecl;
|
||||||
@@ -126,14 +148,19 @@ begin
|
|||||||
FForm := nil;
|
FForm := nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEFLinuxOSRIMEHandler.CreateContext;
|
function TCEFLinuxOSRIMEHandler.CreateContext : boolean;
|
||||||
begin
|
begin
|
||||||
|
Result := False;
|
||||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||||
if not(assigned(FIMContext)) then
|
if not(assigned(FIMContext)) then
|
||||||
begin
|
begin
|
||||||
FIMContext := gtk_im_multicontext_new();
|
FIMContext := gtk_im_multicontext_new();
|
||||||
SetClientWindow;
|
|
||||||
ConnectSignals;
|
if assigned(FIMContext) then
|
||||||
|
begin
|
||||||
|
SetClientWindow;
|
||||||
|
Result := ConnectSignals;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
@@ -152,18 +179,18 @@ end;
|
|||||||
procedure TCEFLinuxOSRIMEHandler.SetClientWindow;
|
procedure TCEFLinuxOSRIMEHandler.SetClientWindow;
|
||||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||||
var
|
var
|
||||||
TempWidget : PGtkWidget;
|
TempWindow : PGdkWindow;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
begin
|
begin
|
||||||
if Initialized then
|
if Initialized then
|
||||||
begin
|
begin
|
||||||
{$IFDEF LCLGTK2}
|
{$IFDEF LCLGTK2}
|
||||||
TempWidget := PGtkWidget(FForm.Handle);
|
TempWindow := PGtkWidget(FForm.Handle)^.window;
|
||||||
gtk_im_context_set_client_window(FIMContext, TempWidget^.window);
|
gtk_im_context_set_client_window(FIMContext, TempWindow);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
{$IFDEF LCLGTK3}
|
{$IFDEF LCLGTK3}
|
||||||
TempWidget := TGtk3Widget(FForm.Handle).Widget;
|
TempWindow := TGtk3Widget(FForm.Handle).Widget^.window;
|
||||||
gtk_im_context_set_client_window(FIMContext, TempWidget^.window);
|
gtk_im_context_set_client_window(FIMContext, TempWindow);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@@ -179,23 +206,48 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEFLinuxOSRIMEHandler.ConnectSignals;
|
function TCEFLinuxOSRIMEHandler.ConnectSignals: boolean;
|
||||||
begin
|
var
|
||||||
if Initialized then
|
TempHandlerID1, TempHandlerID2, TempHandlerID3, TempHandlerID4 : gulong;
|
||||||
begin
|
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||||
{$IFDEF LCLGTK3}
|
TempData : GPointer;
|
||||||
g_signal_connect_data(PGObject(@FIMContext), 'commit', TGCallback(@gtk_commit_cb), GPointer(FPanel.Handle), nil, G_CONNECT_DEFAULT);
|
{$ENDIF}
|
||||||
g_signal_connect_data(PGObject(@FIMContext), 'preedit-start', TGCallback(@gtk_preedit_start_cb), GPointer(FPanel.Handle), nil, G_CONNECT_DEFAULT);
|
begin
|
||||||
g_signal_connect_data(PGObject(@FIMContext), 'preedit-end', TGCallback(@gtk_preedit_end_cb), GPointer(FPanel.Handle), nil, G_CONNECT_DEFAULT);
|
TempHandlerID1 := 0;
|
||||||
g_signal_connect_data(PGObject(@FIMContext), 'preedit-changed', TGCallback(@gtk_preedit_changed_cb), GPointer(FPanel.Handle), nil, G_CONNECT_DEFAULT);
|
TempHandlerID2 := 0;
|
||||||
{$ENDIF}
|
TempHandlerID3 := 0;
|
||||||
{$IFDEF LCLGTK2}
|
TempHandlerID4 := 0;
|
||||||
g_signal_connect(G_OBJECT(FIMContext), 'commit', G_CALLBACK(@gtk_commit_cb), GPointer(FPanel.Handle));
|
|
||||||
g_signal_connect(G_OBJECT(FIMContext), 'preedit-start', G_CALLBACK(@gtk_preedit_start_cb), GPointer(FPanel.Handle));
|
try
|
||||||
g_signal_connect(G_OBJECT(FIMContext), 'preedit-end', G_CALLBACK(@gtk_preedit_end_cb), GPointer(FPanel.Handle));
|
try
|
||||||
g_signal_connect(G_OBJECT(FIMContext), 'preedit-changed', G_CALLBACK(@gtk_preedit_changed_cb), GPointer(FPanel.Handle));
|
if Initialized then
|
||||||
{$ENDIF}
|
begin
|
||||||
|
{$IFDEF LCLGTK3}
|
||||||
|
// This should be the data passed to the callback. We'll enable this line as soon as Lazarus implements SendMessage in GTK3.
|
||||||
|
//TempData := GPointer(TGtk3Widget(FPanel.Handle).Widget);
|
||||||
|
TempData := GPointer(FPanel);
|
||||||
|
|
||||||
|
TempHandlerID1 := g_signal_connect_data(PGObject(FIMContext), 'commit', TGCallback(@gtk_commit_cb), TempData, nil, G_CONNECT_DEFAULT);
|
||||||
|
TempHandlerID2 := g_signal_connect_data(PGObject(FIMContext), 'preedit-start', TGCallback(@gtk_preedit_start_cb), TempData, nil, G_CONNECT_DEFAULT);
|
||||||
|
TempHandlerID3 := g_signal_connect_data(PGObject(FIMContext), 'preedit-end', TGCallback(@gtk_preedit_end_cb), TempData, nil, G_CONNECT_DEFAULT);
|
||||||
|
TempHandlerID4 := g_signal_connect_data(PGObject(FIMContext), 'preedit-changed', TGCallback(@gtk_preedit_changed_cb), TempData, nil, G_CONNECT_DEFAULT);
|
||||||
|
{$ENDIF}
|
||||||
|
{$IFDEF LCLGTK2}
|
||||||
|
TempData := GPointer(FPanel.Handle);
|
||||||
|
|
||||||
|
TempHandlerID1 := g_signal_connect(G_OBJECT(FIMContext), 'commit', G_CALLBACK(@gtk_commit_cb), TempData);
|
||||||
|
TempHandlerID2 := g_signal_connect(G_OBJECT(FIMContext), 'preedit-start', G_CALLBACK(@gtk_preedit_start_cb), TempData);
|
||||||
|
TempHandlerID3 := g_signal_connect(G_OBJECT(FIMContext), 'preedit-end', G_CALLBACK(@gtk_preedit_end_cb), TempData);
|
||||||
|
TempHandlerID4 := g_signal_connect(G_OBJECT(FIMContext), 'preedit-changed', G_CALLBACK(@gtk_preedit_changed_cb), TempData);
|
||||||
|
{$ENDIF}
|
||||||
|
end;
|
||||||
|
except
|
||||||
|
on e : exception do
|
||||||
|
if CustomExceptionHandler('TCEFLinuxOSRIMEHandler.ConnectSignals', e) then raise;
|
||||||
end;
|
end;
|
||||||
|
finally
|
||||||
|
Result := (TempHandlerID1 > 0) and (TempHandlerID2 > 0) and (TempHandlerID3 > 0) and (TempHandlerID4 > 0);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCEFLinuxOSRIMEHandler.Focus;
|
procedure TCEFLinuxOSRIMEHandler.Focus;
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
"UpdateLazPackages" : [
|
"UpdateLazPackages" : [
|
||||||
{
|
{
|
||||||
"ForceNotify" : true,
|
"ForceNotify" : true,
|
||||||
"InternalVersion" : 772,
|
"InternalVersion" : 773,
|
||||||
"Name" : "cef4delphi_lazarus.lpk",
|
"Name" : "cef4delphi_lazarus.lpk",
|
||||||
"Version" : "139.0.28"
|
"Version" : "139.0.28"
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user