From bef1626f317429b08ef66998cb0c0e90f46b26b5 Mon Sep 17 00:00:00 2001 From: Salvador Diaz Fau Date: Mon, 4 Jan 2021 18:39:15 +0100 Subject: [PATCH] Added the PopupBrowser2 demo for Linux Set the CEFLinkedWindowParent1.TabStop to true to fix a focus issue Moved TCEFLinkedWindowParent.UpdateSize to the public section --- .../Lazarus_Linux/PopupBrowser2/00-Delete.bat | 2 + .../PopupBrowser2/PopupBrowser2.lpi | 105 ++++ .../PopupBrowser2/PopupBrowser2.lpr | 73 +++ .../PopupBrowser2/PopupBrowser2.lps | 300 ++++++++++++ demos/Lazarus_Linux/PopupBrowser2/cef.inc | 456 ++++++++++++++++++ .../PopupBrowser2/interfaces.pas | 30 ++ .../PopupBrowser2/uChildForm.dfm | 41 ++ .../PopupBrowser2/uChildForm.pas | 282 +++++++++++ .../Lazarus_Linux/PopupBrowser2/uMainForm.lfm | 71 +++ .../Lazarus_Linux/PopupBrowser2/uMainForm.pas | 443 +++++++++++++++++ .../SimpleOSRBrowser/SimpleOSRBrowser.lps | 214 +++----- .../TabbedBrowser2/TabbedBrowser2.lps | 112 ++--- .../TabbedBrowser2/uBrowserFrame.lfm | 1 + .../TabbedBrowser2/uBrowserFrame.pas | 28 +- source/uCEFLinkedWindowParent.pas | 4 +- update_CEF4Delphi.json | 2 +- 16 files changed, 1952 insertions(+), 212 deletions(-) create mode 100644 demos/Lazarus_Linux/PopupBrowser2/00-Delete.bat create mode 100644 demos/Lazarus_Linux/PopupBrowser2/PopupBrowser2.lpi create mode 100644 demos/Lazarus_Linux/PopupBrowser2/PopupBrowser2.lpr create mode 100644 demos/Lazarus_Linux/PopupBrowser2/PopupBrowser2.lps create mode 100644 demos/Lazarus_Linux/PopupBrowser2/cef.inc create mode 100644 demos/Lazarus_Linux/PopupBrowser2/interfaces.pas create mode 100644 demos/Lazarus_Linux/PopupBrowser2/uChildForm.dfm create mode 100644 demos/Lazarus_Linux/PopupBrowser2/uChildForm.pas create mode 100644 demos/Lazarus_Linux/PopupBrowser2/uMainForm.lfm create mode 100644 demos/Lazarus_Linux/PopupBrowser2/uMainForm.pas diff --git a/demos/Lazarus_Linux/PopupBrowser2/00-Delete.bat b/demos/Lazarus_Linux/PopupBrowser2/00-Delete.bat new file mode 100644 index 00000000..0b5ba5c8 --- /dev/null +++ b/demos/Lazarus_Linux/PopupBrowser2/00-Delete.bat @@ -0,0 +1,2 @@ +rmdir /S /Q lib +rmdir /S /Q backup diff --git a/demos/Lazarus_Linux/PopupBrowser2/PopupBrowser2.lpi b/demos/Lazarus_Linux/PopupBrowser2/PopupBrowser2.lpi new file mode 100644 index 00000000..afee6fe1 --- /dev/null +++ b/demos/Lazarus_Linux/PopupBrowser2/PopupBrowser2.lpi @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + <UseAppBundle Value="False"/> + <ResourceType Value="res"/> + </General> + <BuildModes Count="1"> + <Item1 Name="Default" Default="True"/> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <UseFileFilters Value="True"/> + </PublishOptions> + <RunParams> + <FormatVersion Value="2"/> + <Modes Count="0"/> + </RunParams> + <RequiredPackages Count="2"> + <Item1> + <PackageName Value="CEF4Delphi_Lazarus"/> + </Item1> + <Item2> + <PackageName Value="LCL"/> + </Item2> + </RequiredPackages> + <Units Count="4"> + <Unit0> + <Filename Value="PopupBrowser2.lpr"/> + <IsPartOfProject Value="True"/> + </Unit0> + <Unit1> + <Filename Value="uMainForm.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="MainForm"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + </Unit1> + <Unit2> + <Filename Value="uChildForm.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="ChildForm"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + </Unit2> + <Unit3> + <Filename Value="interfaces.pas"/> + <IsPartOfProject Value="True"/> + </Unit3> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="..\..\..\bin\PopupBrowser2"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <SyntaxMode Value="Delphi"/> + </SyntaxOptions> + </Parsing> + <Linking> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + <Other> + <CustomOptions Value="-dUseCThreads"/> + <OtherDefines Count="1"> + <Define0 Value="UseCThreads"/> + </OtherDefines> + </Other> + </CompilerOptions> + <Debugging> + <Exceptions Count="3"> + <Item1> + <Name Value="EAbort"/> + </Item1> + <Item2> + <Name Value="ECodetoolError"/> + </Item2> + <Item3> + <Name Value="EFOpenError"/> + </Item3> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/demos/Lazarus_Linux/PopupBrowser2/PopupBrowser2.lpr b/demos/Lazarus_Linux/PopupBrowser2/PopupBrowser2.lpr new file mode 100644 index 00000000..7ef05c2b --- /dev/null +++ b/demos/Lazarus_Linux/PopupBrowser2/PopupBrowser2.lpr @@ -0,0 +1,73 @@ +// ************************************************************************ +// ***************************** CEF4Delphi ******************************* +// ************************************************************************ +// +// CEF4Delphi is based on DCEF3 which uses CEF3 to embed a chromium-based +// browser in Delphi applications. +// +// The original license of DCEF3 still applies to CEF4Delphi. +// +// For more information about CEF4Delphi visit : +// https://www.briskbard.com/index.php?lang=en&pageid=cef +// +// Copyright © 2018 Salvador Díaz Fau. All rights reserved. +// +// ************************************************************************ +// ************ vvvv Original license and comments below vvvv ************* +// ************************************************************************ +(* + * Delphi Chromium Embedded 3 + * + * Usage allowed under the restrictions of the Lesser GNU General Public License + * or alternatively the restrictions of the Mozilla Public License 1.1 + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for + * the specific language governing rights and limitations under the License. + * + * Unit owner : Henri Gourvest <hgourvest@gmail.com> + * Web site : http://www.progdigy.com + * Repository : http://code.google.com/p/delphichromiumembedded/ + * Group : http://groups.google.com/group/delphichromiumembedded + * + * Embarcadero Technologies, Inc is not permitted to use or redistribute + * this source code without explicit permission. + * + *) + +program PopupBrowser2; + +{$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, + uCEFApplication, + uMainForm in 'uMainForm.pas' {MainForm}, + uChildForm in 'uChildForm.pas' {ChildForm}; + +//{$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. diff --git a/demos/Lazarus_Linux/PopupBrowser2/PopupBrowser2.lps b/demos/Lazarus_Linux/PopupBrowser2/PopupBrowser2.lps new file mode 100644 index 00000000..e15d2cfe --- /dev/null +++ b/demos/Lazarus_Linux/PopupBrowser2/PopupBrowser2.lps @@ -0,0 +1,300 @@ +<?xml version="1.0" encoding="UTF-8"?> +<CONFIG> + <ProjectSession> + <PathDelim Value="\"/> + <Version Value="11"/> + <BuildModes Active="Default"/> + <Units Count="32"> + <Unit0> + <Filename Value="PopupBrowser2.lpr"/> + <IsPartOfProject Value="True"/> + <IsVisibleTab Value="True"/> + <TopLine Value="28"/> + <CursorPos X="64" Y="53"/> + <UsageCount Value="35"/> + <Loaded Value="True"/> + <DefaultSyntaxHighlighter Value="Delphi"/> + </Unit0> + <Unit1> + <Filename Value="uMainForm.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="MainForm"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <EditorIndex Value="1"/> + <TopLine Value="398"/> + <CursorPos X="71" Y="417"/> + <UsageCount Value="35"/> + <Bookmarks Count="1"> + <Item0 X="50" Y="148" ID="1"/> + </Bookmarks> + <Loaded Value="True"/> + <LoadedDesigner Value="True"/> + <DefaultSyntaxHighlighter Value="Delphi"/> + </Unit1> + <Unit2> + <Filename Value="uChildForm.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="ChildForm"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <EditorIndex Value="2"/> + <TopLine Value="105"/> + <CursorPos X="34" Y="159"/> + <UsageCount Value="35"/> + <Loaded Value="True"/> + <DefaultSyntaxHighlighter Value="Delphi"/> + </Unit2> + <Unit3> + <Filename Value="interfaces.pas"/> + <IsPartOfProject Value="True"/> + <EditorIndex Value="-1"/> + <WindowIndex Value="-1"/> + <TopLine Value="-1"/> + <CursorPos X="-1" Y="-1"/> + <UsageCount Value="32"/> + <DefaultSyntaxHighlighter Value="Delphi"/> + </Unit3> + <Unit4> + <Filename Value="C:\lazarus\lcl\include\wincontrol.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="7431"/> + <CursorPos Y="7444"/> + <UsageCount Value="9"/> + <DefaultSyntaxHighlighter Value="Delphi"/> + </Unit4> + <Unit5> + <Filename Value="..\..\..\source\uCEFChromium.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="40"/> + <CursorPos X="42" Y="193"/> + <UsageCount Value="11"/> + </Unit5> + <Unit6> + <Filename Value="..\..\..\source\uCEFMiscFunctions.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="1608"/> + <CursorPos X="13" Y="1637"/> + <UsageCount Value="10"/> + </Unit6> + <Unit7> + <Filename Value="C:\lazarus\lcl\include\customform.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="2319"/> + <CursorPos Y="2332"/> + <UsageCount Value="9"/> + <DefaultSyntaxHighlighter Value="Delphi"/> + </Unit7> + <Unit8> + <Filename Value="C:\lazarus\lcl\controls.pp"/> + <UnitName Value="Controls"/> + <EditorIndex Value="-1"/> + <TopLine Value="1623"/> + <CursorPos X="15" Y="1633"/> + <UsageCount Value="9"/> + <DefaultSyntaxHighlighter Value="Delphi"/> + </Unit8> + <Unit9> + <Filename Value="..\SimpleBrowser2\usimplebrowser2.pas"/> + <ComponentName Value="Form1"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="uSimpleBrowser2"/> + <EditorIndex Value="-1"/> + <TopLine Value="139"/> + <CursorPos X="35" Y="154"/> + <UsageCount Value="9"/> + <DefaultSyntaxHighlighter Value="Delphi"/> + </Unit9> + <Unit10> + <Filename Value="..\TabbedBrowser2\uMainForm.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="137"/> + <CursorPos X="68" Y="154"/> + <UsageCount Value="9"/> + <DefaultSyntaxHighlighter Value="Delphi"/> + </Unit10> + <Unit11> + <Filename Value="..\..\..\..\..\..\..\usr\share\fpcsrc\3.2.0\rtl\wince\windows.pp"/> + <EditorIndex Value="-1"/> + <TopLine Value="21"/> + <CursorPos X="5" Y="44"/> + <UsageCount Value="10"/> + </Unit11> + <Unit12> + <Filename Value="..\..\..\..\..\..\..\usr\share\lazarus\2.0.10\lcl\forms.pp"/> + <UnitName Value="Forms"/> + <EditorIndex Value="-1"/> + <TopLine Value="1616"/> + <CursorPos X="70" Y="1351"/> + <UsageCount Value="11"/> + </Unit12> + <Unit13> + <Filename Value="..\..\..\source\uCEFLinkedWindowParent.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="155"/> + <CursorPos X="69" Y="185"/> + <UsageCount Value="13"/> + </Unit13> + <Unit14> + <Filename Value="..\..\..\..\..\..\..\usr\share\lazarus\2.0.10\lcl\controls.pp"/> + <UnitName Value="Controls"/> + <EditorIndex Value="-1"/> + <TopLine Value="1445"/> + <CursorPos X="15" Y="1466"/> + <UsageCount Value="11"/> + </Unit14> + <Unit15> + <Filename Value="..\..\..\..\..\..\..\usr\share\lazarus\2.0.10\lcl\include\wincontrol.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="6485"/> + <CursorPos Y="6510"/> + <UsageCount Value="11"/> + </Unit15> + <Unit16> + <Filename Value="..\..\..\source\uCEFWindowParent.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="37"/> + <UsageCount Value="11"/> + </Unit16> + <Unit17> + <Filename Value="..\..\..\source\uCEFWinControl.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="40"/> + <CursorPos X="3" Y="63"/> + <UsageCount Value="11"/> + </Unit17> + <Unit18> + <Filename Value="..\..\..\source\uCEFChromiumCore.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="1930"/> + <CursorPos X="57" Y="1941"/> + <UsageCount Value="11"/> + </Unit18> + <Unit19> + <Filename Value="..\..\..\..\..\..\..\usr\share\lazarus\2.0.10\lcl\include\control.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="4569"/> + <CursorPos X="3" Y="4577"/> + <UsageCount Value="10"/> + </Unit19> + <Unit20> + <Filename Value="..\..\..\source\uCEFApplicationCore.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="971"/> + <CursorPos X="3" Y="975"/> + <UsageCount Value="10"/> + </Unit20> + <Unit21> + <Filename Value="..\ExternalPumpBrowser\uExternalPumpBrowser.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="150"/> + <CursorPos X="74" Y="175"/> + <UsageCount Value="11"/> + <DefaultSyntaxHighlighter Value="Delphi"/> + </Unit21> + <Unit22> + <Filename Value="..\..\..\..\..\..\..\usr\share\lazarus\2.0.10\ide\srcedithintfrm.pas"/> + <UnitName Value="SrcEditHintFrm"/> + <EditorIndex Value="-1"/> + <TopLine Value="108"/> + <CursorPos X="7" Y="131"/> + <UsageCount Value="10"/> + </Unit22> + <Unit23> + <Filename Value="..\..\..\..\..\..\..\usr\share\lazarus\2.0.10\lcl\include\customform.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="3033"/> + <CursorPos X="9" Y="3055"/> + <UsageCount Value="10"/> + </Unit23> + <Unit24> + <Filename Value="..\..\..\..\..\..\..\usr\share\lazarus\2.0.10\lcl\include\application.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="284"/> + <CursorPos X="26" Y="322"/> + <UsageCount Value="10"/> + </Unit24> + <Unit25> + <Filename Value="..\..\..\..\..\..\..\usr\share\lazarus\2.0.10\lcl\interfaces\gtk2\gtk2winapi.inc"/> + <EditorIndex Value="-1"/> + <CursorPos X="48" Y="14"/> + <UsageCount Value="10"/> + </Unit25> + <Unit26> + <Filename Value="..\..\..\..\..\..\..\usr\share\lazarus\2.0.10\lcl\interfaces\gtk2\gtk2winapih.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="171"/> + <CursorPos X="10" Y="200"/> + <UsageCount Value="10"/> + </Unit26> + <Unit27> + <Filename Value="..\..\..\..\..\..\..\usr\share\lazarus\2.0.10\lcl\interfaces\gtk2\gtk2int.pas"/> + <UnitName Value="Gtk2Int"/> + <EditorIndex Value="-1"/> + <CursorPos X="13" Y="17"/> + <UsageCount Value="10"/> + </Unit27> + <Unit28> + <Filename Value="..\..\..\..\..\..\..\usr\share\lazarus\2.0.10\lcl\interfaces\gtk\gtkwinapi.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="9790"/> + <CursorPos X="23" Y="9812"/> + <UsageCount Value="10"/> + </Unit28> + <Unit29> + <Filename Value="..\..\..\..\..\..\..\usr\share\lazarus\2.0.10\lcl\include\winapih.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="214"/> + <CursorPos X="10" Y="237"/> + <UsageCount Value="10"/> + </Unit29> + <Unit30> + <Filename Value="..\..\..\..\..\..\..\usr\share\lazarus\2.0.10\lcl\lclintf.pas"/> + <UnitName Value="LCLIntf"/> + <EditorIndex Value="-1"/> + <UsageCount Value="10"/> + </Unit30> + <Unit31> + <Filename Value="..\..\..\..\..\..\..\usr\share\lazarus\2.0.10\lcl\include\winapi.inc"/> + <EditorIndex Value="-1"/> + <TopLine Value="848"/> + <CursorPos X="3" Y="850"/> + <UsageCount Value="10"/> + </Unit31> + </Units> + <OtherDefines Count="1"> + <Define0 Value="UseCThreads"/> + </OtherDefines> + <JumpHistory Count="6" HistoryIndex="5"> + <Position1> + <Filename Value="uMainForm.pas"/> + <Caret Line="123" Column="20" TopLine="101"/> + </Position1> + <Position2> + <Filename Value="uMainForm.pas"/> + <Caret Line="405" Column="50" TopLine="382"/> + </Position2> + <Position3> + <Filename Value="uMainForm.pas"/> + <Caret Line="123" Column="3" TopLine="108"/> + </Position3> + <Position4> + <Filename Value="uMainForm.pas"/> + <Caret Line="405" Column="50" TopLine="382"/> + </Position4> + <Position5> + <Filename Value="uChildForm.pas"/> + <Caret Line="73" Column="26" TopLine="40"/> + </Position5> + <Position6> + <Filename Value="uMainForm.pas"/> + <Caret Line="209" Column="80" TopLine="179"/> + </Position6> + </JumpHistory> + <RunParams> + <FormatVersion Value="2"/> + <Modes Count="0" ActiveMode=""/> + </RunParams> + </ProjectSession> +</CONFIG> diff --git a/demos/Lazarus_Linux/PopupBrowser2/cef.inc b/demos/Lazarus_Linux/PopupBrowser2/cef.inc new file mode 100644 index 00000000..a4c8d038 --- /dev/null +++ b/demos/Lazarus_Linux/PopupBrowser2/cef.inc @@ -0,0 +1,456 @@ +// ************************************************************************ +// ***************************** CEF4Delphi ******************************* +// ************************************************************************ +// +// CEF4Delphi is based on DCEF3 which uses CEF3 to embed a chromium-based +// browser in Delphi applications. +// +// The original license of DCEF3 still applies to CEF4Delphi. +// +// For more information about CEF4Delphi visit : +// https://www.briskbard.com/index.php?lang=en&pageid=cef +// +// Copyright © 2017 Salvador Diaz Fau. All rights reserved. +// +// ************************************************************************ +// ************ vvvv Original license and comments below vvvv ************* +// ************************************************************************ +(* + * Delphi Chromium Embedded 3 + * + * Usage allowed under the restrictions of the Lesser GNU General Public License + * or alternatively the restrictions of the Mozilla Public License 1.1 + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for + * the specific language governing rights and limitations under the License. + * + * Unit owner : Henri Gourvest <hgourvest@gmail.com> + * Web site : http://www.progdigy.com + * Repository : http://code.google.com/p/delphichromiumembedded/ + * Group : http://groups.google.com/group/delphichromiumembedded + * + * Embarcadero Technologies, Inc is not permitted to use or redistribute + * this source code without explicit permission. + * + *) + + // The complete list of compiler versions is here : + // http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Compiler_Versions + +{$DEFINE DELPHI_VERSION_UNKNOW} + +// Delphi 5 +{$IFDEF VER130} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} +{$ENDIF} + +// Delphi 6 +{$IFDEF VER140} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} +{$ENDIF} + +// Delphi 7 +{$IFDEF VER150} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} +{$ENDIF} + +// Delphi 8 +{$IFDEF VER160} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} +{$ENDIF} + +// Delphi 2005 +{$IFDEF VER170} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} +{$ENDIF} + +{$IFDEF VER180} + {$UNDEF DELPHI_VERSION_UNKNOW} + // Delphi 2007 + {$IFDEF VER185} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + // Delphi 2006 + {$ELSE} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$ENDIF} +{$ENDIF} + +// Delphi 2009 +{$IFDEF VER200} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} +{$ENDIF} + +//Delphi 2010 +{$IFDEF VER210} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} +{$ENDIF} + +// Delphi XE +{$IFDEF VER220} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} +{$ENDIF} + +// Delphi XE2 (First FireMonkey and 64bit compiler) +{$IFDEF VER230} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} +{$ENDIF} + +// Delphi XE3 +{$IFDEF VER240} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} +{$ENDIF} + +// Delphi XE4 +{$IFDEF VER250} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} +{$ENDIF} + +// Delphi XE5 +{$IFDEF VER260} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} +{$ENDIF} + +// Delphi XE6 +{$IFDEF VER270} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} +{$ENDIF} + +// Delphi XE7 +{$IFDEF VER280} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI21_UP} +{$ENDIF} + +// Delphi XE8 +{$IFDEF VER290} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI22_UP} +{$ENDIF VER290} + +// Rad Studio 10 - Delphi Seattle +{$IFDEF VER300} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI23_UP} +{$ENDIF} + +// Rad Studio 10.1 - Delphi Berlin +{$IFDEF VER310} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI24_UP} +{$ENDIF} + +// Rad Studio 10.2 - Delphi Tokyo +{$IFDEF VER320} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI25_UP} +{$ENDIF} + +// Rad Studio 10.3 - Delphi Rio +{$IFDEF VER330} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI25_UP} + {$DEFINE DELPHI26_UP} +{$ENDIF} + +// Rad Studio 10.4 - Delphi Sydney +{$IFDEF VER340} + {$UNDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI25_UP} + {$DEFINE DELPHI26_UP} + {$DEFINE DELPHI27_UP} +{$ENDIF} + +{$IFDEF FPC} + {$DEFINE SUPPORTS_INLINE} + {$IF DEFINED(FPC_FULLVERSION) AND (FPC_FULLVERSION >= 30200)} + {$DEFINE FPC_VER_320} + {$IFEND} +{$ELSE} + {$IFDEF DELPHI_VERSION_UNKNOW} + {$DEFINE DELPHI5_UP} + {$DEFINE DELPHI6_UP} + {$DEFINE DELPHI7_UP} + {$DEFINE DELPHI8_UP} + {$DEFINE DELPHI9_UP} + {$DEFINE DELPHI10_UP} + {$DEFINE DELPHI11_UP} + {$DEFINE DELPHI12_UP} + {$DEFINE DELPHI14_UP} + {$DEFINE DELPHI15_UP} + {$DEFINE DELPHI16_UP} + {$DEFINE DELPHI17_UP} + {$DEFINE DELPHI18_UP} + {$DEFINE DELPHI19_UP} + {$DEFINE DELPHI20_UP} + {$DEFINE DELPHI21_UP} + {$DEFINE DELPHI22_UP} + {$DEFINE DELPHI23_UP} + {$DEFINE DELPHI24_UP} + {$DEFINE DELPHI25_UP} + {$DEFINE DELPHI26_UP} + {$DEFINE DELPHI27_UP} + {$ENDIF} +{$ENDIF} + +{$IFDEF DELPHI9_UP} + {$DEFINE SUPPORTS_INLINE} +{$ENDIF} + +{$IF DEFINED(CPUX32) OR + DEFINED(CPU386) OR + DEFINED(CPUi386) OR + DEFINED(CPUPOWERPC32) OR + DEFINED(CPUSPARC32) OR + DEFINED(CPU32BITS) OR + DEFINED(CPUARM32) OR + DEFINED(WIN32) OR + DEFINED(IOS32) OR + DEFINED(MACOS32) OR + DEFINED(LINUX32) OR + DEFINED(POSIX32) OR + DEFINED(ANDROID32)} + {$DEFINE TARGET_32BITS} +{$IFEND} + diff --git a/demos/Lazarus_Linux/PopupBrowser2/interfaces.pas b/demos/Lazarus_Linux/PopupBrowser2/interfaces.pas new file mode 100644 index 00000000..60c7250f --- /dev/null +++ b/demos/Lazarus_Linux/PopupBrowser2/interfaces.pas @@ -0,0 +1,30 @@ +unit Interfaces; + +{$mode objfpc}{$H+} + +interface + +{$IFDEF UNIX}{$IFNDEF DisableCWString}uses cwstring;{$ENDIF}{$ENDIF} + +procedure CustomWidgetSetInitialization; +procedure CustomWidgetSetFinalization; + +implementation + +uses + {$IFNDEF EnableLibOverlay} + gtk2DisableLibOverlay, + {$ENDIF} + Gtk2Int, Forms; + +procedure CustomWidgetSetInitialization; +begin + CreateWidgetset(TGtk2WidgetSet); +end; + +procedure CustomWidgetSetFinalization; +begin + FreeWidgetSet; +end; + +end. diff --git a/demos/Lazarus_Linux/PopupBrowser2/uChildForm.dfm b/demos/Lazarus_Linux/PopupBrowser2/uChildForm.dfm new file mode 100644 index 00000000..f3186455 --- /dev/null +++ b/demos/Lazarus_Linux/PopupBrowser2/uChildForm.dfm @@ -0,0 +1,41 @@ +object ChildForm: TChildForm + Left = 543 + Height = 256 + Top = 145 + Width = 352 + Caption = 'Popup' + ClientHeight = 256 + ClientWidth = 352 + Color = clBtnFace + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + OnClose = FormClose + OnCloseQuery = FormCloseQuery + OnCreate = FormCreate + OnDestroy = FormDestroy + OnShow = FormShow + Position = poDefault + LCLVersion = '2.0.10.0' + object CEFLinkedWindowParent1: TCEFLinkedWindowParent + Left = 0 + Height = 256 + Top = 0 + Width = 352 + Align = alClient + TabStop = True + TabOrder = 0 + OnEnter = CEFLinkedWindowParent1Enter + OnExit = CEFLinkedWindowParent1Exit + Chromium = Chromium1 + end + object Chromium1: TChromium + OnGotFocus = Chromium1GotFocus + OnTitleChange = Chromium1TitleChange + OnBeforePopup = Chromium1BeforePopup + OnBeforeClose = Chromium1BeforeClose + OnClose = Chromium1Close + Left = 24 + Top = 56 + end +end diff --git a/demos/Lazarus_Linux/PopupBrowser2/uChildForm.pas b/demos/Lazarus_Linux/PopupBrowser2/uChildForm.pas new file mode 100644 index 00000000..a180d0a4 --- /dev/null +++ b/demos/Lazarus_Linux/PopupBrowser2/uChildForm.pas @@ -0,0 +1,282 @@ +// ************************************************************************ +// ***************************** CEF4Delphi ******************************* +// ************************************************************************ +// +// CEF4Delphi is based on DCEF3 which uses CEF to embed a chromium-based +// browser in Delphi applications. +// +// The original license of DCEF3 still applies to CEF4Delphi. +// +// For more information about CEF4Delphi visit : +// https://www.briskbard.com/index.php?lang=en&pageid=cef +// +// Copyright © 2021 Salvador Diaz Fau. All rights reserved. +// +// ************************************************************************ +// ************ vvvv Original license and comments below vvvv ************* +// ************************************************************************ +(* + * Delphi Chromium Embedded 3 + * + * Usage allowed under the restrictions of the Lesser GNU General Public License + * or alternatively the restrictions of the Mozilla Public License 1.1 + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for + * the specific language governing rights and limitations under the License. + * + * Unit owner : Henri Gourvest <hgourvest@gmail.com> + * Web site : http://www.progdigy.com + * Repository : http://code.google.com/p/delphichromiumembedded/ + * Group : http://groups.google.com/group/delphichromiumembedded + * + * Embarcadero Technologies, Inc is not permitted to use or redistribute + * this source code without explicit permission. + * + *) + +unit uChildForm; + +{$mode objfpc}{$H+} + +{$I cef.inc} + +interface + +uses + Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, + LMessages, SyncObjs, + uCEFChromium, uCEFTypes, uCEFInterfaces, uCEFConstants, uCEFWindowParent, + uCEFWinControl, uCEFLinkedWindowParent, uCEFChromiumEvents; + +const + CEF_CLOSECHILD = $A52; + +type + + { TChildForm } + + TChildForm = class(TForm) + CEFLinkedWindowParent1: TCEFLinkedWindowParent; + Chromium1: TChromium; + + procedure CEFLinkedWindowParent1Enter(Sender: TObject); + procedure CEFLinkedWindowParent1Exit(Sender: TObject); + + procedure FormCreate(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); + procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); + + procedure Chromium1BeforePopup(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const targetUrl, targetFrameName: ustring; targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; const popupFeatures: TCefPopupFeatures; var windowInfo: TCefWindowInfo; var client: ICefClient; var settings: TCefBrowserSettings; var extra_info: ICefDictionaryValue; var noJavascriptAccess: Boolean; var Result: Boolean); + procedure Chromium1TitleChange(Sender: TObject; const browser: ICefBrowser; const title: ustring); + procedure Chromium1Close(Sender: TObject; const browser: ICefBrowser; var aAction : TCefCloseBrowserAction); + procedure Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser); + procedure Chromium1GotFocus(Sender: TObject; const browser: ICefBrowser); + procedure FormShow(Sender: TObject); + + protected + FCanClose : boolean; + FClosing : boolean; + FClientInitialized : boolean; + FPopupFeatures : TCefPopupFeatures; + + procedure WMMove(var aMessage: TLMMove); message LM_MOVE; + procedure WMSize(var aMessage: TLMSize); message LM_SIZE; + procedure WMWindowPosChanged(var aMessage: TLMWindowPosChanged); message LM_WINDOWPOSCHANGED; + + procedure BrowserCloseFormMsg(Data: PtrInt); + + public + procedure AfterConstruction; override; + function CreateClientHandler(var windowInfo : TCefWindowInfo; var client : ICefClient; const targetFrameName : string; const popupFeatures : TCefPopupFeatures) : boolean; + procedure ApplyPopupFeatures; + procedure SendCompMessage(aMsg : cardinal; aData : PtrInt = 0); + + property ClientInitialized : boolean read FClientInitialized; + property Closing : boolean read FClosing; + end; + +implementation + +{$R *.dfm} + +uses + Math, + uCEFMiscFunctions, uCEFApplication, uMainForm; + +// Destruction steps +// ================= +// 1. FormCloseQuery sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event. +// 2. TChromium.OnClose sends a CEFBROWSER_DESTROY message to destroy CEFWindowParent1 in the main thread, which triggers the TChromium.OnBeforeClose event. +// 3. TChromium.OnBeforeClose sets FCanClose := True and sends WM_CLOSE to the form. + +procedure TChildForm.AfterConstruction; +begin + inherited AfterConstruction; + + CreateHandle; + + CEFLinkedWindowParent1.CreateHandle; +end; + +function TChildForm.CreateClientHandler(var windowInfo : TCefWindowInfo; + var client : ICefClient; + const targetFrameName : string; + const popupFeatures : TCefPopupFeatures) : boolean; +var + TempRect : TRect; +begin + if Chromium1.CreateClientHandler(client, False) then + begin + Result := True; + FClientInitialized := True; + FPopupFeatures := popupFeatures; + TempRect := CEFLinkedWindowParent1.BoundsRect; + + if (FPopupFeatures.widthset <> 0) then TempRect.Right := max(FPopupFeatures.width, 100); + if (FPopupFeatures.heightset <> 0) then TempRect.Bottom := max(FPopupFeatures.height, 100); + + WindowInfoAsChild(windowInfo, CEFLinkedWindowParent1.Handle, TempRect, ''); + end + else + Result := False; +end; + +procedure TChildForm.ApplyPopupFeatures; +begin + if (FPopupFeatures.xset <> 0) then Chromium1.SetFormLeftTo(FPopupFeatures.x); + if (FPopupFeatures.yset <> 0) then Chromium1.SetFormTopTo(FPopupFeatures.y); + if (FPopupFeatures.widthset <> 0) then Chromium1.ResizeFormWidthTo(FPopupFeatures.width); + if (FPopupFeatures.heightset <> 0) then Chromium1.ResizeFormHeightTo(FPopupFeatures.height); +end; + +procedure TChildForm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser); +begin + // We must wait until all browsers trigger the TChromium.OnBeforeClose event + // in order to close the application safely or we will have shutdown issues. + FCanClose := True; + SendCompMessage(CEF_BEFORECLOSE); +end; + +procedure TChildForm.Chromium1Close(Sender: TObject; const browser: ICefBrowser; var aAction : TCefCloseBrowserAction); +begin + // continue closing the browser + aAction := cbaClose; +end; + +procedure TChildForm.Chromium1TitleChange(Sender: TObject; const browser: ICefBrowser; const title: ustring); +begin + Caption := title; +end; + +procedure TChildForm.WMMove(var aMessage : TLMMove); +begin + inherited; + Chromium1.NotifyMoveOrResizeStarted; +end; + +procedure TChildForm.WMSize(var aMessage: TLMSize); +begin + inherited; + Chromium1.NotifyMoveOrResizeStarted; +end; + +procedure TChildForm.WMWindowPosChanged(var aMessage: TLMWindowPosChanged); +begin + inherited; + Chromium1.NotifyMoveOrResizeStarted; +end; + +procedure TChildForm.FormClose(Sender: TObject; var CloseAction: TCloseAction); +begin + CloseAction := caFree; +end; + +procedure TChildForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean); +begin + CanClose := FCanClose; + + if not(FClosing) then + begin + FClosing := True; + Visible := False; + Chromium1.CloseBrowser(True); + end; +end; + +procedure TChildForm.Chromium1BeforePopup(Sender: TObject; + const browser: ICefBrowser; const frame: ICefFrame; const targetUrl, + targetFrameName: ustring; targetDisposition: TCefWindowOpenDisposition; + userGesture: Boolean; const popupFeatures: TCefPopupFeatures; + var windowInfo: TCefWindowInfo; var client: ICefClient; + var settings: TCefBrowserSettings; var extra_info: ICefDictionaryValue; + var noJavascriptAccess: Boolean; var Result: Boolean); +begin + case targetDisposition of + WOD_NEW_FOREGROUND_TAB, + WOD_NEW_BACKGROUND_TAB, + WOD_NEW_WINDOW : Result := True; // For simplicity, this demo blocks new tabs and new windows. + + WOD_NEW_POPUP : Result := not(TMainForm(Owner).CreateClientHandler(windowInfo, client, targetFrameName, popupFeatures)); + + else Result := False; + end; +end; + +procedure TChildForm.FormCreate(Sender: TObject); +begin + FCanClose := False; + FClosing := False; + FClientInitialized := False; +end; + +// This is a workaround for the CEF issue #2026 +// https://bitbucket.org/chromiumembedded/cef/issues/2026/multiple-major-keyboard-focus-issues-on +// We use CEFLinkedWindowParent1.OnEnter, CEFLinkedWindowParent1.OnExit and +// TChromium.OnGotFocus to avoid most of the focus issues. +// CEFLinkedWindowParent1.TabStop must be TRUE. +procedure TChildForm.CEFLinkedWindowParent1Enter(Sender: TObject); +begin + if not(csDesigning in ComponentState) and + Chromium1.Initialized and + not(Chromium1.FrameIsFocused) then + Chromium1.SendFocusEvent(True); +end; + +procedure TChildForm.CEFLinkedWindowParent1Exit(Sender: TObject); +begin + if not(csDesigning in ComponentState) then + Chromium1.SendCaptureLostEvent; +end; + +procedure TChildForm.Chromium1GotFocus(Sender: TObject; + const browser: ICefBrowser); +begin + CEFLinkedWindowParent1.SetFocus; +end; + +procedure TChildForm.FormShow(Sender: TObject); +begin + +end; + +procedure TChildForm.FormDestroy(Sender: TObject); +begin + if FClientInitialized then + TMainForm(Owner).SendCompMessage(CEF_CHILDDESTROYED); +end; + +procedure TChildForm.BrowserCloseFormMsg(Data: PtrInt); +begin + Close; +end; + +procedure TChildForm.SendCompMessage(aMsg : cardinal; aData : PtrInt); +begin + case aMsg of + CEF_BEFORECLOSE : Application.QueueAsyncCall(@BrowserCloseFormMsg, aData); + end; +end; + +end. diff --git a/demos/Lazarus_Linux/PopupBrowser2/uMainForm.lfm b/demos/Lazarus_Linux/PopupBrowser2/uMainForm.lfm new file mode 100644 index 00000000..262b59c5 --- /dev/null +++ b/demos/Lazarus_Linux/PopupBrowser2/uMainForm.lfm @@ -0,0 +1,71 @@ +object MainForm: TMainForm + Left = 364 + Height = 624 + Top = 213 + Width = 1038 + Caption = 'Initializing browser. Please wait...' + ClientHeight = 624 + ClientWidth = 1038 + Color = clBtnFace + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + OnActivate = FormActivate + OnCloseQuery = FormCloseQuery + OnCreate = FormCreate + OnDestroy = FormDestroy + Position = poScreenCenter + LCLVersion = '2.0.10.0' + object AddressPnl: TPanel + Left = 0 + Height = 21 + Top = 0 + Width = 1038 + Align = alTop + BevelOuter = bvNone + ClientHeight = 21 + ClientWidth = 1038 + Enabled = False + TabOrder = 0 + object AddressEdt: TEdit + Left = 0 + Height = 21 + Top = 0 + Width = 1007 + Align = alClient + TabOrder = 0 + Text = 'file:///PopupBrowser.html' + end + object GoBtn: TButton + Left = 1007 + Height = 21 + Top = 0 + Width = 31 + Align = alRight + Caption = 'Go' + OnClick = GoBtnClick + TabOrder = 1 + end + end + object CEFLinkedWindowParent1: TCEFLinkedWindowParent + Left = 0 + Height = 603 + Top = 21 + Width = 1038 + Align = alClient + TabStop = True + TabOrder = 1 + OnEnter = CEFLinkedWindowParent1Enter + OnExit = CEFLinkedWindowParent1Exit + Chromium = Chromium1 + end + object Chromium1: TChromium + OnGotFocus = Chromium1GotFocus + OnBeforePopup = Chromium1BeforePopup + OnAfterCreated = Chromium1AfterCreated + OnBeforeClose = Chromium1BeforeClose + OnClose = Chromium1Close + Left = 56 + Top = 152 + end +end diff --git a/demos/Lazarus_Linux/PopupBrowser2/uMainForm.pas b/demos/Lazarus_Linux/PopupBrowser2/uMainForm.pas new file mode 100644 index 00000000..77b77117 --- /dev/null +++ b/demos/Lazarus_Linux/PopupBrowser2/uMainForm.pas @@ -0,0 +1,443 @@ +// ************************************************************************ +// ***************************** CEF4Delphi ******************************* +// ************************************************************************ +// +// CEF4Delphi is based on DCEF3 which uses CEF to embed a chromium-based +// browser in Delphi applications. +// +// The original license of DCEF3 still applies to CEF4Delphi. +// +// For more information about CEF4Delphi visit : +// https://www.briskbard.com/index.php?lang=en&pageid=cef +// +// Copyright © 2021 Salvador Diaz Fau. All rights reserved. +// +// ************************************************************************ +// ************ vvvv Original license and comments below vvvv ************* +// ************************************************************************ +(* + * Delphi Chromium Embedded 3 + * + * Usage allowed under the restrictions of the Lesser GNU General Public License + * or alternatively the restrictions of the Mozilla Public License 1.1 + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for + * the specific language governing rights and limitations under the License. + * + * Unit owner : Henri Gourvest <hgourvest@gmail.com> + * Web site : http://www.progdigy.com + * Repository : http://code.google.com/p/delphichromiumembedded/ + * Group : http://groups.google.com/group/delphichromiumembedded + * + * Embarcadero Technologies, Inc is not permitted to use or redistribute + * this source code without explicit permission. + * + *) + +unit uMainForm; + +{$mode objfpc}{$H+} + +{$I cef.inc} + +interface + +uses + Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, + LMessages, SyncObjs, + uCEFChromium, uCEFWindowParent, uCEFInterfaces, uCEFConstants, uCEFTypes, + uChildForm, uCEFWinControl, uCEFChromiumEvents, uCEFLinkedWindowParent; + +const + CEF_CREATENEXTCHILD = $A50; + CEF_CHILDDESTROYED = $A51; + CEF_INITIALIZED = $A52; + +type + + { TMainForm } + + TMainForm = class(TForm) + AddressPnl: TPanel; + AddressEdt: TEdit; + CEFLinkedWindowParent1: TCEFLinkedWindowParent; + GoBtn: TButton; + Chromium1: TChromium; + + procedure CEFLinkedWindowParent1Enter(Sender: TObject); + procedure CEFLinkedWindowParent1Exit(Sender: TObject); + + procedure GoBtnClick(Sender: TObject); + + procedure FormActivate(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure FormDestroy(Sender: TObject); + procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); + + procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); + procedure Chromium1BeforePopup(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const targetUrl, targetFrameName: ustring; targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; const popupFeatures: TCefPopupFeatures; var windowInfo: TCefWindowInfo; var client: ICefClient; var settings: TCefBrowserSettings; var extra_info: ICefDictionaryValue; var noJavascriptAccess: Boolean; var Result: Boolean); + procedure Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser); + procedure Chromium1Close(Sender: TObject; const browser: ICefBrowser; var aAction: TCefCloseBrowserAction); + procedure Chromium1GotFocus(Sender: TObject; const browser: ICefBrowser); + + protected + FChildForm : TChildForm; + FCriticalSection : TCriticalSection; + FCanClose : boolean; // Set to True in TChromium.OnBeforeClose + FClosingMainForm : boolean; // Set to True in the CloseQuery event. + FClosingChildren : boolean; // Set to True in the CloseQuery event. + + function GetPopupChildCount : integer; + + procedure ClosePopupChildren; + procedure CreateHiddenChildForm; + + procedure WMMove(var aMessage: TLMMove); message LM_MOVE; + procedure WMSize(var aMessage: TLMSize); message LM_SIZE; + procedure WMWindowPosChanged(var aMessage: TLMWindowPosChanged); message LM_WINDOWPOSCHANGED; + + procedure BrowserCreatedMsg(Data: PtrInt); + procedure BrowserInitializedMsg(Data: PtrInt); + procedure BrowserCreateNextChildMsg(Data: PtrInt); + procedure BrowserChildDestroyedMsg(Data: PtrInt); + procedure BrowserCloseFormMsg(Data: PtrInt); + + property PopupChildCount : integer read GetPopupChildCount; + + public + function CreateClientHandler(var windowInfo : TCefWindowInfo; var client : ICefClient; const targetFrameName : string; const popupFeatures : TCefPopupFeatures) : boolean; + procedure SendCompMessage(aMsg : cardinal; aData : PtrInt = 0); + end; + +var + MainForm: TMainForm; + +procedure CreateGlobalCEFApp; + +implementation + +{$R *.lfm} + +uses + LCLIntf, + uCEFApplication, uCEFMiscFunctions; + +// This is demo shows how to create popup windows in CEF. + +// You need to understand the SimpleBrowser2 demo completely before trying to understand this demo. + +// When TChromium needs to show a new popup window it executes TChromium.OnBeforePopup. + +// LCL components *MUST* be created and destroyed in the main thread but CEF executes the +// TChromium.OnBeforePopup in a different thread. + +// For this reason this demo creates a hidden popup form (TChildForm) in case CEF needs to show a popup window. +// TChromium.OnBeforePopup calls TChildForm.CreateClientHandler to initialize some parameters and create the new ICefClient. +// After that, it sends a CEF_CREATENEXTCHILD message to show the popup form and create a new one. + +// All the child forms must be correctly destroyed before closing the main form. Read the code comments in uChildForm.pas +// to know how the popup windows are destroyed. + +// The main form close all active popup forms and waits until all of them have sent a CEF_CHILDDESTROYED message. + +// Destruction steps +// ================= +// 1. FormCloseQuery sets CanClose to FALSE and it closes all child forms. +// 2. When all the child forms are closed then FormCloseQuery is triggered again, sets CanClose to FALSE calls TChromium.CloseBrowser which triggers the TChromium.OnClose event. +// 3. TChromium.OnClose sets aAction to cbaClose which triggers the TChromium.OnBeforeClose event. +// 4. TChromium.OnBeforeClose sets FCanClose := True and sends a CEF_BEFORECLOSE message to close the form in the main thread. + + +// Many other demos use a timer to create the browser but this demo sends a +// CEF_INITIALIZED message in the GlobalCEFApp.OnContextInitialized and +// TForm.OnActivate events +procedure GlobalCEFApp_OnContextInitialized; +begin + if (MainForm <> nil) and MainForm.Showing and MainForm.Focused then + MainForm.SendCompMessage(CEF_INITIALIZED); +end; + +procedure CreateGlobalCEFApp; +begin + GlobalCEFApp := TCefApplication.Create; + GlobalCEFApp.OnContextInitialized := @GlobalCEFApp_OnContextInitialized; +end; + +procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean); +begin + FClosingChildren := True; + Visible := False; + + if (PopupChildCount > 0) then + begin + ClosePopupChildren; + CanClose := False; + end + else + begin + CanClose := FCanClose; + + if not(FClosingMainForm) then + begin + FClosingMainForm := True; + Chromium1.CloseBrowser(True); + end; + end; +end; + +procedure TMainForm.FormCreate(Sender: TObject); +begin + FClosingChildren := False; + FClosingMainForm := False; + FCanClose := False; + FCriticalSection := TCriticalSection.Create; + + // CEF can't find the HTML if we load file:///filename.html in Linux so we + // add the full path manually. + // The "Click me to open a file" button in PopupBrowser.html will not work + // because of this limitation. + AddressEdt.Text := 'file://' + IncludeTrailingPathDelimiter(ExtractFileDir(ParamStr(0))) + 'PopupBrowser.html'; + + Chromium1.DefaultURL := UTF8Decode(AddressEdt.Text); + Chromium1.Options.BackgroundColor := CefColorSetARGB($FF, $FF, $FF, $FF); + + CreateHiddenChildForm; +end; + +procedure TMainForm.FormDestroy(Sender: TObject); +begin + FreeAndNil(FCriticalSection); +end; + +procedure TMainForm.Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); +begin + // Now the browser is fully initialized we can send a message to the main form + // to enable the user interface. + SendCompMessage(CEF_AFTERCREATED); +end; + +procedure TMainForm.Chromium1BeforePopup(Sender : TObject; + const browser: ICefBrowser; const frame: ICefFrame; const targetUrl, + targetFrameName: ustring; targetDisposition: TCefWindowOpenDisposition; + userGesture: Boolean; const popupFeatures: TCefPopupFeatures; + var windowInfo: TCefWindowInfo; var client: ICefClient; + var settings: TCefBrowserSettings; + var extra_info: ICefDictionaryValue; + var noJavascriptAccess: Boolean; + var Result: Boolean); +begin + case targetDisposition of + WOD_NEW_FOREGROUND_TAB, + WOD_NEW_BACKGROUND_TAB, + WOD_NEW_WINDOW : Result := True; // For simplicity, this demo blocks new tabs and new windows. + + WOD_NEW_POPUP : Result := not(CreateClientHandler(windowInfo, client, targetFrameName, popupFeatures)); + + else Result := False; + end; +end; + +function TMainForm.CreateClientHandler(var windowInfo : TCefWindowInfo; + var client : ICefClient; + const targetFrameName : string; + const popupFeatures : TCefPopupFeatures) : boolean; +begin + try + FCriticalSection.Acquire; + + if (FChildForm <> nil) and + FChildForm.CreateClientHandler(windowInfo, client, targetFrameName, popupFeatures) then + begin + SendCompMessage(CEF_CREATENEXTCHILD); + Result := True; + end; + finally + FCriticalSection.Release; + end; +end; + +function TMainForm.GetPopupChildCount : integer; +var + i : integer; + TempForm : TCustomForm; +begin + Result := 0; + i := pred(screen.CustomFormCount); + + while (i >= 0) do + begin + TempForm := screen.CustomForms[i]; + + // Only count the fully initialized child forms and not the one waiting to be used. + + if (TempForm is TChildForm) and + TChildForm(TempForm).ClientInitialized then + inc(Result); + + dec(i); + end; +end; + +procedure TMainForm.ClosePopupChildren; +var + i : integer; + TempForm : TCustomForm; +begin + i := pred(screen.CustomFormCount); + + while (i >= 0) do + begin + TempForm := screen.CustomForms[i]; + + // Only send WM_CLOSE to fully initialized child forms. + + if (TempForm is TChildForm) and + TChildForm(TempForm).ClientInitialized and + not(TChildForm(TempForm).Closing) then + TempForm.Close; + + dec(i); + end; +end; + +procedure TMainForm.GoBtnClick(Sender: TObject); +begin + // This will load the URL in the edit box + Chromium1.LoadURL(UTF8Decode(AddressEdt.Text)); +end; + +// This is a workaround for the CEF issue #2026 +// https://bitbucket.org/chromiumembedded/cef/issues/2026/multiple-major-keyboard-focus-issues-on +// We use CEFLinkedWindowParent1.OnEnter, CEFLinkedWindowParent1.OnExit and +// TChromium.OnGotFocus to avoid most of the focus issues. +// CEFLinkedWindowParent1.TabStop must be TRUE. +procedure TMainForm.CEFLinkedWindowParent1Enter(Sender: TObject); +begin + if not(csDesigning in ComponentState) and + Chromium1.Initialized and + not(Chromium1.FrameIsFocused) then + Chromium1.SendFocusEvent(True); +end; + +procedure TMainForm.CEFLinkedWindowParent1Exit(Sender: TObject); +begin + if not(csDesigning in ComponentState) then + Chromium1.SendCaptureLostEvent; +end; + +procedure TMainForm.Chromium1GotFocus(Sender: TObject; + const browser: ICefBrowser); +begin + CEFLinkedWindowParent1.SetFocus; +end; + +procedure TMainForm.FormActivate(Sender: TObject); +begin + // Linux needs a fully formed window to add a Chromium browser so we use this + // event to send a CEF_INITIALIZED message that will create the browser. + SendCompMessage(CEF_INITIALIZED); +end; + +procedure TMainForm.Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser); +begin + // We must wait until all browsers trigger the TChromium.OnBeforeClose event + // in order to close the application safely or we will have shutdown issues. + FCanClose := True; + SendCompMessage(CEF_BEFORECLOSE); +end; + +procedure TMainForm.Chromium1Close(Sender: TObject; const browser: ICefBrowser; + var aAction: TCefCloseBrowserAction); +begin + // continue closing the browser + aAction := cbaClose; +end; + +procedure TMainForm.WMMove(var aMessage : TLMMove); +begin + inherited; + Chromium1.NotifyMoveOrResizeStarted; +end; + +procedure TMainForm.WMSize(var aMessage: TLMSize); +begin + inherited; + Chromium1.NotifyMoveOrResizeStarted; +end; + +procedure TMainForm.WMWindowPosChanged(var aMessage: TLMWindowPosChanged); +begin + inherited; + Chromium1.NotifyMoveOrResizeStarted; +end; + +procedure TMainForm.CreateHiddenChildForm; +begin + // Linux requires a fully formed window in order to add a Chromium browser so + // we show the next popup window outside the visible screen space and then we + // hide it. + FChildForm := TChildForm.Create(self); + FChildForm.Top := -1000; + FChildForm.Left := -1000; + FChildForm.Show; + FChildForm.Hide; + // Center the child form on the screen by default + FChildForm.Top := (screen.Height - FChildForm.Height) div 2; + FChildForm.Left := (screen.Width - FChildForm.Width) div 2; +end; + +procedure TMainForm.BrowserCreatedMsg(Data: PtrInt); +begin + Caption := 'Popup Browser'; + cursor := crDefault; + AddressPnl.Enabled := True; +end; + +procedure TMainForm.BrowserInitializedMsg(Data: PtrInt); +begin + if not(Chromium1.Initialized) then + Chromium1.CreateBrowser(CEFLinkedWindowParent1.Handle, CEFLinkedWindowParent1.BoundsRect); +end; + +procedure TMainForm.BrowserChildDestroyedMsg(Data: PtrInt); +begin + if FClosingChildren and (PopupChildCount = 0) then Close; +end; + +procedure TMainForm.BrowserCreateNextChildMsg(Data: PtrInt); +begin + try + FCriticalSection.Acquire; + + if (FChildForm <> nil) then + begin + FChildForm.ApplyPopupFeatures; + FChildForm.Show; + // SetActiveWindow should bring the child form to the front... + SetActiveWindow(FChildForm.Handle); + end; + + CreateHiddenChildForm; + finally + FCriticalSection.Release; + end; +end; + +procedure TMainForm.BrowserCloseFormMsg(Data: PtrInt); +begin + Close; +end; + +procedure TMainForm.SendCompMessage(aMsg : cardinal; aData : PtrInt); +begin + case aMsg of + CEF_INITIALIZED : Application.QueueAsyncCall(@BrowserInitializedMsg, aData); + CEF_AFTERCREATED : Application.QueueAsyncCall(@BrowserCreatedMsg, aData); + CEF_CREATENEXTCHILD : Application.QueueAsyncCall(@BrowserCreateNextChildMsg, aData); + CEF_CHILDDESTROYED : Application.QueueAsyncCall(@BrowserChildDestroyedMsg, aData); + CEF_BEFORECLOSE : Application.QueueAsyncCall(@BrowserCloseFormMsg, aData); + end; +end; + +end. diff --git a/demos/Lazarus_Linux/SimpleOSRBrowser/SimpleOSRBrowser.lps b/demos/Lazarus_Linux/SimpleOSRBrowser/SimpleOSRBrowser.lps index b2d702f0..2857f6b6 100644 --- a/demos/Lazarus_Linux/SimpleOSRBrowser/SimpleOSRBrowser.lps +++ b/demos/Lazarus_Linux/SimpleOSRBrowser/SimpleOSRBrowser.lps @@ -3,15 +3,14 @@ <ProjectSession> <Version Value="11"/> <BuildModes Active="Default"/> - <Units Count="101"> + <Units Count="108"> <Unit0> <Filename Value="SimpleOSRBrowser.lpr"/> <IsPartOfProject Value="True"/> - <EditorIndex Value="1"/> - <TopLine Value="18"/> + <EditorIndex Value="-1"/> + <TopLine Value="29"/> <CursorPos X="57" Y="58"/> - <UsageCount Value="78"/> - <Loaded Value="True"/> + <UsageCount Value="81"/> </Unit0> <Unit1> <Filename Value="usimpleosrbrowser.pas"/> @@ -20,9 +19,10 @@ <HasResources Value="True"/> <ResourceBaseClass Value="Form"/> <UnitName Value="uSimpleOSRBrowser"/> - <TopLine Value="595"/> - <CursorPos X="53" Y="609"/> - <UsageCount Value="78"/> + <IsVisibleTab Value="True"/> + <TopLine Value="55"/> + <CursorPos X="65" Y="96"/> + <UsageCount Value="81"/> <Bookmarks Count="2"> <Item0 X="47" Y="222" ID="2"/> <Item1 X="76" Y="501" ID="6"/> @@ -34,11 +34,9 @@ <Filename Value="interfaces.pas"/> <IsPartOfProject Value="True"/> <UnitName Value="Interfaces"/> - <IsVisibleTab Value="True"/> - <EditorIndex Value="2"/> + <EditorIndex Value="-1"/> <CursorPos X="40" Y="20"/> - <UsageCount Value="74"/> - <Loaded Value="True"/> + <UsageCount Value="77"/> </Unit2> <Unit3> <Filename Value="/usr/share/lazarus/2.0.6/lcl/lcltype.pp"/> @@ -128,12 +126,12 @@ <Unit15> <Filename Value="../../../source/uCEFBufferPanel.pas"/> <EditorIndex Value="-1"/> - <TopLine Value="363"/> - <CursorPos Y="381"/> - <UsageCount Value="28"/> + <TopLine Value="111"/> + <CursorPos X="17" Y="123"/> + <UsageCount Value="29"/> <Bookmarks Count="4"> - <Item0 Y="997" ID="9"/> - <Item1 X="63" Y="579" ID="8"/> + <Item0 Y="1010" ID="9"/> + <Item1 X="63" Y="581" ID="8"/> <Item2 X="5" Y="345" ID="7"/> <Item3 X="5" Y="375" ID="1"/> </Bookmarks> @@ -202,9 +200,9 @@ <Filename Value="/usr/share/lazarus/2.0.10/lcl/graphics.pp"/> <UnitName Value="Graphics"/> <EditorIndex Value="-1"/> - <TopLine Value="1075"/> - <CursorPos X="15" Y="1083"/> - <UsageCount Value="14"/> + <TopLine Value="1218"/> + <CursorPos X="14" Y="1240"/> + <UsageCount Value="15"/> </Unit24> <Unit25> <Filename Value="/usr/share/lazarus/2.0.10/lcl/include/canvas.inc"/> @@ -707,8 +705,8 @@ <Unit94> <Filename Value="../../../source/uCEFBitmapBitBuffer.pas"/> <EditorIndex Value="-1"/> - <TopLine Value="110"/> - <CursorPos X="29" Y="126"/> + <TopLine Value="153"/> + <CursorPos X="58" Y="183"/> <UsageCount Value="13"/> </Unit94> <Unit95> @@ -755,143 +753,69 @@ <CursorPos Y="357"/> <UsageCount Value="11"/> </Unit100> + <Unit101> + <Filename Value="../../../source/uCEFUrlRequestClientComponent.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="175"/> + <UsageCount Value="10"/> + </Unit101> + <Unit102> + <Filename Value="../../../source/uCEFUrlrequestClient.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="55"/> + <UsageCount Value="10"/> + </Unit102> + <Unit103> + <Filename Value="../../../source/uCEFServerEvents.pas"/> + <EditorIndex Value="-1"/> + <UsageCount Value="10"/> + </Unit103> + <Unit104> + <Filename Value="../../../source/uCEFServerComponent.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="329"/> + <UsageCount Value="10"/> + </Unit104> + <Unit105> + <Filename Value="../../../source/uCEFSentinel.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="73"/> + <CursorPos X="24" Y="101"/> + <UsageCount Value="10"/> + </Unit105> + <Unit106> + <Filename Value="../../../source/uCEFWorkScheduler.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="81"/> + <CursorPos X="17" Y="84"/> + <UsageCount Value="10"/> + </Unit106> + <Unit107> + <Filename Value="../../../source/uCEFLinkedWindowParent.pas"/> + <EditorIndex Value="-1"/> + <TopLine Value="56"/> + <CursorPos X="77" Y="127"/> + <UsageCount Value="10"/> + </Unit107> </Units> <OtherDefines Count="2"> <Define0 Value="UseCthreads"/> <Define1 Value="EnabledGtkThreading"/> </OtherDefines> - <JumpHistory Count="30" HistoryIndex="29"> - <Position1> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="535" Column="58" TopLine="488"/> - </Position1> - <Position2> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="543" Column="51" TopLine="496"/> - </Position2> - <Position3> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="75" Column="32" TopLine="56"/> - </Position3> - <Position4> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="320" Column="3" TopLine="314"/> - </Position4> - <Position5> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="75" Column="15" TopLine="48"/> - </Position5> - <Position6> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="320" Column="3" TopLine="315"/> - </Position6> - <Position7> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="83" Column="28" TopLine="75"/> - </Position7> - <Position8> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="511" Column="3" TopLine="508"/> - </Position8> - <Position9> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="112" Column="23" TopLine="87"/> - </Position9> - <Position10> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="618" Column="3" TopLine="593"/> - </Position10> - <Position11> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="112" Column="29" TopLine="97"/> - </Position11> - <Position12> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="628" Column="84" TopLine="597"/> - </Position12> - <Position13> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="120" Column="31" TopLine="94"/> - </Position13> - <Position14> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="669" Column="24" TopLine="620"/> - </Position14> - <Position15> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="112" Column="25" TopLine="84"/> - </Position15> - <Position16> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="479" Column="50" TopLine="447"/> - </Position16> - <Position17> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="75" Column="15" TopLine="52"/> - </Position17> - <Position18> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="338" Column="59" TopLine="318"/> - </Position18> - <Position19> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="75" Column="31" TopLine="51"/> - </Position19> - <Position20> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="341" Column="3" TopLine="332"/> - </Position20> - <Position21> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="83" Column="15" TopLine="49"/> - </Position21> - <Position22> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="552" Column="57" TopLine="524"/> - </Position22> - <Position23> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="118" Column="30" TopLine="88"/> - </Position23> - <Position24> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="73" Column="31" TopLine="71"/> - </Position24> - <Position25> - <Filename Value="SimpleOSRBrowser.lpr"/> - <Caret Line="58" Column="57" TopLine="18"/> - </Position25> - <Position26> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="101" Column="55" TopLine="81"/> - </Position26> - <Position27> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="625" Column="10" TopLine="578"/> - </Position27> - <Position28> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="100" Column="12" TopLine="74"/> - </Position28> - <Position29> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="625" Column="10" TopLine="578"/> - </Position29> - <Position30> - <Filename Value="usimpleosrbrowser.pas"/> - <Caret Line="100" TopLine="74"/> - </Position30> - </JumpHistory> + <JumpHistory HistoryIndex="-1"/> <RunParams> <FormatVersion Value="2"/> <Modes Count="0" ActiveMode=""/> </RunParams> </ProjectSession> <Debugging> - <Watches Count="1"> + <Watches Count="2"> <Item1> <Expression Value="width"/> </Item1> + <Item2> + <Expression Value="FBitmap.PixelFormat"/> + </Item2> </Watches> </Debugging> </CONFIG> diff --git a/demos/Lazarus_Linux/TabbedBrowser2/TabbedBrowser2.lps b/demos/Lazarus_Linux/TabbedBrowser2/TabbedBrowser2.lps index 22d2f435..e0c3a64b 100644 --- a/demos/Lazarus_Linux/TabbedBrowser2/TabbedBrowser2.lps +++ b/demos/Lazarus_Linux/TabbedBrowser2/TabbedBrowser2.lps @@ -39,13 +39,13 @@ <ResourceBaseClass Value="Frame"/> <IsVisibleTab Value="True"/> <EditorIndex Value="3"/> - <TopLine Value="118"/> - <CursorPos X="16" Y="145"/> + <TopLine Value="442"/> + <CursorPos X="6" Y="440"/> <UsageCount Value="24"/> <Bookmarks Count="3"> - <Item0 X="22" Y="471" ID="2"/> - <Item1 X="50" Y="392" ID="3"/> - <Item2 X="36" Y="415" ID="4"/> + <Item0 X="22" Y="477" ID="2"/> + <Item1 X="50" Y="397" ID="3"/> + <Item2 X="36" Y="420" ID="4"/> </Bookmarks> <Loaded Value="True"/> <LoadedDesigner Value="True"/> @@ -125,123 +125,127 @@ <OtherDefines Count="1"> <Define0 Value="UseCThreads"/> </OtherDefines> - <JumpHistory Count="29" HistoryIndex="28"> + <JumpHistory Count="30" HistoryIndex="29"> <Position1> - <Filename Value="uBrowserFrame.pas"/> - <Caret Line="124" Column="17" TopLine="103"/> - </Position1> - <Position2> - <Filename Value="uBrowserFrame.pas"/> - <Caret Line="463" Column="3" TopLine="436"/> - </Position2> - <Position3> <Filename Value="uBrowserTab.pas"/> <Caret Line="117" Column="67" TopLine="84"/> + </Position1> + <Position2> + <Filename Value="uBrowserTab.pas"/> + <Caret Line="128" Column="61" TopLine="103"/> + </Position2> + <Position3> + <Filename Value="uBrowserFrame.pas"/> + <Caret Line="144" Column="19" TopLine="123"/> </Position3> <Position4> <Filename Value="uBrowserTab.pas"/> - <Caret Line="128" Column="61" TopLine="103"/> + <Caret Line="133" Column="90" TopLine="103"/> </Position4> <Position5> - <Filename Value="uBrowserFrame.pas"/> - <Caret Line="144" Column="19" TopLine="123"/> + <Filename Value="uBrowserTab.pas"/> + <Caret Line="61" Column="67" TopLine="39"/> </Position5> <Position6> <Filename Value="uBrowserTab.pas"/> - <Caret Line="133" Column="90" TopLine="103"/> + <Caret Line="131" Column="41" TopLine="103"/> </Position6> <Position7> <Filename Value="uBrowserTab.pas"/> - <Caret Line="61" Column="67" TopLine="39"/> + <Caret Line="61" Column="19" TopLine="39"/> </Position7> <Position8> <Filename Value="uBrowserTab.pas"/> - <Caret Line="131" Column="41" TopLine="103"/> + <Caret Line="126" Column="42" TopLine="103"/> </Position8> <Position9> - <Filename Value="uBrowserTab.pas"/> - <Caret Line="61" Column="19" TopLine="39"/> - </Position9> - <Position10> - <Filename Value="uBrowserTab.pas"/> - <Caret Line="126" Column="42" TopLine="103"/> - </Position10> - <Position11> <Filename Value="uBrowserFrame.pas"/> <Caret Line="144" Column="19" TopLine="90"/> + </Position9> + <Position10> + <Filename Value="uMainForm.pas"/> + <Caret Line="96" Column="28" TopLine="86"/> + </Position10> + <Position11> + <Filename Value="uMainForm.pas"/> + <Caret Line="264" Column="38" TopLine="240"/> </Position11> <Position12> <Filename Value="uMainForm.pas"/> - <Caret Line="96" Column="28" TopLine="86"/> + <Caret Line="87" Column="15" TopLine="71"/> </Position12> <Position13> <Filename Value="uMainForm.pas"/> - <Caret Line="264" Column="38" TopLine="240"/> + <Caret Line="262" Column="75" TopLine="240"/> </Position13> <Position14> <Filename Value="uMainForm.pas"/> - <Caret Line="87" Column="15" TopLine="71"/> + <Caret Line="303" Column="41" TopLine="261"/> </Position14> <Position15> <Filename Value="uMainForm.pas"/> - <Caret Line="262" Column="75" TopLine="240"/> + <Caret Line="84" Column="15" TopLine="71"/> </Position15> <Position16> <Filename Value="uMainForm.pas"/> - <Caret Line="303" Column="41" TopLine="261"/> + <Caret Line="271" Column="41" TopLine="264"/> </Position16> <Position17> <Filename Value="uMainForm.pas"/> - <Caret Line="84" Column="15" TopLine="71"/> + <Caret Line="85" Column="15" TopLine="63"/> </Position17> <Position18> - <Filename Value="uMainForm.pas"/> - <Caret Line="271" Column="41" TopLine="264"/> - </Position18> - <Position19> - <Filename Value="uMainForm.pas"/> - <Caret Line="85" Column="15" TopLine="63"/> - </Position19> - <Position20> <Filename Value="uBrowserFrame.pas"/> <Caret Line="113" Column="73" TopLine="90"/> - </Position20> - <Position21> + </Position18> + <Position19> <Filename Value="uBrowserFrame.pas"/> <Caret Line="132" Column="32" TopLine="96"/> + </Position19> + <Position20> + <Filename Value="uMainForm.pas"/> + <Caret Line="303" Column="69" TopLine="259"/> + </Position20> + <Position21> + <Filename Value="uMainForm.pas"/> + <Caret Line="190" Column="3" TopLine="170"/> </Position21> <Position22> <Filename Value="uMainForm.pas"/> - <Caret Line="303" Column="69" TopLine="259"/> + <Caret Line="219" TopLine="205"/> </Position22> <Position23> <Filename Value="uMainForm.pas"/> - <Caret Line="190" Column="3" TopLine="170"/> + <Caret Line="71" TopLine="60"/> </Position23> <Position24> - <Filename Value="uMainForm.pas"/> - <Caret Line="219" TopLine="205"/> + <Filename Value="uBrowserFrame.pas"/> + <Caret Line="78" Column="25" TopLine="62"/> </Position24> <Position25> - <Filename Value="uMainForm.pas"/> - <Caret Line="71" TopLine="60"/> + <Filename Value="uBrowserFrame.pas"/> + <Caret Line="359" Column="49" TopLine="355"/> </Position25> <Position26> <Filename Value="uBrowserFrame.pas"/> - <Caret Line="78" Column="25" TopLine="62"/> + <Caret Line="77" Column="17" TopLine="56"/> </Position26> <Position27> <Filename Value="uBrowserFrame.pas"/> - <Caret Line="359" Column="49" TopLine="355"/> + <Caret Line="464" Column="59" TopLine="40"/> </Position27> <Position28> <Filename Value="uBrowserFrame.pas"/> - <Caret Line="77" Column="17" TopLine="56"/> + <Caret Line="73" Column="41" TopLine="63"/> </Position28> <Position29> <Filename Value="uBrowserFrame.pas"/> - <Caret Line="464" Column="59" TopLine="40"/> + <Caret Line="326" Column="43" TopLine="305"/> </Position29> + <Position30> + <Filename Value="uBrowserFrame.pas"/> + <Caret Line="79" Column="17" TopLine="50"/> + </Position30> </JumpHistory> <RunParams> <FormatVersion Value="2"/> diff --git a/demos/Lazarus_Linux/TabbedBrowser2/uBrowserFrame.lfm b/demos/Lazarus_Linux/TabbedBrowser2/uBrowserFrame.lfm index f2a64ec1..0af54084 100644 --- a/demos/Lazarus_Linux/TabbedBrowser2/uBrowserFrame.lfm +++ b/demos/Lazarus_Linux/TabbedBrowser2/uBrowserFrame.lfm @@ -198,6 +198,7 @@ object BrowserFrame: TBrowserFrame Top = 28 Width = 932 Align = alClient + TabStop = True TabOrder = 2 OnEnter = CEFLinkedWindowParent1Enter OnExit = CEFLinkedWindowParent1Exit diff --git a/demos/Lazarus_Linux/TabbedBrowser2/uBrowserFrame.pas b/demos/Lazarus_Linux/TabbedBrowser2/uBrowserFrame.pas index bd9782d4..3cbbcd35 100644 --- a/demos/Lazarus_Linux/TabbedBrowser2/uBrowserFrame.pas +++ b/demos/Lazarus_Linux/TabbedBrowser2/uBrowserFrame.pas @@ -309,18 +309,29 @@ begin SendCompMessage(CEF_AFTERCREATED); end; +// This is a workaround for the CEF issue #2026 +// https://bitbucket.org/chromiumembedded/cef/issues/2026/multiple-major-keyboard-focus-issues-on +// We use CEFLinkedWindowParent1.OnEnter, CEFLinkedWindowParent1.OnExit and +// TChromium.OnGotFocus to avoid most of the focus issues. +// CEFLinkedWindowParent1.TabStop must be TRUE. +procedure TBrowserFrame.CEFLinkedWindowParent1Exit(Sender: TObject); +begin + if not(csDesigning in ComponentState) then + Chromium1.SendCaptureLostEvent; +end; + procedure TBrowserFrame.CEFLinkedWindowParent1Enter(Sender: TObject); begin if not(csDesigning in ComponentState) and Chromium1.Initialized and not(Chromium1.FrameIsFocused) then Chromium1.SendFocusEvent(True); -end; +end; -procedure TBrowserFrame.CEFLinkedWindowParent1Exit(Sender: TObject); +procedure TBrowserFrame.Chromium1GotFocus(Sender: TObject; + const browser: ICefBrowser); begin - if not(csDesigning in ComponentState) then - Chromium1.SendCaptureLostEvent; + CEFLinkedWindowParent1.SetFocus; end; procedure TBrowserFrame.BackBtnClick(Sender: TObject); @@ -360,12 +371,6 @@ begin aAction := cbaClose; end; -procedure TBrowserFrame.Chromium1GotFocus(Sender: TObject; - const browser: ICefBrowser); -begin - CEFLinkedWindowParent1.SetFocus; -end; - procedure TBrowserFrame.Chromium1LoadError(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; errorCode: Integer; const errorText, failedUrl: ustring); @@ -431,7 +436,8 @@ var begin TempURL := BrowserAddress; - if (URLCbx.Items.IndexOf(TempURL) < 0) then URLCbx.Items.Add(TempURL); + if (URLCbx.Items.IndexOf(TempURL) < 0) then + URLCbx.Items.Add(TempURL); URLCbx.Text := TempURL; end; diff --git a/source/uCEFLinkedWindowParent.pas b/source/uCEFLinkedWindowParent.pas index 6fd8aead..399a464c 100644 --- a/source/uCEFLinkedWindowParent.pas +++ b/source/uCEFLinkedWindowParent.pas @@ -70,7 +70,6 @@ type {$IFDEF FPC}{$IFDEF LINUX} procedure SetVisible(Value: Boolean); override; - procedure UpdateSize; override; {$ENDIF}{$ENDIF} procedure SetChromium(aValue : TChromium); @@ -82,6 +81,9 @@ type public constructor Create(AOwner : TComponent); override; + {$IFDEF FPC}{$IFDEF LINUX} + procedure UpdateSize; override; + {$ENDIF}{$ENDIF} published property Chromium : TChromium read FChromium write SetChromium; diff --git a/update_CEF4Delphi.json b/update_CEF4Delphi.json index c511fdec..6943debd 100644 --- a/update_CEF4Delphi.json +++ b/update_CEF4Delphi.json @@ -2,7 +2,7 @@ "UpdateLazPackages" : [ { "ForceNotify" : true, - "InternalVersion" : 221, + "InternalVersion" : 222, "Name" : "cef4delphi_lazarus.lpk", "Version" : "87.1.12.0" }