From e2815ed2f4672c4afa3e8354247ac3f9fad52943 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Salvador=20D=C3=ADaz=20Fau?= Date: Sun, 8 Sep 2024 17:32:30 +0200 Subject: [PATCH] Check macOS version before initialization --- source/uCEFApplicationCore.pas | 46 +++++++++++++-- source/uCEFMacOSFunctions.pas | 103 ++++++++++++++++++++++++++++++--- update_CEF4Delphi.json | 2 +- 3 files changed, 139 insertions(+), 12 deletions(-) diff --git a/source/uCEFApplicationCore.pas b/source/uCEFApplicationCore.pas index 2fc1edd5..d256d636 100644 --- a/source/uCEFApplicationCore.pas +++ b/source/uCEFApplicationCore.pas @@ -384,6 +384,10 @@ type function CheckCEFDLL : boolean; virtual; function CheckWindowsVersion: boolean; virtual; {$ENDIF} + {$IFDEF MACOSX} + function CheckMacOSVersion : boolean; virtual; + {$ENDIF} + function CheckOSVersion: boolean; virtual; procedure ShowErrorMessageDlg(const aError : string); virtual; function ParseProcessType : TCefProcessType; procedure AddCustomCommandLineSwitches(var aKeys, aValues : TStringList); virtual; @@ -1802,7 +1806,7 @@ uses System.Math, System.IOUtils, System.SysUtils, {$IFDEF MSWINDOWS}WinApi.TlHelp32, WinApi.PSAPI,{$ENDIF} {$IFDEF LINUX}{$IFDEF FMX}Posix.Unistd, Posix.Stdio,{$ENDIF}{$ENDIF} - {$IFDEF MACOS}Posix.Stdio, uCEFMacOSFunctions,{$ENDIF} + {$IFDEF MACOS}Posix.Stdio,{$ENDIF} {$ELSE} Math, {$IFDEF DELPHI14_UP}IOUtils,{$ENDIF} SysUtils, {$IFDEF FPC} @@ -1812,6 +1816,7 @@ uses TlHelp32, {$IFDEF MSWINDOWS}PSAPI,{$ENDIF} {$ENDIF} {$ENDIF} + {$IFDEF MACOSX}uCEFMacOSFunctions,{$ENDIF} uCEFLibFunctions, uCEFMiscFunctions, uCEFCommandLine, uCEFConstants, uCEFSchemeHandlerFactory, uCEFCookieManager, uCEFApp, uCEFCompletionCallback, uCEFWaitableEvent; @@ -2590,11 +2595,44 @@ begin end; {$ENDIF} +{$IFDEF MACOSX} +function TCefApplicationCore.CheckMacOSVersion : boolean; +begin + // Chromium crashes with the compatibility mode and old OS versions + // https://source.chromium.org/chromium/chromium/src/+/main:base/mac/mac_util.mm;drc=6166dba74ab72a84a6c7c575cacb438e6bfb2c66;l=338 + // https://support.google.com/chrome/a/answer/7100626?hl=en + if CheckRealMacOSVersion(11, 0) then + Result := True + else + begin + Result := False; + FStatus := asErrorWindowsVersion; + FLastErrorMessage := 'Unsupported macOS version !' + + CRLF + CRLF + + 'Chromium requires macOS 11.0 or later.'; + ShowErrorMessageDlg(FLastErrorMessage); + end; +end; +{$ENDIF} + +function TCefApplicationCore.CheckOSVersion: boolean; +begin + {$IFDEF MSWINDOWS} + Result := CheckWindowsVersion; + {$ELSE} + {$IFDEF MACOSX} + Result := CheckMacOSVersion; + {$ELSE} + Result := True; // Linux + {$ENDIF} + {$ENDIF} +end; + function TCefApplicationCore.CheckCEFLibrary : boolean; var TempOldDir : string; begin - if not(FCheckCEFFiles) or (FProcessType <> ptBrowser) then + if (FProcessType <> ptBrowser) then begin Result := True; exit; @@ -2606,9 +2644,9 @@ begin chdir(GetModulePath); end; - Result := CheckCEFResources; + Result := (not(FCheckCEFFiles) or CheckCEFResources) and CheckOSVersion; {$IFDEF MSWINDOWS} - Result := Result and CheckWindowsVersion and CheckCEFDLL; + Result := Result and (not(FCheckCEFFiles) or CheckCEFDLL); {$ENDIF} if FSetCurrentDir then chdir(TempOldDir); diff --git a/source/uCEFMacOSFunctions.pas b/source/uCEFMacOSFunctions.pas index 0558ed9c..8d192ad2 100644 --- a/source/uCEFMacOSFunctions.pas +++ b/source/uCEFMacOSFunctions.pas @@ -12,16 +12,20 @@ unit uCEFMacOSFunctions; interface uses - System.UITypes, {$IFDEF MACOS} - FMX.Helpers.Mac, System.Messaging, Macapi.CoreFoundation, Macapi.Foundation, + System.UITypes, FMX.Helpers.Mac, System.Messaging, Macapi.CoreFoundation, Macapi.Foundation, + {$ENDIF} + {$IFDEF DARWIN} + SysCtl, SysUtils, Unix, {$ENDIF} uCEFMacOSConstants; {$IFDEF MACOSX} -function KeyToMacOSKeyCode(aKey : Word): integer; +function GetSysCtlValueByName(const aName: AnsiString) : string; +function CheckRealMacOSVersion(aMajor, aMinor: integer): boolean; {$ENDIF} -{$IFDEF MACOS} +{$IFDEF MACOS} +function KeyToMacOSKeyCode(aKey : Word): integer; procedure CopyCEFFramework; procedure CopyCEFHelpers(const aProjectName : string); procedure ShowMessageCF(const aHeading, aMessage : string; const aTimeoutInSecs : double = 0); @@ -33,7 +37,7 @@ implementation {$IFDEF MACOS} uses System.SysUtils, System.Types, System.IOUtils, Posix.Stdio, FMX.Types, - uCEFMiscFunctions; + Posix.SysSysctl, uCEFMiscFunctions; const PRJ_HELPER_SUBFIX = '_helper'; @@ -49,6 +53,93 @@ const {$ENDIF} {$IFDEF MACOSX} +function GetSysCtlValueByName(const aName: AnsiString) : string; +{$IFDEF MACOS} +var + Buffer: TArray; + BufferLength: LongWord; +{$ENDIF} +{$IFDEF DARWIN} +var + Buffer : PChar; + BufferLength : size_t; +{$ENDIF} +begin + {$IFDEF MACOS} + if (SysCtlByName(MarshaledAString(aName), nil, @BufferLength, nil, 0) = 0) and (BufferLength > 0) then + begin + SetLength(Buffer, BufferLength); + try + if (SysCtlByName(MarshaledAString(aName), @Buffer[0], @BufferLength, nil, 0) = 0) then + Result := string(MarshaledAString(@Buffer[0])); + finally + SetLength(Buffer, 0); + end; + end; + {$ENDIF} + {$IFDEF DARWIN} + if (fpSysCtlByName(PChar(aName), nil, @BufferLength, nil, 0) = 0) and (BufferLength > 0) then + begin + GetMem(Buffer, BufferLength); + try + if (fpSysCtlByName(PChar(aName), Buffer, @BufferLength, nil, 0) = 0) then + Result := Buffer; + finally + FreeMem(Buffer); + end; + end; + {$ENDIF} +end; + +function CheckRealMacOSVersion(aMajor, aMinor: integer): boolean; +var + TempValue : string; + TempMajor, TempMinor, i : integer; +begin + TempMajor := 0; + TempMinor := 0; + TempValue := trim(GetSysCtlValueByName('kern.osproductversion')); + + if (length(TempValue) > 0) then + begin + i := pos('.', TempValue); + if (i > 0) then + begin + TempMajor := StrToIntDef(copy(TempValue, 1, pred(i)), 0); + TempValue := copy(TempValue, succ(i), length(TempValue)); + end + else + begin + i := pos(' ', TempValue); + if (i > 0) then + begin + TempMajor := StrToIntDef(copy(TempValue, 1, pred(i)), 0); + TempValue := copy(TempValue, succ(i), length(TempValue)); + end; + end; + + if (length(TempValue) > 0) then + begin + i := pos('.', TempValue); + if (i > 0) then + TempMinor := StrToIntDef(copy(TempValue, 1, pred(i)), 0) + else + begin + i := pos(' ', TempValue); + if (i > 0) then + TempMinor := StrToIntDef(copy(TempValue, 1, pred(i)), 0) + else + TempMinor := StrToIntDef(TempValue, 0); + end; + end; + end; + + Result := (TempMajor > aMajor) or + ((TempMajor = aMajor) and (TempMinor >= aMinor)); +end; +{$ENDIF} + +{$IFDEF MACOS} // 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 @@ -178,9 +269,7 @@ begin else Result := 0; end; end; -{$ENDIF} -{$IFDEF MACOS} procedure CopyAllFiles(const aSrcPath, aDstPath: string); var TempDirectories, TempFiles : TStringDynArray; diff --git a/update_CEF4Delphi.json b/update_CEF4Delphi.json index 6bc2bf2c..15270bbe 100644 --- a/update_CEF4Delphi.json +++ b/update_CEF4Delphi.json @@ -2,7 +2,7 @@ "UpdateLazPackages" : [ { "ForceNotify" : true, - "InternalVersion" : 651, + "InternalVersion" : 652, "Name" : "cef4delphi_lazarus.lpk", "Version" : "128.4.9" }