From 6eddf7b5dac010e87250ffa5a20a1b2d6db99c00 Mon Sep 17 00:00:00 2001 From: Salvador Diaz Fau Date: Sat, 2 Jan 2021 16:40:12 +0100 Subject: [PATCH] Added workaround for focus issues in Linux Added workaround for the CEF issue #2026 : https://bitbucket.org/chromiumembedded/cef/issues/2026/multiple-major-keyboard-focus-issues-on --- .../ExternalPumpBrowser.lps | 32 +++- .../uExternalPumpBrowser.lfm | 1 + .../uExternalPumpBrowser.pas | 29 +++- .../SimpleBrowser2/SimpleBrowser2.lps | 151 +++++++++--------- .../SimpleBrowser2/usimplebrowser2.lfm | 3 + .../SimpleBrowser2/usimplebrowser2.pas | 37 +++-- demos/Lazarus_Linux/SubProcess/SubProcess.lps | 30 +++- .../Lazarus_Linux/SubProcess/uSubProcess.lfm | 1 + .../Lazarus_Linux/SubProcess/uSubProcess.pas | 37 +++-- update_CEF4Delphi.json | 2 +- 10 files changed, 206 insertions(+), 117 deletions(-) diff --git a/demos/Lazarus_Linux/ExternalPumpBrowser/ExternalPumpBrowser.lps b/demos/Lazarus_Linux/ExternalPumpBrowser/ExternalPumpBrowser.lps index c1e8c995..37daa883 100644 --- a/demos/Lazarus_Linux/ExternalPumpBrowser/ExternalPumpBrowser.lps +++ b/demos/Lazarus_Linux/ExternalPumpBrowser/ExternalPumpBrowser.lps @@ -3,7 +3,7 @@ - + @@ -19,12 +19,12 @@ - - + + - - + + @@ -424,8 +424,16 @@ + + + + + + + + - + @@ -466,6 +474,18 @@ + + + + + + + + + + + + diff --git a/demos/Lazarus_Linux/ExternalPumpBrowser/uExternalPumpBrowser.lfm b/demos/Lazarus_Linux/ExternalPumpBrowser/uExternalPumpBrowser.lfm index f6e6a382..307025aa 100644 --- a/demos/Lazarus_Linux/ExternalPumpBrowser/uExternalPumpBrowser.lfm +++ b/demos/Lazarus_Linux/ExternalPumpBrowser/uExternalPumpBrowser.lfm @@ -55,6 +55,7 @@ object Form1: TForm1 Chromium = Chromium1 end object Chromium1: TChromium + OnGotFocus = Chromium1GotFocus OnBeforePopup = Chromium1BeforePopup OnAfterCreated = Chromium1AfterCreated OnBeforeClose = Chromium1BeforeClose diff --git a/demos/Lazarus_Linux/ExternalPumpBrowser/uExternalPumpBrowser.pas b/demos/Lazarus_Linux/ExternalPumpBrowser/uExternalPumpBrowser.pas index 26fad6df..b14ca12b 100644 --- a/demos/Lazarus_Linux/ExternalPumpBrowser/uExternalPumpBrowser.pas +++ b/demos/Lazarus_Linux/ExternalPumpBrowser/uExternalPumpBrowser.pas @@ -65,6 +65,7 @@ type procedure Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser); procedure Chromium1Close(Sender: TObject; const browser: ICefBrowser; var aAction: TCefCloseBrowserAction); procedure Chromium1BeforePopup(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const targetUrl, targetFrameName: ustring; targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; const popupFeatures: TCefPopupFeatures; var windowInfo: TCefWindowInfo; var client: ICefClient; var settings: TCefBrowserSettings; var extra_info: ICefDictionaryValue; var noJavascriptAccess: Boolean; var Result: Boolean); + procedure 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 FormCreate(Sender: TObject); @@ -196,7 +197,7 @@ procedure TForm1.Chromium1BeforePopup(Sender: TObject; 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; +end; procedure TForm1.Chromium1OpenUrlFromTab(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const targetUrl: ustring; @@ -245,14 +246,28 @@ begin AddressPnl.Enabled := True; end; -procedure TForm1.CEFLinkedWindowParent1Enter(Sender: TObject); -begin - If not(csDesigning in ComponentState) 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 TForm1.CEFLinkedWindowParent1Exit(Sender: TObject); begin - if not(csDesigning in ComponentState) then Chromium1.SendCaptureLostEvent; + if not(csDesigning in ComponentState) then + Chromium1.SendCaptureLostEvent; +end; + +procedure TForm1.CEFLinkedWindowParent1Enter(Sender: TObject); +begin + if not(csDesigning in ComponentState) and + Chromium1.Initialized and + not(Chromium1.FrameIsFocused) then + Chromium1.SendFocusEvent(True); +end; + +procedure TForm1.Chromium1GotFocus(Sender: TObject; const browser: ICefBrowser); +begin + CEFLinkedWindowParent1.SetFocus; end; procedure TForm1.WMMove(var Message: TLMMove); diff --git a/demos/Lazarus_Linux/SimpleBrowser2/SimpleBrowser2.lps b/demos/Lazarus_Linux/SimpleBrowser2/SimpleBrowser2.lps index d83991b6..4e595da5 100644 --- a/demos/Lazarus_Linux/SimpleBrowser2/SimpleBrowser2.lps +++ b/demos/Lazarus_Linux/SimpleBrowser2/SimpleBrowser2.lps @@ -3,14 +3,14 @@ - + - + @@ -20,11 +20,12 @@ - - - - - + + + + + + @@ -34,7 +35,7 @@ - + @@ -142,12 +143,11 @@ - - - - - - + + + + + @@ -168,9 +168,9 @@ - - - + + + @@ -203,8 +203,7 @@ - - + @@ -235,9 +234,9 @@ - - - + + + @@ -249,9 +248,9 @@ - - - + + + @@ -277,8 +276,8 @@ - - + + @@ -332,9 +331,12 @@ - - - + + + + + + @@ -414,7 +416,8 @@ - + + @@ -425,91 +428,87 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demos/Lazarus_Linux/SimpleBrowser2/usimplebrowser2.lfm b/demos/Lazarus_Linux/SimpleBrowser2/usimplebrowser2.lfm index 2504cd88..90d9bcd3 100644 --- a/demos/Lazarus_Linux/SimpleBrowser2/usimplebrowser2.lfm +++ b/demos/Lazarus_Linux/SimpleBrowser2/usimplebrowser2.lfm @@ -30,6 +30,7 @@ object Form1: TForm1 Align = alRight Caption = 'Go' OnClick = GoBtnClick + OnEnter = CEFLinkedWindowParent1Exit TabOrder = 0 end object AddressEdt: TEdit @@ -38,6 +39,7 @@ object Form1: TForm1 Top = 0 Width = 932 Align = alClient + OnEnter = CEFLinkedWindowParent1Exit TabOrder = 1 Text = 'https://www.google.com' end @@ -55,6 +57,7 @@ object Form1: TForm1 Chromium = Chromium1 end object Chromium1: TChromium + OnGotFocus = Chromium1GotFocus OnBeforePopup = Chromium1BeforePopup OnAfterCreated = Chromium1AfterCreated OnBeforeClose = Chromium1BeforeClose diff --git a/demos/Lazarus_Linux/SimpleBrowser2/usimplebrowser2.pas b/demos/Lazarus_Linux/SimpleBrowser2/usimplebrowser2.pas index ec2859d6..5728243d 100644 --- a/demos/Lazarus_Linux/SimpleBrowser2/usimplebrowser2.pas +++ b/demos/Lazarus_Linux/SimpleBrowser2/usimplebrowser2.pas @@ -58,13 +58,11 @@ type AddressPnl: TPanel; Timer1: TTimer; - procedure CEFLinkedWindowParent1Enter(Sender: TObject); - procedure CEFLinkedWindowParent1Exit(Sender: TObject); - procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser); procedure Chromium1Close(Sender: TObject; const browser: ICefBrowser; var aAction: TCefCloseBrowserAction); procedure Chromium1BeforePopup(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const targetUrl, targetFrameName: ustring; targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; const popupFeatures: TCefPopupFeatures; var windowInfo: TCefWindowInfo; var client: ICefClient; var settings: TCefBrowserSettings; var extra_info: ICefDictionaryValue; var noJavascriptAccess: Boolean; var Result: Boolean); + procedure 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 FormCreate(Sender: TObject); @@ -72,7 +70,10 @@ type procedure FormCloseQuery(Sender: TObject; var CanClose: boolean); procedure GoBtnClick(Sender: TObject); - procedure Timer1Timer(Sender: TObject); + procedure Timer1Timer(Sender: TObject); + + procedure CEFLinkedWindowParent1Enter(Sender: TObject); + procedure CEFLinkedWindowParent1Exit(Sender: TObject); private protected @@ -182,7 +183,7 @@ procedure TForm1.Chromium1BeforePopup(Sender: TObject; 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; +end; procedure TForm1.Chromium1OpenUrlFromTab(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const targetUrl: ustring; @@ -230,14 +231,28 @@ begin SendCompMessage(CEF_AFTERCREATED); end; -procedure TForm1.CEFLinkedWindowParent1Enter(Sender: TObject); -begin - If not(csDesigning in ComponentState) 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 TForm1.CEFLinkedWindowParent1Exit(Sender: TObject); begin - if not(csDesigning in ComponentState) then Chromium1.SendCaptureLostEvent; + if not(csDesigning in ComponentState) then + Chromium1.SendCaptureLostEvent; +end; + +procedure TForm1.CEFLinkedWindowParent1Enter(Sender: TObject); +begin + if not(csDesigning in ComponentState) and + Chromium1.Initialized and + not(Chromium1.FrameIsFocused) then + Chromium1.SendFocusEvent(True); +end; + +procedure TForm1.Chromium1GotFocus(Sender: TObject; const browser: ICefBrowser); +begin + CEFLinkedWindowParent1.SetFocus; end; procedure TForm1.BrowserCreatedMsg(Data: PtrInt); diff --git a/demos/Lazarus_Linux/SubProcess/SubProcess.lps b/demos/Lazarus_Linux/SubProcess/SubProcess.lps index 7b4914d4..b1c650c2 100644 --- a/demos/Lazarus_Linux/SubProcess/SubProcess.lps +++ b/demos/Lazarus_Linux/SubProcess/SubProcess.lps @@ -3,7 +3,7 @@ - + @@ -20,11 +20,11 @@ - - + + - + @@ -436,8 +436,16 @@ + + + + + + + + - + @@ -538,6 +546,18 @@ + + + + + + + + + + + + diff --git a/demos/Lazarus_Linux/SubProcess/uSubProcess.lfm b/demos/Lazarus_Linux/SubProcess/uSubProcess.lfm index 9f117cf6..fd768abe 100644 --- a/demos/Lazarus_Linux/SubProcess/uSubProcess.lfm +++ b/demos/Lazarus_Linux/SubProcess/uSubProcess.lfm @@ -55,6 +55,7 @@ object Form1: TForm1 Chromium = Chromium1 end object Chromium1: TChromium + OnGotFocus = Chromium1GotFocus OnBeforePopup = Chromium1BeforePopup OnAfterCreated = Chromium1AfterCreated OnBeforeClose = Chromium1BeforeClose diff --git a/demos/Lazarus_Linux/SubProcess/uSubProcess.pas b/demos/Lazarus_Linux/SubProcess/uSubProcess.pas index dd1a87ba..63b8bf4c 100644 --- a/demos/Lazarus_Linux/SubProcess/uSubProcess.pas +++ b/demos/Lazarus_Linux/SubProcess/uSubProcess.pas @@ -58,13 +58,11 @@ type AddressPnl: TPanel; Timer1: TTimer; - procedure CEFLinkedWindowParent1Enter(Sender: TObject); - procedure CEFLinkedWindowParent1Exit(Sender: TObject); - procedure Chromium1AfterCreated(Sender: TObject; const browser: ICefBrowser); procedure Chromium1BeforeClose(Sender: TObject; const browser: ICefBrowser); procedure Chromium1Close(Sender: TObject; const browser: ICefBrowser; var aAction: TCefCloseBrowserAction); procedure Chromium1BeforePopup(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const targetUrl, targetFrameName: ustring; targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; const popupFeatures: TCefPopupFeatures; var windowInfo: TCefWindowInfo; var client: ICefClient; var settings: TCefBrowserSettings; var extra_info: ICefDictionaryValue; var noJavascriptAccess: Boolean; var Result: Boolean); + procedure 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 FormCreate(Sender: TObject); @@ -72,7 +70,10 @@ type procedure FormCloseQuery(Sender: TObject; var CanClose: boolean); procedure GoBtnClick(Sender: TObject); - procedure Timer1Timer(Sender: TObject); + procedure Timer1Timer(Sender: TObject); + + procedure CEFLinkedWindowParent1Enter(Sender: TObject); + procedure CEFLinkedWindowParent1Exit(Sender: TObject); private protected @@ -168,7 +169,7 @@ procedure TForm1.Chromium1BeforePopup(Sender: TObject; 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; +end; procedure TForm1.Chromium1OpenUrlFromTab(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const targetUrl: ustring; @@ -216,14 +217,28 @@ begin SendCompMessage(CEF_AFTERCREATED); end; -procedure TForm1.CEFLinkedWindowParent1Enter(Sender: TObject); -begin - If not(csDesigning in ComponentState) 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 TForm1.CEFLinkedWindowParent1Exit(Sender: TObject); begin - if not(csDesigning in ComponentState) then Chromium1.SendCaptureLostEvent; + if not(csDesigning in ComponentState) then + Chromium1.SendCaptureLostEvent; +end; + +procedure TForm1.CEFLinkedWindowParent1Enter(Sender: TObject); +begin + if not(csDesigning in ComponentState) and + Chromium1.Initialized and + not(Chromium1.FrameIsFocused) then + Chromium1.SendFocusEvent(True); +end; + +procedure TForm1.Chromium1GotFocus(Sender: TObject; const browser: ICefBrowser); +begin + CEFLinkedWindowParent1.SetFocus; end; procedure TForm1.BrowserCreatedMsg(Data: PtrInt); diff --git a/update_CEF4Delphi.json b/update_CEF4Delphi.json index 83438384..7f9c9410 100644 --- a/update_CEF4Delphi.json +++ b/update_CEF4Delphi.json @@ -2,7 +2,7 @@ "UpdateLazPackages" : [ { "ForceNotify" : true, - "InternalVersion" : 218, + "InternalVersion" : 219, "Name" : "cef4delphi_lazarus.lpk", "Version" : "87.1.12.0" }