View Issue Details

IDProjectCategoryView StatusLast Update
0004701NoesisGUIUnrealpublic2026-01-19 20:36
ReporterSillyGoose Assigned Tohcpizzi  
PrioritynormalSeverityminor 
Status resolvedResolutionfixed 
Product Version3.2.10 
Target Version3.2.11Fixed in Version3.2.11 
Summary0004701: Unreal - method of preventing background clicks from switching widget focus to the game viewport & losing Noesis focus
Description

As per this forum post https://www.noesisengine.com/forums/viewtopic.php?p=19346#p19346 - in Unreal when you click the background this makes focus leave the Noesis Viewport and Focus on the GameViewport behind - which stops inputs/keyboard focus working. You can regain focus by clicking an interactive element.

Repro:

  1. Load your Buttons or QuestLog Samples app in Unreal
  2. Use keyboard to navigate up and down options & see it working
  3. Click anywhere in the background (or that isn't a button)
  4. Try use the keyboard - nothing works, as Unreal Focus has changed to the Viewport Widget

Ideally there should be a way to decide which things block clicks in the Noesis asset, so it can prevents clicks reaching the game behind them. I can see cases where you may want to let that happen, e.g. if you click an area not part of UI, but also case where someone may want to setup a background (whether visible or invisible) to block clicks reaching the game.

I guess a solution is needed to support a method to control this.

PlatformWindows

Activities

hcpizzi

hcpizzi

2026-01-19 20:36

developer   ~0011711

We've modified the logic that decides which mouse events to bubble up to the vieport. It will be fixed in 3.2.11, but I've attached a patch with the fix for you to use until then.

4701.patch (5,573 bytes)   
Index: NoesisInstance.cpp
===================================================================
--- NoesisInstance.cpp	(revision 16500)
+++ NoesisInstance.cpp	(working copy)
@@ -1234,24 +1234,23 @@
 {
 	NoesisHitTestVisibleTester(): Hit(nullptr) { }
 
-	Noesis::HitTestFilterBehavior Filter(Noesis::Visual*)
+	Noesis::HitTestFilterBehavior Filter(Noesis::Visual* Visual)
 	{
+		Noesis::UIElement* Element = Noesis::DynamicCast<Noesis::UIElement*>(Visual);
+		if (Element != nullptr && !Element->GetIsHitTestVisible())
+		{
+			return Noesis::HitTestFilterBehavior_ContinueSkipSelfAndChildren;
+		}
 		return Noesis::HitTestFilterBehavior_Continue;
 	}
 
 	Noesis::HitTestResultBehavior Result(const Noesis::HitTestResult& Result)
 	{
-		Noesis::UIElement* Element = Noesis::DynamicCast<Noesis::UIElement*>(Result.visualHit);
-		if (Element && Element->GetIsEnabled())
-		{
-			Hit = Element;
-			return Noesis::HitTestResultBehavior_Stop;
-		}
-
-		return Noesis::HitTestResultBehavior_Continue;
+		Hit = Result.visualHit;
+		return Noesis::HitTestResultBehavior_Stop;
 	}
 
-	Noesis::UIElement* Hit;
+	Noesis::Visual* Hit;
 };
 
 bool UNoesisInstance::HitTest(FVector2D Position) const
@@ -1800,9 +1799,9 @@
 			bool Hit = HitTest(Position);
 
 			Noesis::MouseButton MouseButton = GetNoesisMouseButton(MouseEvent.GetEffectingButton());
-			bool Handled = XamlView->MouseButtonDown(FPlatformMath::RoundToInt(Position.X), FPlatformMath::RoundToInt(Position.Y), MouseButton) || HasMouseCapture();
+			XamlView->MouseButtonDown(FPlatformMath::RoundToInt(Position.X), FPlatformMath::RoundToInt(Position.Y), MouseButton) || HasMouseCapture();
 
-			if (Handled && Hit)
+			if (Hit)
 			{
 				auto Reply = FReply::Handled().PreventThrottling();
 				if (SetUserFocusToViewport)
@@ -1846,9 +1845,9 @@
 			bool Hit = HitTest(Position);
 
 			Noesis::MouseButton MouseButton = GetNoesisMouseButton(MouseEvent.GetEffectingButton());
-			bool Handled = XamlView->MouseButtonUp(FPlatformMath::RoundToInt(Position.X), FPlatformMath::RoundToInt(Position.Y), MouseButton) || HasMouseCapture();
+			XamlView->MouseButtonUp(FPlatformMath::RoundToInt(Position.X), FPlatformMath::RoundToInt(Position.Y), MouseButton) || HasMouseCapture();
 
-			if (Handled && Hit)
+			if (Hit)
 			{
 				auto Reply = FReply::Handled().PreventThrottling();
 				if (SetUserFocusToViewport)
@@ -1879,9 +1878,9 @@
 		FVector2D Position = MyGeometry.AbsoluteToLocal(MouseEvent.GetScreenSpacePosition()) * MyGeometry.Scale;
 		bool Hit = HitTest(Position);
 
-		bool Handled = XamlView->MouseMove(FPlatformMath::RoundToInt(Position.X), FPlatformMath::RoundToInt(Position.Y)) || HasMouseCapture();
+		XamlView->MouseMove(FPlatformMath::RoundToInt(Position.X), FPlatformMath::RoundToInt(Position.Y)) || HasMouseCapture();
 
-		if (Handled && Hit)
+		if (Hit)
 		{
 			auto Reply = FReply::Handled().PreventThrottling();
 			if (SetUserFocusToViewport)
@@ -1912,9 +1911,9 @@
 		bool Hit = HitTest(Position);
 
 		float WheelDelta = MouseEvent.GetWheelDelta();
-		bool Handled = XamlView->MouseWheel(FPlatformMath::RoundToInt(Position.X), FPlatformMath::RoundToInt(Position.Y), FPlatformMath::RoundToInt(WheelDelta * 120.f));
+		XamlView->MouseWheel(FPlatformMath::RoundToInt(Position.X), FPlatformMath::RoundToInt(Position.Y), FPlatformMath::RoundToInt(WheelDelta * 120.f));
 
-		if (Handled && Hit)
+		if (Hit)
 		{
 			auto Reply = FReply::Handled().PreventThrottling();
 			if (HasMouseCapture())
@@ -1941,9 +1940,9 @@
 		bool Hit = HitTest(Position);
 
 		uint32 PointerIndex = TouchEvent.GetPointerIndex();
-		bool Handled = XamlView->TouchDown(FPlatformMath::RoundToInt(Position.X), FPlatformMath::RoundToInt(Position.Y), PointerIndex);
+		XamlView->TouchDown(FPlatformMath::RoundToInt(Position.X), FPlatformMath::RoundToInt(Position.Y), PointerIndex);
 
-		if (Handled && Hit)
+		if (Hit)
 		{
 			auto Reply = FReply::Handled().PreventThrottling();
 			if (HasMouseCapture())
@@ -1970,9 +1969,9 @@
 		bool Hit = HitTest(Position);
 
 		uint32 PointerIndex = TouchEvent.GetPointerIndex();
-		bool Handled = XamlView->TouchMove(FPlatformMath::RoundToInt(Position.X), FPlatformMath::RoundToInt(Position.Y), PointerIndex);
+		XamlView->TouchMove(FPlatformMath::RoundToInt(Position.X), FPlatformMath::RoundToInt(Position.Y), PointerIndex);
 
-		if (Handled && Hit)
+		if (Hit)
 		{
 			auto Reply = FReply::Handled().PreventThrottling();
 			if (HasMouseCapture())
@@ -1999,9 +1998,9 @@
 		bool Hit = HitTest(Position);
 
 		uint32 PointerIndex = TouchEvent.GetPointerIndex();
-		bool Handled = XamlView->TouchUp(FPlatformMath::RoundToInt(Position.X), FPlatformMath::RoundToInt(Position.Y), PointerIndex);
+		XamlView->TouchUp(FPlatformMath::RoundToInt(Position.X), FPlatformMath::RoundToInt(Position.Y), PointerIndex);
 
-		if (Handled && Hit)
+		if (Hit)
 		{
 			auto Reply = FReply::Handled().PreventThrottling();
 			if (HasMouseCapture())
@@ -2028,9 +2027,9 @@
 		bool Hit = HitTest(Position);
 
 		Noesis::MouseButton MouseButton = GetNoesisMouseButton(MouseEvent.GetEffectingButton());
-		bool Handled = XamlView->MouseDoubleClick(FPlatformMath::RoundToInt(Position.X), FPlatformMath::RoundToInt(Position.Y), MouseButton);
+		XamlView->MouseDoubleClick(FPlatformMath::RoundToInt(Position.X), FPlatformMath::RoundToInt(Position.Y), MouseButton);
 
-		if (Handled && Hit)
+		if (Hit)
 		{
 			auto Reply = FReply::Handled().PreventThrottling();
 			if (HasMouseCapture())
4701.patch (5,573 bytes)   

Issue History

Date Modified Username Field Change
2026-01-13 16:48 SillyGoose New Issue
2026-01-13 18:24 jsantos Target Version => 3.2.11
2026-01-13 18:24 jsantos Assigned To => hcpizzi
2026-01-13 18:24 jsantos Status new => assigned
2026-01-19 20:36 hcpizzi Note Added: 0011711
2026-01-19 20:36 hcpizzi File Added: 4701.patch
2026-01-19 20:36 hcpizzi Status assigned => resolved
2026-01-19 20:36 hcpizzi Resolution open => fixed
2026-01-19 20:36 hcpizzi Fixed in Version => 3.2.11