You've already forked CEF4Delphi
mirror of
https://github.com/salvadordf/CEF4Delphi.git
synced 2025-09-30 21:28:55 +02:00
Added SimpleOSRBrowser demo for Lazarus using GTK3
Added uCEFLinuxOSRIMEHandler to the CEF4Delphi source directory. Updated SimpleOSRBrowser for GTK2
This commit is contained in:
@@ -37,7 +37,7 @@
|
||||
<PackageName Value="LCL"/>
|
||||
</Item3>
|
||||
</RequiredPackages>
|
||||
<Units Count="4">
|
||||
<Units Count="3">
|
||||
<Unit0>
|
||||
<Filename Value="SimpleOSRBrowser.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
@@ -55,11 +55,6 @@
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="Interfaces"/>
|
||||
</Unit2>
|
||||
<Unit3>
|
||||
<Filename Value="uceflinuxosrimehandler.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="uCEFLinuxOSRIMEHandler"/>
|
||||
</Unit3>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
@@ -9,7 +9,7 @@ uses
|
||||
// "Interfaces" is a custom unit used to initialize the LCL WidgetSet
|
||||
// We keep the same name to avoid a Lazarus warning.
|
||||
Interfaces, // this includes the LCL widgetset
|
||||
Forms, lazmouseandkeyinput, uSimpleOSRBrowser, uCEFLinuxOSRIMEHandler,
|
||||
Forms, lazmouseandkeyinput, uSimpleOSRBrowser,
|
||||
{ you can add units after this }
|
||||
uCEFApplication;
|
||||
|
||||
|
@@ -1,11 +1,13 @@
|
||||
object Form1: TForm1
|
||||
Left = 1658
|
||||
Left = 561
|
||||
Height = 630
|
||||
Top = 423
|
||||
Top = 252
|
||||
Width = 1000
|
||||
Caption = ' Initializing browser. Please wait...'
|
||||
ClientHeight = 630
|
||||
ClientWidth = 1000
|
||||
Position = poScreenCenter
|
||||
LCLVersion = '4.2.0.0'
|
||||
OnActivate = FormActivate
|
||||
OnCloseQuery = FormCloseQuery
|
||||
OnCreate = FormCreate
|
||||
@@ -13,7 +15,6 @@ object Form1: TForm1
|
||||
OnHide = FormHide
|
||||
OnShow = FormShow
|
||||
OnWindowStateChange = FormWindowStateChange
|
||||
Position = poScreenCenter
|
||||
object AddressPnl: TPanel
|
||||
Left = 0
|
||||
Height = 30
|
||||
@@ -66,7 +67,7 @@ object Form1: TForm1
|
||||
Align = alClient
|
||||
AutoSelect = False
|
||||
ItemHeight = 0
|
||||
ItemIndex = 7
|
||||
ItemIndex = 0
|
||||
Items.Strings = (
|
||||
'https://www.google.com'
|
||||
'https://www.bing.com'
|
||||
@@ -125,7 +126,7 @@ object Form1: TForm1
|
||||
'chrome://process-internals'
|
||||
)
|
||||
TabOrder = 0
|
||||
Text = 'https://www.baidu.com'
|
||||
Text = 'https://www.google.com'
|
||||
OnEnter = AddressCbEnter
|
||||
end
|
||||
end
|
||||
@@ -138,6 +139,8 @@ object Form1: TForm1
|
||||
OnIMEPreEditEnd = Panel1IMEPreEditEnd
|
||||
OnIMEPreEditChanged = Panel1IMEPreEditChanged
|
||||
OnIMECommit = Panel1IMECommit
|
||||
OnGdkKeyPress = Panel1GdkKeyPress
|
||||
OnGdkKeyRelease = Panel1GdkKeyRelease
|
||||
Align = alClient
|
||||
Caption = 'Panel1'
|
||||
Color = clWhite
|
||||
|
File diff suppressed because it is too large
Load Diff
2
demos/Lazarus_Linux_GTK3/SimpleOSRBrowser/00-Delete.bat
Normal file
2
demos/Lazarus_Linux_GTK3/SimpleOSRBrowser/00-Delete.bat
Normal file
@@ -0,0 +1,2 @@
|
||||
rmdir /S /Q lib
|
||||
rmdir /S /Q backup
|
BIN
demos/Lazarus_Linux_GTK3/SimpleOSRBrowser/SimpleOSRBrowser.ico
Normal file
BIN
demos/Lazarus_Linux_GTK3/SimpleOSRBrowser/SimpleOSRBrowser.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 134 KiB |
101
demos/Lazarus_Linux_GTK3/SimpleOSRBrowser/SimpleOSRBrowser.lpi
Normal file
101
demos/Lazarus_Linux_GTK3/SimpleOSRBrowser/SimpleOSRBrowser.lpi
Normal file
@@ -0,0 +1,101 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectOptions>
|
||||
<Version Value="12"/>
|
||||
<General>
|
||||
<Flags>
|
||||
<CompatibilityMode Value="True"/>
|
||||
</Flags>
|
||||
<SessionStorage Value="InProjectDir"/>
|
||||
<Title Value="SimpleOSRBrowser"/>
|
||||
<Scaled Value="True"/>
|
||||
<ResourceType Value="res"/>
|
||||
<UseXPManifest Value="True"/>
|
||||
<XPManifest>
|
||||
<DpiAware Value="True"/>
|
||||
</XPManifest>
|
||||
<Icon Value="0"/>
|
||||
</General>
|
||||
<MacroValues Count="1">
|
||||
<Macro1 Name="LCLWidgetType" Value="gtk3"/>
|
||||
</MacroValues>
|
||||
<BuildModes Count="1">
|
||||
<Item1 Name="Default" Default="True"/>
|
||||
<SharedMatrixOptions Count="1">
|
||||
<Item1 ID="996268604706" Modes="Default" Type="IDEMacro" MacroName="LCLWidgetType" Value="gtk3"/>
|
||||
</SharedMatrixOptions>
|
||||
</BuildModes>
|
||||
<PublishOptions>
|
||||
<Version Value="2"/>
|
||||
<UseFileFilters Value="True"/>
|
||||
</PublishOptions>
|
||||
<RunParams>
|
||||
<FormatVersion Value="2"/>
|
||||
</RunParams>
|
||||
<RequiredPackages Count="3">
|
||||
<Item1>
|
||||
<PackageName Value="lazmouseandkeyinput"/>
|
||||
</Item1>
|
||||
<Item2>
|
||||
<PackageName Value="CEF4Delphi_Lazarus"/>
|
||||
</Item2>
|
||||
<Item3>
|
||||
<PackageName Value="LCL"/>
|
||||
</Item3>
|
||||
</RequiredPackages>
|
||||
<Units Count="3">
|
||||
<Unit0>
|
||||
<Filename Value="SimpleOSRBrowser.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit0>
|
||||
<Unit1>
|
||||
<Filename Value="usimpleosrbrowser.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<ComponentName Value="MainForm"/>
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
<UnitName Value="uSimpleOSRBrowser"/>
|
||||
</Unit1>
|
||||
<Unit2>
|
||||
<Filename Value="interfaces.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit2>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<Target>
|
||||
<Filename Value="../../../bin/SimpleOSRBrowser"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
|
||||
</SearchPaths>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<DebugInfoType Value="dsDwarf3"/>
|
||||
</Debugging>
|
||||
<Options>
|
||||
<Win32>
|
||||
<GraphicApplication Value="True"/>
|
||||
</Win32>
|
||||
</Options>
|
||||
</Linking>
|
||||
<Other>
|
||||
<CustomOptions Value="-dUseCthreads"/>
|
||||
</Other>
|
||||
</CompilerOptions>
|
||||
<Debugging>
|
||||
<Exceptions Count="3">
|
||||
<Item1>
|
||||
<Name Value="EAbort"/>
|
||||
</Item1>
|
||||
<Item2>
|
||||
<Name Value="ECodetoolError"/>
|
||||
</Item2>
|
||||
<Item3>
|
||||
<Name Value="EFOpenError"/>
|
||||
</Item3>
|
||||
</Exceptions>
|
||||
</Debugging>
|
||||
</CONFIG>
|
@@ -0,0 +1,36 @@
|
||||
program SimpleOSRBrowser;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
uses
|
||||
{$IFDEF UNIX}{$IFDEF UseCThreads}
|
||||
cthreads,
|
||||
{$ENDIF}{$ENDIF}
|
||||
// "Interfaces" is a custom unit used to initialize the LCL WidgetSet
|
||||
// We keep the same name to avoid a Lazarus warning.
|
||||
Interfaces, // this includes the LCL widgetset
|
||||
Forms, lazmouseandkeyinput, uSimpleOSRBrowser,
|
||||
{ you can add units after this }
|
||||
uCEFApplication;
|
||||
|
||||
{$R *.res}
|
||||
|
||||
begin
|
||||
CreateGlobalCEFApp;
|
||||
|
||||
if GlobalCEFApp.StartMainProcess then
|
||||
begin
|
||||
// The LCL Widgetset must be initialized after the CEF initialization and
|
||||
// only in the browser process.
|
||||
CustomWidgetSetInitialization;
|
||||
RequireDerivedFormResource:=True;
|
||||
Application.Scaled:=True;
|
||||
Application.Initialize;
|
||||
Application.CreateForm(TMainForm, MainForm);
|
||||
Application.Run;
|
||||
CustomWidgetSetFinalization;
|
||||
end;
|
||||
|
||||
DestroyGlobalCEFApp;
|
||||
end.
|
||||
|
BIN
demos/Lazarus_Linux_GTK3/SimpleOSRBrowser/SimpleOSRBrowser.res
Normal file
BIN
demos/Lazarus_Linux_GTK3/SimpleOSRBrowser/SimpleOSRBrowser.res
Normal file
Binary file not shown.
67
demos/Lazarus_Linux_GTK3/SimpleOSRBrowser/interfaces.pas
Normal file
67
demos/Lazarus_Linux_GTK3/SimpleOSRBrowser/interfaces.pas
Normal file
@@ -0,0 +1,67 @@
|
||||
{
|
||||
/***************************************************************************
|
||||
Interfaces.pp - determines what interface to use
|
||||
-------------------
|
||||
|
||||
Initial Revision : Thu July 1st CST 1999
|
||||
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
*****************************************************************************
|
||||
This file is part of the Lazarus Component Library (LCL)
|
||||
|
||||
See the file COPYING.modifiedLGPL.txt, included in this distribution,
|
||||
for details about the license.
|
||||
*****************************************************************************
|
||||
}
|
||||
|
||||
unit interfaces;
|
||||
|
||||
{$mode objfpc}
|
||||
{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
{$IFDEF UNIX}{$IFNDEF DisableCWString}cwstring,{$ENDIF}{$ENDIF}
|
||||
InterfaceBase;
|
||||
|
||||
procedure CustomWidgetSetInitialization;
|
||||
procedure CustomWidgetSetFinalization;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
gtk3int, Forms, xlib;
|
||||
|
||||
function CustomX11ErrorHandler(Display:PDisplay; ErrorEv:PXErrorEvent):longint;cdecl;
|
||||
begin
|
||||
{$IFDEF DEBUG}
|
||||
XError := ErrorEv^.error_code;
|
||||
WriteLn('Error: ' + IntToStr(XError));
|
||||
{$ENDIF}
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
function CustomXIOErrorHandler(Display:PDisplay):longint;cdecl;
|
||||
begin
|
||||
Result := 0;
|
||||
end;
|
||||
|
||||
procedure CustomWidgetSetInitialization;
|
||||
begin
|
||||
//gdk_set_allowed_backends('X11');
|
||||
CreateWidgetset(TGtk3WidgetSet);
|
||||
// Install xlib error handlers so that the application won't be terminated
|
||||
// on non-fatal errors. Must be done after initializing GTK.
|
||||
XSetErrorHandler(@CustomX11ErrorHandler);
|
||||
XSetIOErrorHandler(@CustomXIOErrorHandler);
|
||||
end;
|
||||
|
||||
procedure CustomWidgetSetFinalization;
|
||||
begin
|
||||
FreeWidgetSet;
|
||||
end;
|
||||
|
||||
end.
|
@@ -6,6 +6,7 @@ interface
|
||||
|
||||
uses
|
||||
{$IFDEF LCLGTK2}gtk2, glib2, gdk2,{$ENDIF}
|
||||
{$IFDEF LCLGTK3}LazGdk3, LazGtk3, LazGObject2, LazGLib2, gtk3procs, gtk3widgets,{$ENDIF}
|
||||
Classes, ExtCtrls, Forms;
|
||||
|
||||
type
|
||||
@@ -14,9 +15,9 @@ type
|
||||
FPanel : TCustomPanel;
|
||||
FForm : TCustomForm;
|
||||
FHasFocus : boolean;
|
||||
{$IFDEF LCLGTK2}
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
FIMContext : PGtkIMContext;
|
||||
{$ENDIF}
|
||||
{$IFEND}
|
||||
|
||||
function GetInitialized : boolean;
|
||||
procedure SetPanel(aValue : TCustomPanel);
|
||||
@@ -33,9 +34,9 @@ type
|
||||
procedure Blur;
|
||||
procedure Reset;
|
||||
procedure SetCursorLocation(X, Y: integer);
|
||||
{$IFDEF LCLGTK2}
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
function FilterKeyPress(aEvent : PGdkEventKey) : boolean;
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
|
||||
property Initialized : boolean read GetInitialized;
|
||||
property HasFocus : boolean read FHasFocus;
|
||||
@@ -48,11 +49,11 @@ implementation
|
||||
// https://chromium.googlesource.com/chromium/src/+/refs/heads/main/ui/gtk/input_method_context_impl_gtk.cc
|
||||
|
||||
uses
|
||||
{$IFDEF LCLGTK2}pango,{$ENDIF}
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}pango,{$ENDIF}
|
||||
{$IFDEF FPC}LCLType, LCLIntf, LMessages,{$ENDIF}
|
||||
SysUtils;
|
||||
|
||||
{$IFDEF LCLGTK2}
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
procedure gtk_commit_cb({%H-}context: PGtkIMContext; const Str: Pgchar; {%H-}Data: Pointer); cdecl;
|
||||
begin
|
||||
SendMessage(HWND(Data), LM_IM_COMPOSITION, GTK_IM_FLAG_COMMIT, LPARAM(Str));
|
||||
@@ -74,7 +75,7 @@ var
|
||||
TempPangoAttr : PPangoAttrList;
|
||||
TempCurpos : gint;
|
||||
begin
|
||||
gtk_im_context_get_preedit_string(context, @TempStr, TempPangoAttr, @TempCurpos);
|
||||
gtk_im_context_get_preedit_string(context, @TempStr, {$IFDEF LCLGTK3}@{$ENDIF}TempPangoAttr, @TempCurpos);
|
||||
SendMessage(HWND(Data), LM_IM_COMPOSITION, GTK_IM_FLAG_PREEDIT, LPARAM(pchar(TempStr)));
|
||||
g_free(TempStr);
|
||||
pango_attr_list_unref(TempPangoAttr);
|
||||
@@ -87,7 +88,7 @@ begin
|
||||
|
||||
FPanel := aPanel;
|
||||
FHasFocus := False;
|
||||
{$IFDEF LCLGTK2}
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
FIMContext := nil;
|
||||
{$ENDIF}
|
||||
|
||||
@@ -107,7 +108,7 @@ end;
|
||||
|
||||
function TCEFLinuxOSRIMEHandler.GetInitialized : boolean;
|
||||
begin
|
||||
{$IFDEF LCLGTK2}
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
Result := assigned(FPanel) and assigned(FIMContext);
|
||||
{$ELSE}
|
||||
Result := False;
|
||||
@@ -127,7 +128,7 @@ end;
|
||||
|
||||
procedure TCEFLinuxOSRIMEHandler.CreateContext;
|
||||
begin
|
||||
{$IFDEF LCLGTK2}
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
if not(assigned(FIMContext)) then
|
||||
begin
|
||||
FIMContext := gtk_im_multicontext_new();
|
||||
@@ -139,7 +140,7 @@ end;
|
||||
|
||||
procedure TCEFLinuxOSRIMEHandler.DestroyContext;
|
||||
begin
|
||||
{$IFDEF LCLGTK2}
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
if assigned(FIMContext) then
|
||||
begin
|
||||
g_object_unref(FIMContext);
|
||||
@@ -149,7 +150,7 @@ begin
|
||||
end;
|
||||
|
||||
procedure TCEFLinuxOSRIMEHandler.SetClientWindow;
|
||||
{$IFDEF LCLGTK2}
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
var
|
||||
TempWidget : PGtkWidget;
|
||||
{$ENDIF}
|
||||
@@ -160,6 +161,10 @@ begin
|
||||
TempWidget := PGtkWidget(FForm.Handle);
|
||||
gtk_im_context_set_client_window(FIMContext, TempWidget^.window);
|
||||
{$ENDIF}
|
||||
{$IFDEF LCLGTK3}
|
||||
TempWidget := TGtk3Widget(FForm.Handle).Widget;
|
||||
gtk_im_context_set_client_window(FIMContext, TempWidget^.window);
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
|
||||
@@ -167,7 +172,7 @@ procedure TCEFLinuxOSRIMEHandler.ResetClientWindow;
|
||||
begin
|
||||
if Initialized then
|
||||
begin
|
||||
{$IFDEF LCLGTK2}
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
gtk_im_context_reset(FIMContext);
|
||||
gtk_im_context_set_client_window(FIMContext, nil);
|
||||
{$ENDIF}
|
||||
@@ -178,6 +183,12 @@ procedure TCEFLinuxOSRIMEHandler.ConnectSignals;
|
||||
begin
|
||||
if Initialized then
|
||||
begin
|
||||
{$IFDEF LCLGTK3}
|
||||
g_signal_connect_data(PGObject(@FIMContext), 'commit', TGCallback(@gtk_commit_cb), GPointer(FPanel.Handle), nil, G_CONNECT_DEFAULT);
|
||||
g_signal_connect_data(PGObject(@FIMContext), 'preedit-start', TGCallback(@gtk_preedit_start_cb), GPointer(FPanel.Handle), nil, G_CONNECT_DEFAULT);
|
||||
g_signal_connect_data(PGObject(@FIMContext), 'preedit-end', TGCallback(@gtk_preedit_end_cb), GPointer(FPanel.Handle), nil, G_CONNECT_DEFAULT);
|
||||
g_signal_connect_data(PGObject(@FIMContext), 'preedit-changed', TGCallback(@gtk_preedit_changed_cb), GPointer(FPanel.Handle), nil, G_CONNECT_DEFAULT);
|
||||
{$ENDIF}
|
||||
{$IFDEF LCLGTK2}
|
||||
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));
|
||||
@@ -191,7 +202,7 @@ procedure TCEFLinuxOSRIMEHandler.Focus;
|
||||
begin
|
||||
if Initialized then
|
||||
begin
|
||||
{$IFDEF LCLGTK2}
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
gtk_im_context_focus_in(FIMContext);
|
||||
{$ENDIF}
|
||||
FHasFocus := True;
|
||||
@@ -202,7 +213,7 @@ procedure TCEFLinuxOSRIMEHandler.Blur;
|
||||
begin
|
||||
if Initialized then
|
||||
begin
|
||||
{$IFDEF LCLGTK2}
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
gtk_im_context_focus_out(FIMContext);
|
||||
{$ENDIF}
|
||||
FHasFocus := False;
|
||||
@@ -213,7 +224,7 @@ procedure TCEFLinuxOSRIMEHandler.Reset;
|
||||
begin
|
||||
if Initialized then
|
||||
begin
|
||||
{$IFDEF LCLGTK2}
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
gtk_im_context_reset(FIMContext);
|
||||
|
||||
// Some input methods may not honour the reset call.
|
||||
@@ -228,14 +239,14 @@ begin
|
||||
end;
|
||||
|
||||
procedure TCEFLinuxOSRIMEHandler.SetCursorLocation(X, Y: integer);
|
||||
{$IFDEF LCLGTK2}
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
var
|
||||
TempCurPos: TGdkRectangle;
|
||||
{$ENDIF}
|
||||
begin
|
||||
if Initialized then
|
||||
begin
|
||||
{$IFDEF LCLGTK2}
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
TempCurPos.x := x;
|
||||
TempCurPos.y := y;
|
||||
TempCurPos.width := 0;
|
||||
@@ -246,7 +257,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{$IFDEF LCLGTK2}
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
function TCEFLinuxOSRIMEHandler.FilterKeyPress(aEvent : PGdkEventKey) : boolean;
|
||||
begin
|
||||
if Initialized then
|
162
demos/Lazarus_Linux_GTK3/SimpleOSRBrowser/usimpleosrbrowser.lfm
Normal file
162
demos/Lazarus_Linux_GTK3/SimpleOSRBrowser/usimpleosrbrowser.lfm
Normal file
@@ -0,0 +1,162 @@
|
||||
object MainForm: TMainForm
|
||||
Left = 1658
|
||||
Height = 630
|
||||
Top = 423
|
||||
Width = 1000
|
||||
Caption = ' Initializing browser. Please wait...'
|
||||
ClientHeight = 630
|
||||
ClientWidth = 1000
|
||||
Position = poScreenCenter
|
||||
LCLVersion = '4.2.0.0'
|
||||
OnActivate = FormActivate
|
||||
OnCloseQuery = FormCloseQuery
|
||||
OnCreate = FormCreate
|
||||
OnDestroy = FormDestroy
|
||||
OnHide = FormHide
|
||||
OnShow = FormShow
|
||||
OnWindowStateChange = FormWindowStateChange
|
||||
object AddressPnl: TPanel
|
||||
Left = 0
|
||||
Height = 30
|
||||
Top = 0
|
||||
Width = 1000
|
||||
Align = alTop
|
||||
ClientHeight = 30
|
||||
ClientWidth = 1000
|
||||
TabOrder = 0
|
||||
object AddressCb: TComboBox
|
||||
Left = 1
|
||||
Height = 28
|
||||
Top = 1
|
||||
Width = 967
|
||||
Align = alClient
|
||||
AutoSelect = False
|
||||
ItemHeight = 0
|
||||
ItemIndex = 0
|
||||
Items.Strings = (
|
||||
'https://www.google.com'
|
||||
'https://www.bing.com'
|
||||
'https://duckduckgo.com'
|
||||
'https://www.qwant.com'
|
||||
'https://yandex.com'
|
||||
'https://www.startpage.com'
|
||||
'https://www.ecosia.org'
|
||||
'https://www.baidu.com'
|
||||
'https://www.whatismybrowser.com/detect/what-http-headers-is-my-browser-sending'
|
||||
'https://www.w3schools.com/js/tryit.asp?filename=tryjs_win_close'
|
||||
'https://www.w3schools.com/js/tryit.asp?filename=tryjs_alert'
|
||||
'https://www.w3schools.com/js/tryit.asp?filename=tryjs_loc_assign'
|
||||
'https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_style_backgroundcolor'
|
||||
'https://www.w3schools.com/Tags/tryit.asp?filename=tryhtml_iframe_name'
|
||||
'https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_input_type_file'
|
||||
'https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_state_throw_error'
|
||||
'https://www.htmlquick.com/es/reference/tags/input-file.html'
|
||||
'https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file'
|
||||
'https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/webkitdirectory'
|
||||
'https://www.w3schools.com/html/html5_video.asp'
|
||||
'http://html5test.com/'
|
||||
'https://webrtc.github.io/samples/src/content/devices/input-output/'
|
||||
'https://test.webrtc.org/'
|
||||
'https://www.browserleaks.com/webrtc'
|
||||
'https://shaka-player-demo.appspot.com/demo/'
|
||||
'http://webglsamples.org/'
|
||||
'https://get.webgl.org/'
|
||||
'https://www.briskbard.com'
|
||||
'https://www.youtube.com'
|
||||
'https://html5demos.com/drag/'
|
||||
'https://frames-per-second.appspot.com/'
|
||||
'https://www.sede.fnmt.gob.es/certificados/persona-fisica/verificar-estado'
|
||||
'https://www.kirupa.com/html5/accessing_your_webcam_in_html5.htm'
|
||||
'https://www.xdumaine.com/enumerateDevices/test/'
|
||||
'https://dagrs.berkeley.edu/sites/default/files/2020-01/sample.pdf'
|
||||
'https://codepen.io/udaymanvar/pen/MWaePBY'
|
||||
'https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/accept'
|
||||
'chrome://version/'
|
||||
'chrome://net-internals/'
|
||||
'chrome://tracing/'
|
||||
'chrome://appcache-internals/'
|
||||
'chrome://blob-internals/'
|
||||
'chrome://view-http-cache/'
|
||||
'chrome://credits/'
|
||||
'chrome://histograms/'
|
||||
'chrome://media-internals/'
|
||||
'chrome://kill'
|
||||
'chrome://crash'
|
||||
'chrome://hang'
|
||||
'chrome://shorthang'
|
||||
'chrome://gpuclean'
|
||||
'chrome://gpucrash'
|
||||
'chrome://gpuhang'
|
||||
'chrome://extensions-support'
|
||||
'chrome://process-internals'
|
||||
)
|
||||
TabOrder = 0
|
||||
Text = 'https://www.google.com'
|
||||
OnEnter = AddressCbEnter
|
||||
end
|
||||
object GoBtn: TButton
|
||||
Left = 968
|
||||
Height = 28
|
||||
Top = 1
|
||||
Width = 31
|
||||
Align = alRight
|
||||
Caption = 'Go'
|
||||
TabOrder = 1
|
||||
OnClick = GoBtnClick
|
||||
OnEnter = GoBtnEnter
|
||||
end
|
||||
end
|
||||
object Panel1: TBufferPanel
|
||||
Tag = 99
|
||||
Left = 0
|
||||
Height = 600
|
||||
Top = 30
|
||||
Width = 1000
|
||||
OnIMEPreEditStart = Panel1IMEPreEditStart
|
||||
OnIMEPreEditEnd = Panel1IMEPreEditEnd
|
||||
OnIMEPreEditChanged = Panel1IMEPreEditChanged
|
||||
OnIMECommit = Panel1IMECommit
|
||||
OnGdkKeyPress = Panel1GdkKeyPress
|
||||
OnGdkKeyRelease = Panel1GdkKeyRelease
|
||||
CopyOriginalBuffer = True
|
||||
Align = alClient
|
||||
Color = clWhite
|
||||
ParentColor = False
|
||||
TabOrder = 1
|
||||
TabStop = True
|
||||
OnEnter = Panel1Enter
|
||||
OnExit = Panel1Exit
|
||||
OnMouseDown = Panel1MouseDown
|
||||
OnMouseMove = Panel1MouseMove
|
||||
OnMouseUp = Panel1MouseUp
|
||||
OnMouseWheel = Panel1MouseWheel
|
||||
OnResize = Panel1Resize
|
||||
OnMouseEnter = Panel1MouseEnter
|
||||
OnMouseLeave = Panel1MouseLeave
|
||||
end
|
||||
object Chromium1: TChromium
|
||||
OnProcessMessageReceived = Chromium1ProcessMessageReceived
|
||||
OnSetFocus = Chromium1SetFocus
|
||||
OnTooltip = Chromium1Tooltip
|
||||
OnCursorChange = Chromium1CursorChange
|
||||
OnBeforePopup = Chromium1BeforePopup
|
||||
OnAfterCreated = Chromium1AfterCreated
|
||||
OnBeforeClose = Chromium1BeforeClose
|
||||
OnOpenUrlFromTab = Chromium1OpenUrlFromTab
|
||||
OnGetViewRect = Chromium1GetViewRect
|
||||
OnGetScreenPoint = Chromium1GetScreenPoint
|
||||
OnGetScreenInfo = Chromium1GetScreenInfo
|
||||
OnPopupShow = Chromium1PopupShow
|
||||
OnPopupSize = Chromium1PopupSize
|
||||
OnPaint = Chromium1Paint
|
||||
OnDevToolsMethodResult = Chromium1DevToolsMethodResult
|
||||
Left = 48
|
||||
Top = 72
|
||||
end
|
||||
object Timer1: TTimer
|
||||
Enabled = False
|
||||
OnTimer = Timer1Timer
|
||||
Left = 48
|
||||
Top = 152
|
||||
end
|
||||
end
|
1364
demos/Lazarus_Linux_GTK3/SimpleOSRBrowser/usimpleosrbrowser.pas
Normal file
1364
demos/Lazarus_Linux_GTK3/SimpleOSRBrowser/usimpleosrbrowser.pas
Normal file
File diff suppressed because it is too large
Load Diff
@@ -901,6 +901,10 @@
|
||||
<Filename Value="..\source\uCEFSettingObserver.pas"/>
|
||||
<UnitName Value="uCEFSettingObserver"/>
|
||||
</Item215>
|
||||
<Item216>
|
||||
<Filename Value="..\source\uceflinuxosrimehandler.pas"/>
|
||||
<UnitName Value="uCEFLinuxOSRIMEHandler"/>
|
||||
</Item216>
|
||||
</Files>
|
||||
<CompatibilityMode Value="True"/>
|
||||
<RequiredPkgs Count="5">
|
||||
|
@@ -15,10 +15,12 @@ uses
|
||||
{$ELSE}
|
||||
{$IFDEF MSWINDOWS}Windows, imm, {$ENDIF} Classes, Forms, Controls, Graphics,
|
||||
{$IFDEF FPC}
|
||||
LCLProc, LCLType, LCLIntf, LResources, LMessages, InterfaceBase, {$IFDEF MSWINDOWS}Win32Extra,{$ENDIF}
|
||||
{$IFDEF LINUXFPC}Messages,{$ENDIF}
|
||||
LCLProc, LCLType, LCLIntf, LResources, LMessages, InterfaceBase, {$IFDEF MSWINDOWS}Win32Extra,{$ENDIF}
|
||||
{$IFDEF LINUXFPC}Messages,{$ENDIF}
|
||||
{$IFDEF LCLGTK2}glib2, gdk2, gtk2,{$ENDIF}
|
||||
{$IFDEF LCLGTK3}LazGdk3, LazGtk3, LazGObject2, LazGLib2, gtk3procs, gtk3objects, gtk3widgets,{$ENDIF}
|
||||
{$ELSE}
|
||||
Messages,
|
||||
Messages,
|
||||
{$ENDIF}
|
||||
ExtCtrls, SyncObjs, SysUtils,
|
||||
{$ENDIF}
|
||||
@@ -31,6 +33,9 @@ type
|
||||
TOnIMEPreEditChangedEvent = procedure(Sender: TObject; aFlag: cardinal; const aPreEditText: ustring) of object;
|
||||
TOnIMECommitEvent = procedure(Sender: TObject; const aCommitText: ustring) of object;
|
||||
{$ENDIF}
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
TOnGdkKeyEvent = procedure(Sender: TObject; aEvent: PGdkEventKey; var aHandled: boolean) of object;
|
||||
{$ENDIF}
|
||||
{$IFDEF MSWINDOWS}
|
||||
TOnHandledMessageEvent = procedure(Sender: TObject; var aMessage: TMessage; var aHandled : boolean) of object;
|
||||
{$ENDIF}
|
||||
@@ -72,6 +77,10 @@ type
|
||||
FOnIMEPreEditChanged : TOnIMEPreEditChangedEvent;
|
||||
FOnIMECommit : TOnIMECommitEvent;
|
||||
{$ENDIF}
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
FOnGdkKeyPress : TOnGdkKeyEvent;
|
||||
FOnGdkKeyRelease : TOnGdkKeyEvent;
|
||||
{$ENDIF}
|
||||
|
||||
procedure CreateSyncObj;
|
||||
|
||||
@@ -118,7 +127,11 @@ type
|
||||
procedure DoOnIMESetComposition(const aText : ustring; const underlines : TCefCompositionUnderlineDynArray; const replacement_range, selection_range : TCefRange); virtual;
|
||||
{$ENDIF}
|
||||
{$IFDEF LINUXFPC}
|
||||
procedure WMIMEComposition(var aMessage: TMessage); message LM_IM_COMPOSITION;
|
||||
procedure WMIMEComposition(var aMessage : TMessage); message LM_IM_COMPOSITION;
|
||||
{$ENDIF}
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
function DoOnGdkKeyPress(aEvent : PGdkEventKey) : boolean; virtual;
|
||||
function DoOnGdkKeyRelease(aEvent : PGdkEventKey) : boolean; virtual;
|
||||
{$ENDIF}
|
||||
|
||||
public
|
||||
@@ -187,6 +200,14 @@ type
|
||||
/// Copy the contents from the original popup buffer copy to the main buffer copy.
|
||||
/// </summary>
|
||||
procedure DrawOrigPopupBuffer(const aSrcRect, aDstRect : TRect);
|
||||
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
/// <summary>
|
||||
/// Connects the GTK signals used to receive key press events.
|
||||
/// </summary>
|
||||
function ConnectSignals: boolean;
|
||||
{$ENDIF}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the scanline size.
|
||||
/// </summary>
|
||||
@@ -379,6 +400,24 @@ type
|
||||
/// </remarks>
|
||||
property OnIMECommit : TOnIMECommitEvent read FOnIMECommit write FOnIMECommit;
|
||||
{$ENDIF}
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
/// <summary>
|
||||
/// Event triggered when the key-press-event signal is received.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para><see href="https://docs.gtk.org/gtk3/signal.Widget.key-press-event.html">See the key-press-event article.</see></para>
|
||||
/// <para>This event only works in GTK2 and GTK3 projects.</para>
|
||||
/// </remarks>
|
||||
property OnGdkKeyPress : TOnGdkKeyEvent read FOnGdkKeyPress write FOnGdkKeyPress;
|
||||
/// <summary>
|
||||
/// Event triggered when the key-release-event signal is received.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para><see href="https://docs.gtk.org/gtk3/signal.Widget.key-release-event.html">See the key-release-event article.</see></para>
|
||||
/// <para>This event only works in GTK2 and GTK3 projects.</para>
|
||||
/// </remarks>
|
||||
property OnGdkKeyRelease : TOnGdkKeyEvent read FOnGdkKeyRelease write FOnGdkKeyRelease;
|
||||
{$ENDIF}
|
||||
/// <summary>
|
||||
/// Event triggered before the AlphaBlend call that transfer the web contents from the
|
||||
/// bitmap buffer to the panel when the Transparent property is True.
|
||||
@@ -552,6 +591,11 @@ begin
|
||||
FOnIMEPreEditChanged := nil;
|
||||
FOnIMECommit := nil;
|
||||
{$ENDIF}
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
FOnGdkKeyPress := nil;
|
||||
FOnGdkKeyRelease := nil;
|
||||
ControlStyle := ControlStyle - [csNoFocus];
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
destructor TBufferPanel.Destroy;
|
||||
@@ -566,6 +610,24 @@ begin
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
function GdkKeyPressCallback(Widget: PGtkWidget; Event: PGdkEventKey; Data: gPointer) : GBoolean; cdecl;
|
||||
begin
|
||||
if assigned(Data) then
|
||||
Result := TBufferPanel(Data).DoOnGdkKeyPress(Event)
|
||||
else
|
||||
Result := False;
|
||||
end;
|
||||
|
||||
function GdkKeyReleaseCallback(Widget: PGtkWidget; Event: PGdkEventKey; Data: gPointer) : GBoolean; cdecl;
|
||||
begin
|
||||
if assigned(Data) then
|
||||
Result := TBufferPanel(Data).DoOnGdkKeyRelease(Event)
|
||||
else
|
||||
Result := False;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
procedure TBufferPanel.AfterConstruction;
|
||||
begin
|
||||
inherited AfterConstruction;
|
||||
@@ -581,6 +643,38 @@ begin
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
function TBufferPanel.ConnectSignals: boolean;
|
||||
var
|
||||
TempHandlerID1, TempHandlerID2 : gulong;
|
||||
begin
|
||||
TempHandlerID1 := 0;
|
||||
TempHandlerID2 := 0;
|
||||
try
|
||||
try
|
||||
if assigned(Parent) then
|
||||
begin
|
||||
{$IFDEF LCLGTK2}
|
||||
TempHandlerID1 := g_signal_connect(PGtkWidget(Handle), 'key-press-event', G_CALLBACK(@GdkKeyPressCallback), gpointer(self));
|
||||
TempHandlerID2 := g_signal_connect(PGtkWidget(Handle), 'key-release-event', G_CALLBACK(@GdkKeyReleaseCallback), gpointer(self));
|
||||
{$ENDIF}
|
||||
{$IFDEF LCLGTK3}
|
||||
gtk_widget_set_can_focus(TGtk3Widget(Handle).Widget, True);
|
||||
gtk_widget_add_events(TGtk3Widget(Handle).Widget, gint(GDK_KEY_PRESS_MASK));
|
||||
TempHandlerID1 := g_signal_connect_data(TGtk3Widget(Handle).Widget, 'key-press-event', TGCallback(@GdkKeyPressCallback), gpointer(self), nil, G_CONNECT_DEFAULT);
|
||||
TempHandlerID2 := g_signal_connect_data(TGtk3Widget(Handle).Widget, 'key-release-event', TGCallback(@GdkKeyReleaseCallback), gpointer(self), nil, G_CONNECT_DEFAULT);
|
||||
{$ENDIF}
|
||||
end;
|
||||
except
|
||||
on e : exception do
|
||||
if CustomExceptionHandler('TBufferPanel.ConnectSignals', e) then raise;
|
||||
end;
|
||||
finally
|
||||
Result := (TempHandlerID1 > 0) and (TempHandlerID2 > 0);
|
||||
end;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
procedure TBufferPanel.CreateIMEHandler;
|
||||
begin
|
||||
{$IFDEF MSWINDOWS}
|
||||
@@ -1064,7 +1158,7 @@ end;
|
||||
{$IFDEF LINUXFPC}
|
||||
// The LM_IM_COMPOSITION message is only used by Lazarus in GTK2 when WITH_GTK2_IM is defined.
|
||||
// You need to open IDE dialog "Tools / Configure 'Build Lazarus'", and there enable the define: WITH_GTK2_IM; then recompile the IDE.
|
||||
procedure TBufferPanel.WMIMEComposition(var aMessage: TMessage);
|
||||
procedure TBufferPanel.WMIMEComposition(var aMessage : TMessage);
|
||||
var
|
||||
TempText : ustring;
|
||||
TempCommit : string;
|
||||
@@ -1095,6 +1189,21 @@ begin
|
||||
end;
|
||||
end;
|
||||
{$ENDIF}
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
function TBufferPanel.DoOnGdkKeyPress(aEvent : PGdkEventKey) : boolean;
|
||||
begin
|
||||
Result := True;
|
||||
if assigned(FOnGdkKeyPress) then
|
||||
FOnGdkKeyPress(self, aEvent, Result);
|
||||
end;
|
||||
|
||||
function TBufferPanel.DoOnGdkKeyRelease(aEvent : PGdkEventKey) : boolean;
|
||||
begin
|
||||
Result := True;
|
||||
if assigned(FOnGdkKeyRelease) then
|
||||
FOnGdkKeyRelease(self, aEvent, Result);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
function TBufferPanel.GetBufferBits : pointer;
|
||||
begin
|
||||
|
269
source/uceflinuxosrimehandler.pas
Normal file
269
source/uceflinuxosrimehandler.pas
Normal file
@@ -0,0 +1,269 @@
|
||||
unit uCEFLinuxOSRIMEHandler;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
{$IFDEF LCLGTK2}gtk2, glib2, gdk2,{$ENDIF}
|
||||
{$IFDEF LCLGTK3}LazGdk3, LazGtk3, LazGObject2, LazGLib2, gtk3procs, gtk3widgets,{$ENDIF}
|
||||
Classes, ExtCtrls, Forms;
|
||||
|
||||
type
|
||||
TCEFLinuxOSRIMEHandler = class
|
||||
protected
|
||||
FPanel : TCustomPanel;
|
||||
FForm : TCustomForm;
|
||||
FHasFocus : boolean;
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
FIMContext : PGtkIMContext;
|
||||
{$IFEND}
|
||||
|
||||
function GetInitialized : boolean;
|
||||
procedure SetPanel(aValue : TCustomPanel);
|
||||
|
||||
public
|
||||
constructor Create(aPanel : TCustomPanel);
|
||||
destructor Destroy; override;
|
||||
procedure CreateContext;
|
||||
procedure DestroyContext;
|
||||
procedure SetClientWindow;
|
||||
procedure ResetClientWindow;
|
||||
procedure ConnectSignals;
|
||||
procedure Focus;
|
||||
procedure Blur;
|
||||
procedure Reset;
|
||||
procedure SetCursorLocation(X, Y: integer);
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
function FilterKeyPress(aEvent : PGdkEventKey) : boolean;
|
||||
{$ENDIF}
|
||||
|
||||
property Initialized : boolean read GetInitialized;
|
||||
property HasFocus : boolean read FHasFocus;
|
||||
property Panel : TCustomPanel read FPanel write SetPanel;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
// https://chromium.googlesource.com/chromium/src/+/4079d37114e1dd416e99d5edc535f4214b787fc7/chrome/browser/ui/gtk/input_method_context_impl_gtk.cc
|
||||
// https://chromium.googlesource.com/chromium/src/+/refs/heads/main/ui/gtk/input_method_context_impl_gtk.cc
|
||||
|
||||
uses
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}pango,{$ENDIF}
|
||||
{$IFDEF FPC}LCLType, LCLIntf, LMessages,{$ENDIF}
|
||||
SysUtils;
|
||||
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
procedure gtk_commit_cb({%H-}context: PGtkIMContext; const Str: Pgchar; {%H-}Data: Pointer); cdecl;
|
||||
begin
|
||||
SendMessage(HWND(Data), LM_IM_COMPOSITION, GTK_IM_FLAG_COMMIT, LPARAM(Str));
|
||||
end;
|
||||
|
||||
procedure gtk_preedit_start_cb({%H-}context: PGtkIMContext; {%H-}Data: Pointer); cdecl;
|
||||
begin
|
||||
SendMessage(HWND(Data), LM_IM_COMPOSITION, GTK_IM_FLAG_START, LPARAM(context));
|
||||
end;
|
||||
|
||||
procedure gtk_preedit_end_cb({%H-}context: PGtkIMContext; {%H-}Data: Pointer); cdecl;
|
||||
begin
|
||||
SendMessage(HWND(Data), LM_IM_COMPOSITION, GTK_IM_FLAG_END, LPARAM(context));
|
||||
end;
|
||||
|
||||
procedure gtk_preedit_changed_cb({%H-}context:PGtkIMContext; {%H-}Data:Pointer); cdecl;
|
||||
var
|
||||
TempStr : Pgchar;
|
||||
TempPangoAttr : PPangoAttrList;
|
||||
TempCurpos : gint;
|
||||
begin
|
||||
gtk_im_context_get_preedit_string(context, @TempStr, {$IFDEF LCLGTK3}@{$ENDIF}TempPangoAttr, @TempCurpos);
|
||||
SendMessage(HWND(Data), LM_IM_COMPOSITION, GTK_IM_FLAG_PREEDIT, LPARAM(pchar(TempStr)));
|
||||
g_free(TempStr);
|
||||
pango_attr_list_unref(TempPangoAttr);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
constructor TCEFLinuxOSRIMEHandler.Create(aPanel : TCustomPanel);
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
FPanel := aPanel;
|
||||
FHasFocus := False;
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
FIMContext := nil;
|
||||
{$ENDIF}
|
||||
|
||||
if assigned(FPanel) then
|
||||
FForm := GetParentForm(FPanel)
|
||||
else
|
||||
FForm := nil;
|
||||
end;
|
||||
|
||||
destructor TCEFLinuxOSRIMEHandler.Destroy;
|
||||
begin
|
||||
ResetClientWindow;
|
||||
DestroyContext;
|
||||
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
function TCEFLinuxOSRIMEHandler.GetInitialized : boolean;
|
||||
begin
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
Result := assigned(FPanel) and assigned(FIMContext);
|
||||
{$ELSE}
|
||||
Result := False;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
procedure TCEFLinuxOSRIMEHandler.SetPanel(aValue : TCustomPanel);
|
||||
|
||||
begin
|
||||
FPanel := aValue;
|
||||
|
||||
if assigned(FPanel) then
|
||||
FForm := GetParentForm(FPanel)
|
||||
else
|
||||
FForm := nil;
|
||||
end;
|
||||
|
||||
procedure TCEFLinuxOSRIMEHandler.CreateContext;
|
||||
begin
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
if not(assigned(FIMContext)) then
|
||||
begin
|
||||
FIMContext := gtk_im_multicontext_new();
|
||||
SetClientWindow;
|
||||
ConnectSignals;
|
||||
end;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
procedure TCEFLinuxOSRIMEHandler.DestroyContext;
|
||||
begin
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
if assigned(FIMContext) then
|
||||
begin
|
||||
g_object_unref(FIMContext);
|
||||
FIMContext := nil;
|
||||
end;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
procedure TCEFLinuxOSRIMEHandler.SetClientWindow;
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
var
|
||||
TempWidget : PGtkWidget;
|
||||
{$ENDIF}
|
||||
begin
|
||||
if Initialized then
|
||||
begin
|
||||
{$IFDEF LCLGTK2}
|
||||
TempWidget := PGtkWidget(FForm.Handle);
|
||||
gtk_im_context_set_client_window(FIMContext, TempWidget^.window);
|
||||
{$ENDIF}
|
||||
{$IFDEF LCLGTK3}
|
||||
TempWidget := TGtk3Widget(FForm.Handle).Widget;
|
||||
gtk_im_context_set_client_window(FIMContext, TempWidget^.window);
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCEFLinuxOSRIMEHandler.ResetClientWindow;
|
||||
begin
|
||||
if Initialized then
|
||||
begin
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
gtk_im_context_reset(FIMContext);
|
||||
gtk_im_context_set_client_window(FIMContext, nil);
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCEFLinuxOSRIMEHandler.ConnectSignals;
|
||||
begin
|
||||
if Initialized then
|
||||
begin
|
||||
{$IFDEF LCLGTK3}
|
||||
g_signal_connect_data(PGObject(@FIMContext), 'commit', TGCallback(@gtk_commit_cb), GPointer(FPanel.Handle), nil, G_CONNECT_DEFAULT);
|
||||
g_signal_connect_data(PGObject(@FIMContext), 'preedit-start', TGCallback(@gtk_preedit_start_cb), GPointer(FPanel.Handle), nil, G_CONNECT_DEFAULT);
|
||||
g_signal_connect_data(PGObject(@FIMContext), 'preedit-end', TGCallback(@gtk_preedit_end_cb), GPointer(FPanel.Handle), nil, G_CONNECT_DEFAULT);
|
||||
g_signal_connect_data(PGObject(@FIMContext), 'preedit-changed', TGCallback(@gtk_preedit_changed_cb), GPointer(FPanel.Handle), nil, G_CONNECT_DEFAULT);
|
||||
{$ENDIF}
|
||||
{$IFDEF LCLGTK2}
|
||||
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));
|
||||
g_signal_connect(G_OBJECT(FIMContext), 'preedit-end', G_CALLBACK(@gtk_preedit_end_cb), GPointer(FPanel.Handle));
|
||||
g_signal_connect(G_OBJECT(FIMContext), 'preedit-changed', G_CALLBACK(@gtk_preedit_changed_cb), GPointer(FPanel.Handle));
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCEFLinuxOSRIMEHandler.Focus;
|
||||
begin
|
||||
if Initialized then
|
||||
begin
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
gtk_im_context_focus_in(FIMContext);
|
||||
{$ENDIF}
|
||||
FHasFocus := True;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCEFLinuxOSRIMEHandler.Blur;
|
||||
begin
|
||||
if Initialized then
|
||||
begin
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
gtk_im_context_focus_out(FIMContext);
|
||||
{$ENDIF}
|
||||
FHasFocus := False;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCEFLinuxOSRIMEHandler.Reset;
|
||||
begin
|
||||
if Initialized then
|
||||
begin
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
gtk_im_context_reset(FIMContext);
|
||||
|
||||
// Some input methods may not honour the reset call.
|
||||
// Focusing out/in the to make sure it gets reset correctly.
|
||||
if FHasFocus then
|
||||
begin
|
||||
gtk_im_context_focus_out(FIMContext);
|
||||
gtk_im_context_focus_in(FIMContext);
|
||||
end;
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCEFLinuxOSRIMEHandler.SetCursorLocation(X, Y: integer);
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
var
|
||||
TempCurPos: TGdkRectangle;
|
||||
{$ENDIF}
|
||||
begin
|
||||
if Initialized then
|
||||
begin
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
TempCurPos.x := x;
|
||||
TempCurPos.y := y;
|
||||
TempCurPos.width := 0;
|
||||
TempCurPos.height := 0;
|
||||
|
||||
gtk_im_context_set_cursor_location(FIMContext, @TempCurPos);
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
|
||||
{$IF DEFINED(LCLGTK2) or DEFINED(LCLGTK3)}
|
||||
function TCEFLinuxOSRIMEHandler.FilterKeyPress(aEvent : PGdkEventKey) : boolean;
|
||||
begin
|
||||
if Initialized then
|
||||
Result := gtk_im_context_filter_keypress(FIMContext, aEvent);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
end.
|
||||
|
@@ -2,7 +2,7 @@
|
||||
"UpdateLazPackages" : [
|
||||
{
|
||||
"ForceNotify" : true,
|
||||
"InternalVersion" : 769,
|
||||
"InternalVersion" : 770,
|
||||
"Name" : "cef4delphi_lazarus.lpk",
|
||||
"Version" : "139.0.28"
|
||||
}
|
||||
|
Reference in New Issue
Block a user