diff --git a/demos/Lazarus_Linux_QT6/SimpleBrowser/00-Delete.bat b/demos/Lazarus_Linux_QT6/SimpleBrowser/00-Delete.bat new file mode 100644 index 00000000..0b5ba5c8 --- /dev/null +++ b/demos/Lazarus_Linux_QT6/SimpleBrowser/00-Delete.bat @@ -0,0 +1,2 @@ +rmdir /S /Q lib +rmdir /S /Q backup diff --git a/demos/Lazarus_Linux_QT6/SimpleBrowser/SimpleBrowser.ico b/demos/Lazarus_Linux_QT6/SimpleBrowser/SimpleBrowser.ico new file mode 100644 index 00000000..86b10384 Binary files /dev/null and b/demos/Lazarus_Linux_QT6/SimpleBrowser/SimpleBrowser.ico differ diff --git a/demos/Lazarus_Linux_QT6/SimpleBrowser/SimpleBrowser.lpi b/demos/Lazarus_Linux_QT6/SimpleBrowser/SimpleBrowser.lpi new file mode 100644 index 00000000..438f2810 --- /dev/null +++ b/demos/Lazarus_Linux_QT6/SimpleBrowser/SimpleBrowser.lpi @@ -0,0 +1,98 @@ + + + + + + + + <Scaled Value="True"/> + <ResourceType Value="res"/> + <UseXPManifest Value="True"/> + <XPManifest> + <DpiAware Value="True"/> + </XPManifest> + <Icon Value="0"/> + </General> + <MacroValues Count="1"> + <Macro1 Name="LCLWidgetType" Value="qt6"/> + </MacroValues> + <BuildModes> + <Item Name="Default" Default="True"/> + <SharedMatrixOptions Count="1"> + <Item1 ID="204233492819" Modes="Default" Type="IDEMacro" MacroName="LCLWidgetType" Value="qt6"/> + </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="SimpleBrowser.lpr"/> + <IsPartOfProject Value="True"/> + </Unit> + <Unit> + <Filename Value="umainform.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="MainForm"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="uMainForm"/> + </Unit> + <Unit> + <Filename Value="interfaces.pas"/> + <IsPartOfProject Value="True"/> + </Unit> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <Target> + <Filename Value="../../../bin/SimpleBrowser"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Linking> + <Debugging> + <DebugInfoType Value="dsDwarf3"/> + </Debugging> + <Options> + <Win32> + <GraphicApplication Value="True"/> + </Win32> + </Options> + </Linking> + <Other> + <CustomOptions Value="-dUseCThreads"/> + <OtherDefines Count="1"> + <Define0 Value="UseCThreads"/> + </OtherDefines> + </Other> + </CompilerOptions> + <Debugging> + <Exceptions> + <Item> + <Name Value="EAbort"/> + </Item> + <Item> + <Name Value="ECodetoolError"/> + </Item> + <Item> + <Name Value="EFOpenError"/> + </Item> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/demos/Lazarus_Linux_QT6/SimpleBrowser/SimpleBrowser.lpr b/demos/Lazarus_Linux_QT6/SimpleBrowser/SimpleBrowser.lpr new file mode 100644 index 00000000..8b8e97ad --- /dev/null +++ b/demos/Lazarus_Linux_QT6/SimpleBrowser/SimpleBrowser.lpr @@ -0,0 +1,42 @@ +program SimpleBrowser; + +{$mode objfpc}{$H+} + +uses + {$IFDEF UNIX} + cthreads, + {$ENDIF} + {$IFDEF HASAMIGA} + athreads, + {$ENDIF} + Interfaces, // this includes the LCL widgetset + Forms, uMainForm + { you can add units after this }, + uCEFApplication; + +{$R *.res} + +begin + CreateGlobalCEFApp; + + if StartMainProcess then + begin + // The LCL Widgetset must be initialized after the CEF initialization and + // only in the browser process. + CustomWidgetSetInitialization; + + RequireDerivedFormResource:=True; + Application.Scaled:=True; + {$PUSH}{$WARN 5044 OFF} + Application.MainFormOnTaskbar:=True; + {$POP} + Application.Initialize; + Application.CreateForm(TMainForm, MainForm); + Application.Run; + + CustomWidgetSetFinalization; + end; + + DestroyGlobalCEFApp; +end. + diff --git a/demos/Lazarus_Linux_QT6/SimpleBrowser/SimpleBrowser.res b/demos/Lazarus_Linux_QT6/SimpleBrowser/SimpleBrowser.res new file mode 100644 index 00000000..d3a9f901 Binary files /dev/null and b/demos/Lazarus_Linux_QT6/SimpleBrowser/SimpleBrowser.res differ diff --git a/demos/Lazarus_Linux_QT6/SimpleBrowser/interfaces.pas b/demos/Lazarus_Linux_QT6/SimpleBrowser/interfaces.pas new file mode 100644 index 00000000..4c39e518 --- /dev/null +++ b/demos/Lazarus_Linux_QT6/SimpleBrowser/interfaces.pas @@ -0,0 +1,66 @@ +{ + /*************************************************************************** + Interfaces.pp - determines what interface to use + ------------------- + + Initial Revision : Thu July 1st CST 1999 + + + ***************************************************************************/ + + ***************************************************************************** + This file is part of the Lazarus Component Library (LCL) + + See the file COPYING.modifiedLGPL.txt, included in this distribution, + for details about the license. + ***************************************************************************** +} + +unit interfaces; + +{$mode objfpc} +{$H+} + +interface + +uses + {$IFDEF UNIX}{$IFNDEF DisableCWString}cwstring,{$ENDIF}{$ENDIF} + InterfaceBase; + +procedure CustomWidgetSetInitialization; +procedure CustomWidgetSetFinalization; + +implementation + +uses + qtint, Forms, xlib; + +function CustomX11ErrorHandler(Display:PDisplay; ErrorEv:PXErrorEvent):longint;cdecl; +begin + {$IFDEF DEBUG} + XError := ErrorEv^.error_code; + WriteLn('Error: ' + IntToStr(XError)); + {$ENDIF} + Result := 0; +end; + +function CustomXIOErrorHandler(Display:PDisplay):longint;cdecl; +begin + Result := 0; +end; + +procedure CustomWidgetSetInitialization; +begin + CreateWidgetset(TQtWidgetSet); + // Install xlib error handlers so that the application won't be terminated + // on non-fatal errors. Must be done after initializing QT. + XSetErrorHandler(@CustomX11ErrorHandler); + XSetIOErrorHandler(@CustomXIOErrorHandler); +end; + +procedure CustomWidgetSetFinalization; +begin + FreeWidgetSet; +end; + +end. diff --git a/demos/Lazarus_Linux_QT6/SimpleBrowser/umainform.lfm b/demos/Lazarus_Linux_QT6/SimpleBrowser/umainform.lfm new file mode 100644 index 00000000..ed963bb5 --- /dev/null +++ b/demos/Lazarus_Linux_QT6/SimpleBrowser/umainform.lfm @@ -0,0 +1,124 @@ +object MainForm: TMainForm + Left = 342 + Height = 768 + Top = 31 + Width = 1024 + Caption = 'Simple Browser. Initializing...' + ClientHeight = 768 + ClientWidth = 1024 + Position = poScreenCenter + OnActivate = FormActivate + OnCloseQuery = FormCloseQuery + OnCreate = FormCreate + object CEFLinkedWindowParent1: TCEFLinkedWindowParent + Left = 0 + Height = 742 + Top = 26 + Width = 1024 + Align = alClient + TabStop = True + TabOrder = 1 + OnEnter = CEFLinkedWindowParent1Enter + OnExit = CEFLinkedWindowParent1Exit + Chromium = Chromium1 + end + object AddressPnl: TPanel + Left = 0 + Height = 26 + Top = 0 + Width = 1024 + Align = alTop + BevelOuter = bvNone + ClientHeight = 26 + ClientWidth = 1024 + TabOrder = 0 + object AddressCb: TComboBox + Left = 0 + Height = 26 + Top = 0 + Width = 965 + Align = alClient + ItemHeight = 0 + ItemIndex = 0 + Items.Strings = ( + 'https://www.google.com' + 'https://www.bing.com' + 'https://duckduckgo.com' + 'https://www.qwant.com' + 'https://yandex.com' + 'https://www.startpage.com' + 'https://www.ecosia.org' + 'https://www.baidu.com' + 'https://www.whatismybrowser.com/detect/what-http-headers-is-my-browser-sending' + 'https://www.w3schools.com/js/tryit.asp?filename=tryjs_win_close' + 'https://www.w3schools.com/js/tryit.asp?filename=tryjs_alert' + 'https://www.w3schools.com/js/tryit.asp?filename=tryjs_loc_assign' + 'https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_style_backgroundcolor' + 'https://www.w3schools.com/Tags/tryit.asp?filename=tryhtml_iframe_name' + 'https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_input_type_file' + 'https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_state_throw_error' + 'https://www.htmlquick.com/es/reference/tags/input-file.html' + 'https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file' + 'https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/webkitdirectory' + 'https://www.w3schools.com/html/html5_video.asp' + 'http://html5test.com/' + 'https://webrtc.github.io/samples/src/content/devices/input-output/' + 'https://test.webrtc.org/' + 'https://www.browserleaks.com/webrtc' + 'https://shaka-player-demo.appspot.com/demo/' + 'http://webglsamples.org/' + 'https://get.webgl.org/' + 'https://www.briskbard.com' + 'https://www.youtube.com' + 'https://html5demos.com/drag/' + 'https://frames-per-second.appspot.com/' + 'https://www.sede.fnmt.gob.es/certificados/persona-fisica/verificar-estado' + 'https://www.kirupa.com/html5/accessing_your_webcam_in_html5.htm' + 'https://www.xdumaine.com/enumerateDevices/test/' + 'https://dagrs.berkeley.edu/sites/default/files/2020-01/sample.pdf' + 'https://codepen.io/udaymanvar/pen/MWaePBY' + 'https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/accept' + 'chrome://version/' + 'chrome://net-internals/' + 'chrome://tracing/' + 'chrome://appcache-internals/' + 'chrome://blob-internals/' + 'chrome://view-http-cache/' + 'chrome://credits/' + 'chrome://histograms/' + 'chrome://media-internals/' + 'chrome://kill' + 'chrome://crash' + 'chrome://hang' + 'chrome://shorthang' + 'chrome://gpuclean' + 'chrome://gpucrash' + 'chrome://gpuhang' + 'chrome://extensions-support' + 'chrome://process-internals' + ) + TabOrder = 0 + Text = 'https://www.google.com' + end + object GoBtn: TButton + Left = 965 + Height = 26 + Top = 0 + Width = 59 + Align = alRight + Caption = 'Go' + TabOrder = 1 + OnClick = GoBtnClick + end + end + object Chromium1: TChromium + OnGotFocus = Chromium1GotFocus + OnBeforePopup = Chromium1BeforePopup + OnAfterCreated = Chromium1AfterCreated + OnBeforeClose = Chromium1BeforeClose + OnClose = Chromium1Close + OnOpenUrlFromTab = Chromium1OpenUrlFromTab + Left = 106 + Top = 69 + end +end diff --git a/demos/Lazarus_Linux_QT6/SimpleBrowser/umainform.pas b/demos/Lazarus_Linux_QT6/SimpleBrowser/umainform.pas new file mode 100644 index 00000000..d30ead86 --- /dev/null +++ b/demos/Lazarus_Linux_QT6/SimpleBrowser/umainform.pas @@ -0,0 +1,296 @@ +unit uMainForm; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, Forms, Controls, Graphics, SyncObjs, Dialogs, ExtCtrls, + LMessages, StdCtrls, + uCEFChromium, uCEFLinkedWindowParent, uCEFInterfaces, uCEFChromiumEvents, + uCEFTypes; + +const + CEF_SETFOCUS = 1; + +type + { TMainForm } + + TMainForm = class(TForm) + GoBtn: TButton; + CEFLinkedWindowParent1: TCEFLinkedWindowParent; + Chromium1: TChromium; + AddressCb: TComboBox; + AddressPnl: TPanel; + + procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); + procedure Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser); + procedure Chromium1BeforePopup(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: Boolean; var Result: Boolean); + procedure Chromium1Close(Sender: TObject; const browser: ICefBrowser; var aAction: TCefCloseBrowserAction); + procedure Chromium1GotFocus(Sender: TObject; const browser: ICefBrowser); + procedure Chromium1OpenUrlFromTab(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const targetUrl: ustring; targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; out Result: Boolean); + + procedure FormActivate(Sender: TObject); + procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); + procedure FormCreate(Sender: TObject); + + procedure GoBtnClick(Sender: TObject); + procedure CEFLinkedWindowParent1Enter(Sender: TObject); + procedure CEFLinkedWindowParent1Exit(Sender: TObject); + private + + protected + // Variables to control when can we destroy the form safely + FCanClose : boolean; // Set to True in TChromium.OnBeforeClose + FClosing : boolean; // Set to True in the CloseQuery event. + + // CEF needs to handle these messages to call TChromium.NotifyMoveOrResizeStarted + procedure WMMove(var Message: TLMMove); message LM_MOVE; + procedure WMSize(var Message: TLMSize); message LM_SIZE; + procedure WMWindowPosChanged(var Message: TLMWindowPosChanged); message LM_WINDOWPOSCHANGED; + + procedure SendCompMessage(aMsg : cardinal; aData: PtrInt = 0); + + procedure BrowserCreatedMsg(Data: PtrInt); + procedure BrowserCloseFormMsg(Data: PtrInt); + procedure BrowserSetFocusMsg(Data: PtrInt); + + public + + end; + +var + MainForm: TMainForm; + +procedure CreateGlobalCEFApp; +function StartMainProcess: boolean; + +implementation + +{$R *.lfm} + +uses + Math, + uCEFMiscFunctions, uCEFApplication, uCEFLinuxFunctions, uCEFConstants; + +var + MainAppEvent : TEventObject; + +{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.SetCurrentDir := True; + GlobalCEFApp.DisableZygote := True; + 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} + +{TForm events} +{%Region} +procedure TMainForm.FormCreate(Sender: TObject); +begin + FCanClose := False; + FClosing := False; + + // CEF requires a native widget + CEFLinkedWindowParent1.SetQTWidgetAsNative; + + Chromium1.DefaultURL := UTF8Decode(AddressCb.Text); +end; + +procedure TMainForm.FormActivate(Sender: TObject); +var + TempRect : TRect; +begin + TempRect := Rect(0, 0, CEFLinkedWindowParent1.Width, CEFLinkedWindowParent1.Height); + Chromium1.CreateBrowser(CEFLinkedWindowParent1.Handle, TempRect); +end; + +procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean); +begin + if not Chromium1.Initialized then + begin + FCanClose := True; + FClosing := True; + end; + + CanClose := FCanClose; + + if not(FClosing) then + begin + FClosing := True; + Visible := False; + Chromium1.CloseBrowser(True); + + if Chromium1.RuntimeStyle = CEF_RUNTIME_STYLE_CHROME then + CEFLinkedWindowParent1.Free; + end; +end; +{%Endregion} + +{TCEFLinkedWindowParent events} +{%Region} +procedure TMainForm.CEFLinkedWindowParent1Enter(Sender: TObject); +begin + if not(csDesigning in ComponentState) and + Chromium1.Initialized and + not(Chromium1.FrameIsFocused) then + Chromium1.SetFocus(True); +end; + +// This is a workaround for the CEF issue #2026 +// https://bitbucket.org/chromiumembedded/cef/issues/2026/multiple-major-keyboard-focus-issues-on +// We use CEFLinkedWindowParent1.OnEnter, CEFLinkedWindowParent1.OnExit and +// TChromium.OnGotFocus to avoid most of the focus issues. +// CEFLinkedWindowParent1.TabStop must be TRUE. +procedure TMainForm.CEFLinkedWindowParent1Exit(Sender: TObject); +begin + if not(csDesigning in ComponentState) then + Chromium1.SendCaptureLostEvent; +end; +{%Endregion} + +{Message handlers} +{%Region} +procedure TMainForm.BrowserCreatedMsg(Data: PtrInt); +begin + Caption := 'Simple Browser'; + AddressPnl.Enabled := True; + Chromium1.UpdateXWindowVisibility(True); + CEFLinkedWindowParent1.UpdateSize; + CEFLinkedWindowParent1.InvalidateChildren; +end; + +procedure TMainForm.BrowserCloseFormMsg(Data: PtrInt); +begin + Close; +end; + +procedure TMainForm.BrowserSetFocusMsg(Data: PtrInt); +begin + CEFLinkedWindowParent1.SetFocus; +end; + +procedure TMainForm.WMMove(var Message: TLMMove); +begin + inherited; + Chromium1.NotifyMoveOrResizeStarted; +end; + +procedure TMainForm.WMSize(var Message: TLMSize); +begin + inherited; + Chromium1.NotifyMoveOrResizeStarted; +end; + +procedure TMainForm.WMWindowPosChanged(var Message: TLMWindowPosChanged); +begin + inherited; + Chromium1.NotifyMoveOrResizeStarted; +end; +{%Endregion} + +{Misc functions} +{%Region} +procedure TMainForm.SendCompMessage(aMsg : cardinal; aData: PtrInt); +begin + case aMsg of + CEF_AFTERCREATED : Application.QueueAsyncCall(@BrowserCreatedMsg, 0); + CEF_BEFORECLOSE : Application.QueueAsyncCall(@BrowserCloseFormMsg, 0); + CEF_SETFOCUS : Application.QueueAsyncCall(@BrowserSetFocusMsg, 0); + end; +end; + +procedure TMainForm.GoBtnClick(Sender: TObject); +begin + Chromium1.LoadURL(UTF8Decode(AddressCb.Text)); +end; +{%Endregion} + +{TChromium events} +{%Region} +procedure TMainForm.Chromium1AfterCreated(Sender: TObject; + const browser: ICefBrowser); +begin + // Now the browser is fully initialized we can initialize the UI. + SendCompMessage(CEF_AFTERCREATED); +end; + +procedure TMainForm.Chromium1BeforeClose(Sender: TObject; + const browser: ICefBrowser); +begin + // We must wait until all browsers trigger the TChromium.OnBeforeClose event + // in order to close the application safely or we will have shutdown issues. + FCanClose := True; + SendCompMessage(CEF_BEFORECLOSE); +end; + +procedure TMainForm.Chromium1BeforePopup(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: Boolean; + var 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 TMainForm.Chromium1Close(Sender: TObject; const browser: ICefBrowser; + var aAction: TCefCloseBrowserAction); +begin + // continue closing the browser + aAction := cbaClose; +end; + +procedure TMainForm.Chromium1GotFocus(Sender: TObject; + const browser: ICefBrowser); +begin + SendCompMessage(CEF_SETFOCUS); +end; + +procedure TMainForm.Chromium1OpenUrlFromTab(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} + +initialization + MainAppEvent := TEventObject.Create(nil, True, False, 'MainAppEvent'); + +finalization + if assigned(MainAppEvent) then + FreeAndNil(MainAppEvent); + +end. + diff --git a/source/uCEFChromiumCore.pas b/source/uCEFChromiumCore.pas index 7bb8e666..adc79b7a 100644 --- a/source/uCEFChromiumCore.pas +++ b/source/uCEFChromiumCore.pas @@ -4246,6 +4246,9 @@ uses {$IFDEF LINUX}x, xatom, {$IFDEF LCLGTK2}gdk2x, gtk2,{$ENDIF} {$IFDEF LCLGTK3}LazGdk3, LazGtk3, LazGLib2,{$ENDIF} + {$IFDEF LCLQT}qt4,{$ENDIF} + {$IFDEF LCLQT5}qt5,{$ENDIF} + {$IFDEF LCLQT6}qtint,{$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} @@ -5887,7 +5890,7 @@ end; {$IFDEF LINUX} function TChromiumCore.GetXDisplay : PXDisplay; -{$IFDEF FPC} +{$IFDEF LCLGTK2} var TempParent : TCefWindowHandle; {$ENDIF} @@ -5903,13 +5906,14 @@ begin FXDisplay := GDK_WINDOW_XDISPLAY(PGtkWidget(TempParent)^.Window); {$ENDIF} {$IFDEF LCLGTK3} - TempParent := ParentFormHandle; - { - if ValidCefWindowHandle(TempParent) and - (PGtkWidget(TempParent)^.Window <> nil) then - FXDisplay := GDK_WINDOW_XDISPLAY(PGtkWidget(TempParent)^.Window); } FXDisplay := gdk_x11_get_default_xdisplay(); {$ENDIF} + {$IF DEFINED(LCLQT) OR DEFINED(LCLQT5)} + FXDisplay := QX11Info_display(); + {$IFEND} + {$IFDEF LCLQT6} + FXDisplay := TQtWidgetSet(WidgetSet).x11Display; + {$ENDIF} {$ENDIF} // GlobalCEFApp.XDisplay can only be called in the CEF UI thread. diff --git a/source/uCEFLinkedWinControlBase.pas b/source/uCEFLinkedWinControlBase.pas index 08eb97ac..dcab7acd 100644 --- a/source/uCEFLinkedWinControlBase.pas +++ b/source/uCEFLinkedWinControlBase.pas @@ -187,7 +187,13 @@ begin if not(csDesigning in ComponentState) and (Chromium <> nil) and Chromium.Initialized then - Chromium.UpdateBrowserSize(Left, Top, Width, Height); + begin + {$IF DEFINED(LCLQT) OR DEFINED(LCLQT5) OR DEFINED(LCLQT6)} + Chromium.UpdateBrowserSize(0, 0, Width, Height); + {$ELSE} + Chromium.UpdateBrowserSize(Left, Top, Width, Height); + {$IFEND} + end; {$ENDIF} {$IFDEF MACOSX} diff --git a/source/uCEFWinControl.pas b/source/uCEFWinControl.pas index 043ef452..e3103b8f 100644 --- a/source/uCEFWinControl.pas +++ b/source/uCEFWinControl.pas @@ -59,6 +59,12 @@ type /// Updates the size of the child windows created by the browser. /// </summary> procedure UpdateSize; virtual; + {$IF DEFINED(LCLQT) OR DEFINED(LCLQT5) OR DEFINED(LCLQT6)} + /// <summary> + /// Set this widget as native with a native window handle. + /// </summary> + procedure SetQTWidgetAsNative; + {$IFEND} /// <summary> /// Handle of the first child window created by the browser. /// </summary> @@ -101,6 +107,9 @@ type implementation uses + {$IFDEF LCLQT}qtwidgets, qt4,{$ENDIF} + {$IFDEF LCLQT5}qtwidgets, qt5,{$ENDIF} + {$IFDEF LCLQT6}qtwidgets, qt6,{$ENDIF} uCEFMiscFunctions, uCEFClient, uCEFConstants; function TCEFWinControl.GetChildWindowHandle : {$IFNDEF MSWINDOWS}{$IFDEF FPC}LclType.{$ENDIF}{$ENDIF}THandle; @@ -118,6 +127,14 @@ begin inherited CreateHandle; end; +{$IF DEFINED(LCLQT) OR DEFINED(LCLQT5) OR DEFINED(LCLQT6)} +procedure TCEFWinControl.SetQTWidgetAsNative; +begin + TQtWidget(Handle).setAttribute(QtWA_NativeWindow); // This widget becomes native... + TQtWidget(Handle).setAttribute(QtWA_DontCreateNativeAncestors); // ...but not the ancestors. +end; +{$IFEND} + procedure TCEFWinControl.InvalidateChildren; begin if HandleAllocated then diff --git a/source/uCEFWindowInfoWrapper.pas b/source/uCEFWindowInfoWrapper.pas index a1d91470..49b7d404 100644 --- a/source/uCEFWindowInfoWrapper.pas +++ b/source/uCEFWindowInfoWrapper.pas @@ -538,6 +538,7 @@ begin {$IF DEFINED(LCLQT) OR DEFINED(LCLQT5) OR DEFINED(LCLQT6)} if ValidCefWindowHandle(aParent) then begin + // CEF requires a native widget with an associated native window handle. TempParent := QWidget_winId(TQtWidget(aParent).Widget); end; {$IFEND} diff --git a/update_CEF4Delphi.json b/update_CEF4Delphi.json index 1f7eb48c..e8792bbd 100644 --- a/update_CEF4Delphi.json +++ b/update_CEF4Delphi.json @@ -2,7 +2,7 @@ "UpdateLazPackages" : [ { "ForceNotify" : true, - "InternalVersion" : 784, + "InternalVersion" : 785, "Name" : "cef4delphi_lazarus.lpk", "Version" : "139.0.40" }