You've already forked CEF4Delphi
mirror of
https://github.com/salvadordf/CEF4Delphi.git
synced 2025-09-30 21:28:55 +02:00
Added GTKBrowser demo. (work in progress)
Added GlobalCEFApp.OzonePlatform Added TCefOzonePlatform Added gdk_x11_display_get_xdisplay Added gdk_x11_screen_get_screen_number Added gdk_x11_visual_get_xvisual Added UseDefaultX11VisualForGtk Added FlushDisplay Fixed TCEFWindowInfoWrapper.AsChild in GTK3
This commit is contained in:
2
demos/Lazarus_Linux_GTK3/GTKBrowser/00-Delete.bat
Normal file
2
demos/Lazarus_Linux_GTK3/GTKBrowser/00-Delete.bat
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
rmdir /S /Q lib
|
||||||
|
rmdir /S /Q backup
|
82
demos/Lazarus_Linux_GTK3/GTKBrowser/GTKBrowser.lpi
Normal file
82
demos/Lazarus_Linux_GTK3/GTKBrowser/GTKBrowser.lpi
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<CONFIG>
|
||||||
|
<ProjectOptions>
|
||||||
|
<Version Value="12"/>
|
||||||
|
<General>
|
||||||
|
<Flags>
|
||||||
|
<MainUnitHasCreateFormStatements Value="False"/>
|
||||||
|
<MainUnitHasTitleStatement Value="False"/>
|
||||||
|
<MainUnitHasScaledStatement Value="False"/>
|
||||||
|
</Flags>
|
||||||
|
<SessionStorage Value="InProjectDir"/>
|
||||||
|
<Title Value="GTKBrowser"/>
|
||||||
|
<UseAppBundle Value="False"/>
|
||||||
|
<ResourceType Value="res"/>
|
||||||
|
</General>
|
||||||
|
<MacroValues Count="1">
|
||||||
|
<Macro1 Name="LCLWidgetType" Value="gtk3"/>
|
||||||
|
</MacroValues>
|
||||||
|
<BuildModes>
|
||||||
|
<Item Name="Default" Default="True"/>
|
||||||
|
<SharedMatrixOptions Count="1">
|
||||||
|
<Item1 ID="267891709676" Modes="Default" Type="IDEMacro" MacroName="LCLWidgetType" Value="gtk3"/>
|
||||||
|
</SharedMatrixOptions>
|
||||||
|
</BuildModes>
|
||||||
|
<PublishOptions>
|
||||||
|
<Version Value="2"/>
|
||||||
|
<UseFileFilters Value="True"/>
|
||||||
|
</PublishOptions>
|
||||||
|
<RunParams>
|
||||||
|
<FormatVersion Value="2"/>
|
||||||
|
</RunParams>
|
||||||
|
<RequiredPackages>
|
||||||
|
<Item>
|
||||||
|
<PackageName Value="CEF4Delphi_Lazarus"/>
|
||||||
|
</Item>
|
||||||
|
<Item>
|
||||||
|
<PackageName Value="LCL"/>
|
||||||
|
</Item>
|
||||||
|
</RequiredPackages>
|
||||||
|
<Units>
|
||||||
|
<Unit>
|
||||||
|
<Filename Value="GTKBrowser.lpr"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
</Unit>
|
||||||
|
<Unit>
|
||||||
|
<Filename Value="umainwindow.pas"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
</Unit>
|
||||||
|
</Units>
|
||||||
|
</ProjectOptions>
|
||||||
|
<CompilerOptions>
|
||||||
|
<Version Value="11"/>
|
||||||
|
<Target>
|
||||||
|
<Filename Value="../../../bin/GTKBrowser"/>
|
||||||
|
</Target>
|
||||||
|
<SearchPaths>
|
||||||
|
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||||
|
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
|
||||||
|
</SearchPaths>
|
||||||
|
<Linking>
|
||||||
|
<Debugging>
|
||||||
|
<DebugInfoType Value="dsDwarf3"/>
|
||||||
|
</Debugging>
|
||||||
|
</Linking>
|
||||||
|
<Other>
|
||||||
|
<CustomOptions Value="-dUseCthreads"/>
|
||||||
|
</Other>
|
||||||
|
</CompilerOptions>
|
||||||
|
<Debugging>
|
||||||
|
<Exceptions>
|
||||||
|
<Item>
|
||||||
|
<Name Value="EAbort"/>
|
||||||
|
</Item>
|
||||||
|
<Item>
|
||||||
|
<Name Value="ECodetoolError"/>
|
||||||
|
</Item>
|
||||||
|
<Item>
|
||||||
|
<Name Value="EFOpenError"/>
|
||||||
|
</Item>
|
||||||
|
</Exceptions>
|
||||||
|
</Debugging>
|
||||||
|
</CONFIG>
|
24
demos/Lazarus_Linux_GTK3/GTKBrowser/GTKBrowser.lpr
Normal file
24
demos/Lazarus_Linux_GTK3/GTKBrowser/GTKBrowser.lpr
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
program GTKBrowser;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
uses
|
||||||
|
{$IFDEF UseCThreads}
|
||||||
|
cthreads,
|
||||||
|
{$ENDIF}
|
||||||
|
uCEFApplication, umainwindow;
|
||||||
|
|
||||||
|
begin
|
||||||
|
CreateGlobalCEFApp;
|
||||||
|
|
||||||
|
if StartMainProcess then
|
||||||
|
begin
|
||||||
|
MainWindow := TMainWindow.Create;
|
||||||
|
MainWindow.Show;
|
||||||
|
MainWindow.Run;
|
||||||
|
MainWindow.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
DestroyGlobalCEFApp;
|
||||||
|
end.
|
||||||
|
|
355
demos/Lazarus_Linux_GTK3/GTKBrowser/umainwindow.pas
Normal file
355
demos/Lazarus_Linux_GTK3/GTKBrowser/umainwindow.pas
Normal file
@@ -0,0 +1,355 @@
|
|||||||
|
unit umainwindow;
|
||||||
|
|
||||||
|
{$mode ObjFPC}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, SyncObjs,
|
||||||
|
LazGtk3, LazGdk3, LazGObject2, LazGLib2, xlib,
|
||||||
|
uCEFApplication, uCEFConstants, uCEFTypes, uCEFChromium,
|
||||||
|
uCEFMiscFunctions, uCEFLinuxFunctions, uCEFInterfaces;
|
||||||
|
|
||||||
|
type
|
||||||
|
TMainWindow = class
|
||||||
|
private
|
||||||
|
FCanClose : boolean;
|
||||||
|
FClosing : boolean;
|
||||||
|
FInitializing : boolean;
|
||||||
|
FLoading : boolean;
|
||||||
|
FWindow : PGtkWidget;
|
||||||
|
FChromium : TChromium;
|
||||||
|
|
||||||
|
function GetTitle : string;
|
||||||
|
function GetWidth : integer;
|
||||||
|
function GetHeight : integer;
|
||||||
|
|
||||||
|
procedure SetTitle(const aValue : string);
|
||||||
|
|
||||||
|
procedure DoAfterCreated;
|
||||||
|
procedure DoBeforeClose;
|
||||||
|
procedure DoCloseQuery(var aCanClose: Boolean);
|
||||||
|
procedure DoResize;
|
||||||
|
|
||||||
|
procedure UpdateBrowserSize(aLeft, aTop, aWidth, aHeight : integer);
|
||||||
|
procedure UpdateXWindowVisibility(aVisible : boolean);
|
||||||
|
procedure NotifyMoveOrResizeStarted;
|
||||||
|
procedure CloseBrowser(aForceClose : boolean);
|
||||||
|
procedure CreateBrowser;
|
||||||
|
procedure CreateWidgets;
|
||||||
|
|
||||||
|
procedure OnAfterCreated(Sender: TObject; const browser: ICefBrowser);
|
||||||
|
procedure OnBeforeClose(Sender: TObject; const browser: ICefBrowser);
|
||||||
|
procedure OnBeforePopup(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; popup_id: Integer; 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, Result: Boolean);
|
||||||
|
procedure OnOpenUrlFromTab(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const targetUrl: ustring; targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; out Result: Boolean);
|
||||||
|
|
||||||
|
public
|
||||||
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
|
procedure AfterConstruction; override;
|
||||||
|
procedure Show;
|
||||||
|
procedure Run;
|
||||||
|
|
||||||
|
property Width : integer read GetWidth;
|
||||||
|
property Height : integer read GetHeight;
|
||||||
|
property Title : string read GetTitle write SetTitle;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
MainWindow : TMainWindow = nil;
|
||||||
|
|
||||||
|
procedure CreateGlobalCEFApp;
|
||||||
|
function StartMainProcess: boolean;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
var
|
||||||
|
MainAppEvent : TEventObject = nil;
|
||||||
|
|
||||||
|
{GlobalCEFApp functions}
|
||||||
|
{%Region}
|
||||||
|
procedure GlobalCEFApp_OnContextInitialized();
|
||||||
|
begin
|
||||||
|
MainAppEvent.SetEvent;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CreateGlobalCEFApp;
|
||||||
|
begin
|
||||||
|
GlobalCEFApp := TCefApplication.Create;
|
||||||
|
GlobalCEFApp.LogFile := 'debug.log';
|
||||||
|
GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO;
|
||||||
|
GlobalCEFApp.RootCache := 'RootCache';
|
||||||
|
GlobalCEFApp.DisableZygote := True;
|
||||||
|
GlobalCEFApp.SetCurrentDir := True;
|
||||||
|
GlobalCEFApp.MultiThreadedMessageLoop := False;
|
||||||
|
GlobalCEFApp.ExternalMessagePump := False;
|
||||||
|
GlobalCEFApp.GTKVersion := gtkVersion3;
|
||||||
|
GlobalCEFApp.OzonePlatform := ozpX11;
|
||||||
|
GlobalCEFApp.OnContextInitialized := @GlobalCEFApp_OnContextInitialized;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function StartMainProcess: boolean;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
|
||||||
|
if GlobalCEFApp.StartMainProcess then
|
||||||
|
begin
|
||||||
|
// Wait until the context is initialized before initializing GTK.
|
||||||
|
if (MainAppEvent.WaitFor(10000) = wrTimeout) then
|
||||||
|
CefDebugLog('CEF initialization failure!')
|
||||||
|
else
|
||||||
|
Result := True;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
{%Endregion}
|
||||||
|
|
||||||
|
{Message handlers}
|
||||||
|
{%Region}
|
||||||
|
function DeleteEventHandler(widget: PGtkWidget; event: PGdkEventAny): gboolean; cdecl;
|
||||||
|
var
|
||||||
|
TempCanClose : boolean;
|
||||||
|
begin
|
||||||
|
MainWindow.DoCloseQuery(TempCanClose);
|
||||||
|
Result := not(TempCanClose);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function DestroyEventHandler(widget: PGtkWidget; event: PGdkEventAny): gboolean; cdecl;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
GlobalCEFApp.QuitMessageLoop;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ShowEventHandler(Widget: PGtkWidget; Data: gPointer): gboolean; cdecl;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
MainWindow.CreateBrowser;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ConfigureEvent(widget: PGtkWidget; event: PGdkEventConfigure): gboolean; cdecl;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
MainWindow.DoResize;
|
||||||
|
MainWindow.NotifyMoveOrResizeStarted;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function CustomX11ErrorHandler(Display: PDisplay; ErrorEv: PXErrorEvent) : longint; cdecl;
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function CustomXIOErrorHandler(Display: PDisplay) : longint; cdecl;
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
end;
|
||||||
|
{%Endregion}
|
||||||
|
|
||||||
|
{Public methods}
|
||||||
|
{%Region}
|
||||||
|
constructor TMainWindow.Create;
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
|
||||||
|
FCanClose := False;
|
||||||
|
FClosing := False;
|
||||||
|
FInitializing := True;
|
||||||
|
FLoading := False;
|
||||||
|
FWindow := nil;
|
||||||
|
FChromium := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TMainWindow.Destroy;
|
||||||
|
begin
|
||||||
|
if (FChromium <> nil) then
|
||||||
|
FreeAndNil(FChromium);
|
||||||
|
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainWindow.AfterConstruction;
|
||||||
|
begin
|
||||||
|
inherited AfterConstruction;
|
||||||
|
|
||||||
|
// Force Gtk to use Xwayland (in case a Wayland compositor is being used).
|
||||||
|
gdk_set_allowed_backends('x11');
|
||||||
|
|
||||||
|
// The Chromium sandbox requires that there only be a single thread during
|
||||||
|
// initialization. Therefore initialize GTK after CEF.
|
||||||
|
gtk_init(@argc, @argv);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
FChromium := TChromium.Create(nil);
|
||||||
|
FChromium.DefaultURL := 'https://www.google.com';
|
||||||
|
FChromium.OnAfterCreated := @OnAfterCreated;
|
||||||
|
FChromium.OnBeforeClose := @OnBeforeClose;
|
||||||
|
FChromium.OnBeforePopup := @OnBeforePopup;
|
||||||
|
FChromium.OnOpenUrlFromTab := @OnOpenUrlFromTab;
|
||||||
|
|
||||||
|
CreateWidgets;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainWindow.Show;
|
||||||
|
begin
|
||||||
|
// Show the GTK window.
|
||||||
|
UseDefaultX11VisualForGtk(FWindow);
|
||||||
|
gtk_widget_show_all(FWindow);
|
||||||
|
|
||||||
|
// Flush the display to make sure the underlying X11 window gets created
|
||||||
|
// immediately.
|
||||||
|
FlushDisplay(FWindow);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainWindow.Run;
|
||||||
|
begin
|
||||||
|
GlobalCEFApp.RunMessageLoop;
|
||||||
|
end;
|
||||||
|
{%Endregion}
|
||||||
|
|
||||||
|
{Property setters and getters}
|
||||||
|
{%Region}
|
||||||
|
function TMainWindow.GetTitle: string;
|
||||||
|
begin
|
||||||
|
Result := gtk_window_get_title(PGtkWindow(FWindow));
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TMainWindow.GetWidth : integer;
|
||||||
|
begin
|
||||||
|
Result := gtk_widget_get_allocated_width(FWindow);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TMainWindow.GetHeight : integer;
|
||||||
|
begin
|
||||||
|
Result := gtk_widget_get_allocated_height(FWindow);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainWindow.SetTitle(const aValue : string);
|
||||||
|
begin
|
||||||
|
gtk_window_set_title(PGtkWindow(FWindow), PGChar(aValue));
|
||||||
|
end;
|
||||||
|
{%Endregion}
|
||||||
|
|
||||||
|
{Chromium events}
|
||||||
|
{%Region}
|
||||||
|
procedure TMainWindow.OnAfterCreated(Sender: TObject; const browser: ICefBrowser);
|
||||||
|
begin
|
||||||
|
TThread.Synchronize(nil, @DoAfterCreated);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainWindow.OnBeforeClose(Sender: TObject; const browser: ICefBrowser);
|
||||||
|
begin
|
||||||
|
FCanClose := True;
|
||||||
|
TThread.Synchronize(nil, @DoBeforeClose);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainWindow.OnBeforePopup(Sender: TObject;
|
||||||
|
const browser: ICefBrowser; const frame: ICefFrame; popup_id: Integer;
|
||||||
|
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, Result: Boolean);
|
||||||
|
begin
|
||||||
|
// For simplicity, this demo blocks all popup windows and new tabs
|
||||||
|
Result := (targetDisposition in [CEF_WOD_NEW_FOREGROUND_TAB, CEF_WOD_NEW_BACKGROUND_TAB, CEF_WOD_NEW_POPUP, CEF_WOD_NEW_WINDOW]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainWindow.OnOpenUrlFromTab(Sender: TObject;
|
||||||
|
const browser: ICefBrowser; const frame: ICefFrame;
|
||||||
|
const targetUrl: ustring; targetDisposition: TCefWindowOpenDisposition;
|
||||||
|
userGesture: Boolean; out Result: Boolean);
|
||||||
|
begin
|
||||||
|
// For simplicity, this demo blocks all popup windows and new tabs
|
||||||
|
Result := (targetDisposition in [CEF_WOD_NEW_FOREGROUND_TAB, CEF_WOD_NEW_BACKGROUND_TAB, CEF_WOD_NEW_POPUP, CEF_WOD_NEW_WINDOW]);
|
||||||
|
end;
|
||||||
|
{%Endregion}
|
||||||
|
|
||||||
|
{Private methods}
|
||||||
|
{%Region}
|
||||||
|
procedure TMainWindow.UpdateBrowserSize(aLeft, aTop, aWidth, aHeight : integer);
|
||||||
|
begin
|
||||||
|
if (FChromium <> nil) and FChromium.Initialized then
|
||||||
|
FChromium.UpdateBrowserSize(aLeft, aTop, aWidth, aHeight);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainWindow.UpdateXWindowVisibility(aVisible : boolean);
|
||||||
|
begin
|
||||||
|
if (FChromium <> nil) and FChromium.Initialized then
|
||||||
|
FChromium.UpdateXWindowVisibility(aVisible);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainWindow.DoAfterCreated;
|
||||||
|
begin
|
||||||
|
UpdateXWindowVisibility(True);
|
||||||
|
UpdateBrowserSize(0, 0, Width, Height);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainWindow.DoBeforeClose;
|
||||||
|
begin
|
||||||
|
gtk_window_close(PGtkWindow(FWindow));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainWindow.DoResize;
|
||||||
|
begin
|
||||||
|
UpdateBrowserSize(0, 0, Width, Height);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainWindow.DoCloseQuery(var aCanClose: Boolean);
|
||||||
|
begin
|
||||||
|
aCanClose := FCanClose;
|
||||||
|
|
||||||
|
if not(FClosing) then
|
||||||
|
begin
|
||||||
|
FClosing := True;
|
||||||
|
FChromium.CloseBrowser(True);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainWindow.CreateBrowser;
|
||||||
|
begin
|
||||||
|
if (FChromium <> nil) and not(FChromium.Initialized) then
|
||||||
|
begin
|
||||||
|
if not(FChromium.CreateBrowser(TCefWindowHandle(FWindow), Rect(0, 0, Width, Height))) then
|
||||||
|
CefDebugLog('CreateBrowser failed');
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainWindow.CreateWidgets;
|
||||||
|
begin
|
||||||
|
FWindow := gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||||
|
|
||||||
|
gtk_window_set_default_size(PGtkWindow(FWindow), 1024, 768);
|
||||||
|
gtk_window_move(PGtkWindow(FWindow), 300, 200);
|
||||||
|
|
||||||
|
g_signal_connect_data(FWindow, 'delete_event', TGCallback(@DeleteEventHandler), nil, nil, G_CONNECT_DEFAULT);
|
||||||
|
g_signal_connect_data(FWindow, 'destroy', TGCallback(@DestroyEventHandler), nil, nil, G_CONNECT_DEFAULT);
|
||||||
|
g_signal_connect_data(FWindow, 'show', TGCallback(@ShowEventHandler), nil, nil, G_CONNECT_DEFAULT);
|
||||||
|
g_signal_connect_data(FWindow, 'configure-event', TGCallback(@ConfigureEvent), nil, nil, G_CONNECT_DEFAULT);
|
||||||
|
|
||||||
|
Title := 'GTKBrowser';
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainWindow.NotifyMoveOrResizeStarted;
|
||||||
|
begin
|
||||||
|
if (FChromium <> nil) then
|
||||||
|
FChromium.NotifyMoveOrResizeStarted;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainWindow.CloseBrowser(aForceClose : boolean);
|
||||||
|
begin
|
||||||
|
if (FChromium <> nil) then
|
||||||
|
FChromium.CloseBrowser(aForceClose);
|
||||||
|
end;
|
||||||
|
{%Endregion}
|
||||||
|
|
||||||
|
initialization
|
||||||
|
MainAppEvent := TEventObject.Create(nil, True, False, 'MainAppEvent');
|
||||||
|
|
||||||
|
finalization
|
||||||
|
if assigned(MainAppEvent) then
|
||||||
|
FreeAndNil(MainAppEvent);
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
@@ -167,6 +167,7 @@ type
|
|||||||
{$IFDEF LINUX}
|
{$IFDEF LINUX}
|
||||||
FPasswordStorage : TCefPasswordStorage;
|
FPasswordStorage : TCefPasswordStorage;
|
||||||
FGTKVersion : TCefGTKVersion;
|
FGTKVersion : TCefGTKVersion;
|
||||||
|
FOzonePlatform : TCefOzonePlatform;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
|
|
||||||
@@ -1351,6 +1352,13 @@ type
|
|||||||
/// <para><see href="https://github.com/chromium/chromium/blob/main/ui/gtk/gtk_compat.cc">See the LoadGtkImpl function in ui/gtk/gtk_compat.cc</see></para>
|
/// <para><see href="https://github.com/chromium/chromium/blob/main/ui/gtk/gtk_compat.cc">See the LoadGtkImpl function in ui/gtk/gtk_compat.cc</see></para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
property GTKVersion : TCefGTKVersion read FGTKVersion write FGTKVersion;
|
property GTKVersion : TCefGTKVersion read FGTKVersion write FGTKVersion;
|
||||||
|
/// <summary>
|
||||||
|
/// Preferred GTK version loaded by Chromium.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para><see href="https://peter.sh/experiments/chromium-command-line-switches/#ozone-platform">Uses the following command line switch: --ozone-platform</see></para>
|
||||||
|
/// </remarks>
|
||||||
|
property OzonePlatform : TCefOzonePlatform read FOzonePlatform write FOzonePlatform;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ignores certificate-related errors.
|
/// Ignores certificate-related errors.
|
||||||
@@ -2063,6 +2071,7 @@ begin
|
|||||||
{$IFDEF LINUX}
|
{$IFDEF LINUX}
|
||||||
FPasswordStorage := psDefault;
|
FPasswordStorage := psDefault;
|
||||||
FGTKVersion := gtkVersionDefault;
|
FGTKVersion := gtkVersionDefault;
|
||||||
|
FOzonePlatform := ozpDefault;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
// Fields used during the CEF initialization
|
// Fields used during the CEF initialization
|
||||||
@@ -3754,6 +3763,12 @@ begin
|
|||||||
gtkVersion3 : ReplaceSwitch(aKeys, aValues, '--gtk-version', '3');
|
gtkVersion3 : ReplaceSwitch(aKeys, aValues, '--gtk-version', '3');
|
||||||
gtkVersion4 : ReplaceSwitch(aKeys, aValues, '--gtk-version', '4');
|
gtkVersion4 : ReplaceSwitch(aKeys, aValues, '--gtk-version', '4');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
case FOzonePlatform of
|
||||||
|
ozpWayland : ReplaceSwitch(aKeys, aValues, '--ozone-platform', 'wayland');
|
||||||
|
ozpX11 : ReplaceSwitch(aKeys, aValues, '--ozone-platform', 'x11');
|
||||||
|
ozpHeadless : ReplaceSwitch(aKeys, aValues, '--ozone-platform', 'headless');
|
||||||
|
end;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
// The list of features you can enable is here :
|
// The list of features you can enable is here :
|
||||||
|
@@ -62,6 +62,13 @@ function gdk_screen_get_resolution(screen:PGdkScreen):gdouble; cdecl; external '
|
|||||||
function gdk_x11_window_get_xid(window: PGdkWindow): TXID; cdecl; external 'libgdk-3.so.0';
|
function gdk_x11_window_get_xid(window: PGdkWindow): TXID; cdecl; external 'libgdk-3.so.0';
|
||||||
function gdk_x11_get_default_xdisplay: PDisplay; cdecl; external 'libgdk-3.so.0';
|
function gdk_x11_get_default_xdisplay: PDisplay; cdecl; external 'libgdk-3.so.0';
|
||||||
procedure gdk_set_allowed_backends(const backends: PGchar); cdecl; external 'libgdk-3.so.0';
|
procedure gdk_set_allowed_backends(const backends: PGchar); cdecl; external 'libgdk-3.so.0';
|
||||||
|
function gdk_x11_display_get_xdisplay(display: PGdkDisplay): PDisplay; cdecl; external 'libgdk-3.so.0';
|
||||||
|
function gdk_x11_screen_get_screen_number(screen: PGdkScreen): longint; cdecl; external 'libgdk-3.so.0';
|
||||||
|
function gdk_x11_visual_get_xvisual(visual: PGdkVisual): PVisual; cdecl; external 'libgdk-3.so.0';
|
||||||
|
procedure UseDefaultX11VisualForGtk(widget : PGtkWidget); overload;
|
||||||
|
procedure UseDefaultX11VisualForGtk(aHandle : TCefWindowHandle); overload;
|
||||||
|
procedure FlushDisplay(widget : PGtkWidget); overload;
|
||||||
|
procedure FlushDisplay(aHandle : TCefWindowHandle); overload;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
procedure ShowX11Message(const aMessage : string);
|
procedure ShowX11Message(const aMessage : string);
|
||||||
{$ENDIF}{$ENDIF}
|
{$ENDIF}{$ENDIF}
|
||||||
@@ -74,6 +81,7 @@ uses
|
|||||||
{$ELSE}
|
{$ELSE}
|
||||||
SysUtils,
|
SysUtils,
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
{$IFDEF LCLGTK3}gtk3widgets,{$ENDIF}
|
||||||
uCEFLinuxConstants, uCEFConstants;
|
uCEFLinuxConstants, uCEFConstants;
|
||||||
|
|
||||||
{$IFDEF LINUX}
|
{$IFDEF LINUX}
|
||||||
@@ -657,6 +665,96 @@ begin
|
|||||||
|
|
||||||
XCloseDisplay(TempDisplay);
|
XCloseDisplay(TempDisplay);
|
||||||
end;
|
end;
|
||||||
{$ENDIF}{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
|
{$IFDEF LCLGTK3}
|
||||||
|
procedure UseDefaultX11VisualForGtk(widget : PGtkWidget);
|
||||||
|
type
|
||||||
|
PGdkX11Screen = type PGdkScreen;
|
||||||
|
var
|
||||||
|
screen : PGdkScreen;
|
||||||
|
visuals, cursor : PGList;
|
||||||
|
x11_screen : PGdkX11Screen;
|
||||||
|
default_xvisual : PVisual;
|
||||||
|
visual : PGdkVisual;
|
||||||
|
|
||||||
|
function GDK_X11_VISUAL(obj : pointer) : PGdkVisual;
|
||||||
|
begin
|
||||||
|
Result := PGdkVisual(obj);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GDK_SCREEN_X11(obj : pointer) : PGdkX11Screen;
|
||||||
|
begin
|
||||||
|
GDK_SCREEN_X11 := PGdkX11Screen(obj);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GDK_SCREEN_XDISPLAY(screen : PGdkScreen) : PDisplay;
|
||||||
|
begin
|
||||||
|
GDK_SCREEN_XDISPLAY := gdk_x11_display_get_xdisplay(gdk_screen_get_display(screen));
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GDK_SCREEN_XNUMBER(screen : PGdkScreen) : longint;
|
||||||
|
begin
|
||||||
|
GDK_SCREEN_XNUMBER := gdk_x11_screen_get_screen_number(screen);
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
// GTK+ > 3.15.1 uses an X11 visual optimized for GTK+'s OpenGL stuff
|
||||||
|
// since revid dae447728d: https://github.com/GNOME/gtk/commit/dae447728d
|
||||||
|
// However, it breaks CEF: https://github.com/cztomczak/cefcapi/issues/9
|
||||||
|
// Let's use the default X11 visual instead of the GTK's blessed one.
|
||||||
|
// Copied from: https://github.com/cztomczak/cefcapi.
|
||||||
|
screen := gdk_screen_get_default();
|
||||||
|
visuals := gdk_screen_list_visuals(screen);
|
||||||
|
x11_screen := GDK_SCREEN_X11(screen);
|
||||||
|
|
||||||
|
if (x11_screen <> nil) then
|
||||||
|
begin
|
||||||
|
default_xvisual := DefaultVisual(GDK_SCREEN_XDISPLAY(x11_screen),
|
||||||
|
GDK_SCREEN_XNUMBER(x11_screen));
|
||||||
|
|
||||||
|
if (default_xvisual <> nil) then
|
||||||
|
begin
|
||||||
|
cursor := visuals;
|
||||||
|
|
||||||
|
while (cursor <> nil) do
|
||||||
|
begin
|
||||||
|
visual := GDK_X11_VISUAL(cursor^.data);
|
||||||
|
|
||||||
|
if (default_xvisual^.visualid = gdk_x11_visual_get_xvisual(visual)^.visualid) then
|
||||||
|
begin
|
||||||
|
gtk_widget_set_visual(widget, visual);
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
|
||||||
|
cursor := cursor^.next;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
g_list_free(visuals);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure UseDefaultX11VisualForGtk(aHandle : TCefWindowHandle);
|
||||||
|
begin
|
||||||
|
UseDefaultX11VisualForGtk(TGtk3Widget(aHandle).Widget);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure FlushDisplay(widget : PGtkWidget);
|
||||||
|
var
|
||||||
|
gdk_window : PGdkWindow;
|
||||||
|
display : PGdkDisplay;
|
||||||
|
begin
|
||||||
|
gdk_window := gtk_widget_get_window(widget);
|
||||||
|
display := gdk_window_get_display(gdk_window);
|
||||||
|
gdk_display_flush(display);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure FlushDisplay(aHandle : TCefWindowHandle);
|
||||||
|
begin
|
||||||
|
FlushDisplay(TGtk3Widget(aHandle).Widget);
|
||||||
|
end;
|
||||||
|
{$ENDIF}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
@@ -478,6 +478,31 @@ type
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
gtkVersion4
|
gtkVersion4
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ozone platform implementation type.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para><see href="https://peter.sh/experiments/chromium-command-line-switches/#ozone-platform">Used by the --ozone-platform switch</see></para>
|
||||||
|
/// </remarks>
|
||||||
|
TCefOzonePlatform = (
|
||||||
|
/// <summary>
|
||||||
|
/// Default platform.
|
||||||
|
/// </summary>
|
||||||
|
ozpDefault,
|
||||||
|
/// <summary>
|
||||||
|
/// Wayland platform.
|
||||||
|
/// </summary>
|
||||||
|
ozpWayland,
|
||||||
|
/// <summary>
|
||||||
|
/// X11 platform.
|
||||||
|
/// </summary>
|
||||||
|
ozpX11,
|
||||||
|
/// <summary>
|
||||||
|
/// Headless platform. Not supported by CEF.
|
||||||
|
/// </summary>
|
||||||
|
ozpHeadless
|
||||||
|
);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@@ -13,9 +13,9 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
{$IFDEF DELPHI16_UP}
|
{$IFDEF DELPHI16_UP}
|
||||||
{$IFDEF MSWINDOWS}WinApi.Windows,{$ENDIF}System.Classes, System.Types,
|
{$IFDEF MSWINDOWS}WinApi.Windows,{$ENDIF}System.Classes, System.Types, System.SysUtils,
|
||||||
{$ELSE}
|
{$ELSE}
|
||||||
{$IFDEF MSWINDOWS}Windows,{$ENDIF}Classes, Types,
|
{$IFDEF MSWINDOWS}Windows,{$ENDIF}Classes, Types, SysUtils,
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
uCEFTypes;
|
uCEFTypes;
|
||||||
|
|
||||||
@@ -236,7 +236,7 @@ uses
|
|||||||
{$IFDEF LINUX}{$IFDEF FPC}
|
{$IFDEF LINUX}{$IFDEF FPC}
|
||||||
ctypes, keysym, xf86keysym, x, xlib,
|
ctypes, keysym, xf86keysym, x, xlib,
|
||||||
{$IFDEF LCLGTK2}gtk2, glib2, gdk2, gtk2proc, gtk2int, Gtk2Def, gdk2x, Gtk2Extra,{$ENDIF}
|
{$IFDEF LCLGTK2}gtk2, glib2, gdk2, gtk2proc, gtk2int, Gtk2Def, gdk2x, Gtk2Extra,{$ENDIF}
|
||||||
{$IFDEF LCLGTK3}LazGdk3, LazGtk3, LazGLib2, gtk3widgets,{$ENDIF}
|
{$IFDEF LCLGTK3}LazGdk3, LazGtk3, LazGLib2, Gtk3Widgets, Gtk3Procs, LazGObject2,{$ENDIF}
|
||||||
uCEFLinuxFunctions,
|
uCEFLinuxFunctions,
|
||||||
{$ENDIF}{$ENDIF}
|
{$ENDIF}{$ENDIF}
|
||||||
uCEFMiscFunctions;
|
uCEFMiscFunctions;
|
||||||
@@ -475,6 +475,9 @@ class procedure TCEFWindowInfoWrapper.AsChild(var aWindowInfo: TCEFWindowInfo; a
|
|||||||
{$IFDEF LINUX}
|
{$IFDEF LINUX}
|
||||||
var
|
var
|
||||||
TempParent : TCefWindowHandle;
|
TempParent : TCefWindowHandle;
|
||||||
|
{$IFDEF LCLGTK3}
|
||||||
|
TempWidget : PGtkWidget;
|
||||||
|
{$ENDIF}
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
begin
|
begin
|
||||||
aWindowInfo.size := SizeOf(TCEFWindowInfo);
|
aWindowInfo.size := SizeOf(TCEFWindowInfo);
|
||||||
@@ -499,24 +502,34 @@ begin
|
|||||||
|
|
||||||
{$IFDEF FPC}
|
{$IFDEF FPC}
|
||||||
{$IFDEF LCLGTK2}
|
{$IFDEF LCLGTK2}
|
||||||
if ValidCefWindowHandle(aParent) and (PGtkWidget(aParent)^.window <> nil) then
|
if ValidCefWindowHandle(aParent) then
|
||||||
TempParent := gdk_window_xwindow(PGtkWidget(aParent)^.window);
|
begin
|
||||||
|
// This is a translation of the GetXWindowForWidget function found in
|
||||||
|
// tests/cefclient/browser/browser_window_std_gtk.cc
|
||||||
|
// That function calls GDK_WINDOW_XID(gtk_widget_get_window(widget)) to get the TempParent value.
|
||||||
|
|
||||||
|
// /usr/include/gtk-2.0/gdk/gdkx.h defines GDK_WINDOW_XID as gdk_x11_drawable_get_xid
|
||||||
|
// /usr/share/lazarus/4.2.0/lcl/interfaces/gtk2/gtk2extrah.inc renames gdk_x11_drawable_get_xid as gdk_window_xwindow
|
||||||
|
|
||||||
|
// aParent is an LCL Handle which can be casted as a PGtkWidget in GTK2.
|
||||||
|
TempParent := gdk_window_xwindow(PGtkWidget(aParent)^.window);
|
||||||
|
end;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
{$IFDEF LCLGTK3}
|
{$IFDEF LCLGTK3}
|
||||||
if ValidCefWindowHandle(aParent) and (TGtk3Widget(aParent).Widget <> nil) then
|
if ValidCefWindowHandle(aParent) then
|
||||||
begin
|
begin
|
||||||
// cefclient creates the main window with this code in root_window_gtk.cc
|
// This is a translation of the GetXWindowForWidget function found in
|
||||||
// window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
// tests/cefclient/browser/browser_window_std_gtk.cc
|
||||||
// Then if populates window_info with :
|
// That function calls GDK_WINDOW_XID(gtk_widget_get_window(widget)) to get the TempParent value.
|
||||||
// window_info.SetAsChild(GetXWindowForWidget(parent_handle), rect);
|
|
||||||
// GetXWindowForWidget returns this :
|
// /usr/include/gtk-3.0/gdk/x11/gdkx11window.h defines GDK_WINDOW_XID as gdk_x11_window_get_xid
|
||||||
// GDK_WINDOW_XID(gtk_widget_get_window(widget));
|
|
||||||
// GDK_WINDOW_XID is a macro equivalent to gdk_x11_drawable_get_xid in gtk2 but
|
if Gtk3IsWidget(PGObject(aParent)) then
|
||||||
// in gtk3 we use gdk_x11_window_get_xid instead.
|
TempWidget := PGtkWidget(aParent)
|
||||||
// LCL sets TGtk3Widget.Widget to gtk_window_new(GTK_WINDOW_TOPLEVEL) for the main form.
|
else
|
||||||
// When we call TChromium.CreateBrowser with the main form as parent we get this error in the console (not in the log) :
|
TempWidget := TGtk3Widget(aParent).Widget; // aParent is an LCL Handle which can be casted as a TGtk3Widget in GTK3.
|
||||||
// [19140:19166:0604/174851.690766:ERROR:x11_software_bitmap_presenter.cc(144)] XGetWindowAttributes failed for window XXXXXXX
|
|
||||||
TempParent := gdk_x11_window_get_xid(gtk_widget_get_window(TGtk3Widget(aParent).Widget));
|
TempParent := gdk_x11_window_get_xid(gtk_widget_get_window(TempWidget));
|
||||||
end;
|
end;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
Reference in New Issue
Block a user