Embedded Unity Application in WPF, loses focus, after mouseclick

I am building a Unity application (version 2019.3.12f1), embedded into a WPF host application.
In the host Application, the user can switch between different tabs (one of them being the “view” → our Unity Application).
When unity Tab is “closed” it stays active in background (checked checkmark in Unity Player Settings).
However, when “tabbing” back into Unity, it loses it’s focus, after any mouseclick and hence won’t respond to additional UI-Click events, GetMouseButton or Mouse.GetAxis("Mouse X) events. Strangely, OnMouseEnter, OnMouseExit and OnMouseDown events (over normal GameObjects) still fire the defined functions.
What I’ve tried so far:
Importing DLL32 and using SetForegroundWindow(IntPtr hwnd); ,
ShowWindow(…), ShowWindowAsync(…).
Sadly I can’t debug directly into unity (because it only runs as standalone version in the WPF application). So for now, all I’m doing is displaying things like Application.isFocused.ToString(); in simple Text elements.
Has anyone run into similar problems?

Figured it out… WPF got stuck inside the loading event, ran into an exception but somehow didn’t show it in Visual studio.

Can you explane what exactly you doing? And how did you solve the problem?

I have the same or similar problem.
I’m building a player of Unity’s URP sample scene.
I created a UnityHostControl.cs that lives in wpf.

Everything is working (keyboard, mouse), but as soon as I enter the text box, Unity no longer intercepts keyboard commands anymore (mouse still works).

Here is my code

public class UnityHwndHost : HwndHost {
        internal delegate int WindowEnumProc(IntPtr hwnd, IntPtr lparam);
        [DllImport("user32.dll")]
        internal static extern bool EnumChildWindows(IntPtr hwnd, WindowEnumProc func, IntPtr lParam);
        [DllImport("user32.dll", SetLastError = true)]
        internal static extern uint GetWindowThreadProcessId(IntPtr hwnd, out uint processId);
        [DllImport("user32.dll", EntryPoint = "GetWindowLong")]
        internal static extern IntPtr GetWindowLong32(IntPtr hWnd, Int32 nIndex);
        [DllImport("user32.dll", EntryPoint = "GetWindowLongPtr")]
        internal static extern IntPtr GetWindowLongPtr64(IntPtr hWnd, Int32 nIndex);
        internal const Int32 GWLP_USERDATA = -21;
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        internal static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        internal static extern IntPtr PostMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
        internal const UInt32 WM_CLOSE = 0x0010;

        private Process process = null;
        private IntPtr unityHWND = IntPtr.Zero;

        //private JobObject job;

        private const int WM_ACTIVATE = 0x0006;
        private readonly IntPtr WA_ACTIVE = new IntPtr(1);
        private readonly IntPtr WA_INACTIVE = new IntPtr(0);

        public string AppPath { get; set; }


        protected override HandleRef BuildWindowCore(HandleRef hwndParent) {
            Debug.WriteLine("Going to launch Unity at: " + AppPath);
            process = new Process();
            process.StartInfo.FileName = AppPath;
            process.StartInfo.Arguments = "-parentHWND " + hwndParent.Handle.ToInt32() + " " + Environment.CommandLine;
            process.StartInfo.UseShellExecute = true;
            process.StartInfo.CreateNoWindow = true;

            process.Start();
            process.WaitForInputIdle();

            //job = JobObject.CreateAsKillOnJobClose();
            //job.AssignProcess(process);

            int repeat = 50;
            while (unityHWND == IntPtr.Zero && repeat-- > 0) {
                Thread.Sleep(100);
                EnumChildWindows(hwndParent.Handle, WindowEnum, IntPtr.Zero);
            }
            if (unityHWND == IntPtr.Zero)
                throw new Exception("Unable to find Unity window");
            Debug.WriteLine("Found Unity window: " + unityHWND);

            repeat += 150;
            while ((GetWindowLong(unityHWND, GWLP_USERDATA).ToInt32() & 1) == 0 && --repeat > 0) {
                Thread.Sleep(100);
                Debug.WriteLine("Waiting for Unity to initialize... " + repeat);
            }
            if (repeat == 0) {
                Debug.WriteLine("Timed out while waiting for Unity to initialize");
            } else {
                Debug.WriteLine("Unity initialized!");
            }

            ActivateUnityWindow();

            return new HandleRef(this, unityHWND);
        }

        private void ActivateUnityWindow() {
            SendMessage(unityHWND, WM_ACTIVATE, WA_ACTIVE, IntPtr.Zero);
        }

        private void DeactivateUnityWindow() {
            SendMessage(unityHWND, WM_ACTIVATE, WA_INACTIVE, IntPtr.Zero);
        }

        private int WindowEnum(IntPtr hwnd, IntPtr lparam) {
            if (unityHWND != IntPtr.Zero)
                throw new Exception("Found multiple Unity windows");
            unityHWND = hwnd;
            return 0;
        }
        private IntPtr GetWindowLong(IntPtr hWnd, int nIndex) {
            if (IntPtr.Size == 4) {
                return GetWindowLong32(hWnd, nIndex);
            }
            return GetWindowLongPtr64(hWnd, nIndex);
        }

        protected override void DestroyWindowCore(HandleRef hwnd) {
            Destroy();
        }

        public void Destroy() {
            Debug.WriteLine("Asking Unity to exit...");
            PostMessage(unityHWND, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
            //process.CloseMainWindow();
            //Thread.Sleep(1000);
            //while (process.HasExited == false) {
            //    process.Kill();
            //}
            //job.Dispose();
            //job = null;
            process.Dispose();
            process = null;
            unityHWND = IntPtr.Zero;
        }
    }

WPF Window

<Window x:Class="Example.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Example"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800" Activated="Window_Activated" Closed="Window_Closed" Deactivated="Window_Deactivated" Loaded="Window_Loaded">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="250"/>
        </Grid.ColumnDefinitions>
        <local:UnityHwndHost x:Name="UnityHostControl" Grid.Column ="0" AppPath=".\Unity\URPTest.exe"/>
        <TextBox Grid.Column="1" HorizontalAlignment="Stretch" Height="23" Margin="10,10,10,10" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" TextChanged="TextBox_TextChanged"/>
    </Grid>
</Window>