From 44896524e8fb7cbca0e3a970b92c0b23a9f74652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Salvador=20D=C3=ADaz=20Fau?= Date: Wed, 26 May 2021 19:32:10 +0200 Subject: [PATCH] Improved keyboard and mouse support in FMXExternalPumpBrowser for MacOS Added X11 error handling functions to FMXExternalPumpBrowser2 demo for Linux. Deleted FMXExternalPumpBrowser demo for Linux. Added uCEFMacOSConstants and uCEFMacOSFunctions units for MacOS. Replaced TThread.Queue for TThread.ForceQueue to avoid executing that method immediately in some cases. --- .../FMXExternalPumpBrowser/00-DeleteDCUs.bat | 23 - .../FMXExternalPumpBrowser.dpr | 80 - .../FMXExternalPumpBrowser.dproj | 1317 ----------------- .../FMXExternalPumpBrowser/cef.inc | 468 ------ .../FMXExternalPumpBrowser/uCEFLoader.pas | 100 -- .../uFMXExternalPumpBrowser.fmx | 141 -- .../uFMXExternalPumpBrowser.pas | 915 ------------ .../FMXExternalPumpBrowser2_sp.dpr | 9 +- .../FMXExternalPumpBrowser2/uCEFLoader.pas | 25 +- .../uFMXExternalPumpBrowser2.fmx | 11 +- .../uFMXExternalPumpBrowser2.pas | 96 +- .../FMXExternalPumpBrowser.dpr | 4 +- .../FMXExternalPumpBrowser.dproj | 1 - .../uFMXExternalPumpBrowser.fmx | 53 +- .../uFMXExternalPumpBrowser.pas | 254 ++-- source/uCEFBufferPanel.pas | 2 +- source/uCEFChromiumCore.pas | 8 +- source/uCEFFMXWorkScheduler.pas | 8 +- source/uCEFLinuxFunctions.pas | 7 + source/uCEFLinuxTypes.pas | 12 + source/uCEFMacOSConstants.pas | 240 +++ .../uCEFMacOSFunctions.pas | 177 ++- source/uCEFWorkScheduler.pas | 86 +- source/uCEFWorkSchedulerQueueThread.pas | 2 +- source/uCEFWorkSchedulerThread.pas | 4 +- update_CEF4Delphi.json | 2 +- 26 files changed, 726 insertions(+), 3319 deletions(-) delete mode 100644 demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/00-DeleteDCUs.bat delete mode 100644 demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/FMXExternalPumpBrowser.dpr delete mode 100644 demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/FMXExternalPumpBrowser.dproj delete mode 100644 demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/cef.inc delete mode 100644 demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/uCEFLoader.pas delete mode 100644 demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/uFMXExternalPumpBrowser.fmx delete mode 100644 demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/uFMXExternalPumpBrowser.pas create mode 100644 source/uCEFMacOSConstants.pas rename demos/Delphi_FMX_Mac/FMXExternalPumpBrowser/uFMXMiscFunctions.pas => source/uCEFMacOSFunctions.pas (51%) diff --git a/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/00-DeleteDCUs.bat b/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/00-DeleteDCUs.bat deleted file mode 100644 index 160b94f1..00000000 --- a/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/00-DeleteDCUs.bat +++ /dev/null @@ -1,23 +0,0 @@ -del /s /q *. -del /s /q *.o -del /s /q *.dcu -del /s /q *.exe -del /s /q *.res -del /s /q *.rsm -del /s /q *.log -del /s /q *.dsk -del /s /q *.identcache -del /s /q *.stat -del /s /q *.local -del /s /q *.~* -rmdir Win32\Debug -rmdir Win32\Release -rmdir Win32 -rmdir Win64\Debug -rmdir Win64\Release -rmdir Win64 -rmdir Linux64\Debug -rmdir Linux64\Release -rmdir Linux64 -rmdir __history -rmdir __recovery diff --git a/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/FMXExternalPumpBrowser.dpr b/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/FMXExternalPumpBrowser.dpr deleted file mode 100644 index 1ce1a79c..00000000 --- a/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/FMXExternalPumpBrowser.dpr +++ /dev/null @@ -1,80 +0,0 @@ -// ************************************************************************ -// ***************************** 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 - * 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 FMXExternalPumpBrowser; - -uses - // FMX initializes GTK in the initialization section of some of its units and - // that means that GTK is already initialized when the code in the DPR is - // executed. - // Chromium has to be initialized in a process with only one thread but GTK - // creates several threads during its initialization. To avoid this problem - // we have to initialize CEF before GTK. - // uCEFLoader *MUST* be the first unit in the DPR file to make sure Chromium - // is initialized before GTK. - // uCEFLoader *MUST NOT* make any reference to any FMX unit to keep the right - // initalization order. - // Read the answer to this question for more more information : - // https://stackoverflow.com/questions/52103407/changing-the-initialization-order-of-the-unit-in-delphi - uCEFLoader in 'uCEFLoader.pas', - System.StartUpCopy, - FMX.Forms, - uCEFApplication, - uCEFWorkScheduler, - uFMXExternalPumpBrowser in 'uFMXExternalPumpBrowser.pas' {FMXExternalPumpBrowserFrm}; - -{$R *.res} - -begin - CreateGlobalCEFApp; - - if GlobalCEFApp.StartMainProcess then - begin - {$IFDEF LINUX}InitializeGTK;{$ENDIF} - Application.Initialize; - Application.CreateForm(TFMXExternalPumpBrowserFrm, FMXExternalPumpBrowserFrm); - Application.Run; - - // The form needs to be destroyed *BEFORE* stopping the work scheduler. - FMXExternalPumpBrowserFrm.Free; - - GlobalCEFWorkScheduler.StopScheduler; - end; - - DestroyGlobalCEFApp; - DestroyGlobalCEFWorkScheduler; -end. diff --git a/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/FMXExternalPumpBrowser.dproj b/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/FMXExternalPumpBrowser.dproj deleted file mode 100644 index 371cdd00..00000000 --- a/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/FMXExternalPumpBrowser.dproj +++ /dev/null @@ -1,1317 +0,0 @@ - - - {BE24D13B-2634-4064-8746-AB331419C5FA} - 19.2 - FMX - FMXExternalPumpBrowser.dpr - True - Debug - Linux64 - 131 - Application - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_1 - true - true - - - true - Cfg_1 - true - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - .\$(Platform)\$(Config) - ..\..\..\bin - false - false - false - false - false - RESTComponents;emsclientfiredac;FireDAC;FireDACSqliteDriver;soaprtl;FireDACIBDriver;soapmidas;FireDACCommon;emsclient;RESTBackendComponents;soapserver;FireDACCommonDriver;CloudService;inet;$(DCC_UsePackage) - System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) - $(BDS)\bin\delphi_PROJECTICON.ico - $(BDS)\bin\delphi_PROJECTICNS.icns - FMXExternalPumpBrowser - 3082 - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - $(FrameworkType);$(DCC_Define) - - - $(fmxlinux)\Lib\$(ProductVersion)\$(Config);$(DCC_UnitSearchPath) - - - DBXSqliteDriver;bindcompdbx;fmxase;DBXDb2Driver;DBXInterBaseDriver;vcl;DBXSybaseASEDriver;vclactnband;vclFireDAC;FireDACDb2Driver;DataSnapFireDAC;svnui;tethering;dsnapcon;FireDACADSDriver;FireDACMSAccDriver;fmxFireDAC;DBXMSSQLDriver;vclimg;FireDACInfxDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;Componentes_UI;vcldb;bindcompfmx;svn;FireDACPgDriver;DBXOracleDriver;inetdb;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;CEF4Delphi;DbxCommonDriver;IndyProtocols240;IndySystem240;fmx;DataSnapServer;xmlrtl;DataSnapNativeClient;fmxobj;fmxdae;vclwinx;rtl;FireDACDSDriver;DbxClientDriver;IndyCore240;DBXSybaseASADriver;CustomIPTransport;vcldsnap;dbexpress;FireDACDBXDriver;vclx;bindcomp;appanalytics;dsnap;DataSnapCommon;DBXInformixDriver;bindcompvcl;DataSnapConnectors;VCLRESTComponents;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;dsnapxml;FireDACMySQLDriver;dbrtl;inetdbxpress;DBXFirebirdDriver;DataSnapProviderClient;FireDACMongoDBDriver;FireDACCommonODBC;DataSnapClient;DataSnapServerMidas;$(DCC_UsePackage) - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - Debug - true - 1033 - $(BDS)\bin\default_app.manifest - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png - - - DBXSqliteDriver;bindcompdbx;fmxase;DBXDb2Driver;DBXInterBaseDriver;vcl;DBXSybaseASEDriver;vclactnband;vclFireDAC;FireDACDb2Driver;DataSnapFireDAC;tethering;dsnapcon;FireDACADSDriver;FireDACMSAccDriver;fmxFireDAC;DBXMSSQLDriver;vclimg;FireDACInfxDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;FireDACPgDriver;DBXOracleDriver;inetdb;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;DbxCommonDriver;IndyProtocols240;IndySystem240;fmx;DataSnapServer;xmlrtl;DataSnapNativeClient;fmxobj;fmxdae;vclwinx;rtl;FireDACDSDriver;DbxClientDriver;IndyCore240;DBXSybaseASADriver;CustomIPTransport;vcldsnap;dbexpress;FireDACDBXDriver;vclx;bindcomp;appanalytics;dsnap;DataSnapCommon;DBXInformixDriver;bindcompvcl;DataSnapConnectors;VCLRESTComponents;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;dsnapxml;FireDACMySQLDriver;dbrtl;inetdbxpress;DBXFirebirdDriver;DataSnapProviderClient;FireDACMongoDBDriver;FireDACCommonODBC;DataSnapClient;DataSnapServerMidas;$(DCC_UsePackage) - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) - Debug - true - 1033 - $(BDS)\bin\default_app.manifest - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png - - - DEBUG;$(DCC_Define) - true - false - true - true - true - - - false - true - 1033 - PerMonitor - true - - - true - PerMonitorV2 - - - false - RELEASE;$(DCC_Define) - 0 - 0 - - - true - PerMonitor - true - 1033 - - - true - PerMonitorV2 - - - - MainSource - - - -
FMXExternalPumpBrowserFrm
-
- - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - -
- - Delphi.Personality.12 - Application - - - - FMXExternalPumpBrowser.dpr - - - IP Abstraction Indy Implementation Design Time - DBExpress Enterprise Data Explorer Integration - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - - - true - - - - - FMXExternalPumpBrowser.exe - true - - - - - .\ - FMXExternalPumpBrowser - true - - - - - true - - - - - true - - - - - true - - - - - true - - - - - true - - - - - 1 - - - Contents\MacOS - 1 - - - 0 - - - - - classes - 1 - - - classes - 1 - - - - - res\xml - 1 - - - res\xml - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - library\lib\armeabi - 1 - - - library\lib\armeabi - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - library\lib\mips - 1 - - - library\lib\mips - 1 - - - - - library\lib\armeabi-v7a - 1 - - - library\lib\arm64-v8a - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - res\drawable - 1 - - - res\drawable - 1 - - - - - res\values - 1 - - - res\values - 1 - - - - - res\values-v21 - 1 - - - res\values-v21 - 1 - - - - - res\values - 1 - - - res\values - 1 - - - - - res\drawable - 1 - - - res\drawable - 1 - - - - - res\drawable-xxhdpi - 1 - - - res\drawable-xxhdpi - 1 - - - - - res\drawable-xxxhdpi - 1 - - - res\drawable-xxxhdpi - 1 - - - - - res\drawable-ldpi - 1 - - - res\drawable-ldpi - 1 - - - - - res\drawable-mdpi - 1 - - - res\drawable-mdpi - 1 - - - - - res\drawable-hdpi - 1 - - - res\drawable-hdpi - 1 - - - - - res\drawable-xhdpi - 1 - - - res\drawable-xhdpi - 1 - - - - - res\drawable-mdpi - 1 - - - res\drawable-mdpi - 1 - - - - - res\drawable-hdpi - 1 - - - res\drawable-hdpi - 1 - - - - - res\drawable-xhdpi - 1 - - - res\drawable-xhdpi - 1 - - - - - res\drawable-xxhdpi - 1 - - - res\drawable-xxhdpi - 1 - - - - - res\drawable-xxxhdpi - 1 - - - res\drawable-xxxhdpi - 1 - - - - - res\drawable-small - 1 - - - res\drawable-small - 1 - - - - - res\drawable-normal - 1 - - - res\drawable-normal - 1 - - - - - res\drawable-large - 1 - - - res\drawable-large - 1 - - - - - res\drawable-xlarge - 1 - - - res\drawable-xlarge - 1 - - - - - res\values - 1 - - - res\values - 1 - - - - - 1 - - - Contents\MacOS - 1 - - - 0 - - - - - Contents\MacOS - 1 - .framework - - - Contents\MacOS - 1 - .framework - - - 0 - - - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - Contents\MacOS - 1 - .dylib - - - Contents\MacOS - 1 - .dylib - - - 0 - .dll;.bpl - - - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - Contents\MacOS - 1 - .dylib - - - Contents\MacOS - 1 - .dylib - - - 0 - .bpl - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - Contents\Resources\StartUp\ - 0 - - - Contents\Resources\StartUp\ - 0 - - - 0 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - 1 - - - 1 - - - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\LaunchScreenImage.imageset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - ..\$(PROJECTNAME).launchscreen\Assets\AppIcon.appiconset - 1 - - - - - 1 - - - 1 - - - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - - - 1 - - - 1 - - - - - ..\ - 1 - - - ..\ - 1 - - - - - 1 - - - 1 - - - 1 - - - - - ..\$(PROJECTNAME).launchscreen - 64 - - - ..\$(PROJECTNAME).launchscreen - 64 - - - - - 1 - - - 1 - - - 1 - - - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - - - ..\ - 1 - - - ..\ - 1 - - - - - Contents - 1 - - - Contents - 1 - - - - - Contents\Resources - 1 - - - Contents\Resources - 1 - - - - - library\lib\armeabi-v7a - 1 - - - library\lib\arm64-v8a - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - Contents\MacOS - 1 - - - Contents\MacOS - 1 - - - 0 - - - - - library\lib\armeabi-v7a - 1 - - - - - 1 - - - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - - - - - - - - - - - True - True - True - - - 12 - - - - -
diff --git a/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/cef.inc b/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/cef.inc deleted file mode 100644 index c8ce967e..00000000 --- a/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/cef.inc +++ /dev/null @@ -1,468 +0,0 @@ -// ************************************************************************ -// ***************************** 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 - * 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} - -// Delphi uses MACOS for the new MacOSX and DARWIN is not defined -// FPC uses DARWIN for the new MacOSX and MACOS is defined for the classic Macintosh OS (System 7) -// We define MACOSX to avoid conflicts in both situations -{$IFDEF FPC} - {$IFDEF DARWIN} - {$DEFINE MACOSX} - {$ENDIF} -{$ELSE} - {$IFDEF MACOS} - {$DEFINE MACOSX} - {$ENDIF} -{$ENDIF} diff --git a/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/uCEFLoader.pas b/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/uCEFLoader.pas deleted file mode 100644 index 4970a380..00000000 --- a/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/uCEFLoader.pas +++ /dev/null @@ -1,100 +0,0 @@ -// ************************************************************************ -// ***************************** 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 - * 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 uCEFLoader; - -interface - -{$IFDEF LINUX} -uses - FMUX.Config; - -procedure InitializeGTK; -{$ENDIF} - -implementation - -{$IFDEF LINUX} -uses - System.SysUtils, System.IOUtils; - -function GetLibDirName: string; -begin - {$IFNDEF FMXLINUX_EXTERNAL_RUNTIME} - Result := TPath.Combine(TPath.GetHomePath, '.fmxlinux'); - {$ELSE} - Result := ExtractFilePath(ParamStr(0)); - {$ENDIF} -end; - -function GetLibFileName: string; -const - LibName = 'libfmux'; - LibVer = '1.60'; -begin - {$IFDEF FMXLINUX_EXTERNAL_RUNTIME} - Result := TPath.Combine(GetLibDirName, LibName + '.so'); - {$ELSE} - {$IFDEF TRIAL} - Result := TPath.Combine(GetLibDirName, LibName + '-Trial-' + LibVer + '.so'); - {$ELSEIF GETIT} - Result := TPath.Combine(GetLibDirName, LibName + '-Getit' + LibVer + '.so'); - {$ELSE} - Result := TPath.Combine(GetLibDirName, LibName + '-' + LibVer + '.so'); - {$ENDIF} - {$ENDIF} -end; - -procedure InitializeGTK; -var - FmuxInit: procedure (Flags: Integer); cdecl; - TempHandle : NativeInt; -begin - TempHandle := LoadLibrary(PChar(GetLibFileName)); - - if (TempHandle <> 0) then - begin - FmuxInit := GetProcAddress(TempHandle, 'FmuxInit'); - FmuxInit(0); - end; -end; - -initialization - DoNotCallFmuxInit := True; -{$ENDIF} - -end. diff --git a/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/uFMXExternalPumpBrowser.fmx b/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/uFMXExternalPumpBrowser.fmx deleted file mode 100644 index 465c3fde..00000000 --- a/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/uFMXExternalPumpBrowser.fmx +++ /dev/null @@ -1,141 +0,0 @@ -object FMXExternalPumpBrowserFrm: TFMXExternalPumpBrowserFrm - Left = 0 - Top = 0 - Caption = 'Initializing browser. Please wait...' - ClientHeight = 633 - ClientWidth = 800 - Position = ScreenCenter - FormFactor.Width = 320 - FormFactor.Height = 480 - FormFactor.Devices = [Desktop] - OnActivate = FormActivate - OnCreate = FormCreate - OnCloseQuery = FormCloseQuery - OnDestroy = FormDestroy - OnShow = FormShow - OnHide = FormHide - DesignerMasterStyle = 0 - object AddressPnl: TPanel - Align = Top - Padding.Left = 5.000000000000000000 - Padding.Top = 5.000000000000000000 - Padding.Right = 5.000000000000000000 - Padding.Bottom = 5.000000000000000000 - Size.Width = 800.000000000000000000 - Size.Height = 33.000000000000000000 - Size.PlatformDefault = False - TabOrder = 1 - object AddressEdt: TEdit - Touch.InteractiveGestures = [LongTap, DoubleTap] - Align = Client - TabOrder = 0 - Text = 'https://www.google.com' - Size.Width = 709.000000000000000000 - Size.Height = 23.000000000000000000 - Size.PlatformDefault = False - OnEnter = AddressEdtEnter - end - object Layout1: TLayout - Align = Right - Padding.Left = 5.000000000000000000 - Position.X = 714.000000000000000000 - Position.Y = 5.000000000000000000 - Size.Width = 81.000000000000000000 - Size.Height = 23.000000000000000000 - Size.PlatformDefault = False - TabOrder = 2 - object GoBtn: TButton - Align = Left - Position.X = 5.000000000000000000 - Size.Width = 36.000000000000000000 - Size.Height = 23.000000000000000000 - Size.PlatformDefault = False - TabOrder = 0 - Text = 'Go' - OnClick = GoBtnClick - OnEnter = GoBtnEnter - end - object SnapshotBtn: TButton - Align = Right - StyledSettings = [Style, FontColor] - Position.X = 45.000000000000000000 - Size.Width = 36.000000000000000000 - Size.Height = 23.000000000000000000 - Size.PlatformDefault = False - TabOrder = 1 - Text = #181 - TextSettings.Font.Family = 'Webdings' - TextSettings.Font.Size = 32.000000000000000000 - OnClick = SnapshotBtnClick - OnEnter = SnapshotBtnEnter - end - end - end - object Timer1: TTimer - Enabled = False - Interval = 300 - OnTimer = Timer1Timer - Left = 40 - Top = 137 - end - object SaveDialog1: TSaveDialog - DefaultExt = 'bmp' - Filter = 'Bitmap files (*.bmp)|*.BMP' - Title = 'Save snapshot' - Left = 40 - Top = 201 - end - object Panel1: TFMXBufferPanel - Align = Client - TabOrder = 0 - CanFocus = True - Size.Width = 800.000000000000000000 - Size.Height = 578.000000000000000000 - Size.PlatformDefault = False - OnEnter = Panel1Enter - OnExit = Panel1Exit - OnResize = Panel1Resize - OnClick = Panel1Click - OnMouseDown = Panel1MouseDown - OnMouseMove = Panel1MouseMove - OnMouseUp = Panel1MouseUp - OnMouseLeave = Panel1MouseLeave - OnMouseWheel = Panel1MouseWheel - OnKeyDown = Panel1KeyDown - OnDialogKey = Panel1DialogKey - end - object StatusBar1: TStatusBar - Position.Y = 611.000000000000000000 - ShowSizeGrip = True - Size.Width = 800.000000000000000000 - Size.Height = 22.000000000000000000 - Size.PlatformDefault = False - TabOrder = 5 - object StatusLbl: TLabel - Align = Client - Margins.Left = 5.000000000000000000 - Margins.Right = 50.000000000000000000 - Size.Width = 745.000000000000000000 - Size.Height = 22.000000000000000000 - Size.PlatformDefault = False - TabOrder = 0 - end - end - object chrmosr: TFMXChromium - OnLoadError = chrmosrLoadError - OnLoadingStateChange = chrmosrLoadingStateChange - OnTooltip = chrmosrTooltip - OnCursorChange = chrmosrCursorChange - OnBeforePopup = chrmosrBeforePopup - OnAfterCreated = chrmosrAfterCreated - OnBeforeClose = chrmosrBeforeClose - OnGetViewRect = chrmosrGetViewRect - OnGetScreenPoint = chrmosrGetScreenPoint - OnGetScreenInfo = chrmosrGetScreenInfo - OnPopupShow = chrmosrPopupShow - OnPopupSize = chrmosrPopupSize - OnPaint = chrmosrPaint - Left = 40 - Top = 73 - end -end diff --git a/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/uFMXExternalPumpBrowser.pas b/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/uFMXExternalPumpBrowser.pas deleted file mode 100644 index f7f6d9ad..00000000 --- a/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser/uFMXExternalPumpBrowser.pas +++ /dev/null @@ -1,915 +0,0 @@ -// ************************************************************************ -// ***************************** 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 - * 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 uFMXExternalPumpBrowser; - -{$I cef.inc} - -interface - -uses - {$IFDEF MSWINDOWS}WinApi.Windows,{$ENDIF} - System.Types, System.UITypes, System.Classes, System.SyncObjs, - FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.Edit, FMX.StdCtrls, - FMX.Controls.Presentation, FMX.Graphics, FMX.Layouts, FMX.DialogService, - uCEFFMXChromium, uCEFFMXBufferPanel, uCEFFMXWorkScheduler, - uCEFInterfaces, uCEFTypes, uCEFConstants, uCEFChromiumCore; - -type - TFMXExternalPumpBrowserFrm = class(TForm) - AddressPnl: TPanel; - AddressEdt: TEdit; - chrmosr: TFMXChromium; - Timer1: TTimer; - SaveDialog1: TSaveDialog; - Panel1: TFMXBufferPanel; - Layout1: TLayout; - GoBtn: TButton; - SnapshotBtn: TButton; - StatusBar1: TStatusBar; - StatusLbl: TLabel; - - procedure GoBtnClick(Sender: TObject); - procedure GoBtnEnter(Sender: TObject); - - procedure Panel1Enter(Sender: TObject); - procedure Panel1Exit(Sender: TObject); - procedure Panel1Resize(Sender: TObject); - procedure Panel1Click(Sender: TObject); - procedure Panel1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); - procedure Panel1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); - procedure Panel1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single); - procedure Panel1MouseLeave(Sender: TObject); - procedure Panel1MouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; var Handled: Boolean); - procedure Panel1KeyDown(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState); - procedure Panel1DialogKey(Sender: TObject; var Key: Word; Shift: TShiftState); - - procedure FormCreate(Sender: TObject); - procedure FormDestroy(Sender: TObject); - procedure FormActivate(Sender: TObject); - procedure FormShow(Sender: TObject); - procedure FormHide(Sender: TObject); - procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); - - procedure chrmosrPaint(Sender: TObject; const browser: ICefBrowser; type_: TCefPaintElementType; dirtyRectsCount: NativeUInt; const dirtyRects: PCefRectArray; const buffer: Pointer; width, height: Integer); - procedure chrmosrGetViewRect(Sender: TObject; const browser: ICefBrowser; var rect: TCefRect); - procedure chrmosrGetScreenPoint(Sender: TObject; const browser: ICefBrowser; viewX, viewY: Integer; var screenX, screenY: Integer; out Result: Boolean); - procedure chrmosrGetScreenInfo(Sender: TObject; const browser: ICefBrowser; var screenInfo: TCefScreenInfo; out Result: Boolean); - procedure chrmosrPopupShow(Sender: TObject; const browser: ICefBrowser; show: Boolean); - procedure chrmosrPopupSize(Sender: TObject; const browser: ICefBrowser; const rect: PCefRect); - procedure chrmosrBeforeClose(Sender: TObject; const browser: ICefBrowser); - procedure chrmosrTooltip(Sender: TObject; const browser: ICefBrowser; var text: ustring; out Result: Boolean); - procedure chrmosrBeforePopup(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 chrmosrAfterCreated(Sender: TObject; const browser: ICefBrowser); - procedure chrmosrCursorChange(Sender: TObject; const browser: ICefBrowser; cursor_: TCefCursorHandle; cursorType: TCefCursorType; const customCursorInfo: PCefCursorInfo; var aResult: Boolean); - procedure chrmosrLoadingStateChange(Sender: TObject; const browser: ICefBrowser; isLoading, canGoBack, canGoForward: Boolean); - procedure chrmosrLoadError(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; errorCode: Integer; const errorText, failedUrl: ustring); - - procedure Timer1Timer(Sender: TObject); - procedure AddressEdtEnter(Sender: TObject); - - procedure SnapshotBtnClick(Sender: TObject); - procedure SnapshotBtnEnter(Sender: TObject); - - protected - FPopUpBitmap : TBitmap; - FPopUpRect : TRect; - FShowPopUp : boolean; - FResizing : boolean; - FPendingResize : boolean; - FCanClose : boolean; - FClosing : boolean; - FResizeCS : TCriticalSection; - {$IFDEF DELPHI17_UP} - FMouseWheelService : IFMXMouseService; - {$ENDIF} - - procedure LoadURL; - function getModifiers(Shift: TShiftState): TCefEventFlags; - function GetButton(Button: TMouseButton): TCefMouseButtonType; - function GetMousePosition(var aPoint : TPointF) : boolean; - - public - procedure DoResize; - procedure NotifyMoveOrResizeStarted; - procedure SendCaptureLostEvent; - procedure SetBounds(ALeft: Integer; ATop: Integer; AWidth: Integer; AHeight: Integer); override; - procedure SendCEFKeyEvent(const aCefEvent : TCefKeyEvent); - end; - -var - FMXExternalPumpBrowserFrm : TFMXExternalPumpBrowserFrm; - -procedure CreateGlobalCEFApp; - -// *************************** -// ********* WARNING ********* -// *************************** -// This is a demo for LINUX and it's in BETA state. -// It still has several features unimplemented!!! - - - -// This is a simple browser using FireMonkey components in OSR mode (off-screen rendering) -// and a external message pump. - -// All FMX applications using CEF4Delphi should add the $(FrameworkType) conditional define -// in the project options to avoid duplicated resources. -// This demo has that define in the menu option : -// Project -> Options -> Building -> Delphi compiler -> Conditional defines (All configurations) - -// This is the destruction sequence in OSR mode : -// 1- FormCloseQuery sets CanClose to the initial FCanClose value (False) and -// calls chrmosr.CloseBrowser(True). -// 2- chrmosr.CloseBrowser(True) will trigger chrmosr.OnClose and the default -// implementation will destroy the internal browser immediately, which will -// trigger the chrmosr.OnBeforeClose event. -// 3- chrmosr.OnBeforeClose sets FCanClose to True and enables the timer to -// close the form after a few milliseconds. - -implementation - -{$R *.fmx} - -uses - System.SysUtils, System.Math, System.IOUtils, - FMX.Platform, {$IFDEF LINUX}FMX.Platform.Linux,{$ENDIF} - uCEFApplication, uCEFWorkScheduler, uCEFMiscFunctions, uCEFLinuxTypes, - uCEFLinuxConstants, uCEFLinuxFunctions; - -{$IFDEF LINUX} -function GTKKeyPress(Widget: PGtkWidget; Event: PGdkEventKey; Data: gPointer) : GBoolean; cdecl; -var - TempCefEvent : TCefKeyEvent; -begin - if FMXExternalPumpBrowserFrm.Panel1.IsFocused then - begin - GdkEventKeyToCEFKeyEvent(Event, TempCefEvent); - - if (Event^._type = GDK_KEY_PRESS) then - begin - TempCefEvent.kind := KEYEVENT_RAWKEYDOWN; - FMXExternalPumpBrowserFrm.SendCEFKeyEvent(TempCefEvent); - TempCefEvent.kind := KEYEVENT_CHAR; - FMXExternalPumpBrowserFrm.SendCEFKeyEvent(TempCefEvent); - end - else - begin - TempCefEvent.kind := KEYEVENT_KEYUP; - FMXExternalPumpBrowserFrm.SendCEFKeyEvent(TempCefEvent); - end; - end; - - Result := True; -end; - -procedure ConnectKeyPressReleaseEvents(const aWidget : PGtkWidget); -begin - g_signal_connect(aWidget, 'key-press-event', TGCallback(@GTKKeyPress), nil); - g_signal_connect(aWidget, 'key-release-event', TGCallback(@GTKKeyPress), nil); -end; -{$ENDIF} - -procedure GlobalCEFApp_OnScheduleMessagePumpWork(const aDelayMS : int64); -begin - if (GlobalCEFWorkScheduler <> nil) then - GlobalCEFWorkScheduler.ScheduleMessagePumpWork(aDelayMS); -end; - -procedure CreateGlobalCEFApp; -begin - // TCEFWorkScheduler will call cef_do_message_loop_work when - // it's told in the GlobalCEFApp.OnScheduleMessagePumpWork event. - // GlobalCEFWorkScheduler needs to be created before the - // GlobalCEFApp.StartMainProcess call. - // We use CreateDelayed in order to have a single thread in the process while - // CEF is initialized. - GlobalCEFWorkScheduler := TCEFWorkScheduler.CreateDelayed; - - GlobalCEFApp := TCefApplication.Create; - GlobalCEFApp.WindowlessRenderingEnabled := True; - GlobalCEFApp.EnableHighDPISupport := True; - GlobalCEFApp.ExternalMessagePump := True; - GlobalCEFApp.MultiThreadedMessageLoop := False; - GlobalCEFApp.DisableZygote := True; - GlobalCEFApp.OnScheduleMessagePumpWork := GlobalCEFApp_OnScheduleMessagePumpWork; - - // You can deploy the CEF binaries with the executable or you can set these - // properties to use the CEF binaries in your home directory - GlobalCEFApp.FrameworkDirPath := TPath.GetHomePath + TPath.DirectorySeparatorChar + 'cef'; - GlobalCEFApp.ResourcesDirPath := GlobalCEFApp.FrameworkDirPath; - GlobalCEFApp.LocalesDirPath := GlobalCEFApp.FrameworkDirPath + TPath.DirectorySeparatorChar + 'locales'; - - // This is a workaround to fix a Chromium initialization crash. - // The current FMX solution to initialize CEF with a loader unit - // creates a race condition with the media key controller in Chromium. - GlobalCEFApp.DisableFeatures := 'HardwareMediaKeyHandling'; -end; - -procedure TFMXExternalPumpBrowserFrm.FormActivate(Sender: TObject); -var - TempError : string; -begin - if not(FCanClose) and ((GlobalCEFApp = nil) or not(GlobalCEFApp.LibLoaded)) then - begin - FCanClose := True; - FClosing := True; - TempError := 'CEF binaries missing!'; - - if (GlobalCEFApp = nil) then - TempError := TempError + CRLF + CRLF + 'GlobalCEFApp was not created!' - else - if (length(GlobalCEFApp.MissingLibFiles) > 0) then - TempError := TempError + CRLF + CRLF + - 'The missing files are :' + CRLF + - trim(GlobalCEFApp.MissingLibFiles); - - TDialogService.MessageDialog(TempError, TMsgDlgType.mtError, - [TMsgDlgBtn.mbOK], TMsgDlgBtn.mbOK, 0, - procedure(const AResult: TModalResult) - begin - Timer1.Enabled := True; - end); - end - else - if not(chrmosr.Initialized) then - begin - {$IFDEF LINUX} - ConnectKeyPressReleaseEvents(TLinuxWindowHandle(Handle).NativeHandle); - {$ENDIF} - - // opaque white background color - chrmosr.Options.BackgroundColor := CefColorSetARGB($FF, $FF, $FF, $FF); - - if not(chrmosr.CreateBrowser) then Timer1.Enabled := True; - end; -end; - -procedure TFMXExternalPumpBrowserFrm.FormCloseQuery(Sender: TObject; var CanClose: Boolean); -begin - CanClose := FCanClose; - - if not(FClosing) then - begin - FClosing := True; - Visible := False; - AddressPnl.Enabled := False; - chrmosr.CloseBrowser(True); - end; -end; - -procedure TFMXExternalPumpBrowserFrm.FormCreate(Sender: TObject); -begin - FPopUpBitmap := nil; - FPopUpRect := rect(0, 0, 0, 0); - FShowPopUp := False; - FResizing := False; - FPendingResize := False; - FCanClose := False; - FClosing := False; - FResizeCS := TCriticalSection.Create; - - chrmosr.DefaultURL := AddressEdt.Text; - - {$IFDEF DELPHI17_UP} - if TPlatformServices.Current.SupportsPlatformService(IFMXMouseService) then - FMouseWheelService := TPlatformServices.Current.GetPlatformService(IFMXMouseService) as IFMXMouseService; - {$ENDIF} -end; - -procedure TFMXExternalPumpBrowserFrm.FormDestroy(Sender: TObject); -begin - FResizeCS.Free; - if (FPopUpBitmap <> nil) then FreeAndNil(FPopUpBitmap); -end; - -procedure TFMXExternalPumpBrowserFrm.FormHide(Sender: TObject); -begin - chrmosr.SendFocusEvent(False); - chrmosr.WasHidden(True); -end; - -procedure TFMXExternalPumpBrowserFrm.FormShow(Sender: TObject); -begin - chrmosr.WasHidden(False); - chrmosr.SendFocusEvent(True); -end; - -procedure TFMXExternalPumpBrowserFrm.GoBtnClick(Sender: TObject); -begin - LoadURL; -end; - -procedure TFMXExternalPumpBrowserFrm.LoadURL; -begin - FResizeCS.Acquire; - FResizing := False; - FPendingResize := False; - FResizeCS.Release; - - chrmosr.LoadURL(AddressEdt.Text); -end; - -procedure TFMXExternalPumpBrowserFrm.GoBtnEnter(Sender: TObject); -begin - chrmosr.SendFocusEvent(False); -end; - -procedure TFMXExternalPumpBrowserFrm.Panel1Click(Sender: TObject); -begin - Panel1.SetFocus; -end; - -procedure TFMXExternalPumpBrowserFrm.Panel1DialogKey(Sender: TObject; - var Key: Word; Shift: TShiftState); -begin - if (Key = vkTab) then Key := 0; -end; - -procedure TFMXExternalPumpBrowserFrm.Panel1Enter(Sender: TObject); -begin - chrmosr.SendFocusEvent(True); -end; - -procedure TFMXExternalPumpBrowserFrm.Panel1Exit(Sender: TObject); -begin - chrmosr.SendFocusEvent(False); -end; - -procedure TFMXExternalPumpBrowserFrm.Panel1KeyDown( Sender : TObject; - var Key : Word; - var KeyChar : Char; - Shift : TShiftState); -var - TempKeyEvent : TCefKeyEvent; -begin - if not(Panel1.IsFocused) then exit; - - if (Key = 0) and (KeyChar <> #0) then - begin - TempKeyEvent.kind := KEYEVENT_CHAR; - TempKeyEvent.modifiers := getModifiers(Shift); - TempKeyEvent.windows_key_code := ord(KeyChar); - TempKeyEvent.native_key_code := 0; - TempKeyEvent.is_system_key := ord(False); - TempKeyEvent.character := #0; - TempKeyEvent.unmodified_character := #0; - TempKeyEvent.focus_on_editable_field := ord(False); - - chrmosr.SendKeyEvent(@TempKeyEvent); - end - else - if (Key <> 0) and (KeyChar = #0) and - (Key in [vkLeft, vkRight, vkUp, vkDown]) then - Key := 0; -end; - -procedure TFMXExternalPumpBrowserFrm.Panel1MouseDown(Sender : TObject; - Button : TMouseButton; - Shift : TShiftState; - X, Y : Single); -var - TempEvent : TCefMouseEvent; -begin - if not(ssTouch in Shift) then - begin - Panel1.SetFocus; - - TempEvent.x := round(X); - TempEvent.y := round(Y); - TempEvent.modifiers := getModifiers(Shift); - chrmosr.SendMouseClickEvent(@TempEvent, GetButton(Button), False, 1); - end; -end; - -function TFMXExternalPumpBrowserFrm.GetMousePosition(var aPoint : TPointF) : boolean; -begin - if (FMouseWheelService <> nil) then - begin - aPoint := FMouseWheelService.GetMousePos; - Result := True; - end - else - begin - aPoint.x := 0; - aPoint.y := 0; - Result := False; - end; -end; - -procedure TFMXExternalPumpBrowserFrm.Panel1MouseLeave(Sender: TObject); -var - TempEvent : TCefMouseEvent; - TempPoint : TPointF; -begin - if GetMousePosition(TempPoint) then - begin - TempPoint := Panel1.ScreenToClient(TempPoint); - - TempEvent.x := round(TempPoint.x); - TempEvent.y := round(TempPoint.y); - TempEvent.modifiers := EVENTFLAG_NONE; - chrmosr.SendMouseMoveEvent(@TempEvent, True); - end; -end; - -procedure TFMXExternalPumpBrowserFrm.Panel1MouseMove(Sender : TObject; - Shift : TShiftState; - X, Y : Single); -var - TempEvent : TCefMouseEvent; -begin - if not(ssTouch in Shift) then - begin - TempEvent.x := round(x); - TempEvent.y := round(y); - TempEvent.modifiers := getModifiers(Shift); - chrmosr.SendMouseMoveEvent(@TempEvent, False); - end; -end; - -procedure TFMXExternalPumpBrowserFrm.Panel1MouseUp(Sender : TObject; - Button : TMouseButton; - Shift : TShiftState; - X, Y : Single); -var - TempEvent : TCefMouseEvent; -begin - if not(ssTouch in Shift) then - begin - TempEvent.x := round(X); - TempEvent.y := round(Y); - TempEvent.modifiers := getModifiers(Shift); - chrmosr.SendMouseClickEvent(@TempEvent, GetButton(Button), True, 1); - end; -end; - -procedure TFMXExternalPumpBrowserFrm.Panel1MouseWheel( Sender : TObject; - Shift : TShiftState; - WheelDelta : Integer; - var Handled : Boolean); -var - TempEvent : TCefMouseEvent; - TempPoint : TPointF; -begin - if Panel1.IsFocused and GetMousePosition(TempPoint) then - begin - TempPoint := Panel1.ScreenToClient(TempPoint); - TempEvent.x := round(TempPoint.x); - TempEvent.y := round(TempPoint.y); - TempEvent.modifiers := getModifiers(Shift); - chrmosr.SendMouseWheelEvent(@TempEvent, 0, WheelDelta); - end; -end; - -procedure TFMXExternalPumpBrowserFrm.Panel1Resize(Sender: TObject); -begin - DoResize; -end; - -procedure TFMXExternalPumpBrowserFrm.Timer1Timer(Sender: TObject); -begin - Timer1.Enabled := False; - - if FClosing then - close - else - if not(chrmosr.CreateBrowser) and not(chrmosr.Initialized) then - Timer1.Enabled := True; -end; - -procedure TFMXExternalPumpBrowserFrm.AddressEdtEnter(Sender: TObject); -begin - chrmosr.SendFocusEvent(False); -end; - -procedure TFMXExternalPumpBrowserFrm.chrmosrAfterCreated(Sender: TObject; const browser: ICefBrowser); -begin - // Now the browser is fully initialized we can enable the UI. - Caption := 'FMX External Pump Browser'; - AddressPnl.Enabled := True; - Panel1.SetFocus; -end; - -procedure TFMXExternalPumpBrowserFrm.chrmosrBeforeClose(Sender: TObject; const browser: ICefBrowser); -begin - FCanClose := True; - // We need to close the form outside this event so we use the timer - Timer1.Enabled := True; -end; - -procedure TFMXExternalPumpBrowserFrm.chrmosrBeforePopup( Sender : TObject; - const browser : ICefBrowser; - const frame : ICefFrame; - const targetUrl : ustring; - const 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 - // For simplicity, this demo blocks all popup windows and new tabs - Result := (targetDisposition in [WOD_NEW_FOREGROUND_TAB, WOD_NEW_BACKGROUND_TAB, WOD_NEW_POPUP, WOD_NEW_WINDOW]); -end; - -procedure TFMXExternalPumpBrowserFrm.chrmosrCursorChange( Sender : TObject; - const browser : ICefBrowser; - cursor_ : TCefCursorHandle; - cursorType : TCefCursorType; - const customCursorInfo : PCefCursorInfo; - var aResult : Boolean); -begin - Panel1.Cursor := CefCursorToWindowsCursor(cursorType); - aResult := True; -end; - -procedure TFMXExternalPumpBrowserFrm.chrmosrGetScreenInfo( Sender : TObject; - const browser : ICefBrowser; - var screenInfo : TCefScreenInfo; - out Result : Boolean); -var - TempRect : TCEFRect; -begin - TempRect.x := 0; - TempRect.y := 0; - TempRect.width := round(Panel1.Width); - TempRect.height := round(Panel1.Height); - - screenInfo.device_scale_factor := Panel1.ScreenScale; - screenInfo.depth := 0; - screenInfo.depth_per_component := 0; - screenInfo.is_monochrome := Ord(False); - screenInfo.rect := TempRect; - screenInfo.available_rect := TempRect; - - Result := True; -end; - -procedure TFMXExternalPumpBrowserFrm.chrmosrGetScreenPoint( Sender : TObject; - const browser : ICefBrowser; - viewX : Integer; - viewY : Integer; - var screenX : Integer; - var screenY : Integer; - out Result : Boolean); -var - TempScreenPt, TempViewPt : TPoint; -begin - // TFMXBufferPanel.ClientToScreen applies the scale factor. No need to call LogicalToDevice to set TempViewPt. - TempViewPt.x := viewX; - TempViewPt.y := viewY; - TempScreenPt := Panel1.ClientToScreen(TempViewPt); - screenX := TempScreenPt.x; - screenY := TempScreenPt.y; - Result := True; -end; - -procedure TFMXExternalPumpBrowserFrm.chrmosrGetViewRect( Sender : TObject; - const browser : ICefBrowser; - var rect : TCefRect); -begin - rect.x := 0; - rect.y := 0; - rect.width := round(Panel1.Width); - rect.height := round(Panel1.Height); -end; - -procedure TFMXExternalPumpBrowserFrm.chrmosrLoadError(Sender: TObject; - const browser: ICefBrowser; const frame: ICefFrame; errorCode: Integer; - const errorText, failedUrl: ustring); -var - TempString : ustring; -begin - if (errorCode = ERR_ABORTED) then exit; - - TempString := '' + - '

Failed to load URL ' + failedUrl + - ' with error ' + errorText + - ' (' + inttostr(errorCode) + ').

'; - - chrmosr.LoadString(TempString, frame); -end; - -procedure TFMXExternalPumpBrowserFrm.chrmosrLoadingStateChange(Sender: TObject; - const browser: ICefBrowser; isLoading, canGoBack, canGoForward: Boolean); -begin - if isLoading then - StatusLbl.Text := 'Loading...' - else - StatusLbl.Text := ''; -end; - -procedure TFMXExternalPumpBrowserFrm.chrmosrPaint( Sender : TObject; - const browser : ICefBrowser; - type_ : TCefPaintElementType; - dirtyRectsCount : NativeUInt; - const dirtyRects : PCefRectArray; - const buffer : Pointer; - width : Integer; - height : Integer); -var - src, dst: PByte; - i, j, TempLineSize, TempSrcOffset, TempDstOffset, SrcStride, TempWidth, TempHeight : Integer; - n : NativeUInt; - {$IFNDEF DELPHI17_UP} - TempScanlineSize, DstStride : integer; - {$ENDIF} - TempBufferBits : Pointer; - TempForcedResize : boolean; - TempBitmapData : TBitmapData; - TempBitmap : TBitmap; - TempSrcRect, TempDstRect : TRectF; -begin - try - FResizeCS.Acquire; - TempForcedResize := False; - - if Panel1.BeginBufferDraw then - try - if (type_ = PET_POPUP) then - begin - if (FPopUpBitmap = nil) or - (width <> FPopUpBitmap.Width) or - (height <> FPopUpBitmap.Height) then - begin - if (FPopUpBitmap <> nil) then FPopUpBitmap.Free; - - FPopUpBitmap := TBitmap.Create(width, height); - {$IFDEF DELPHI17_UP} - FPopUpBitmap.BitmapScale := Panel1.ScreenScale; - {$ENDIF} - end; - - TempWidth := FPopUpBitmap.Width; - TempHeight := FPopUpBitmap.Height; - {$IFNDEF DELPHI17_UP} - TempScanlineSize := FPopUpBitmap.BytesPerLine; - {$ENDIF} - TempBitmap := FPopUpBitmap; - end - else - begin - TempForcedResize := Panel1.UpdateBufferDimensions(Width, Height) or not(Panel1.BufferIsResized(False)); - TempWidth := Panel1.BufferWidth; - TempHeight := Panel1.BufferHeight; - {$IFNDEF DELPHI17_UP} - TempScanlineSize := Panel1.ScanlineSize; - {$ENDIF} - TempBitmap := Panel1.Buffer; - end; - - - if (TempBitmap <> nil) {$IFDEF DELPHI17_UP}and TempBitmap.Map(TMapAccess.ReadWrite, TempBitmapData){$ENDIF} then - begin - try - {$IFNDEF DELPHI17_UP} - TempBufferBits := TempBitmapData.StartLine; - DstStride := TempScanlineSize; - {$ENDIF} - SrcStride := Width * SizeOf(TRGBQuad); - - n := 0; - - while (n < dirtyRectsCount) do - begin - if (dirtyRects[n].x >= 0) and (dirtyRects[n].y >= 0) then - begin - TempLineSize := min(dirtyRects[n].width, TempWidth - dirtyRects[n].x) * SizeOf(TRGBQuad); - - if (TempLineSize > 0) then - begin - TempSrcOffset := ((dirtyRects[n].y * Width) + dirtyRects[n].x) * SizeOf(TRGBQuad); - - {$IFDEF DELPHI17_UP} - TempDstOffset := (dirtyRects[n].x * SizeOf(TRGBQuad)); - {$ELSE} - TempDstOffset := (dirtyRects[n].y * TempScanlineSize) + (dirtyRects[n].x * SizeOf(TRGBQuad)); - {$ENDIF} - - src := @PByte(buffer)[TempSrcOffset]; - {$IFNDEF DELPHI17_UP} - dst := @PByte(TempBufferBits)[TempDstOffset]; - {$ENDIF} - - i := 0; - j := min(dirtyRects[n].height, TempHeight - dirtyRects[n].y); - - while (i < j) do - begin - {$IFDEF DELPHI17_UP} - TempBufferBits := TempBitmapData.GetScanline(dirtyRects[n].y + i); - dst := @PByte(TempBufferBits)[TempDstOffset]; - {$ENDIF} - - Move(src^, dst^, TempLineSize); - - {$IFNDEF DELPHI17_UP} - inc(dst, DstStride); - {$ENDIF} - inc(src, SrcStride); - inc(i); - end; - end; - end; - - inc(n); - end; - - Panel1.InvalidatePanel; - finally - {$IFDEF DELPHI17_UP} - TempBitmap.Unmap(TempBitmapData); - {$ENDIF} - end; - - if FShowPopup and (FPopUpBitmap <> nil) then - begin - TempSrcRect := RectF(0, 0, - min(FPopUpRect.Width, FPopUpBitmap.Width), - min(FPopUpRect.Height, FPopUpBitmap.Height)); - - TempDstRect.Left := FPopUpRect.Left / GlobalCEFApp.DeviceScaleFactor; - TempDstRect.Top := FPopUpRect.Top / GlobalCEFApp.DeviceScaleFactor; - TempDstRect.Right := TempDstRect.Left + (TempSrcRect.Width / GlobalCEFApp.DeviceScaleFactor); - TempDstRect.Bottom := TempDstRect.Top + (TempSrcRect.Height / GlobalCEFApp.DeviceScaleFactor); - - Panel1.BufferDraw(FPopUpBitmap, TempSrcRect, TempDstRect); - end; - end; - - if (type_ = PET_VIEW) then - begin - if TempForcedResize or FPendingResize then - TThread.Queue(nil, DoResize); - - FResizing := False; - FPendingResize := False; - end; - finally - Panel1.EndBufferDraw; - end; - finally - FResizeCS.Release; - end; -end; - -procedure TFMXExternalPumpBrowserFrm.chrmosrPopupShow( Sender : TObject; - const browser : ICefBrowser; - show : Boolean); -begin - if show then - FShowPopUp := True - else - begin - FShowPopUp := False; - FPopUpRect := rect(0, 0, 0, 0); - - chrmosr.Invalidate(PET_VIEW); - end; -end; - -procedure TFMXExternalPumpBrowserFrm.chrmosrPopupSize( Sender : TObject; - const browser : ICefBrowser; - const rect : PCefRect); -begin - if (GlobalCEFApp <> nil) then - begin - LogicalToDevice(rect^, GlobalCEFApp.DeviceScaleFactor); - - FPopUpRect.Left := rect.x; - FPopUpRect.Top := rect.y; - FPopUpRect.Right := rect.x + rect.width - 1; - FPopUpRect.Bottom := rect.y + rect.height - 1; - end; -end; - -procedure TFMXExternalPumpBrowserFrm.chrmosrTooltip( Sender : TObject; - const browser : ICefBrowser; - var text : ustring; - out Result : Boolean); -begin - Panel1.Hint := text; - Panel1.ShowHint := (length(text) > 0); - Result := True; -end; - -procedure TFMXExternalPumpBrowserFrm.DoResize; -begin - try - if (FResizeCS <> nil) then - begin - FResizeCS.Acquire; - - if FResizing then - FPendingResize := True - else - if Panel1.BufferIsResized then - chrmosr.Invalidate(PET_VIEW) - else - begin - FResizing := True; - chrmosr.WasResized; - end; - end; - finally - if (FResizeCS <> nil) then FResizeCS.Release; - end; -end; - -procedure TFMXExternalPumpBrowserFrm.SetBounds(ALeft, ATop, AWidth, AHeight: Integer); -var - PositionChanged: Boolean; -begin - PositionChanged := (ALeft <> Left) or (ATop <> Top); - - inherited SetBounds(ALeft, ATop, AWidth, AHeight); - - if PositionChanged then NotifyMoveOrResizeStarted; -end; - -procedure TFMXExternalPumpBrowserFrm.SendCEFKeyEvent(const aCefEvent : TCefKeyEvent); -begin - chrmosr.SendKeyEvent(@aCefEvent); -end; - -procedure TFMXExternalPumpBrowserFrm.NotifyMoveOrResizeStarted; -begin - if (chrmosr <> nil) then chrmosr.NotifyMoveOrResizeStarted; -end; - -procedure TFMXExternalPumpBrowserFrm.SendCaptureLostEvent; -begin - if (chrmosr <> nil) then chrmosr.SendCaptureLostEvent; -end; - -function TFMXExternalPumpBrowserFrm.getModifiers(Shift: TShiftState): TCefEventFlags; -begin - Result := EVENTFLAG_NONE; - - if (ssShift in Shift) then Result := Result or EVENTFLAG_SHIFT_DOWN; - if (ssAlt in Shift) then Result := Result or EVENTFLAG_ALT_DOWN; - if (ssCtrl in Shift) then Result := Result or EVENTFLAG_CONTROL_DOWN; - if (ssLeft in Shift) then Result := Result or EVENTFLAG_LEFT_MOUSE_BUTTON; - if (ssRight in Shift) then Result := Result or EVENTFLAG_RIGHT_MOUSE_BUTTON; - if (ssMiddle in Shift) then Result := Result or EVENTFLAG_MIDDLE_MOUSE_BUTTON; -end; - -function TFMXExternalPumpBrowserFrm.GetButton(Button: TMouseButton): TCefMouseButtonType; -begin - case Button of - TMouseButton.mbRight : Result := MBT_RIGHT; - TMouseButton.mbMiddle : Result := MBT_MIDDLE; - else Result := MBT_LEFT; - end; -end; - -procedure TFMXExternalPumpBrowserFrm.SnapshotBtnClick(Sender: TObject); -begin - if SaveDialog1.Execute then Panel1.SaveToFile(SaveDialog1.FileName); -end; - -procedure TFMXExternalPumpBrowserFrm.SnapshotBtnEnter(Sender: TObject); -begin - chrmosr.SendFocusEvent(False); -end; - -end. diff --git a/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser2/FMXExternalPumpBrowser2_sp.dpr b/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser2/FMXExternalPumpBrowser2_sp.dpr index d55969a1..bdb34b70 100644 --- a/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser2/FMXExternalPumpBrowser2_sp.dpr +++ b/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser2/FMXExternalPumpBrowser2_sp.dpr @@ -43,7 +43,7 @@ program FMXExternalPumpBrowser2_sp; uses System.IOUtils, - uCEFApplicationCore; + uCEFApplicationCore, uCEFConstants; begin GlobalCEFApp := TCefApplicationCore.Create; @@ -52,12 +52,19 @@ begin GlobalCEFApp.ExternalMessagePump := True; GlobalCEFApp.MultiThreadedMessageLoop := False; + // Use these settings if you already have the CEF binaries in a directory called "cef" inside your home directory. + // You can also use the "Deployment" window but debugging might be slower. GlobalCEFApp.FrameworkDirPath := TPath.GetHomePath + TPath.DirectorySeparatorChar + 'cef'; GlobalCEFApp.ResourcesDirPath := GlobalCEFApp.FrameworkDirPath; GlobalCEFApp.LocalesDirPath := GlobalCEFApp.FrameworkDirPath + TPath.DirectorySeparatorChar + 'locales'; GlobalCEFApp.cache := GlobalCEFApp.FrameworkDirPath + TPath.DirectorySeparatorChar + 'cache'; GlobalCEFApp.UserDataPath := GlobalCEFApp.FrameworkDirPath + TPath.DirectorySeparatorChar + 'User Data'; + {$IFDEF DEBUG} + GlobalCEFApp.LogFile := TPath.GetHomePath + TPath.DirectorySeparatorChar + 'debug.log'; + GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO; + {$ENDIF} + // This is a workaround to fix a Chromium initialization crash. // The current FMX solution to initialize CEF with a loader unit // creates a race condition with the media key controller in Chromium. diff --git a/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser2/uCEFLoader.pas b/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser2/uCEFLoader.pas index a3e30f06..6b8c1452 100644 --- a/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser2/uCEFLoader.pas +++ b/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser2/uCEFLoader.pas @@ -48,10 +48,21 @@ uses // Read the answer to this question for more more information : // https://stackoverflow.com/questions/52103407/changing-the-initialization-order-of-the-unit-in-delphi System.IOUtils, - uCEFApplication, uCEFConstants, uCEFWorkScheduler; + uCEFApplication, uCEFConstants, uCEFWorkScheduler, uCEFLinuxFunctions, + uCEFLinuxTypes; implementation +function CustomX11ErrorHandler(Display:PDisplay; ErrorEv:PXErrorEvent):longint;cdecl; +begin + Result := 0; +end; + +function CustomXIOErrorHandler(Display:PDisplay):longint;cdecl; +begin + Result := 0; +end; + procedure GlobalCEFApp_OnScheduleMessagePumpWork(const aDelayMS : int64); begin if (GlobalCEFWorkScheduler <> nil) then @@ -76,6 +87,8 @@ begin GlobalCEFApp.DisableZygote := True; GlobalCEFApp.OnScheduleMessagePumpWork := GlobalCEFApp_OnScheduleMessagePumpWork; + // Use these settings if you already have the CEF binaries in a directory called "cef" inside your home directory. + // You can also use the "Deployment" window but debugging might be slower. GlobalCEFApp.FrameworkDirPath := TPath.GetHomePath + TPath.DirectorySeparatorChar + 'cef'; GlobalCEFApp.ResourcesDirPath := GlobalCEFApp.FrameworkDirPath; GlobalCEFApp.LocalesDirPath := GlobalCEFApp.FrameworkDirPath + TPath.DirectorySeparatorChar + 'locales'; @@ -83,6 +96,11 @@ begin GlobalCEFApp.UserDataPath := GlobalCEFApp.FrameworkDirPath + TPath.DirectorySeparatorChar + 'User Data'; GlobalCEFApp.BrowserSubprocessPath := GlobalCEFApp.FrameworkDirPath + TPath.DirectorySeparatorChar + 'FMXExternalPumpBrowser2_sp'; + {$IFDEF DEBUG} + GlobalCEFApp.LogFile := TPath.GetHomePath + TPath.DirectorySeparatorChar + 'debug.log'; + GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO; + {$ENDIF} + // This is a workaround to fix a Chromium initialization crash. // The current FMX solution to initialize CEF with a loader unit // creates a race condition with the media key controller in Chromium. @@ -90,6 +108,11 @@ begin GlobalCEFApp.StartMainProcess; GlobalCEFWorkScheduler.CreateThread; + + // 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; initialization diff --git a/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser2/uFMXExternalPumpBrowser2.fmx b/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser2/uFMXExternalPumpBrowser2.fmx index 465c3fde..1df38569 100644 --- a/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser2/uFMXExternalPumpBrowser2.fmx +++ b/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser2/uFMXExternalPumpBrowser2.fmx @@ -17,6 +17,7 @@ object FMXExternalPumpBrowserFrm: TFMXExternalPumpBrowserFrm DesignerMasterStyle = 0 object AddressPnl: TPanel Align = Top + Enabled = False Padding.Left = 5.000000000000000000 Padding.Top = 5.000000000000000000 Padding.Right = 5.000000000000000000 @@ -24,7 +25,8 @@ object FMXExternalPumpBrowserFrm: TFMXExternalPumpBrowserFrm Size.Width = 800.000000000000000000 Size.Height = 33.000000000000000000 Size.PlatformDefault = False - TabOrder = 1 + TabOrder = 0 + TabStop = False object AddressEdt: TEdit Touch.InteractiveGestures = [LongTap, DoubleTap] Align = Client @@ -43,7 +45,8 @@ object FMXExternalPumpBrowserFrm: TFMXExternalPumpBrowserFrm Size.Width = 81.000000000000000000 Size.Height = 23.000000000000000000 Size.PlatformDefault = False - TabOrder = 2 + TabOrder = 1 + TabStop = False object GoBtn: TButton Align = Left Position.X = 5.000000000000000000 @@ -87,7 +90,7 @@ object FMXExternalPumpBrowserFrm: TFMXExternalPumpBrowserFrm end object Panel1: TFMXBufferPanel Align = Client - TabOrder = 0 + TabOrder = 1 CanFocus = True Size.Width = 800.000000000000000000 Size.Height = 578.000000000000000000 @@ -101,8 +104,6 @@ object FMXExternalPumpBrowserFrm: TFMXExternalPumpBrowserFrm OnMouseUp = Panel1MouseUp OnMouseLeave = Panel1MouseLeave OnMouseWheel = Panel1MouseWheel - OnKeyDown = Panel1KeyDown - OnDialogKey = Panel1DialogKey end object StatusBar1: TStatusBar Position.Y = 611.000000000000000000 diff --git a/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser2/uFMXExternalPumpBrowser2.pas b/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser2/uFMXExternalPumpBrowser2.pas index 9d50fddc..ff45583a 100644 --- a/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser2/uFMXExternalPumpBrowser2.pas +++ b/demos/Delphi_FMX_Linux/FMXExternalPumpBrowser2/uFMXExternalPumpBrowser2.pas @@ -34,9 +34,7 @@ * this source code without explicit permission. * *) - unit uFMXExternalPumpBrowser2; - {$I cef.inc} interface @@ -74,8 +72,6 @@ type procedure Panel1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single); procedure Panel1MouseLeave(Sender: TObject); procedure Panel1MouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; var Handled: Boolean); - procedure Panel1KeyDown(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState); - procedure Panel1DialogKey(Sender: TObject; var Key: Word; Shift: TShiftState); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); @@ -121,7 +117,6 @@ type function getModifiers(Shift: TShiftState): TCefEventFlags; function GetButton(Button: TMouseButton): TCefMouseButtonType; function GetMousePosition(var aPoint : TPointF) : boolean; - public procedure DoResize; procedure NotifyMoveOrResizeStarted; @@ -136,11 +131,9 @@ var // *************************** // ********* WARNING ********* // *************************** -// This is a demo for LINUX and it's in BETA state. +// This is a demo for LINUX and it's in ALPHA state. // It still has several features unimplemented!!! - - // This is a simple browser using FireMonkey components in OSR mode (off-screen rendering) // and a external message pump. @@ -187,9 +180,11 @@ begin TempCefEvent.kind := KEYEVENT_KEYUP; FMXExternalPumpBrowserFrm.SendCEFKeyEvent(TempCefEvent); end; - end; - Result := True; + Result := True; + end + else + Result := False; end; procedure ConnectKeyPressReleaseEvents(const aWidget : PGtkWidget); @@ -231,7 +226,8 @@ begin // opaque white background color chrmosr.Options.BackgroundColor := CefColorSetARGB($FF, $FF, $FF, $FF); - if not(chrmosr.CreateBrowser) then Timer1.Enabled := True; + if not(chrmosr.CreateBrowser) then + Timer1.Enabled := True; end; end; @@ -302,7 +298,7 @@ end; procedure TFMXExternalPumpBrowserFrm.GoBtnEnter(Sender: TObject); begin - chrmosr.SendFocusEvent(False); + if (chrmosr <> nil) then chrmosr.SendFocusEvent(False); end; procedure TFMXExternalPumpBrowserFrm.Panel1Click(Sender: TObject); @@ -310,48 +306,14 @@ begin Panel1.SetFocus; end; -procedure TFMXExternalPumpBrowserFrm.Panel1DialogKey(Sender: TObject; - var Key: Word; Shift: TShiftState); -begin - if (Key = vkTab) then Key := 0; -end; - procedure TFMXExternalPumpBrowserFrm.Panel1Enter(Sender: TObject); begin - chrmosr.SendFocusEvent(True); + if (chrmosr <> nil) then chrmosr.SendFocusEvent(True); end; procedure TFMXExternalPumpBrowserFrm.Panel1Exit(Sender: TObject); begin - chrmosr.SendFocusEvent(False); -end; - -procedure TFMXExternalPumpBrowserFrm.Panel1KeyDown( Sender : TObject; - var Key : Word; - var KeyChar : Char; - Shift : TShiftState); -var - TempKeyEvent : TCefKeyEvent; -begin - if not(Panel1.IsFocused) then exit; - - if (Key = 0) and (KeyChar <> #0) then - begin - TempKeyEvent.kind := KEYEVENT_CHAR; - TempKeyEvent.modifiers := getModifiers(Shift); - TempKeyEvent.windows_key_code := ord(KeyChar); - TempKeyEvent.native_key_code := 0; - TempKeyEvent.is_system_key := ord(False); - TempKeyEvent.character := #0; - TempKeyEvent.unmodified_character := #0; - TempKeyEvent.focus_on_editable_field := ord(False); - - chrmosr.SendKeyEvent(@TempKeyEvent); - end - else - if (Key <> 0) and (KeyChar = #0) and - (Key in [vkLeft, vkRight, vkUp, vkDown]) then - Key := 0; + if (chrmosr <> nil) then chrmosr.SendFocusEvent(False); end; procedure TFMXExternalPumpBrowserFrm.Panel1MouseDown(Sender : TObject; @@ -374,12 +336,14 @@ end; function TFMXExternalPumpBrowserFrm.GetMousePosition(var aPoint : TPointF) : boolean; begin + {$IFDEF DELPHI17_UP} if (FMouseWheelService <> nil) then begin aPoint := FMouseWheelService.GetMousePos; Result := True; end else + {$ENDIF} begin aPoint.x := 0; aPoint.y := 0; @@ -464,13 +428,14 @@ begin if FClosing then close else - if not(chrmosr.CreateBrowser) and not(chrmosr.Initialized) then + if not(chrmosr.CreateBrowser) then Timer1.Enabled := True; end; procedure TFMXExternalPumpBrowserFrm.AddressEdtEnter(Sender: TObject); begin - chrmosr.SendFocusEvent(False); + if (chrmosr <> nil) then + chrmosr.SendFocusEvent(False); end; procedure TFMXExternalPumpBrowserFrm.chrmosrAfterCreated(Sender: TObject; const browser: ICefBrowser); @@ -478,14 +443,15 @@ begin // Now the browser is fully initialized we can enable the UI. Caption := 'FMX External Pump Browser 2'; AddressPnl.Enabled := True; - Panel1.SetFocus; end; procedure TFMXExternalPumpBrowserFrm.chrmosrBeforeClose(Sender: TObject; const browser: ICefBrowser); begin FCanClose := True; - // We need to close the form outside this event so we use the timer - Timer1.Enabled := True; + TThread.ForceQueue(nil, procedure + begin + close; + end); end; procedure TFMXExternalPumpBrowserFrm.chrmosrBeforePopup( Sender : TObject; @@ -569,13 +535,17 @@ begin rect.height := round(Panel1.Height); end; -procedure TFMXExternalPumpBrowserFrm.chrmosrLoadError(Sender: TObject; - const browser: ICefBrowser; const frame: ICefFrame; errorCode: Integer; - const errorText, failedUrl: ustring); +procedure TFMXExternalPumpBrowserFrm.chrmosrLoadError( Sender : TObject; + const browser : ICefBrowser; + const frame : ICefFrame; + errorCode : Integer; + const errorText : ustring; + const failedUrl : ustring); var TempString : ustring; begin - if (errorCode = ERR_ABORTED) then exit; + if (errorCode = ERR_ABORTED) then + exit; TempString := '' + '

Failed to load URL ' + failedUrl + @@ -585,8 +555,11 @@ begin chrmosr.LoadString(TempString, frame); end; -procedure TFMXExternalPumpBrowserFrm.chrmosrLoadingStateChange(Sender: TObject; - const browser: ICefBrowser; isLoading, canGoBack, canGoForward: Boolean); +procedure TFMXExternalPumpBrowserFrm.chrmosrLoadingStateChange( Sender : TObject; + const browser : ICefBrowser; + isLoading : Boolean; + canGoBack : Boolean; + canGoForward : Boolean); begin if isLoading then StatusLbl.Text := 'Loading...' @@ -735,7 +708,7 @@ begin if (type_ = PET_VIEW) then begin if TempForcedResize or FPendingResize then - TThread.Queue(nil, DoResize); + TThread.ForceQueue(nil, DoResize); FResizing := False; FPendingResize := False; @@ -790,6 +763,9 @@ end; procedure TFMXExternalPumpBrowserFrm.DoResize; begin + if (chrmosr = nil) or not(chrmosr.Initialized) then + exit; + try if (FResizeCS <> nil) then begin diff --git a/demos/Delphi_FMX_Mac/FMXExternalPumpBrowser/FMXExternalPumpBrowser.dpr b/demos/Delphi_FMX_Mac/FMXExternalPumpBrowser/FMXExternalPumpBrowser.dpr index ab2a851b..e82489b6 100644 --- a/demos/Delphi_FMX_Mac/FMXExternalPumpBrowser/FMXExternalPumpBrowser.dpr +++ b/demos/Delphi_FMX_Mac/FMXExternalPumpBrowser/FMXExternalPumpBrowser.dpr @@ -46,9 +46,9 @@ uses FMX.Forms, uCEFApplication, uCEFFMXWorkScheduler, + uCEFMacOSFunctions, uFMXExternalPumpBrowser in 'uFMXExternalPumpBrowser.pas' {FMXExternalPumpBrowserFrm}, - uFMXApplicationService in 'uFMXApplicationService.pas', - uFMXMiscFunctions in 'uFMXMiscFunctions.pas'; + uFMXApplicationService in 'uFMXApplicationService.pas'; {$R *.res} diff --git a/demos/Delphi_FMX_Mac/FMXExternalPumpBrowser/FMXExternalPumpBrowser.dproj b/demos/Delphi_FMX_Mac/FMXExternalPumpBrowser/FMXExternalPumpBrowser.dproj index 214d38db..1a9cd265 100644 --- a/demos/Delphi_FMX_Mac/FMXExternalPumpBrowser/FMXExternalPumpBrowser.dproj +++ b/demos/Delphi_FMX_Mac/FMXExternalPumpBrowser/FMXExternalPumpBrowser.dproj @@ -160,7 +160,6 @@
FMXExternalPumpBrowserFrm
- Cfg_2 Base diff --git a/demos/Delphi_FMX_Mac/FMXExternalPumpBrowser/uFMXExternalPumpBrowser.fmx b/demos/Delphi_FMX_Mac/FMXExternalPumpBrowser/uFMXExternalPumpBrowser.fmx index 9da61602..a8d79bd6 100644 --- a/demos/Delphi_FMX_Mac/FMXExternalPumpBrowser/uFMXExternalPumpBrowser.fmx +++ b/demos/Delphi_FMX_Mac/FMXExternalPumpBrowser/uFMXExternalPumpBrowser.fmx @@ -93,7 +93,6 @@ object FMXExternalPumpBrowserFrm: TFMXExternalPumpBrowserFrm Size.Width = 800.000000000000000000 Size.Height = 600.000000000000000000 Size.PlatformDefault = False - OnResized = Panel1Resize OnEnter = Panel1Enter OnExit = Panel1Exit OnResize = Panel1Resize @@ -107,6 +106,58 @@ object FMXExternalPumpBrowserFrm: TFMXExternalPumpBrowserFrm OnKeyDown = Panel1KeyDown OnDialogKey = Panel1DialogKey end + object MainMenu1: TMainMenu + Left = 40 + Top = 273 + object EditMenu: TMenuItem + Text = 'Edit' + object UndoMenuItem: TMenuItem + Locked = True + ShortCut = 4186 + Text = 'Undo' + OnClick = UndoMenuItemClick + end + object RedoMenuItem: TMenuItem + Locked = True + ShortCut = 12378 + Text = 'Redo' + OnClick = RedoMenuItemClick + end + object SeparatorMenuItem: TMenuItem + Locked = True + Text = '-' + end + object CutMenuItem: TMenuItem + Locked = True + ShortCut = 4184 + Text = 'Cut' + OnClick = CutMenuItemClick + end + object CopyMenuItem: TMenuItem + Locked = True + ShortCut = 4163 + Text = 'Copy' + OnClick = CopyMenuItemClick + end + object PasteMenuItem: TMenuItem + Locked = True + ShortCut = 4182 + Text = 'Paste' + OnClick = PasteMenuItemClick + end + object DeleteMenuItem: TMenuItem + Locked = True + Text = 'Delete' + OnClick = DeleteMenuItemClick + end + object SelectAllMenuItem: TMenuItem + Locked = True + ShortCut = 4161 + Text = 'Select all' + OnClick = SelectAllMenuItemClick + end + end + end object chrmosr: TFMXChromium OnTooltip = chrmosrTooltip OnCursorChange = chrmosrCursorChange diff --git a/demos/Delphi_FMX_Mac/FMXExternalPumpBrowser/uFMXExternalPumpBrowser.pas b/demos/Delphi_FMX_Mac/FMXExternalPumpBrowser/uFMXExternalPumpBrowser.pas index 29783f5f..09981b4f 100644 --- a/demos/Delphi_FMX_Mac/FMXExternalPumpBrowser/uFMXExternalPumpBrowser.pas +++ b/demos/Delphi_FMX_Mac/FMXExternalPumpBrowser/uFMXExternalPumpBrowser.pas @@ -48,7 +48,7 @@ uses {$IFDEF DELPHI17_UP}FMX.Graphics,{$ENDIF} uCEFFMXChromium, uCEFFMXBufferPanel, uCEFFMXWorkScheduler, uCEFInterfaces, uCEFTypes, uCEFConstants, uCEFChromiumCore, FMX.Layouts, - FMX.Memo.Types, FMX.ScrollBox, FMX.Memo; + FMX.Memo.Types, FMX.ScrollBox, FMX.Memo, FMX.Menus; type tagRGBQUAD = record @@ -69,6 +69,16 @@ type Layout1: TLayout; GoBtn: TButton; SnapshotBtn: TButton; + MainMenu1: TMainMenu; + EditMenu: TMenuItem; + UndoMenuItem: TMenuItem; + RedoMenuItem: TMenuItem; + SeparatorMenuItem: TMenuItem; + CutMenuItem: TMenuItem; + CopyMenuItem: TMenuItem; + PasteMenuItem: TMenuItem; + DeleteMenuItem: TMenuItem; + SelectAllMenuItem: TMenuItem; procedure GoBtnClick(Sender: TObject); procedure GoBtnEnter(Sender: TObject); @@ -110,6 +120,13 @@ type procedure SnapshotBtnClick(Sender: TObject); procedure SnapshotBtnEnter(Sender: TObject); + procedure CopyMenuItemClick(Sender: TObject); + procedure CutMenuItemClick(Sender: TObject); + procedure DeleteMenuItemClick(Sender: TObject); + procedure PasteMenuItemClick(Sender: TObject); + procedure RedoMenuItemClick(Sender: TObject); + procedure SelectAllMenuItemClick(Sender: TObject); + procedure UndoMenuItemClick(Sender: TObject); protected FPopUpBitmap : TBitmap; @@ -124,17 +141,10 @@ type FMouseWheelService : IFMXMouseService; {$ENDIF} - FLastClickCount : integer; - FLastClickTime : integer; - FLastClickPoint : TPointF; - FLastClickButton : TMouseButton; - procedure LoadURL; - function getModifiers(Shift: TShiftState): TCefEventFlags; + function getModifiers(Shift: TShiftState; KeyCode: integer = 0): TCefEventFlags; function GetButton(Button: TMouseButton): TCefMouseButtonType; function GetMousePosition(var aPoint : TPointF) : boolean; - procedure InitializeLastClick; - function CancelPreviousClick(const x, y : single; var aCurrentTime : integer) : boolean; public procedure DoResize; @@ -152,10 +162,7 @@ var // This demo is in ALPHA state. It's incomplete and some features may not work! // **************************************************************************** // Known issues and missing features : -// - Keyboard support is incomplete. // - Full screen event is not handled correctly. -// - The CrAppProtocol implementation in uFMXApplicationService needs to be tested. -// - All Windows code in this demo must be removed. // - Right-click crashes the demo. @@ -227,8 +234,10 @@ implementation {$R *.fmx} uses - System.SysUtils, System.Math, FMX.Platform, {$IFDEF MSWINDOWS}FMX.Platform.Win,{$ENDIF} - uCEFMiscFunctions, uCEFApplication, uFMXApplicationService; + System.SysUtils, System.Math, System.IOUtils, + FMX.Platform, + uCEFMiscFunctions, uCEFApplication, uFMXApplicationService, + uCEFMacOSConstants, uCEFMacOSFunctions; procedure GlobalCEFApp_OnScheduleMessagePumpWork(const aDelayMS : int64); begin @@ -252,13 +261,12 @@ begin GlobalCEFApp.ExternalMessagePump := True; GlobalCEFApp.MultiThreadedMessageLoop := False; GlobalCEFApp.UseMockKeyChain := True; - //GlobalCEFApp.SingleProcess := True; GlobalCEFApp.OnScheduleMessagePumpWork := GlobalCEFApp_OnScheduleMessagePumpWork; - //GlobalCEFApp.EnableGPU := True; - // Replace with your username to create a log file in your home directory - //GlobalCEFApp.LogFile := '/Users//debug.log'; - //GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO; + {$IFDEF DEBUG} + GlobalCEFApp.LogFile := TPath.GetHomePath + TPath.DirectorySeparatorChar + 'debug.log'; + GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO; + {$ENDIF} end; procedure TFMXExternalPumpBrowserFrm.FormActivate(Sender: TObject); @@ -268,7 +276,8 @@ begin // opaque white background color chrmosr.Options.BackgroundColor := CefColorSetARGB($FF, $FF, $FF, $FF); - if not(chrmosr.CreateBrowser) then Timer1.Enabled := True; + if not(chrmosr.CreateBrowser) then + Timer1.Enabled := True; end; end; @@ -286,10 +295,6 @@ begin end; procedure TFMXExternalPumpBrowserFrm.FormCreate(Sender: TObject); -{$IFDEF MSWINDOWS} -var - TempMajorVer, TempMinorVer : DWORD; -{$ENDIF} begin TFMXApplicationService.AddPlatformService; @@ -304,8 +309,6 @@ begin chrmosr.DefaultURL := AddressEdt.Text; - InitializeLastClick; - {$IFDEF DELPHI17_UP} if TPlatformServices.Current.SupportsPlatformService(IFMXMouseService) then FMouseWheelService := TPlatformServices.Current.GetPlatformService(IFMXMouseService) as IFMXMouseService; @@ -358,8 +361,9 @@ begin Panel1.SetFocus; end; -procedure TFMXExternalPumpBrowserFrm.Panel1DialogKey(Sender: TObject; - var Key: Word; Shift: TShiftState); +procedure TFMXExternalPumpBrowserFrm.Panel1DialogKey( Sender : TObject; + var Key : Word; + Shift : TShiftState); begin if (Key = vkTab) then Key := 0; end; @@ -374,29 +378,23 @@ begin chrmosr.SendFocusEvent(False); end; -procedure TFMXExternalPumpBrowserFrm.Panel1KeyUp(Sender: TObject; var Key: Word; - var KeyChar: Char; Shift: TShiftState); +procedure TFMXExternalPumpBrowserFrm.Panel1KeyUp( Sender : TObject; + var Key : Word; + var KeyChar : Char; + Shift : TShiftState); var TempKeyEvent : TCefKeyEvent; - TempChar : char; begin - if not(Panel1.IsFocused) then exit; - - if (KeyChar <> #0) then - TempChar := KeyChar - else - if (Key <> 0) then - TempChar := chr(Key) - else - TempChar := #0; + if not(Panel1.IsFocused) or (KeyChar = #0) then + exit; TempKeyEvent.kind := KEYEVENT_KEYUP; - TempKeyEvent.modifiers := getModifiers(Shift); + TempKeyEvent.native_key_code := KeyToMacOSKeyCode(Key); + TempKeyEvent.modifiers := getModifiers(Shift, TempKeyEvent.native_key_code); TempKeyEvent.windows_key_code := 0; - TempKeyEvent.native_key_code := 0; TempKeyEvent.is_system_key := ord(False); - TempKeyEvent.character := TempChar; - TempKeyEvent.unmodified_character := TempChar; + TempKeyEvent.character := KeyChar; + TempKeyEvent.unmodified_character := KeyChar; TempKeyEvent.focus_on_editable_field := ord(False); chrmosr.SendKeyEvent(@TempKeyEvent); @@ -408,40 +406,27 @@ procedure TFMXExternalPumpBrowserFrm.Panel1KeyDown( Sender : TObject; Shift : TShiftState); var TempKeyEvent : TCefKeyEvent; - TempChar : char; begin if not(Panel1.IsFocused) then exit; - if (KeyChar <> #0) then - TempChar := KeyChar - else - if (Key <> 0) then - begin - TempChar := chr(Key); - - if (Key in [vkLeft, vkRight, vkUp, vkDown]) then - begin - Key := 0; - exit; - end; - end - else - TempChar := #0; - TempKeyEvent.kind := KEYEVENT_KEYDOWN; - TempKeyEvent.modifiers := getModifiers(Shift); + TempKeyEvent.native_key_code := KeyToMacOSKeyCode(Key); + TempKeyEvent.modifiers := getModifiers(Shift, TempKeyEvent.native_key_code); TempKeyEvent.windows_key_code := 0; - TempKeyEvent.native_key_code := 0; TempKeyEvent.is_system_key := ord(False); - TempKeyEvent.character := TempChar; - TempKeyEvent.unmodified_character := TempChar; + TempKeyEvent.character := KeyChar; + TempKeyEvent.unmodified_character := KeyChar; TempKeyEvent.focus_on_editable_field := ord(False); chrmosr.SendKeyEvent(@TempKeyEvent); - TempKeyEvent.kind := KEYEVENT_CHAR; - - chrmosr.SendKeyEvent(@TempKeyEvent); + if not(TempKeyEvent.native_key_code in CEF_MACOS_KEYPAD_KEYS + + CEF_MACOS_ARROW_KEYS + + CEF_MACOS_FUNCTION_KEYS) then + begin + TempKeyEvent.kind := KEYEVENT_CHAR; + chrmosr.SendKeyEvent(@TempKeyEvent); + end; end; procedure TFMXExternalPumpBrowserFrm.Panel1MouseDown(Sender : TObject; @@ -450,28 +435,22 @@ procedure TFMXExternalPumpBrowserFrm.Panel1MouseDown(Sender : TObject; X, Y : Single); var TempEvent : TCefMouseEvent; - TempTime : integer; + TempCount : integer; begin if not(ssTouch in Shift) then begin Panel1.SetFocus; - if not(CancelPreviousClick(x, y, TempTime)) and (Button = FLastClickButton) then - inc(FLastClickCount) - else - begin - FLastClickPoint.x := x; - FLastClickPoint.y := y; - FLastClickCount := 1; - end; - - FLastClickTime := TempTime; - FLastClickButton := Button; - TempEvent.x := round(X); TempEvent.y := round(Y); TempEvent.modifiers := getModifiers(Shift); - chrmosr.SendMouseClickEvent(@TempEvent, GetButton(Button), False, FLastClickCount); + + if (ssDouble in Shift) then + TempCount := 2 + else + TempCount := 1; + + chrmosr.SendMouseClickEvent(@TempEvent, GetButton(Button), False, TempCount); end; end; @@ -499,21 +478,14 @@ procedure TFMXExternalPumpBrowserFrm.Panel1MouseLeave(Sender: TObject); var TempEvent : TCefMouseEvent; TempPoint : TPointF; - TempTime : integer; begin if GetMousePosition(TempPoint) then begin - TempPoint := Panel1.ScreenToClient(TempPoint); - - if CancelPreviousClick(TempPoint.x, TempPoint.y, TempTime) then InitializeLastClick; - + TempPoint := Panel1.ScreenToClient(TempPoint); TempEvent.x := round(TempPoint.x); TempEvent.y := round(TempPoint.y); - {$IFDEF MSWINDOWS} - TempEvent.modifiers := GetCefMouseModifiers; - {$ELSE} TempEvent.modifiers := EVENTFLAG_NONE; - {$ENDIF} + chrmosr.SendMouseMoveEvent(@TempEvent, True); end; end; @@ -523,15 +495,13 @@ procedure TFMXExternalPumpBrowserFrm.Panel1MouseMove(Sender : TObject; X, Y : Single); var TempEvent : TCefMouseEvent; - TempTime : integer; begin if not(ssTouch in Shift) then begin - if CancelPreviousClick(x, y, TempTime) then InitializeLastClick; - TempEvent.x := round(x); TempEvent.y := round(y); TempEvent.modifiers := getModifiers(Shift); + chrmosr.SendMouseMoveEvent(@TempEvent, False); end; end; @@ -542,13 +512,20 @@ procedure TFMXExternalPumpBrowserFrm.Panel1MouseUp(Sender : TObject; X, Y : Single); var TempEvent : TCefMouseEvent; + TempCount : integer; begin if not(ssTouch in Shift) then begin TempEvent.x := round(X); TempEvent.y := round(Y); TempEvent.modifiers := getModifiers(Shift); - chrmosr.SendMouseClickEvent(@TempEvent, GetButton(Button), True, FLastClickCount); + + if (ssDouble in Shift) then + TempCount := 2 + else + TempCount := 1; + + chrmosr.SendMouseClickEvent(@TempEvent, GetButton(Button), True, TempCount); end; end; @@ -566,6 +543,7 @@ begin TempEvent.x := round(TempPoint.x); TempEvent.y := round(TempPoint.y); TempEvent.modifiers := getModifiers(Shift); + chrmosr.SendMouseWheelEvent(@TempEvent, 0, WheelDelta); end; end; @@ -575,6 +553,16 @@ begin DoResize; end; +procedure TFMXExternalPumpBrowserFrm.PasteMenuItemClick(Sender: TObject); +begin + chrmosr.ClipboardPaste; +end; + +procedure TFMXExternalPumpBrowserFrm.RedoMenuItemClick(Sender: TObject); +begin + chrmosr.ClipboardRedo; +end; + procedure TFMXExternalPumpBrowserFrm.Timer1Timer(Sender: TObject); begin Timer1.Enabled := False; @@ -583,6 +571,11 @@ begin Timer1.Enabled := True; end; +procedure TFMXExternalPumpBrowserFrm.UndoMenuItemClick(Sender: TObject); +begin + chrmosr.ClipboardUndo; +end; + procedure TFMXExternalPumpBrowserFrm.AddressEdtEnter(Sender: TObject); begin chrmosr.SendFocusEvent(False); @@ -600,10 +593,10 @@ procedure TFMXExternalPumpBrowserFrm.chrmosrBeforeClose(Sender: TObject; const b begin FCanClose := True; - TThread.Queue(nil, procedure - begin - close - end); + TThread.ForceQueue(nil, procedure + begin + close + end); end; procedure TFMXExternalPumpBrowserFrm.chrmosrBeforePopup( Sender : TObject; @@ -842,7 +835,7 @@ begin if (type_ = PET_VIEW) then begin if TempForcedResize or FPendingResize then - TThread.Queue(nil, DoResize); + TThread.ForceQueue(nil, DoResize); FResizing := False; FPendingResize := False; @@ -895,6 +888,21 @@ begin Result := True; end; +procedure TFMXExternalPumpBrowserFrm.CopyMenuItemClick(Sender: TObject); +begin + chrmosr.ClipboardCopy; +end; + +procedure TFMXExternalPumpBrowserFrm.CutMenuItemClick(Sender: TObject); +begin + chrmosr.ClipboardCut; +end; + +procedure TFMXExternalPumpBrowserFrm.DeleteMenuItemClick(Sender: TObject); +begin + chrmosr.ClipboardDel; +end; + procedure TFMXExternalPumpBrowserFrm.DoResize; begin try @@ -934,21 +942,30 @@ begin if (chrmosr <> nil) then chrmosr.NotifyMoveOrResizeStarted; end; +procedure TFMXExternalPumpBrowserFrm.SelectAllMenuItemClick(Sender: TObject); +begin + chrmosr.SelectAll; +end; + procedure TFMXExternalPumpBrowserFrm.SendCaptureLostEvent; begin if (chrmosr <> nil) then chrmosr.SendCaptureLostEvent; end; -function TFMXExternalPumpBrowserFrm.getModifiers(Shift: TShiftState): TCefEventFlags; +function TFMXExternalPumpBrowserFrm.getModifiers(Shift: TShiftState; KeyCode: integer): TCefEventFlags; begin Result := EVENTFLAG_NONE; - if (ssShift in Shift) then Result := Result or EVENTFLAG_SHIFT_DOWN; - if (ssAlt in Shift) then Result := Result or EVENTFLAG_ALT_DOWN; - if (ssCtrl in Shift) then Result := Result or EVENTFLAG_CONTROL_DOWN; - if (ssLeft in Shift) then Result := Result or EVENTFLAG_LEFT_MOUSE_BUTTON; - if (ssRight in Shift) then Result := Result or EVENTFLAG_RIGHT_MOUSE_BUTTON; - if (ssMiddle in Shift) then Result := Result or EVENTFLAG_MIDDLE_MOUSE_BUTTON; + if (ssShift in Shift) then Result := Result or EVENTFLAG_SHIFT_DOWN; + if (ssAlt in Shift) then Result := Result or EVENTFLAG_ALT_DOWN; + if (ssCtrl in Shift) then Result := Result or EVENTFLAG_CONTROL_DOWN; + if (ssLeft in Shift) then Result := Result or EVENTFLAG_LEFT_MOUSE_BUTTON; + if (ssRight in Shift) then Result := Result or EVENTFLAG_RIGHT_MOUSE_BUTTON; + if (ssMiddle in Shift) then Result := Result or EVENTFLAG_MIDDLE_MOUSE_BUTTON; + if (ssCommand in Shift) then Result := Result or EVENTFLAG_COMMAND_DOWN; + + if (KeyCode in CEF_MACOS_KEYPAD_KEYS) then + Result := Result or EVENTFLAG_IS_KEY_PAD; end; function TFMXExternalPumpBrowserFrm.GetButton(Button: TMouseButton): TCefMouseButtonType; @@ -960,29 +977,6 @@ begin end; end; -procedure TFMXExternalPumpBrowserFrm.InitializeLastClick; -begin - FLastClickCount := 1; - FLastClickTime := 0; - FLastClickPoint.x := 0; - FLastClickPoint.y := 0; - FLastClickButton := TMouseButton.mbLeft; -end; - -function TFMXExternalPumpBrowserFrm.CancelPreviousClick(const x, y : single; var aCurrentTime : integer) : boolean; -begin - {$IFDEF MSWINDOWS} - aCurrentTime := GetMessageTime; - - Result := (abs(FLastClickPoint.x - x) > (GetSystemMetrics(SM_CXDOUBLECLK) div 2)) or - (abs(FLastClickPoint.y - y) > (GetSystemMetrics(SM_CYDOUBLECLK) div 2)) or - (cardinal(aCurrentTime - FLastClickTime) > GetDoubleClickTime); - {$ELSE} - aCurrentTime := 0; - Result := False; - {$ENDIF} -end; - procedure TFMXExternalPumpBrowserFrm.SnapshotBtnClick(Sender: TObject); begin if SaveDialog1.Execute then Panel1.SaveToFile(SaveDialog1.FileName); diff --git a/source/uCEFBufferPanel.pas b/source/uCEFBufferPanel.pas index 34b50524..9d815398 100644 --- a/source/uCEFBufferPanel.pas +++ b/source/uCEFBufferPanel.pas @@ -491,7 +491,7 @@ begin Result := HandleAllocated and PostMessage(Handle, CM_INVALIDATE, 0, 0); {$ELSE} Result := True; - TThread.Queue(nil, @Invalidate); + TThread.ForceQueue(nil, @Invalidate); {$ENDIF} end; diff --git a/source/uCEFChromiumCore.pas b/source/uCEFChromiumCore.pas index 317a0464..6bef7168 100644 --- a/source/uCEFChromiumCore.pas +++ b/source/uCEFChromiumCore.pas @@ -748,6 +748,7 @@ type procedure ClearDataForOrigin(const aOrigin : ustring; aStorageTypes : TCefClearDataStorageTypes = cdstAll); procedure ClearCache; + function DeleteCookies(const url : ustring = ''; const cookieName : ustring = ''; aDeleteImmediately : boolean = False) : boolean; function VisitAllCookies(aID : integer = 0) : boolean; function VisitURLCookies(const url : ustring; includeHttpOnly : boolean = False; aID : integer = 0) : boolean; @@ -2165,6 +2166,7 @@ begin Browser.Host.Print; end; +// The TChromiumCore.OnPdfPrintFinished event will be triggered when the PDF file is created. procedure TChromiumCore.PrintToPDF(const aFilePath, aTitle, aURL : ustring); var TempSettings : TCefPdfPrintSettings; @@ -2512,7 +2514,7 @@ begin Browser.Host.StartDownload(aURL); end; -// Use the OnDownloadImageFinished event to receive the image +// Use the TChromiumCore.OnDownloadImageFinished event to receive the image procedure TChromiumCore.DownloadImage(const imageUrl : ustring; isFavicon : boolean; maxImageSize : cardinal; @@ -3634,6 +3636,7 @@ begin end; // Leave aFrameName empty to get the HTML source from the main frame +// The TChromiumCore.OnTextResultAvailable event will be triggered with the HTML contents procedure TChromiumCore.RetrieveHTML(const aFrameName : ustring); var TempFrame : ICefFrame; @@ -3692,6 +3695,7 @@ begin end; // Leave aFrameName empty to get the HTML source from the main frame +// The TChromiumCore.OnTextResultAvailable event will be triggered with the text contents procedure TChromiumCore.RetrieveText(const aFrameName : ustring); var TempFrame : ICefFrame; @@ -3749,6 +3753,7 @@ begin end; end; +// The TChromiumCore.OnNavigationVisitorResultAvailable event will be triggered for each entry procedure TChromiumCore.GetNavigationEntries(currentOnly: Boolean); var TempVisitor : ICefNavigationEntryVisitor; @@ -6616,6 +6621,7 @@ begin end; end; +// This procedure will trigger OnMediaSinkDeviceInfo with the device info. procedure TChromiumCore.GetDeviceInfo(const aMediaSink: ICefMediaSink); var TempCallback : ICefMediaSinkDeviceInfoCallback; diff --git a/source/uCEFFMXWorkScheduler.pas b/source/uCEFFMXWorkScheduler.pas index dcdc5f28..7ae7a97e 100644 --- a/source/uCEFFMXWorkScheduler.pas +++ b/source/uCEFFMXWorkScheduler.pas @@ -276,10 +276,10 @@ begin if FUseQueueThread and (FQueueThread <> nil) and FQueueThread.Ready then FQueueThread.EnqueueValue(integer(delay_ms)) else - TThread.Queue(nil, procedure - begin - ScheduleWork(delay_ms); - end); + TThread.ForceQueue(nil, procedure + begin + ScheduleWork(delay_ms); + end); end; procedure TFMXWorkScheduler.StopScheduler; diff --git a/source/uCEFLinuxFunctions.pas b/source/uCEFLinuxFunctions.pas index 3a863c2f..4764acc5 100644 --- a/source/uCEFLinuxFunctions.pas +++ b/source/uCEFLinuxFunctions.pas @@ -65,6 +65,13 @@ function GdkEventToWindowsKeyCode(Event: PGdkEventKey) : integer; function GetWindowsKeyCodeWithoutLocation(key_code : integer) : integer; function GetControlCharacter(windows_key_code : integer; shift : boolean) : integer; {$IFDEF FMX} +type + TXErrorHandler = function (para1:PDisplay; para2:PXErrorEvent):longint; cdecl; + TXIOErrorHandler = function (para1:PDisplay):longint; cdecl; + +function XSetErrorHandler(para1:TXErrorHandler):TXErrorHandler; cdecl; external 'libX11.so'; +function XSetIOErrorHandler(para1:TXIOErrorHandler):TXIOErrorHandler; cdecl; external 'libX11.so'; + function gdk_keyval_to_unicode(keyval: guint): guint32; cdecl; external 'libgdk-3.so'; function g_signal_connect_data(instance: gpointer; detailed_signal: Pgchar; c_handler: TGCallback; data: gpointer; destroy_data: TGClosureNotify; connect_flags: TGConnectFlags): gulong; cdecl; external 'libgobject-2.0.so'; function g_signal_connect(instance: gpointer; detailed_signal: Pgchar; c_handler: TGCallback; data: gpointer): gulong; overload; diff --git a/source/uCEFLinuxTypes.pas b/source/uCEFLinuxTypes.pas index 13350cc0..d8d07750 100644 --- a/source/uCEFLinuxTypes.pas +++ b/source/uCEFLinuxTypes.pas @@ -80,6 +80,18 @@ type TGdkEventType = int32; PGdkEventKey = ^TGdkEventKey; PXDisplay = pointer; + PDisplay = pointer; + + PXErrorEvent = ^TXErrorEvent; + TXErrorEvent = record + _type : longint; + display : PDisplay; + resourceid : uint64; + serial : uint64; + error_code : uint8; + request_code : uint8; + minor_code : uint8; + end; PGTypeClass = ^TGTypeClass; TGTypeClass = record diff --git a/source/uCEFMacOSConstants.pas b/source/uCEFMacOSConstants.pas new file mode 100644 index 00000000..9ada0ea2 --- /dev/null +++ b/source/uCEFMacOSConstants.pas @@ -0,0 +1,240 @@ +// ************************************************************************ +// ***************************** 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 + * 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 uCEFMacOSConstants; + +{$IFDEF FPC} + {$MODE OBJFPC}{$H+} +{$ENDIF} + +{$IFNDEF CPUX64}{$ALIGN ON}{$ENDIF} +{$MINENUMSIZE 4} + +{$I cef.inc} + +interface + +{$IFDEF MACOSX} +const + // Virtual Keycode constants defined in + // /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/Headers/Events.h + // /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/Headers/Events.h + + // These constants are the virtual keycodes defined originally in + // Inside Mac Volume V, pg. V-191. They identify physical keys on a + // keyboard. Those constants with "ANSI" in the name are labeled + // according to the key position on an ANSI-standard US keyboard. + // For example, kVK_ANSI_A indicates the virtual keycode for the key + // with the letter 'A' in the US keyboard layout. Other keyboard + // layouts may have the 'A' key label on a different physical key; + // in this case, pressing 'A' will generate a different virtual + // keycode. + + kVK_ANSI_A = $00; + kVK_ANSI_S = $01; + kVK_ANSI_D = $02; + kVK_ANSI_F = $03; + kVK_ANSI_H = $04; + kVK_ANSI_G = $05; + kVK_ANSI_Z = $06; + kVK_ANSI_X = $07; + kVK_ANSI_C = $08; + kVK_ANSI_V = $09; + kVK_ANSI_B = $0B; + kVK_ANSI_Q = $0C; + kVK_ANSI_W = $0D; + kVK_ANSI_E = $0E; + kVK_ANSI_R = $0F; + kVK_ANSI_Y = $10; + kVK_ANSI_T = $11; + kVK_ANSI_1 = $12; + kVK_ANSI_2 = $13; + kVK_ANSI_3 = $14; + kVK_ANSI_4 = $15; + kVK_ANSI_6 = $16; + kVK_ANSI_5 = $17; + kVK_ANSI_Equal = $18; + kVK_ANSI_9 = $19; + kVK_ANSI_7 = $1A; + kVK_ANSI_Minus = $1B; + kVK_ANSI_8 = $1C; + kVK_ANSI_0 = $1D; + kVK_ANSI_RightBracket = $1E; + kVK_ANSI_O = $1F; + kVK_ANSI_U = $20; + kVK_ANSI_LeftBracket = $21; + kVK_ANSI_I = $22; + kVK_ANSI_P = $23; + kVK_ANSI_L = $25; + kVK_ANSI_J = $26; + kVK_ANSI_Quote = $27; + kVK_ANSI_K = $28; + kVK_ANSI_Semicolon = $29; + kVK_ANSI_Backslash = $2A; + kVK_ANSI_Comma = $2B; + kVK_ANSI_Slash = $2C; + kVK_ANSI_N = $2D; + kVK_ANSI_M = $2E; + kVK_ANSI_Period = $2F; + kVK_ANSI_Grave = $32; + kVK_ANSI_KeypadDecimal = $41; + kVK_ANSI_KeypadMultiply = $43; + kVK_ANSI_KeypadPlus = $45; + kVK_ANSI_KeypadClear = $47; + kVK_ANSI_KeypadDivide = $4B; + kVK_ANSI_KeypadEnter = $4C; + kVK_ANSI_KeypadMinus = $4E; + kVK_ANSI_KeypadEquals = $51; + kVK_ANSI_Keypad0 = $52; + kVK_ANSI_Keypad1 = $53; + kVK_ANSI_Keypad2 = $54; + kVK_ANSI_Keypad3 = $55; + kVK_ANSI_Keypad4 = $56; + kVK_ANSI_Keypad5 = $57; + kVK_ANSI_Keypad6 = $58; + kVK_ANSI_Keypad7 = $59; + kVK_ANSI_Keypad8 = $5B; + kVK_ANSI_Keypad9 = $5C; + + // keycodes for keys that are independent of keyboard layout + kVK_Return = $24; + kVK_Tab = $30; + kVK_Space = $31; + kVK_Delete = $33; + kVK_Escape = $35; + kVK_Command = $37; + kVK_Shift = $38; + kVK_CapsLock = $39; + kVK_Option = $3A; + kVK_Control = $3B; + kVK_RightShift = $3C; + kVK_RightOption = $3D; + kVK_RightControl = $3E; + kVK_Function = $3F; + kVK_F17 = $40; + kVK_VolumeUp = $48; + kVK_VolumeDown = $49; + kVK_Mute = $4A; + kVK_F18 = $4F; + kVK_F19 = $50; + kVK_F20 = $5A; + kVK_F5 = $60; + kVK_F6 = $61; + kVK_F7 = $62; + kVK_F3 = $63; + kVK_F8 = $64; + kVK_F9 = $65; + kVK_F11 = $67; + kVK_F13 = $69; + kVK_F16 = $6A; + kVK_F14 = $6B; + kVK_F10 = $6D; + kVK_F12 = $6F; + kVK_F15 = $71; + kVK_Help = $72; + kVK_Home = $73; + kVK_PageUp = $74; + kVK_ForwardDelete = $75; + kVK_F4 = $76; + kVK_End = $77; + kVK_F2 = $78; + kVK_PageDown = $79; + kVK_F1 = $7A; + kVK_LeftArrow = $7B; + kVK_RightArrow = $7C; + kVK_DownArrow = $7D; + kVK_UpArrow = $7E; + + // ISO keyboards only + kVK_ISO_Section = $0A; + + // JIS keyboards only + kVK_JIS_Yen = $5D; + kVK_JIS_Underscore = $5E; + kVK_JIS_KeypadComma = $5F; + kVK_JIS_Eisu = $66; + kVK_JIS_Kana = $68; + + CEF_MACOS_KEYPAD_KEYS = [kVK_ANSI_KeypadDecimal, + kVK_ANSI_KeypadMultiply, + kVK_ANSI_KeypadPlus, + kVK_ANSI_KeypadClear, + kVK_ANSI_KeypadDivide, + kVK_ANSI_KeypadEnter, + kVK_ANSI_KeypadMinus, + kVK_ANSI_KeypadEquals, + kVK_ANSI_Keypad0, + kVK_ANSI_Keypad1, + kVK_ANSI_Keypad2, + kVK_ANSI_Keypad3, + kVK_ANSI_Keypad4, + kVK_ANSI_Keypad5, + kVK_ANSI_Keypad6, + kVK_ANSI_Keypad7, + kVK_ANSI_Keypad8, + kVK_ANSI_Keypad9]; + + CEF_MACOS_ARROW_KEYS = [kVK_LeftArrow, + kVK_RightArrow, + kVK_DownArrow, + kVK_UpArrow]; + + CEF_MACOS_FUNCTION_KEYS = [kVK_F1, + kVK_F2, + kVK_F3, + kVK_F4, + kVK_F5, + kVK_F6, + kVK_F7, + kVK_F8, + kVK_F9, + kVK_F10, + kVK_F11, + kVK_F12, + kVK_F13, + kVK_F14, + kVK_F15, + kVK_F16, + kVK_F17, + kVK_F18, + kVK_F19, + kVK_F20]; +{$ENDIF} + +implementation + +end. diff --git a/demos/Delphi_FMX_Mac/FMXExternalPumpBrowser/uFMXMiscFunctions.pas b/source/uCEFMacOSFunctions.pas similarity index 51% rename from demos/Delphi_FMX_Mac/FMXExternalPumpBrowser/uFMXMiscFunctions.pas rename to source/uCEFMacOSFunctions.pas index d0b481a7..13264703 100644 --- a/demos/Delphi_FMX_Mac/FMXExternalPumpBrowser/uFMXMiscFunctions.pas +++ b/source/uCEFMacOSFunctions.pas @@ -35,17 +35,37 @@ * *) -unit uFMXMiscFunctions; +unit uCEFMacOSFunctions; + +{$IFDEF FPC} + {$MODE OBJFPC}{$H+} +{$ENDIF} + +{$IFNDEF CPUX64}{$ALIGN ON}{$ENDIF} +{$MINENUMSIZE 4} + +{$I cef.inc} interface +uses + System.UITypes, + uCEFMacOSConstants; + +{$IFDEF MACOSX} +function KeyToMacOSKeyCode(aKey : Word): integer; +{$IFDEF FMX} procedure CopyCEFFramework; procedure CopyCEFHelpers(const aProjectName : string); +{$ENDIF} +{$ENDIF} implementation +{$IFDEF MACOSX} +{$IFDEF FMX} uses - System.SysUtils, System.Types, System.IOUtils, Posix.Stdio, + System.SysUtils, System.Types, System.IOUtils, Posix.Stdio, FMX.Types, uCEFMiscFunctions; const @@ -53,11 +73,144 @@ const PRJ_GPU_SUBFIX = '_helper_gpu'; PRJ_PLUGIN_SUBFIX = '_helper_plugin'; PRJ_RENDERER_SUBFIX = '_helper_renderer'; - HELPER_SUBFIX = ' Helper'; - GPU_SUBFIX = ' Helper (GPU)'; - PLUGIN_SUBFIX = ' Helper (Plugin)'; - RENDERER_SUBFIX = ' Helper (Renderer)'; + HELPER_SUBFIX = ' Helper'; + GPU_SUBFIX = ' Helper (GPU)'; + PLUGIN_SUBFIX = ' Helper (Plugin)'; + RENDERER_SUBFIX = ' Helper (Renderer)'; +{$ENDIF} +// Key Code translation following the information found in these documents : +// https://developer.apple.com/library/archive/documentation/mac/pdf/MacintoshToolboxEssentials.pdf +// https://eastmanreference.com/complete-list-of-applescript-key-codes + +function KeyToMacOSKeyCode(aKey : Word): integer; +begin + case aKey of + vkBack : Result := kVK_Delete; + vkTab : Result := kVK_Tab; + vkClear : Result := kVK_ANSI_KeypadClear; + vkReturn : Result := kVK_Return; + vkShift : Result := kVK_Shift; + vkControl : Result := kVK_Control; + vkMenu : Result := kVK_Option; + vkPause : Result := kVK_F15; + vkCapital : Result := kVK_CapsLock; + vkEscape : Result := kVK_Escape; + vkSpace : Result := kVK_Space; + vkPrior : Result := kVK_PageUp; + vkNext : Result := kVK_PageDown; + vkEnd : Result := kVK_End; + vkHome : Result := kVK_Home; + vkLeft : Result := kVK_LeftArrow; + vkUp : Result := kVK_UpArrow; + vkRight : Result := kVK_RightArrow; + vkDown : Result := kVK_DownArrow; + vkSnapshot : Result := kVK_F13; + vkHelp, + vkInsert : Result := kVK_Help; + vkDelete : Result := kVK_ForwardDelete; + vk0 : Result := kVK_ANSI_0; + vk1 : Result := kVK_ANSI_1; + vk2 : Result := kVK_ANSI_2; + vk3 : Result := kVK_ANSI_3; + vk4 : Result := kVK_ANSI_4; + vk5 : Result := kVK_ANSI_5; + vk6 : Result := kVK_ANSI_6; + vk7 : Result := kVK_ANSI_7; + vk8 : Result := kVK_ANSI_8; + vk9 : Result := kVK_ANSI_9; + vkA : Result := kVK_ANSI_A; + vkB : Result := kVK_ANSI_B; + vkC : Result := kVK_ANSI_C; + vkD : Result := kVK_ANSI_D; + vkE : Result := kVK_ANSI_E; + vkF : Result := kVK_ANSI_F; + vkG : Result := kVK_ANSI_G; + vkH : Result := kVK_ANSI_H; + vkI : Result := kVK_ANSI_I; + vkJ : Result := kVK_ANSI_J; + vkK : Result := kVK_ANSI_K; + vkL : Result := kVK_ANSI_L; + vkM : Result := kVK_ANSI_M; + vkN : Result := kVK_ANSI_N; + vkO : Result := kVK_ANSI_O; + vkP : Result := kVK_ANSI_P; + vkQ : Result := kVK_ANSI_Q; + vkR : Result := kVK_ANSI_R; + vkS : Result := kVK_ANSI_S; + vkT : Result := kVK_ANSI_T; + vkU : Result := kVK_ANSI_U; + vkV : Result := kVK_ANSI_V; + vkW : Result := kVK_ANSI_W; + vkX : Result := kVK_ANSI_X; + vkY : Result := kVK_ANSI_Y; + vkZ : Result := kVK_ANSI_Z; + vkLWin : Result := kVK_Option; + vkRWin : Result := kVK_RightOption; + vkNumpad0 : Result := kVK_ANSI_Keypad0; + vkNumpad1 : Result := kVK_ANSI_Keypad1; + vkNumpad2 : Result := kVK_ANSI_Keypad2; + vkNumpad3 : Result := kVK_ANSI_Keypad3; + vkNumpad4 : Result := kVK_ANSI_Keypad4; + vkNumpad5 : Result := kVK_ANSI_Keypad5; + vkNumpad6 : Result := kVK_ANSI_Keypad6; + vkNumpad7 : Result := kVK_ANSI_Keypad7; + vkNumpad8 : Result := kVK_ANSI_Keypad8; + vkNumpad9 : Result := kVK_ANSI_Keypad9; + vkMultiply : Result := kVK_ANSI_KeypadMultiply; + vkAdd : Result := kVK_ANSI_KeypadPlus; + vkSubtract : Result := kVK_ANSI_KeypadMinus; + vkDecimal : Result := kVK_ANSI_KeypadDecimal; + vkDivide : Result := kVK_ANSI_KeypadDivide; + vkF1 : Result := kVK_F1; + vkF2 : Result := kVK_F2; + vkF3 : Result := kVK_F3; + vkF4 : Result := kVK_F4; + vkF5 : Result := kVK_F5; + vkF6 : Result := kVK_F6; + vkF7 : Result := kVK_F7; + vkF8 : Result := kVK_F8; + vkF9 : Result := kVK_F9; + vkF10 : Result := kVK_F10; + vkF11 : Result := kVK_F11; + vkF12 : Result := kVK_F12; + vkF13 : Result := kVK_F13; + vkF14 : Result := kVK_F14; + vkF15 : Result := kVK_F15; + vkF16 : Result := kVK_F16; + vkF17 : Result := kVK_F17; + vkF18 : Result := kVK_F18; + vkF19 : Result := kVK_F19; + vkF20 : Result := kVK_F20; + vkNumLock : Result := kVK_ANSI_KeypadClear; + vkScroll : Result := kVK_F14; + vkLShift : Result := kVK_Shift; + vkRShift : Result := kVK_RightShift; + vkLControl : Result := kVK_Control; + vkRControl : Result := kVK_RightControl; + vkLMenu, + vkRMenu : Result := kVK_Command; + vkVolumeMute : Result := kVK_Mute; + vkVolumeDown : Result := kVK_VolumeDown; + vkVolumeUp : Result := kVK_VolumeUp; + vkSemicolon : Result := kVK_ANSI_Semicolon; + vkEqual : Result := kVK_ANSI_Equal; + vkComma : Result := kVK_ANSI_Comma; + vkMinus : Result := kVK_ANSI_Minus; + vkPeriod : Result := kVK_ANSI_Period; + vkSlash : Result := kVK_ANSI_Slash; + vkTilde : Result := kVK_ANSI_Grave; + vkLeftBracket : Result := kVK_ANSI_LeftBracket; + vkBackslash : Result := kVK_ANSI_Backslash; + vkRightBracket : Result := kVK_ANSI_RightBracket; + vkQuote : Result := kVK_ANSI_Quote; + vkOem102 : Result := kVK_ANSI_Backslash; // kVK_JIS_Yen in Japanese keyboards ? + vkOemClear : Result := kVK_ANSI_KeypadClear; + else Result := 0; + end; +end; + +{$IFDEF FMX} procedure CopyAllFiles(const aSrcPath, aDstPath: string); var TempDirectories, TempFiles : TStringDynArray; @@ -88,7 +241,7 @@ begin end; except on e : exception do - WriteLn('CopyAllFiles error : ' + e.Message); + FMX.Types.Log.d('CopyAllFiles error : ' + e.Message); end; end; @@ -114,7 +267,7 @@ begin end; except on e : exception do - WriteLn('CopyCEFFramework error : ' + e.Message); + FMX.Types.Log.d('CopyCEFFramework error : ' + e.Message); end; end; @@ -171,8 +324,8 @@ begin RenameFile(aHelperPrjPath, appNewBundlePath); end; except - on e: exception do - WriteLn('RenameCEFHelper error : ' + e.Message); + on e : exception do + FMX.Types.Log.d('RenameCEFHelper error : ' + e.Message); end; end; @@ -212,7 +365,7 @@ begin end; end; end; - - +{$ENDIF} +{$ENDIF} end. diff --git a/source/uCEFWorkScheduler.pas b/source/uCEFWorkScheduler.pas index 840129eb..491a97c5 100644 --- a/source/uCEFWorkScheduler.pas +++ b/source/uCEFWorkScheduler.pas @@ -46,13 +46,6 @@ unit uCEFWorkScheduler; {$I cef.inc} -// Define this conditional to use TCEFWorkSchedulerQueueThread instead of using -// PostMessage, Application.QueueAsyncCall or TThread.Queue inside -// TCEFWorkScheduler.ScheduleMessagePumpWork -// TCEFWorkSchedulerQueueThread is just a new experimental way to handle the -// external message pump events for all platforms. -{.$DEFINE USEQUEUETHREAD} - interface uses @@ -66,7 +59,7 @@ uses Messages, {$ENDIF} {$ENDIF} - uCEFConstants, {$IFDEF USEQUEUETHREAD}uCEFWorkSchedulerQueueThread,{$ENDIF} uCEFWorkSchedulerThread; + uCEFConstants, uCEFWorkSchedulerQueueThread, uCEFWorkSchedulerThread; type @@ -74,13 +67,12 @@ type TCEFWorkScheduler = class(TComponent) protected FThread : TCEFWorkSchedulerThread; - {$IFDEF USEQUEUETHREAD} FQueueThread : TCEFWorkSchedulerQueueThread; - {$ENDIF} FDepleteWorkCycles : cardinal; FDepleteWorkDelay : cardinal; FDefaultInterval : integer; FStopped : boolean; + FUseQueueThread : boolean; {$IFDEF MSWINDOWS} {$WARN SYMBOL_PLATFORM OFF} FCompHandle : HWND; @@ -88,11 +80,9 @@ type {$WARN SYMBOL_PLATFORM ON} {$ENDIF} - {$IFDEF USEQUEUETHREAD} procedure CreateQueueThread; procedure DestroyQueueThread; procedure QueueThread_OnPulse(Sender : TObject; aDelay : integer); - {$ENDIF} procedure DestroyThread; procedure DepleteWork; @@ -136,6 +126,7 @@ type property DefaultInterval : integer read FDefaultInterval write SetDefaultInterval default CEF_TIMER_MAXDELAY; property DepleteWorkCycles : cardinal read FDepleteWorkCycles write FDepleteWorkCycles default CEF_TIMER_DEPLETEWORK_CYCLES; property DepleteWorkDelay : cardinal read FDepleteWorkDelay write FDepleteWorkDelay default CEF_TIMER_DEPLETEWORK_DELAY; + property UseQueueThread : boolean read FUseQueueThread write FUseQueueThread default False; end; var @@ -199,9 +190,7 @@ end; destructor TCEFWorkScheduler.Destroy; begin DestroyThread; - {$IFDEF USEQUEUETHREAD} DestroyQueueThread; - {$ENDIF} {$IFDEF MSWINDOWS} DeallocateWindowHandle; {$ENDIF} @@ -210,10 +199,9 @@ end; procedure TCEFWorkScheduler.Initialize; begin + FUseQueueThread := False; FThread := nil; - {$IFDEF USEQUEUETHREAD} FQueueThread := nil; - {$ENDIF} FStopped := False; {$IFDEF MSWINDOWS} {$WARN SYMBOL_PLATFORM OFF} @@ -246,12 +234,10 @@ begin {$ENDIF} {$ENDIF} - {$IFDEF USEQUEUETHREAD} - CreateQueueThread; - {$ENDIF} -end; + if FUseQueueThread then + CreateQueueThread; +end; -{$IFDEF USEQUEUETHREAD} procedure TCEFWorkScheduler.CreateQueueThread; begin FQueueThread := TCEFWorkSchedulerQueueThread.Create; @@ -287,7 +273,6 @@ procedure TCEFWorkScheduler.QueueThread_OnPulse(Sender : TObject; aDelay : integ begin ScheduleWork(aDelay); end; -{$ENDIF} procedure TCEFWorkScheduler.DestroyThread; begin @@ -322,6 +307,14 @@ begin FCompHandle := 0; end; end; + +{$WARN SYMBOL_PLATFORM OFF} +procedure TCEFWorkScheduler.SetPriority(aValue : TThreadPriority); +begin + FPriority := aValue; + if (FThread <> nil) then FThread.Priority := aValue; +end; +{$WARN SYMBOL_PLATFORM ON} {$ENDIF} procedure TCEFWorkScheduler.DoMessageLoopWork; @@ -335,16 +328,6 @@ begin if (FThread <> nil) then FThread.DefaultInterval := aValue; end; -{$IFDEF MSWINDOWS} -{$WARN SYMBOL_PLATFORM OFF} -procedure TCEFWorkScheduler.SetPriority(aValue : TThreadPriority); -begin - FPriority := aValue; - if (FThread <> nil) then FThread.Priority := aValue; -end; -{$WARN SYMBOL_PLATFORM ON} -{$ENDIF} - procedure TCEFWorkScheduler.DepleteWork; var i : cardinal; @@ -363,27 +346,24 @@ procedure TCEFWorkScheduler.ScheduleMessagePumpWork(const delay_ms : int64); begin if FStopped then exit; - {$IFDEF USEQUEUETHREAD} - if (FQueueThread <> nil) and FQueueThread.Ready then - begin - FQueueThread.EnqueueValue(integer(delay_ms)); - exit; - end; - {$ENDIF} - - {$IFDEF MSWINDOWS} - if (FCompHandle <> 0) then - PostMessage(FCompHandle, CEF_PUMPHAVEWORK, 0, LPARAM(delay_ms)); - {$ELSE} - {$IFDEF FPC} - Application.QueueAsyncCall(@ScheduleWorkAsync, integer(delay_ms)); - {$ELSE} - TThread.Queue(nil, procedure - begin - ScheduleWork(delay_ms); - end); - {$ENDIF} - {$ENDIF} + if FUseQueueThread and (FQueueThread <> nil) and FQueueThread.Ready then + FQueueThread.EnqueueValue(integer(delay_ms)) + else + begin + {$IFDEF MSWINDOWS} + if (FCompHandle <> 0) then + PostMessage(FCompHandle, CEF_PUMPHAVEWORK, 0, LPARAM(delay_ms)); + {$ELSE} + {$IFDEF FPC} + Application.QueueAsyncCall(@ScheduleWorkAsync, integer(delay_ms)); + {$ELSE} + TThread.ForceQueue(nil, procedure + begin + ScheduleWork(delay_ms); + end); + {$ENDIF} + {$ENDIF} + end; end; {$IFNDEF MSWINDOWS}{$IFDEF FPC} diff --git a/source/uCEFWorkSchedulerQueueThread.pas b/source/uCEFWorkSchedulerQueueThread.pas index 26f02cf6..71ab91bf 100644 --- a/source/uCEFWorkSchedulerQueueThread.pas +++ b/source/uCEFWorkSchedulerQueueThread.pas @@ -91,7 +91,7 @@ type procedure EnqueueValue(aValue : integer); property Ready : boolean read FReady; - property OnPulse : TOnPulseEvent read FOnPulse write FOnPulse; + property OnPulse : TOnPulseEvent read FOnPulse write FOnPulse; end; implementation diff --git a/source/uCEFWorkSchedulerThread.pas b/source/uCEFWorkSchedulerThread.pas index c2eba4af..3cf7e42e 100644 --- a/source/uCEFWorkSchedulerThread.pas +++ b/source/uCEFWorkSchedulerThread.pas @@ -176,7 +176,9 @@ begin FPulsing := False; finally Unlock; - if not(Terminated) then Synchronize({$IFDEF FPC}self, @{$ENDIF}DoOnPulseEvent); + + if not(Terminated) then + Synchronize({$IFDEF FPC}self, @{$ENDIF}DoOnPulseEvent); end; end; diff --git a/update_CEF4Delphi.json b/update_CEF4Delphi.json index ccef7748..f7a0951e 100644 --- a/update_CEF4Delphi.json +++ b/update_CEF4Delphi.json @@ -2,7 +2,7 @@ "UpdateLazPackages" : [ { "ForceNotify" : true, - "InternalVersion" : 296, + "InternalVersion" : 297, "Name" : "cef4delphi_lazarus.lpk", "Version" : "90.6.6.0" }