Skip to content

Commit

Permalink
Merge pull request #2512 from cwensley/curtis/mac-gtk-got-lost-focus-…
Browse files Browse the repository at this point in the history
…along-with-window-focus

Mac/Gtk: Ensure control gets Got/LostFocus events when window Got/LostFocus is triggered
  • Loading branch information
cwensley authored Jul 4, 2023
2 parents 9931162 + f79994f commit be8742e
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 3 deletions.
4 changes: 2 additions & 2 deletions src/Eto.Gtk/Forms/GtkControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ void Widget_SetFocus(object sender, EventArgs e)
Eto.Forms.Application.Instance.AsyncInvoke(GrabFocus);
}

public bool HasFocus
public virtual bool HasFocus
{
get { return Control.HasFocus; }
}
Expand Down Expand Up @@ -691,7 +691,7 @@ public virtual void FocusInEvent(object o, Gtk.FocusInEventArgs args)
var handler = Handler;
if (handler == null)
return;
handler.Callback.OnGotFocus(handler.Widget, EventArgs.Empty);
Application.Instance.AsyncInvoke(() => handler.Callback.OnGotFocus(handler.Widget, EventArgs.Empty));
}

public virtual void FocusOutEvent(object o, Gtk.FocusOutEventArgs args)
Expand Down
2 changes: 2 additions & 0 deletions src/Eto.Gtk/Forms/GtkWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ public override Size MinimumSize
}
}

public override bool HasFocus => Control.HasToplevelFocus;

public Gtk.Widget WindowContentControl
{
get { return vbox; }
Expand Down
2 changes: 1 addition & 1 deletion src/Eto.Mac/Forms/MacView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1062,7 +1062,7 @@ public virtual bool HasFocus
{
get
{
return ShouldHaveFocus ?? (FocusControl.Window != null && FocusControl.Window.FirstResponder == Control);
return ShouldHaveFocus ?? (FocusControl.Window?.FirstResponder == Control && FocusControl.Window?.IsKeyWindow == true);
}
}

Expand Down
18 changes: 18 additions & 0 deletions src/Eto.Mac/Forms/MacWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -339,13 +339,23 @@ static void HandleGotFocus(object sender, EventArgs e)
if (handler == null)
return;
handler.Callback.OnGotFocus(handler.Widget, EventArgs.Empty);
if (GetHandler(handler.Control.FirstResponder) is IMacViewHandler ctlHandler)
{
ctlHandler.Callback.OnGotFocus(ctlHandler.Widget, EventArgs.Empty);
}
}

static void HandleLostFocus(object sender, EventArgs e)
{
var handler = GetHandler(sender) as MacWindow<TControl, TWidget, TCallback>;
if (handler == null)
return;

if (GetHandler(handler.Control.FirstResponder) is IMacViewHandler ctlHandler)
{
ctlHandler.Callback.OnLostFocus(ctlHandler.Widget, EventArgs.Empty);
}

handler.Callback.OnLostFocus(handler.Widget, EventArgs.Empty);
}

Expand Down Expand Up @@ -1043,6 +1053,14 @@ public bool AnimateSizeChanges
set => Widget.Properties.Set(MacWindow.AnimateSizeChanges_Key, value);
}

protected override void Initialize()
{
base.Initialize();

// need to send Got/LostFocus to child when window Got/LostFocus is called
HandleEvent(Window.LostFocusEvent);
HandleEvent(Window.GotFocusEvent);
}

public override void OnLoad(EventArgs e)
{
Expand Down
26 changes: 26 additions & 0 deletions test/Eto.Test/Sections/Behaviors/FocusEventsSection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,32 @@ namespace Eto.Test.Sections.Behaviors
[Section("Behaviors", "Focus Events")]
public class FocusEventsSection : AllControlsBase
{
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
ParentWindow.GotFocus += Window_GotFocus;
ParentWindow.LostFocus += Window_LostFocus;
}

protected override void OnUnLoad(EventArgs e)
{
base.OnUnLoad(e);
ParentWindow.GotFocus -= Window_GotFocus;
ParentWindow.LostFocus -= Window_LostFocus;
}

protected void Window_GotFocus(object sender, EventArgs e)
{
if (sender is Window window)
Log.Write(sender, $"Window.GotFocus, HasFocus: {window.HasFocus}");
}

protected void Window_LostFocus(object sender, EventArgs e)
{
if (sender is Window window)
Log.Write(sender, $"Window.LostFocus, HasFocus: {window.HasFocus}");
}

protected override void LogEvents(Control control)
{
base.LogEvents(control);
Expand Down

0 comments on commit be8742e

Please sign in to comment.