Skip to content

Commit

Permalink
SEBWIN-841: Implemented focus handler API in attempt to resolve issue…
Browse files Browse the repository at this point in the history
… (without success).
  • Loading branch information
dbuechel committed Oct 17, 2024
1 parent 339abdf commit 8093c86
Show file tree
Hide file tree
Showing 11 changed files with 204 additions and 1 deletion.
6 changes: 6 additions & 0 deletions SafeExamBrowser.Browser/BrowserControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ internal class BrowserControl : IBrowserControl
private readonly IDialogHandler dialogHandler;
private readonly IDisplayHandler displayHandler;
private readonly IDownloadHandler downloadHandler;
private readonly IFocusHandler focusHandler;
private readonly IKeyboardHandler keyboardHandler;
private readonly ILogger logger;
private readonly IRenderProcessMessageHandler renderProcessMessageHandler;
Expand All @@ -47,6 +48,7 @@ public BrowserControl(
IDialogHandler dialogHandler,
IDisplayHandler displayHandler,
IDownloadHandler downloadHandler,
IFocusHandler focusHandler,
IKeyboardHandler keyboardHandler,
ILogger logger,
IRenderProcessMessageHandler renderProcessMessageHandler,
Expand All @@ -57,6 +59,7 @@ public BrowserControl(
this.dialogHandler = dialogHandler;
this.displayHandler = displayHandler;
this.downloadHandler = downloadHandler;
this.focusHandler = focusHandler;
this.keyboardHandler = keyboardHandler;
this.logger = logger;
this.renderProcessMessageHandler = renderProcessMessageHandler;
Expand Down Expand Up @@ -128,6 +131,7 @@ public void Initialize()
control.FaviconUrlChanged += (w, b, u) => displayHandler.OnFaviconUrlChange(w, b, u);
control.FileDialogRequested += (w, b, m, t, p, f, e, d, c) => dialogHandler.OnFileDialog(w, b, m, t, p, f, e, d, c);
control.FocusedNodeChanged += (w, b, f, n) => renderProcessMessageHandler.OnFocusedNodeChanged(w, b, f, n);
control.GotFocusCefSharp += (w, b) => focusHandler.OnGotFocus(w, b);
control.IsBrowserInitializedChanged += Control_IsBrowserInitializedChanged;
control.KeyEvent += (w, b, t, k, n, m, s) => keyboardHandler.OnKeyEvent(w, b, t, k, n, m, s);
control.LoadError += (o, e) => LoadFailed?.Invoke((int) e.ErrorCode, e.ErrorText, e.Frame.IsMain, e.FailedUrl);
Expand All @@ -136,6 +140,8 @@ public void Initialize()
control.OpenUrlFromTab += (w, b, f, u, t, g, a) => a.Value = requestHandler.OnOpenUrlFromTab(w, b, f, u, t, g);
control.PreKeyEvent += (IWebBrowser w, IBrowser b, KeyType t, int k, int n, CefEventFlags m, bool i, ref bool s, GenericEventArgs a) => a.Value = keyboardHandler.OnPreKeyEvent(w, b, t, k, n, m, i, ref s);
control.ResourceRequestHandlerRequired += (IWebBrowser w, IBrowser b, IFrame f, IRequest r, bool n, bool d, string i, ref bool h, ResourceRequestEventArgs a) => a.Handler = requestHandler.GetResourceRequestHandler(w, b, f, r, n, d, i, ref h);
control.SetFocus += (w, b, s, a) => a.Value = focusHandler.OnSetFocus(w, b, s);
control.TakeFocus += (w, b, n) => focusHandler.OnTakeFocus(w, b, n);
control.TitleChanged += (o, e) => TitleChanged?.Invoke(e.Title);
control.UncaughtExceptionEvent += (w, b, f, e) => renderProcessMessageHandler.OnUncaughtException(w, b, f, e);

Expand Down
3 changes: 2 additions & 1 deletion SafeExamBrowser.Browser/BrowserWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ internal void InitializeControl()
var displayHandler = new DisplayHandler();
var downloadLogger = logger.CloneFor($"{nameof(DownloadHandler)} #{Id}");
var downloadHandler = new DownloadHandler(appConfig, downloadLogger, settings, WindowSettings);
var focusHandler = new FocusHandler(logger.CloneFor($"{nameof(FocusHandler)} #{Id}"));
var keyboardHandler = new KeyboardHandler();
var renderHandler = new RenderProcessMessageHandler(appConfig, clipboard, keyGenerator, settings, text);
var requestFilter = new RequestFilter();
Expand Down Expand Up @@ -195,7 +196,7 @@ internal void InitializeControl()

InitializeRequestFilter(requestFilter);

Control = new BrowserControl(clipboard, cefSharpControl, dialogHandler, displayHandler, downloadHandler, keyboardHandler, controlLogger, renderHandler, requestHandler);
Control = new BrowserControl(clipboard, cefSharpControl, dialogHandler, displayHandler, downloadHandler, focusHandler, keyboardHandler, controlLogger, renderHandler, requestHandler);
Control.AddressChanged += Control_AddressChanged;
Control.LoadFailed += Control_LoadFailed;
Control.LoadingStateChanged += Control_LoadingStateChanged;
Expand Down
36 changes: 36 additions & 0 deletions SafeExamBrowser.Browser/Handlers/FocusHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2024 ETH Zürich, IT Services
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

using CefSharp;
using SafeExamBrowser.Logging.Contracts;

namespace SafeExamBrowser.Browser.Handlers
{
internal class FocusHandler : IFocusHandler
{
private readonly ILogger logger;

internal FocusHandler(ILogger logger)
{
this.logger = logger;
}

public void OnGotFocus(IWebBrowser webBrowser, IBrowser browser)
{
}

public bool OnSetFocus(IWebBrowser webBrowser, IBrowser browser, CefFocusSource source)
{
return true;
}

public void OnTakeFocus(IWebBrowser webBrowser, IBrowser browser, bool next)
{
}
}
}
5 changes: 5 additions & 0 deletions SafeExamBrowser.Browser/SafeExamBrowser.Browser.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
<Compile Include="Handlers\DialogHandler.cs" />
<Compile Include="Handlers\DisplayHandler.cs" />
<Compile Include="Handlers\DownloadHandler.cs" />
<Compile Include="Handlers\FocusHandler.cs" />
<Compile Include="Handlers\KeyboardHandler.cs" />
<Compile Include="Handlers\RenderProcessMessageHandler.cs" />
<Compile Include="Handlers\RequestHandler.cs" />
Expand All @@ -125,18 +126,22 @@
<Compile Include="Wrapper\Events\FaviconUrlChangedEventHandler.cs" />
<Compile Include="Wrapper\Events\FileDialogRequestedEventHandler.cs" />
<Compile Include="Wrapper\Events\FocusedNodeChangedEventHandler.cs" />
<Compile Include="Wrapper\Events\GotFocusEventHandler.cs" />
<Compile Include="Wrapper\Events\KeyEventHandler.cs" />
<Compile Include="Wrapper\Events\LoadingProgressChangedEventHandler.cs" />
<Compile Include="Wrapper\Events\GenericEventArgs.cs" />
<Compile Include="Wrapper\Events\OpenUrlFromTabEventHandler.cs" />
<Compile Include="Wrapper\Events\PreKeyEventHandler.cs" />
<Compile Include="Wrapper\Events\ResourceRequestEventArgs.cs" />
<Compile Include="Wrapper\Events\ResourceRequestEventHandler.cs" />
<Compile Include="Wrapper\Events\SetFocusEventHandler.cs" />
<Compile Include="Wrapper\Events\TakeFocusEventHandler.cs" />
<Compile Include="Wrapper\Events\UncaughtExceptionEventHandler.cs" />
<Compile Include="Wrapper\Extensions.cs" />
<Compile Include="Wrapper\Handlers\DialogHandlerSwitch.cs" />
<Compile Include="Wrapper\Handlers\DisplayHandlerSwitch.cs" />
<Compile Include="Wrapper\Handlers\DownloadHandlerSwitch.cs" />
<Compile Include="Wrapper\Handlers\FocusHandlerSwitch.cs" />
<Compile Include="Wrapper\Handlers\KeyboardHandlerSwitch.cs" />
<Compile Include="Wrapper\Handlers\RenderProcessMessageHandlerSwitch.cs" />
<Compile Include="Wrapper\Handlers\RequestHandlerSwitch.cs" />
Expand Down
19 changes: 19 additions & 0 deletions SafeExamBrowser.Browser/Wrapper/CefSharpBrowserControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,22 @@ internal class CefSharpBrowserControl : ChromiumWebBrowser, ICefSharpControl
public event FaviconUrlChangedEventHandler FaviconUrlChanged;
public event FileDialogRequestedEventHandler FileDialogRequested;
public event FocusedNodeChangedEventHandler FocusedNodeChanged;
public event GotFocusEventHandler GotFocusCefSharp;
public event KeyEventHandler KeyEvent;
public event LoadingProgressChangedEventHandler LoadingProgressChanged;
public event OpenUrlFromTabEventHandler OpenUrlFromTab;
public event PreKeyEventHandler PreKeyEvent;
public event ResourceRequestEventHandler ResourceRequestHandlerRequired;
public event SetFocusEventHandler SetFocus;
public event TakeFocusEventHandler TakeFocus;
public event UncaughtExceptionEventHandler UncaughtExceptionEvent;

public CefSharpBrowserControl(ILifeSpanHandler lifeSpanHandler, string url) : base(url)
{
DialogHandler = new DialogHandlerSwitch();
DisplayHandler = new DisplayHandlerSwitch();
DownloadHandler = new DownloadHandlerSwitch();
FocusHandler = new FocusHandlerSwitch();
KeyboardHandler = new KeyboardHandlerSwitch();
LifeSpanHandler = lifeSpanHandler;
MenuHandler = new ContextMenuHandler();
Expand Down Expand Up @@ -106,6 +110,11 @@ public void OnFocusedNodeChanged(IWebBrowser webBrowser, IBrowser browser, IFram
FocusedNodeChanged?.Invoke(webBrowser, browser, frame, node);
}

public void OnGotFocus(IWebBrowser webBrowser, IBrowser browser)
{
GotFocusCefSharp?.Invoke(webBrowser, browser);
}

public void OnKeyEvent(IWebBrowser webBrowser, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey)
{
KeyEvent?.Invoke(webBrowser, browser, type, windowsKeyCode, nativeKeyCode, modifiers, isSystemKey);
Expand All @@ -126,6 +135,16 @@ public void OnPreKeyEvent(IWebBrowser webBrowser, IBrowser browser, KeyType type
PreKeyEvent?.Invoke(webBrowser, browser, type, windowsKeyCode, nativeKeyCode, modifiers, isSystemKey, ref isKeyboardShortcut, args);
}

public void OnSetFocus(IWebBrowser webBrowser, IBrowser browser, CefFocusSource source, GenericEventArgs args)
{
SetFocus?.Invoke(webBrowser, browser, source, args);
}

public void OnTakeFocus(IWebBrowser webBrowser, IBrowser browser, bool next)
{
TakeFocus?.Invoke(webBrowser, browser, next);
}

public void OnUncaughtException(IWebBrowser webBrowser, IBrowser browser, IFrame frame, JavascriptException exception)
{
UncaughtExceptionEvent?.Invoke(webBrowser, browser, frame, exception);
Expand Down
18 changes: 18 additions & 0 deletions SafeExamBrowser.Browser/Wrapper/CefSharpPopupControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@ internal class CefSharpPopupControl : ChromiumHostControl, ICefSharpControl
public event FaviconUrlChangedEventHandler FaviconUrlChanged;
public event FileDialogRequestedEventHandler FileDialogRequested;
public event FocusedNodeChangedEventHandler FocusedNodeChanged;
public event GotFocusEventHandler GotFocusCefSharp;
public event KeyEventHandler KeyEvent;
public event LoadingProgressChangedEventHandler LoadingProgressChanged;
public event OpenUrlFromTabEventHandler OpenUrlFromTab;
public event PreKeyEventHandler PreKeyEvent;
public event ResourceRequestEventHandler ResourceRequestHandlerRequired;
public event SetFocusEventHandler SetFocus;
public event TakeFocusEventHandler TakeFocus;
public event UncaughtExceptionEventHandler UncaughtExceptionEvent;

void ICefSharpControl.Dispose(bool disposing)
Expand Down Expand Up @@ -100,6 +103,11 @@ public void OnFocusedNodeChanged(IWebBrowser webBrowser, IBrowser browser, IFram
FocusedNodeChanged?.Invoke(webBrowser, browser, frame, node);
}

public void OnGotFocus(IWebBrowser webBrowser, IBrowser browser)
{
GotFocusCefSharp?.Invoke(webBrowser, browser);
}

public void OnKeyEvent(IWebBrowser webBrowser, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey)
{
KeyEvent?.Invoke(webBrowser, browser, type, windowsKeyCode, nativeKeyCode, modifiers, isSystemKey);
Expand All @@ -120,6 +128,16 @@ public void OnPreKeyEvent(IWebBrowser webBrowser, IBrowser browser, KeyType type
PreKeyEvent?.Invoke(webBrowser, browser, type, windowsKeyCode, nativeKeyCode, modifiers, isSystemKey, ref isKeyboardShortcut, args);
}

public void OnSetFocus(IWebBrowser webBrowser, IBrowser browser, CefFocusSource source, GenericEventArgs args)
{
SetFocus?.Invoke(webBrowser, browser, source, args);
}

public void OnTakeFocus(IWebBrowser webBrowser, IBrowser browser, bool next)
{
TakeFocus?.Invoke(webBrowser, browser, next);
}

public void OnUncaughtException(IWebBrowser webBrowser, IBrowser browser, IFrame frame, JavascriptException exception)
{
UncaughtExceptionEvent?.Invoke(webBrowser, browser, frame, exception);
Expand Down
14 changes: 14 additions & 0 deletions SafeExamBrowser.Browser/Wrapper/Events/GotFocusEventHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright (c) 2024 ETH Zürich, IT Services
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

using CefSharp;

namespace SafeExamBrowser.Browser.Wrapper.Events
{
internal delegate void GotFocusEventHandler(IWebBrowser webBrowser, IBrowser browser);
}
14 changes: 14 additions & 0 deletions SafeExamBrowser.Browser/Wrapper/Events/SetFocusEventHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright (c) 2024 ETH Zürich, IT Services
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

using CefSharp;

namespace SafeExamBrowser.Browser.Wrapper.Events
{
internal delegate void SetFocusEventHandler(IWebBrowser webBrowser, IBrowser browser, CefFocusSource source, GenericEventArgs args);
}
14 changes: 14 additions & 0 deletions SafeExamBrowser.Browser/Wrapper/Events/TakeFocusEventHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright (c) 2024 ETH Zürich, IT Services
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

using CefSharp;

namespace SafeExamBrowser.Browser.Wrapper.Events
{
internal delegate void TakeFocusEventHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, bool next);
}
70 changes: 70 additions & 0 deletions SafeExamBrowser.Browser/Wrapper/Handlers/FocusHandlerSwitch.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2024 ETH Zürich, IT Services
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

using CefSharp;
using CefSharp.WinForms;
using CefSharp.WinForms.Host;
using SafeExamBrowser.Browser.Wrapper.Events;

namespace SafeExamBrowser.Browser.Wrapper.Handlers
{
internal class FocusHandlerSwitch : IFocusHandler
{
public void OnGotFocus(IWebBrowser webBrowser, IBrowser browser)
{
if (browser.IsPopup)
{
var control = ChromiumHostControl.FromBrowser(browser) as CefSharpPopupControl;

control?.OnGotFocus(webBrowser, browser);
}
else
{
var control = ChromiumWebBrowser.FromBrowser(browser) as CefSharpBrowserControl;

control?.OnGotFocus(webBrowser, browser);
}
}

public bool OnSetFocus(IWebBrowser webBrowser, IBrowser browser, CefFocusSource source)
{
var args = new GenericEventArgs { Value = false };

if (browser.IsPopup)
{
var control = ChromiumHostControl.FromBrowser(browser) as CefSharpPopupControl;

control?.OnSetFocus(webBrowser, browser, source, args);
}
else
{
var control = ChromiumWebBrowser.FromBrowser(browser) as CefSharpBrowserControl;

control?.OnSetFocus(webBrowser, browser, source, args);
}

return args.Value;
}

public void OnTakeFocus(IWebBrowser webBrowser, IBrowser browser, bool next)
{
if (browser.IsPopup)
{
var control = ChromiumHostControl.FromBrowser(browser) as CefSharpPopupControl;

control?.OnTakeFocus(webBrowser, browser, next);
}
else
{
var control = ChromiumWebBrowser.FromBrowser(browser) as CefSharpBrowserControl;

control?.OnTakeFocus(webBrowser, browser, next);
}
}
}
}
6 changes: 6 additions & 0 deletions SafeExamBrowser.Browser/Wrapper/ICefSharpControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,14 @@ internal interface ICefSharpControl : IChromiumWebBrowserBase, IWinFormsChromium
event FaviconUrlChangedEventHandler FaviconUrlChanged;
event FileDialogRequestedEventHandler FileDialogRequested;
event FocusedNodeChangedEventHandler FocusedNodeChanged;
event GotFocusEventHandler GotFocusCefSharp;
event KeyEventHandler KeyEvent;
event LoadingProgressChangedEventHandler LoadingProgressChanged;
event OpenUrlFromTabEventHandler OpenUrlFromTab;
event PreKeyEventHandler PreKeyEvent;
event ResourceRequestEventHandler ResourceRequestHandlerRequired;
event SetFocusEventHandler SetFocus;
event TakeFocusEventHandler TakeFocus;
event UncaughtExceptionEventHandler UncaughtExceptionEvent;

void Dispose(bool disposing);
Expand All @@ -48,10 +51,13 @@ internal interface ICefSharpControl : IChromiumWebBrowserBase, IWinFormsChromium
void OnFaviconUrlChange(IWebBrowser webBrowser, IBrowser browser, IList<string> urls);
void OnFileDialog(IWebBrowser webBrowser, IBrowser browser, CefFileDialogMode mode, string title, string defaultFilePath, IReadOnlyCollection<string> acceptFilters, IReadOnlyCollection<string> acceptExtensions, IReadOnlyCollection<string> acceptDescriptions, IFileDialogCallback callback);
void OnFocusedNodeChanged(IWebBrowser webBrowser, IBrowser browser, IFrame frame, IDomNode node);
void OnGotFocus(IWebBrowser webBrowser, IBrowser browser);
void OnKeyEvent(IWebBrowser webBrowser, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey);
void OnLoadingProgressChange(IWebBrowser webBrowser, IBrowser browser, double progress);
void OnOpenUrlFromTab(IWebBrowser webBrowser, IBrowser browser, IFrame frame, string targetUrl, WindowOpenDisposition targetDisposition, bool userGesture, GenericEventArgs args);
void OnPreKeyEvent(IWebBrowser webBrowser, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey, ref bool isKeyboardShortcut, GenericEventArgs args);
void OnSetFocus(IWebBrowser webBrowser, IBrowser browser, CefFocusSource source, GenericEventArgs args);
void OnTakeFocus(IWebBrowser webBrowser, IBrowser browser, bool next);
void OnUncaughtException(IWebBrowser webBrowser, IBrowser browser, IFrame frame, JavascriptException exception);
}
}

0 comments on commit 8093c86

Please sign in to comment.