Skip to content

Commit

Permalink
IFocusHandler - Add IWebBrowser and IBrowser Params
Browse files Browse the repository at this point in the history
IFocusHandler methods are now called for popups, use browser.IsPopup to differentiate
DefaultFocusHandler has been updated accordingly

Resolves #2468
  • Loading branch information
amaitland committed Jul 24, 2018
1 parent d28ce08 commit 430c439
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 50 deletions.
29 changes: 9 additions & 20 deletions CefSharp.Core/Internals/ClientAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -978,12 +978,9 @@ namespace CefSharp
return;
}

// NOTE: a popup handler for OnGotFocus doesn't make sense yet because
// non-offscreen windows don't wrap popup browser's yet.
if (!browser->IsPopup())
{
handler->OnGotFocus();
}
auto browserWrapper = GetBrowserWrapper(browser->GetIdentifier(), browser->IsPopup());

handler->OnGotFocus(_browserControl, browserWrapper);
}

bool ClientAdapter::OnSetFocus(CefRefPtr<CefBrowser> browser, FocusSource source)
Expand All @@ -996,14 +993,9 @@ namespace CefSharp
return false;
}

// NOTE: a popup handler for OnGotFocus doesn't make sense yet because
// non-offscreen windows don't wrap popup browser's yet.
if (!browser->IsPopup())
{
return handler->OnSetFocus((CefFocusSource)source);
}
// Allow the focus to be set by default.
return false;
auto browserWrapper = GetBrowserWrapper(browser->GetIdentifier(), browser->IsPopup());

return handler->OnSetFocus(_browserControl, browserWrapper, (CefFocusSource)source);
}

void ClientAdapter::OnTakeFocus(CefRefPtr<CefBrowser> browser, bool next)
Expand All @@ -1015,12 +1007,9 @@ namespace CefSharp
return;
}

// NOTE: a popup handler for OnGotFocus doesn't make sense yet because
// non-offscreen windows don't wrap popup browser's yet.
if (!browser->IsPopup())
{
handler->OnTakeFocus(next);
}
auto browserWrapper = GetBrowserWrapper(browser->GetIdentifier(), browser->IsPopup());

handler->OnTakeFocus(_browserControl, browserWrapper, next);
}

bool ClientAdapter::OnJSDialog(CefRefPtr<CefBrowser> browser, const CefString& origin_url,
Expand Down
2 changes: 1 addition & 1 deletion CefSharp.WinForms/ChromiumWebBrowser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ private void InitializeFieldsAndCefIfRequired()

if (FocusHandler == null)
{
FocusHandler = new DefaultFocusHandler(this);
FocusHandler = new DefaultFocusHandler();
}

if (ResourceHandlerFactory == null)
Expand Down
61 changes: 35 additions & 26 deletions CefSharp.WinForms/Internals/DefaultFocusHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,32 @@
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

using CefSharp.Internals;
using System;
using System.Windows.Forms;
namespace CefSharp.WinForms.Internals
{
/// <summary>
/// Default implementation of <see cref="CefSharp.IFocusHandler" />
/// Default implementation of <see cref="IFocusHandler" />
/// for the WinForms implementation
/// </summary>
/// <seealso cref="CefSharp.IFocusHandler" />
public class DefaultFocusHandler : IFocusHandler
{
/// <summary>
/// The browser
/// </summary>
private readonly ChromiumWebBrowser browser;

/// <summary>
/// Initializes a new instance of the <see cref="DefaultFocusHandler"/> class.
/// </summary>
/// <param name="browser">The browser.</param>
public DefaultFocusHandler(ChromiumWebBrowser browser)
{
this.browser = browser;
}

/// <summary>
/// Called when the browser component has received focus.
/// </summary>
/// <param name="chromiumWebBrowser">the ChromiumWebBrowser control</param>
/// <param name="browser">the browser object</param>
/// <remarks>Try to avoid needing to override this logic in a subclass. The implementation in
/// DefaultFocusHandler relies on very detailed behavior of how WinForms and
/// Windows interact during window activation.</remarks>
public virtual void OnGotFocus()
public virtual void OnGotFocus(IWebBrowser chromiumWebBrowser, IBrowser browser)
{
//We don't deal with popups as they're rendered by default entirely by CEF
if (browser.IsPopup)
{
return;
}

var winFormsChromiumWebBrowser = (ChromiumWebBrowser)chromiumWebBrowser;
// During application activation, CEF receives a WM_SETFOCUS
// message from Windows because it is the top window
// on the CEF UI thread.
Expand Down Expand Up @@ -70,29 +62,36 @@ public virtual void OnGotFocus()
// * This method will clear the activation state (if any)
// on the ChromiumWebBrowser control, due to the race
// condition the WinForm UI thread cannot.
if (browser.IsActivating)
if (winFormsChromiumWebBrowser.IsActivating)
{
browser.IsActivating = false;
winFormsChromiumWebBrowser.IsActivating = false;
}
else
{
// Otherwise, we're not being activated
// so we must activate the ChromiumWebBrowser control
// for WinForms focus tracking.
browser.InvokeOnUiThreadIfRequired(() =>
winFormsChromiumWebBrowser.InvokeOnUiThreadIfRequired(() =>
{
browser.Activate();
winFormsChromiumWebBrowser.Activate();
});
}
}

/// <summary>
/// Called when the browser component is requesting focus.
/// </summary>
/// <param name="chromiumWebBrowser">the ChromiumWebBrowser control</param>
/// <param name="browser">the browser object</param>
/// <param name="source">Indicates where the focus request is originating from.</param>
/// <returns>Return false to allow the focus to be set or true to cancel setting the focus.</returns>
public virtual bool OnSetFocus(CefFocusSource source)
public virtual bool OnSetFocus(IWebBrowser chromiumWebBrowser, IBrowser browser, CefFocusSource source)
{
//We don't deal with popups as they're rendered by default entirely by CEF
if (browser.IsPopup)
{
return false;
}
// Do not let the browser take focus when a Load method has been called
return source == CefFocusSource.FocusSourceNavigation;
}
Expand All @@ -101,12 +100,22 @@ public virtual bool OnSetFocus(CefFocusSource source)
/// Called when the browser component is about to lose focus.
/// For instance, if focus was on the last HTML element and the user pressed the TAB key.
/// </summary>
/// <param name="chromiumWebBrowser">the ChromiumWebBrowser control</param>
/// <param name="browser">the browser object</param>
/// <param name="next">Will be true if the browser is giving focus to the next component
/// and false if the browser is giving focus to the previous component.</param>
public virtual void OnTakeFocus(bool next)
public virtual void OnTakeFocus(IWebBrowser chromiumWebBrowser, IBrowser browser, bool next)
{
//We don't deal with popups as they're rendered by default entirely by CEF
if (browser.IsPopup)
{
return;
}

var winFormsChromiumWebBrowser = (ChromiumWebBrowser)chromiumWebBrowser;

// NOTE: OnTakeFocus means leaving focus / not taking focus
browser.InvokeOnUiThreadIfRequired(() => browser.SelectNextControl(next));
winFormsChromiumWebBrowser.InvokeOnUiThreadIfRequired(() => winFormsChromiumWebBrowser.SelectNextControl(next));
}
}
}
12 changes: 9 additions & 3 deletions CefSharp/Handler/IFocusHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,27 @@ public interface IFocusHandler
/// <summary>
/// Called when the browser component has received focus.
/// </summary>
void OnGotFocus();
/// <param name="chromiumWebBrowser">the ChromiumWebBrowser control</param>
/// <param name="browser">the browser object</param>
void OnGotFocus(IWebBrowser chromiumWebBrowser, IBrowser browser);

/// <summary>
/// Called when the browser component is requesting focus.
/// </summary>
/// <param name="chromiumWebBrowser">the ChromiumWebBrowser control</param>
/// <param name="browser">the browser object</param>
/// <param name="source">Indicates where the focus request is originating from.</param>
/// <returns>Return false to allow the focus to be set or true to cancel setting the focus.</returns>
bool OnSetFocus(CefFocusSource source);
bool OnSetFocus(IWebBrowser chromiumWebBrowser, IBrowser browser, CefFocusSource source);

/// <summary>
/// Called when the browser component is about to lose focus.
/// For instance, if focus was on the last HTML element and the user pressed the TAB key.
/// </summary>
/// <param name="chromiumWebBrowser">the ChromiumWebBrowser control</param>
/// <param name="browser">the browser object</param>
/// <param name="next">Will be true if the browser is giving focus to the next component
/// and false if the browser is giving focus to the previous component.</param>
void OnTakeFocus(bool next);
void OnTakeFocus(IWebBrowser chromiumWebBrowser, IBrowser browser, bool next);
}
}

0 comments on commit 430c439

Please sign in to comment.