Index: Plugins/NoesisGUI/Source/NoesisRuntime/Classes/NoesisInstance.h
===================================================================
--- Plugins/NoesisGUI/Source/NoesisRuntime/Classes/NoesisInstance.h	(revision 14201)
+++ Plugins/NoesisGUI/Source/NoesisRuntime/Classes/NoesisInstance.h	(working copy)
@@ -216,6 +216,7 @@
 	void OnPreviewLostKeyboardFocus(Noesis::BaseComponent* Component, const Noesis::KeyboardFocusChangedEventArgs& Args);
 
 	bool HitTest(FVector2D Position) const;
+	bool HasMouseCapture() const;
 
 	void TermInstance();
 
@@ -264,9 +265,17 @@
 	virtual FReply NativeOnTouchEnded(const FGeometry& MyGeometry, const FPointerEvent& InTouchEvent) override;
 	virtual FCursorReply NativeOnCursorQuery(const FGeometry& MyGeometry, const FPointerEvent& CursorEvent) override;
 	virtual FReply NativeOnMouseButtonDoubleClick(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
+	virtual void NativeOnMouseEnter(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent) override;
+	virtual void NativeOnMouseLeave(const FPointerEvent& InMouseEvent) override;
 	virtual bool NativeSupportsKeyboardFocus() const override;
 	virtual void NativeConstruct() override;
 	virtual void NativeDestruct() override;
+	virtual FReply NativeOnFocusReceived(const FGeometry& InGeometry, const FFocusEvent& InFocusEvent) override;
+	virtual void NativeOnFocusLost(const FFocusEvent& InFocusEvent) override;
+	virtual void NativeOnFocusChanging(const FWeakWidgetPath& PreviousFocusPath, const FWidgetPath& NewWidgetPath, const FFocusEvent& InFocusEvent) override;
+	virtual void NativeOnAddedToFocusPath(const FFocusEvent& InFocusEvent) override;
+	virtual void NativeOnRemovedFromFocusPath(const FFocusEvent& InFocusEvent) override;
+	virtual FNavigationReply NativeOnNavigation(const FGeometry& MyGeometry, const FNavigationEvent& InNavigationEvent, const FNavigationReply& InDefaultReply) override;
 	// End of UUserWidget interface
 };
 
Index: Plugins/NoesisGUI/Source/NoesisRuntime/Private/NoesisInstance.cpp
===================================================================
--- Plugins/NoesisGUI/Source/NoesisRuntime/Private/NoesisInstance.cpp	(revision 14201)
+++ Plugins/NoesisGUI/Source/NoesisRuntime/Private/NoesisInstance.cpp	(working copy)
@@ -1162,6 +1162,18 @@
 	return HitTester.Hit != nullptr;
 }
 
+bool UNoesisInstance::HasMouseCapture() const
+{
+	if (XamlView)
+	{
+		auto Root = XamlView->GetContent();
+		auto Mouse = Root != nullptr ? Root->GetMouse() : nullptr;
+		return Mouse != nullptr && Mouse->GetCaptured() != nullptr;
+	}
+
+	return false;
+}
+
 void UNoesisInstance::TermInstance()
 {
 	if (XamlView)
@@ -1465,10 +1477,17 @@
 	{
 		TCHAR Character = CharacterEvent.GetCharacter();
 
-		XamlView->Char(CharCast<char>(Character));
+		bool Handled = XamlView->Char(CharCast<char>(Character));
+
+		if (Handled)
+		{
+			UE_LOG(LogNoesis, Warning, TEXT("Char handled %c"), Character);
+			return FReply::Handled();
+		}
 	}
 
-	return Super::NativeOnKeyChar(MyGeometry, CharacterEvent);
+	UE_LOG(LogNoesis, Warning, TEXT("Char unhandled %c"), CharacterEvent.GetCharacter());
+	return FReply::Unhandled();
 }
 
 static TMap<FKey, Noesis::Key> InitKeyMap()
@@ -1595,11 +1614,18 @@
 		Noesis::Key* NoesisKey = KeyToNoesisKey(Key);
 		if (NoesisKey != nullptr)
 		{
-			XamlView->KeyDown(*NoesisKey);
+			bool Handled = XamlView->KeyDown(*NoesisKey);
+
+			if (Handled)
+			{
+				UE_LOG(LogNoesis, Warning, TEXT("KeyDown handled %s"), *KeyEvent.GetKey().ToString());
+				return FReply::Handled();
+			}
 		}
 	}
 
-	return Super::NativeOnKeyDown(MyGeometry, KeyEvent);
+	UE_LOG(LogNoesis, Warning, TEXT("KeyDown unhandled %s"), *KeyEvent.GetKey().ToString());
+	return FReply::Unhandled();
 }
 
 FReply UNoesisInstance::NativeOnKeyUp(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent)
@@ -1611,31 +1637,22 @@
 		Noesis::Key* NoesisKey = KeyToNoesisKey(Key);
 		if (NoesisKey != nullptr)
 		{
-			XamlView->KeyUp(*NoesisKey);
+			bool Handled = XamlView->KeyUp(*NoesisKey);
+
+			if (Handled)
+			{
+				UE_LOG(LogNoesis, Warning, TEXT("KeyUp handled %s"), *KeyEvent.GetKey().ToString());
+				return FReply::Handled();
+			}
 		}
 	}
 
-	return Super::NativeOnKeyUp(MyGeometry, KeyEvent);
+	UE_LOG(LogNoesis, Warning, TEXT("KeyUp unhandled %s"), *KeyEvent.GetKey().ToString());
+	return FReply::Unhandled();
 }
 
 FReply UNoesisInstance::NativeOnAnalogValueChanged(const FGeometry& MyGeometry, const FAnalogInputEvent& InAnalogEvent)
 {
-	SCOPE_CYCLE_COUNTER(STAT_NoesisInstance_OnAnalogValueChanged);
-	if (XamlView)
-	{
-		if (FMath::Abs(InAnalogEvent.GetAnalogValue()) > 0.25f)
-		{
-			if (InAnalogEvent.GetKey() == EKeys::Gamepad_RightX)
-			{
-				XamlView->HScroll(InAnalogEvent.GetAnalogValue());
-			}
-			else if (InAnalogEvent.GetKey() == EKeys::Gamepad_RightY)
-			{
-				XamlView->Scroll(InAnalogEvent.GetAnalogValue());
-			}
-		}
-	}
-
 	return Super::NativeOnAnalogValueChanged(MyGeometry, InAnalogEvent);
 }
 
@@ -1670,7 +1687,7 @@
 
 			if (Handled)
 			{
-				return FReply::Handled().PreventThrottling().CaptureMouse(MyWidget.Pin().ToSharedRef());
+				return FReply::Handled().PreventThrottling().CaptureMouse(TakeWidget());
 			}
 		}
 		else
@@ -1679,15 +1696,27 @@
 			bool Hit = HitTest(Position);
 
 			Noesis::MouseButton MouseButton = GetNoesisMouseButton(MouseEvent.GetEffectingButton());
-			bool Handled = XamlView->MouseButtonDown(FPlatformMath::RoundToInt(Position.X), FPlatformMath::RoundToInt(Position.Y), MouseButton);
+			bool Handled = XamlView->MouseButtonDown(FPlatformMath::RoundToInt(Position.X), FPlatformMath::RoundToInt(Position.Y), MouseButton) || HasMouseCapture();
 
 			if (Handled && Hit)
 			{
-				return FReply::Handled().PreventThrottling();
+				auto Reply = FReply::Handled().PreventThrottling().SetUserFocus(FSlateApplication::Get().GetGameViewport().ToSharedRef());
+				if (HasMouseCapture())
+				{
+					UE_LOG(LogNoesis, Warning, TEXT("MouseButtonDown CaptureMouse"));
+					Reply.CaptureMouse(TakeWidget());
+				}
+				else
+				{
+					UE_LOG(LogNoesis, Warning, TEXT("MouseButtonDown ReleaseMouseCapture"));
+					Reply.ReleaseMouseCapture();
+				}
+				return Reply;
 			}
 		}
 	}
 
+	UE_LOG(LogNoesis, Warning, TEXT("MouseButtonDown Unhandled"));
 	return FReply::Unhandled();
 }
 
@@ -1712,15 +1741,27 @@
 			bool Hit = HitTest(Position);
 
 			Noesis::MouseButton MouseButton = GetNoesisMouseButton(MouseEvent.GetEffectingButton());
-			bool Handled = XamlView->MouseButtonUp(FPlatformMath::RoundToInt(Position.X), FPlatformMath::RoundToInt(Position.Y), MouseButton);
+			bool Handled = XamlView->MouseButtonUp(FPlatformMath::RoundToInt(Position.X), FPlatformMath::RoundToInt(Position.Y), MouseButton) || HasMouseCapture();
 
 			if (Handled && Hit)
 			{
-				return FReply::Handled().PreventThrottling();
+				auto Reply = FReply::Handled().PreventThrottling().SetUserFocus(FSlateApplication::Get().GetGameViewport().ToSharedRef());
+				if (HasMouseCapture())
+				{
+					UE_LOG(LogNoesis, Warning, TEXT("MouseButtonUp CaptureMouse"));
+					Reply.CaptureMouse(TakeWidget());
+				}
+				else
+				{
+					UE_LOG(LogNoesis, Warning, TEXT("MouseButtonUp ReleaseMouseCapture"));
+					Reply.ReleaseMouseCapture();
+				}
+				return Reply;
 			}
 		}
 	}
 
+	UE_LOG(LogNoesis, Warning, TEXT("MouseButtonUp Unhandled"));
 	return FReply::Unhandled();
 }
 
@@ -1732,14 +1773,29 @@
 		FVector2D Position = MyGeometry.AbsoluteToLocal(MouseEvent.GetScreenSpacePosition()) * MyGeometry.Scale;
 		bool Hit = HitTest(Position);
 
-		bool Handled = XamlView->MouseMove(FPlatformMath::RoundToInt(Position.X), FPlatformMath::RoundToInt(Position.Y));
+		bool Handled = XamlView->MouseMove(FPlatformMath::RoundToInt(Position.X), FPlatformMath::RoundToInt(Position.Y)) || HasMouseCapture();
 
 		if (Handled && Hit)
 		{
-			return FReply::Handled().PreventThrottling();
+			auto Reply = FReply::Handled().PreventThrottling().SetUserFocus(FSlateApplication::Get().GetGameViewport().ToSharedRef());
+			if (HasMouseCapture())
+			{
+				UE_LOG(LogNoesis, Warning, TEXT("MouseMove CaptureMouse"));
+				Reply.CaptureMouse(TakeWidget());
+			}
+			else
+			{
+				UE_LOG(LogNoesis, Warning, TEXT("MouseMove ReleaseMouseCapture"));
+				Reply.ReleaseMouseCapture();
+			}
+			return Reply;
 		}
 	}
 
+	if (!MouseEvent.GetCursorDelta().IsZero())
+	{
+		UE_LOG(LogNoesis, Warning, TEXT("MouseMove Unhandled"));
+	}
 	return FReply::Unhandled();
 }
 
@@ -1756,7 +1812,16 @@
 
 		if (Handled && Hit)
 		{
-			return FReply::Handled().PreventThrottling();
+			auto Reply = FReply::Handled().PreventThrottling();
+			if (HasMouseCapture())
+			{
+				Reply.CaptureMouse(TakeWidget());
+			}
+			else
+			{
+				Reply.ReleaseMouseCapture();
+			}
+			return Reply;
 		}
 	}
 
@@ -1776,7 +1841,16 @@
 
 		if (Handled && Hit)
 		{
-			return FReply::Handled().PreventThrottling();
+			auto Reply = FReply::Handled().PreventThrottling();
+			if (HasMouseCapture())
+			{
+				Reply.CaptureMouse(TakeWidget());
+			}
+			else
+			{
+				Reply.ReleaseMouseCapture();
+			}
+			return Reply;
 		}
 	}
 
@@ -1796,7 +1870,16 @@
 
 		if (Handled && Hit)
 		{
-			return FReply::Handled().PreventThrottling();
+			auto Reply = FReply::Handled().PreventThrottling();
+			if (HasMouseCapture())
+			{
+				Reply.CaptureMouse(TakeWidget());
+			}
+			else
+			{
+				Reply.ReleaseMouseCapture();
+			}
+			return Reply;
 		}
 	}
 
@@ -1816,7 +1899,16 @@
 
 		if (Handled && Hit)
 		{
-			return FReply::Handled().PreventThrottling();
+			auto Reply = FReply::Handled().PreventThrottling();
+			if (HasMouseCapture())
+			{
+				Reply.CaptureMouse(TakeWidget());
+			}
+			else
+			{
+				Reply.ReleaseMouseCapture();
+			}
+			return Reply;
 		}
 	}
 
@@ -1841,7 +1933,16 @@
 
 		if (Handled && Hit)
 		{
-			return FReply::Handled().PreventThrottling();
+			auto Reply = FReply::Handled().PreventThrottling();
+			if (HasMouseCapture())
+			{
+				Reply.CaptureMouse(TakeWidget());
+			}
+			else
+			{
+				Reply.ReleaseMouseCapture();
+			}
+			return Reply;
 		}
 	}
 
@@ -1848,6 +1949,59 @@
 	return FReply::Unhandled();
 }
 
+void UNoesisInstance::NativeOnMouseEnter(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent)
+{
+	UE_LOG(LogNoesis, Warning, TEXT("MouseEnter"));
+	if (XamlView)
+	{
+		UE_LOG(LogNoesis, Warning, TEXT("Activate View"));
+		XamlView->Activate();
+	}
+}
+
+void UNoesisInstance::NativeOnMouseLeave(const FPointerEvent& InMouseEvent)
+{
+	UE_LOG(LogNoesis, Warning, TEXT("MouseLeave"));
+	if (XamlView && !HasMouseCapture())
+	{
+		UE_LOG(LogNoesis, Warning, TEXT("Deactivate View"));
+		XamlView->Deactivate();
+	}
+}
+
+FReply UNoesisInstance::NativeOnFocusReceived(const FGeometry& InGeometry, const FFocusEvent& InFocusEvent)
+{
+	UE_LOG(LogNoesis, Warning, TEXT("FocusReceived"));
+	return Super::NativeOnFocusReceived(InGeometry, InFocusEvent);
+	//return FReply::Handled().ClearUserFocus();
+}
+
+void UNoesisInstance::NativeOnFocusLost(const FFocusEvent& InFocusEvent)
+{
+	UE_LOG(LogNoesis, Warning, TEXT("FocusLost"));
+}
+
+void UNoesisInstance::NativeOnFocusChanging(const FWeakWidgetPath& PreviousFocusPath, const FWidgetPath& NewWidgetPath, const FFocusEvent& InFocusEvent)
+{
+	UE_LOG(LogNoesis, Warning, TEXT("FocusChanging"));
+}
+
+void UNoesisInstance::NativeOnAddedToFocusPath(const FFocusEvent& InFocusEvent)
+{
+	UE_LOG(LogNoesis, Warning, TEXT("AddedToFocusPath"));
+}
+
+void UNoesisInstance::NativeOnRemovedFromFocusPath(const FFocusEvent& InFocusEvent)
+{
+	UE_LOG(LogNoesis, Warning, TEXT("RemovedFromFocusPath"));
+}
+
+FNavigationReply UNoesisInstance::NativeOnNavigation(const FGeometry& MyGeometry, const FNavigationEvent& InNavigationEvent, const FNavigationReply& InDefaultReply)
+{
+	UE_LOG(LogNoesis, Warning, TEXT("Navigation"));
+	return Super::NativeOnNavigation(MyGeometry, InNavigationEvent, InDefaultReply);
+}
+
 bool UNoesisInstance::NativeSupportsKeyboardFocus() const
 {
 	// SObjectWidget::OnKeyDown calls UNoesisInstance::NativeOnKeyDown. There we set SupportsKeyboardFocus = !EnableActions.
Index: Source/Inventory/DragItemBehavior.cpp
===================================================================
--- Source/Inventory/DragItemBehavior.cpp	(revision 14126)
+++ Source/Inventory/DragItemBehavior.cpp	(working copy)
@@ -100,14 +100,32 @@
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 void DragItemBehavior::OnMouseDown(BaseComponent*, const MouseButtonEventArgs& e)
 {
+    UE_LOG(LogNoesisInventory, Warning, TEXT("DragItemBehavior::OnMouseDown"));
     _mouseClicked = true;
     e.handled = true;
 }
 
+static void ResetFocus(BaseComponent* source)
+{
+    auto element = Noesis::DynamicCast<UIElement*>(source);
+    if (element != nullptr)
+    {
+        auto keyboard = element->GetKeyboard();
+        if (keyboard != nullptr)
+        {
+            keyboard->Focus(nullptr);
+        }
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////////////////////////
-void DragItemBehavior::OnMouseUp(BaseComponent*, const MouseButtonEventArgs&)
+void DragItemBehavior::OnMouseUp(BaseComponent* source, const MouseButtonEventArgs& e)
 {
+    UE_LOG(LogNoesisInventory, Warning, TEXT("DragItemBehavior::OnMouseUp"));
     _mouseClicked = false;
+    e.handled = true;
+
+    ResetFocus(source);
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -118,6 +136,7 @@
         return;
     }
 
+    UE_LOG(LogNoesisInventory, Warning, TEXT("DragItemBehavior::OnMouseMove"));
     _mouseClicked = false;
 
     FrameworkElement* element = GetAssociatedObject();
@@ -131,7 +150,7 @@
 
             startDrag->Execute(item);
 
-            DragDrop::DoDragDrop(element, item, DragDropEffects_Move, [this](DependencyObject*,
+            DragDrop::DoDragDrop(element, item, DragDropEffects_Move, [this](DependencyObject* source,
                 BaseComponent*, UIElement*, const Noesis::Point&, uint32_t effects)
             {
                 Noesis::Ptr<BaseComponent> dragSuccess = Boxing::Box<bool>(effects != DragDropEffects_None);
@@ -140,9 +159,13 @@
                 {
                     endDrag->Execute(dragSuccess);
                 }
+
+                ResetFocus(source);
             });
         }
     }
+
+    e.handled = true;
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
Index: Source/Inventory/InventoryGame.cpp
===================================================================
--- Source/Inventory/InventoryGame.cpp	(revision 14126)
+++ Source/Inventory/InventoryGame.cpp	(working copy)
@@ -11,6 +11,8 @@
 #include "DragItemBehavior.h"
 #include "DropItemBehavior.h"
 
+DEFINE_LOG_CATEGORY(LogNoesisInventory);
+
 class InventoryModule : public FDefaultGameModuleImpl
 {
     virtual void StartupModule() override
