Skip to content

Commit

Permalink
Merge pull request #2495 from cwensley/curtis/fix-disabled-mouse-events
Browse files Browse the repository at this point in the history
Mac: Ensure controls only get mouse events when enabled
  • Loading branch information
cwensley authored Jun 6, 2023
2 parents fd15dcb + e7919f9 commit a6088fa
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/Eto.Mac/Forms/Controls/DrawableHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public override void DrawRect(CGRect dirtyRect)

public bool CanFocus { get; set; }

public override bool AcceptsFirstResponder() => CanFocus;
public override bool AcceptsFirstResponder() => CanFocus && Drawable?.Enabled == true;

public override NSView HitTest(CGPoint aPoint)
{
Expand Down
14 changes: 9 additions & 5 deletions src/Eto.Mac/Forms/MacView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ class MouseDelegate : NSObject
public void MouseMoved(NSEvent theEvent)
{
var h = Handler;
if (h == null) return;
if (h == null || !h.Enabled) return;
h.Callback.OnMouseMove(h.Widget, MacConversions.GetMouseEvent(h, theEvent, false));
}

[Export("mouseEntered:")]
public void MouseEntered(NSEvent theEvent)
{
var h = Handler;
if (h == null) return;
if (h == null || !h.Enabled) return;
h.Callback.OnMouseEnter(h.Widget, MacConversions.GetMouseEvent(h, theEvent, false));
}

Expand All @@ -45,7 +45,7 @@ public void CursorUpdate(NSEvent theEvent)
public void MouseExited(NSEvent theEvent)
{
var h = Handler;
if (h == null) return;
if (h == null || !h.Enabled) return;
h.Callback.OnMouseLeave(h.Widget, MacConversions.GetMouseEvent(h, theEvent, false));
}

Expand Down Expand Up @@ -84,6 +84,7 @@ public interface IMacViewHandler : IMacControlHandler
bool TextInputCancelled { get; set; }
bool TextInputImplemented { get; }
bool UseNSBoxBackgroundColor { get; set; }
bool Enabled { get; set; }

DragEventArgs GetDragEventArgs(NSDraggingInfo info, object customControl);

Expand Down Expand Up @@ -234,7 +235,7 @@ static void TriggerMouseUp(IntPtr sender, IntPtr sel, IntPtr e)
{
var obj = Runtime.GetNSObject(sender);

if (MacBase.GetHandler(obj) is IMacViewHandler handler)
if (MacBase.GetHandler(obj) is IMacViewHandler handler && handler.Enabled)
{
var theEvent = Messaging.GetNSObject<NSEvent>(e);
handler.TriggerMouseUp(obj, sel, theEvent);
Expand All @@ -245,7 +246,7 @@ static void TriggerMouseUp(IntPtr sender, IntPtr sel, IntPtr e)
static void TriggerMouseWheel(IntPtr sender, IntPtr sel, IntPtr e)
{
var obj = Runtime.GetNSObject(sender);
if (MacBase.GetHandler(obj) is IMacViewHandler handler)
if (MacBase.GetHandler(obj) is IMacViewHandler handler && handler.Enabled)
{
var theEvent = Messaging.GetNSObject<NSEvent>(e);
var args = MacConversions.GetMouseEvent(handler, theEvent, true);
Expand Down Expand Up @@ -1460,6 +1461,9 @@ public virtual MouseEventArgs TriggerMouseDown(NSObject obj, IntPtr sel, NSEvent
// showing context menus, dialogs, etc.
MacView.InMouseTrackingLoop = true;

if (!Enabled)
return null;

var args = MacConversions.GetMouseEvent(this, theEvent, false);
if (theEvent.ClickCount >= 2)
Callback.OnMouseDoubleClick(Widget, args);
Expand Down
4 changes: 2 additions & 2 deletions src/Eto.Wpf/Forms/WpfFrameworkElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -329,8 +329,8 @@ public SizeF GetPreferredSize(SizeF availableSize)

public virtual bool Enabled
{
get { return Control.IsEnabled; }
set { Control.IsEnabled = value; }
get { return ContainerControl.IsEnabled; }
set { ContainerControl.IsEnabled = value; }
}

public virtual Cursor Cursor
Expand Down
11 changes: 7 additions & 4 deletions test/Eto.Test/Sections/UnitTestSection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ namespace Eto.Test.Sections
[Section("Automated Tests", "Unit Tests")]
public class UnitTestSection : Panel
{
UnitTestPanel unitTestPanel;
static UnitTestPanel unitTestPanel;
UnitTestRunner runner;

public UnitTestSection()
{
runner = new UnitTestRunner(((TestApplication)TestApplication.Instance).TestAssemblies);
unitTestPanel = new UnitTestPanel(runner, false);
unitTestPanel.Log += (sender, e) => Log.Write(null, e.Message);
if (unitTestPanel == null)
{
runner = new UnitTestRunner(((TestApplication)TestApplication.Instance).TestAssemblies);
unitTestPanel = new UnitTestPanel(runner, false);
unitTestPanel.Log += (sender, e) => Log.Write(null, e.Message);
}

Content = unitTestPanel;
}
Expand Down
68 changes: 68 additions & 0 deletions test/Eto.Test/UnitTests/Forms/Controls/ControlTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -388,5 +388,73 @@ public void ControlsShouldHavePreferredSize(IControlTypeInfo<Control> info)
Assert.That(containerSize.Height, Is.EqualTo(size.Height + padding.Vertical).Within(0.1), "#2.2 - panel with padding should have correct height");
}

[ManualTest]
[TestCaseSource(nameof(GetControlTypes))]
public void ControlsShouldNotGetMouseOrFocusEventsWhenDisabled(IControlTypeInfo<Control> info)
{
ControlsShouldNotGetMouseOrFocusEventsWhenParentDisabled(info, false);
}

[ManualTest]
[TestCaseSource(nameof(GetControlTypes))]
public void ControlsShouldNotGetMouseOrFocusEventsWhenParentDisabled(IControlTypeInfo<Control> info)
{
ControlsShouldNotGetMouseOrFocusEventsWhenParentDisabled(info, true);
}

public void ControlsShouldNotGetMouseOrFocusEventsWhenParentDisabled(IControlTypeInfo<Control> info, bool disableWithParent)
{
bool gotFocus = false;
bool gotMouseDown = false;
bool gotMouseUp = false;
bool gotMouseEnter = false;
bool gotMouseLeave = false;
ManualForm("Click on the Drawable, it should not get focus", form =>
{
var control = info.CreatePopulatedControl();
if (!disableWithParent)
control.Enabled = false;
control.GotFocus += (sender, e) =>
{
Console.WriteLine("GotFocus");
gotFocus = true;
};
control.LostFocus += (sender, e) =>
{
Console.WriteLine("LostFocus");
};
control.MouseDown += (sender, e) =>
{
Console.WriteLine("MouseDown");
gotMouseDown = true;
};
control.MouseUp += (sender, e) =>
{
Console.WriteLine("MouseUp");
gotMouseUp = true;
};
control.MouseEnter += (sender, e) =>
{
Console.WriteLine("MouseEnter");
gotMouseEnter = true;
};
control.MouseLeave += (sender, e) =>
{
Console.WriteLine("MouseLeave");
gotMouseLeave = true;
};
var panel = new Panel { Content = control };
if (disableWithParent)
panel.Enabled = false;
return panel;
});
Assert.IsFalse(gotFocus, "#1.1 - Control should not be able to get focus");
Assert.IsFalse(gotMouseEnter, "#1.2 - Got MouseEnter");
Assert.IsFalse(gotMouseLeave, "#1.3 - Got MouseLeave");
Assert.IsFalse(gotMouseDown, "#1.4 - Got MouseDown");
Assert.IsFalse(gotMouseUp, "#1.5 - Got MouseUp");
}
}
}

0 comments on commit a6088fa

Please sign in to comment.