public override bool Initialize(GameHost host)
        {
            this.host = host;

            host.Window.MouseLeave += (s, e) => mouseInWindow = false;
            host.Window.MouseEnter += (s, e) => mouseInWindow = true;

            mouseInWindow = host.Window.CursorInWindow;

            Enabled.ValueChanged += enabled =>
            {
                if (enabled)
                {
                    host.Window.MouseMove  += handleMouseEvent;
                    host.Window.MouseDown  += handleMouseEvent;
                    host.Window.MouseUp    += handleMouseEvent;
                    host.Window.MouseWheel += handleMouseEvent;

                    // polling is used to keep a valid mouse position when we aren't receiving events.
                    host.InputThread.Scheduler.Add(scheduled = new ScheduledDelegate(delegate
                    {
                        // we should be getting events if the mouse is inside the window.
                        if (mouseInWindow || !host.Window.Visible || host.Window.WindowState == WindowState.Minimized)
                        {
                            return;
                        }

                        var state = OpenTK.Input.Mouse.GetCursorState();

                        if (state.Equals(lastState))
                        {
                            return;
                        }

                        lastState = state;

                        var mapped = host.Window.PointToClient(new Point(state.X, state.Y));

                        handleState(lastPollState = new OpenTKPollMouseState(state, host.IsActive, new Vector2(mapped.X, mapped.Y)));
                    }, 0, 1000.0 / 60));
                }
                else
                {
                    scheduled?.Cancel();

                    host.Window.MouseMove  -= handleMouseEvent;
                    host.Window.MouseDown  -= handleMouseEvent;
                    host.Window.MouseUp    -= handleMouseEvent;
                    host.Window.MouseWheel -= handleMouseEvent;

                    lastState = null;
                }
            };
            Enabled.TriggerChange();
            return(true);
        }
        public override bool Initialize(GameHost host)
        {
            base.Initialize(host);

            Enabled.BindValueChanged(enabled =>
            {
                if (enabled)
                {
                    host.Window.MouseMove  += handleMouseEvent;
                    host.Window.MouseDown  += handleMouseEvent;
                    host.Window.MouseUp    += handleMouseEvent;
                    host.Window.MouseWheel += handleMouseEvent;

                    // polling is used to keep a valid mouse position when we aren't receiving events.
                    OpenTK.Input.MouseState?lastCursorState  = null;
                    host.InputThread.Scheduler.Add(scheduled = new ScheduledDelegate(delegate
                    {
                        // we should be getting events if the mouse is inside the window.
                        if (MouseInWindow || !host.Window.Visible || host.Window.WindowState == WindowState.Minimized)
                        {
                            return;
                        }

                        var cursorState = OpenTK.Input.Mouse.GetCursorState();

                        if (cursorState.Equals(lastCursorState))
                        {
                            return;
                        }

                        lastCursorState = cursorState;

                        var mapped = host.Window.PointToClient(new Point(cursorState.X, cursorState.Y));

                        var newState = new OpenTKPollMouseState(cursorState, host.IsActive, new Vector2(mapped.X, mapped.Y));
                        HandleState(newState, lastPollState, true);
                        lastPollState = newState;
                    }, 0, 1000.0 / 60));
                }
                else
                {
                    scheduled?.Cancel();

                    host.Window.MouseMove  -= handleMouseEvent;
                    host.Window.MouseDown  -= handleMouseEvent;
                    host.Window.MouseUp    -= handleMouseEvent;
                    host.Window.MouseWheel -= handleMouseEvent;

                    lastPollState  = null;
                    lastEventState = null;
                }
            }, true);

            return(true);
        }
        public override bool Initialize(GameHost host)
        {
            base.Initialize(host);

            // Get the bindables we need to determine whether to confine the mouse to window or not
            if (host.Window is DesktopGameWindow desktopWindow)
            {
                confineMode.BindTo(desktopWindow.ConfineMouseMode);
                windowMode.BindTo(desktopWindow.WindowMode);
                mapAbsoluteInputToWindow.BindTo(desktopWindow.MapAbsoluteInputToWindow);
            }

            Enabled.ValueChanged += enabled =>
            {
                if (enabled)
                {
                    host.InputThread.Scheduler.Add(scheduled = new ScheduledDelegate(delegate
                    {
                        if (!host.Window.Visible || host.Window.WindowState == WindowState.Minimized)
                        {
                            return;
                        }

                        if ((MouseInWindow || lastEachDeviceStates.Any(s => s != null && s.HasAnyButtonPressed)) && host.Window.Focused)
                        {
                            var newRawStates = new List <OpenTK.Input.MouseState>(mostSeenStates + 1);

                            for (int i = 0; i <= mostSeenStates + 1; i++)
                            {
                                var s = OpenTK.Input.Mouse.GetState(i);
                                if (s.IsConnected || i < mostSeenStates)
                                {
                                    newRawStates.Add(s);
                                    mostSeenStates = i;
                                }
                            }

                            while (lastEachDeviceStates.Count < newRawStates.Count)
                            {
                                lastEachDeviceStates.Add(null);
                            }

                            for (int i = 0; i < newRawStates.Count; i++)
                            {
                                if (newRawStates[i].IsConnected != true)
                                {
                                    lastEachDeviceStates[i] = null;
                                    continue;
                                }

                                var rawState  = newRawStates[i];
                                var lastState = lastEachDeviceStates[i];

                                if (lastState != null && rawState.Equals(lastState.RawState))
                                {
                                    continue;
                                }

                                var newState = new OpenTKPollMouseState(rawState, host.IsActive, getUpdatedPosition(rawState, lastState));

                                HandleState(newState, lastState, (rawState.Flags & MouseStateFlags.MoveAbsolute) > 0);

                                lastEachDeviceStates[i] = newState;
                                lastUnfocusedState      = null;
                            }
                        }
                        else
                        {
                            var state       = OpenTK.Input.Mouse.GetCursorState();
                            var screenPoint = host.Window.PointToClient(new Point(state.X, state.Y));

                            var newState = new UnfocusedMouseState(new OpenTK.Input.MouseState(), host.IsActive, new Vector2(screenPoint.X, screenPoint.Y));

                            HandleState(newState, lastUnfocusedState, true);

                            lastUnfocusedState = newState;
                            lastEachDeviceStates.Clear();
                        }
                    }, 0, 0));
                }
                else
                {
                    scheduled?.Cancel();
                    lastEachDeviceStates.Clear();
                    lastUnfocusedState = null;
                }
            };

            Enabled.TriggerChange();
            return(true);
        }
        public override bool Initialize(GameHost host)
        {
            host.Window.MouseEnter += window_MouseEnter;
            host.Window.MouseLeave += window_MouseLeave;

            mouseInWindow = host.Window.CursorInWindow;

            // Get the bindables we need to determine whether to confine the mouse to window or not
            DesktopGameWindow desktopWindow = host.Window as DesktopGameWindow;

            if (desktopWindow != null)
            {
                confineMode.BindTo(desktopWindow.ConfineMouseMode);
                windowMode.BindTo(desktopWindow.WindowMode);
            }

            Enabled.ValueChanged += enabled =>
            {
                if (enabled)
                {
                    host.InputThread.Scheduler.Add(scheduled = new ScheduledDelegate(delegate
                    {
                        if (!host.Window.Visible)
                        {
                            return;
                        }

                        bool useRawInput = mouseInWindow && host.Window.Focused;

                        var state = useRawInput ? OpenTK.Input.Mouse.GetState() : OpenTK.Input.Mouse.GetCursorState();

                        if (state.Equals(lastState))
                        {
                            return;
                        }

                        if (useRawInput)
                        {
                            if (!lastState.HasValue)
                            {
                                // when we return from being outside of the window, we want to set the new position of our game cursor
                                // to where the OS cursor is, just once.
                                var cursorState = OpenTK.Input.Mouse.GetCursorState();
                                var screenPoint = host.Window.PointToClient(new Point(cursorState.X, cursorState.Y));
                                currentPosition = new Vector2(screenPoint.X, screenPoint.Y);
                            }
                            else
                            {
                                currentPosition += new Vector2(state.X - lastState.Value.X, state.Y - lastState.Value.Y) * (float)sensitivity.Value;

                                // When confining, clamp to the window size.
                                if (confineMode.Value == ConfineMouseMode.Always || confineMode.Value == ConfineMouseMode.Fullscreen && windowMode.Value == WindowMode.Fullscreen)
                                {
                                    currentPosition = Vector2.Clamp(currentPosition, Vector2.Zero, new Vector2(host.Window.Width, host.Window.Height));
                                }

                                // update the windows cursor to match our raw cursor position.
                                // this is important when sensitivity is decreased below 1.0, where we need to ensure the cursor stays withing the window.
                                var screenPoint = host.Window.PointToScreen(new Point((int)currentPosition.X, (int)currentPosition.Y));
                                OpenTK.Input.Mouse.SetPosition(screenPoint.X, screenPoint.Y);
                            }
                        }
                        else
                        {
                            var screenPoint = host.Window.PointToClient(new Point(state.X, state.Y));
                            currentPosition = new Vector2(screenPoint.X, screenPoint.Y);
                        }

                        IMouseState newState;

                        // While not focused, let's silently ignore everything but position.
                        if (host.IsActive)
                        {
                            lastState = state;
                            newState  = new OpenTKPollMouseState(state, host.IsActive, currentPosition);
                        }
                        else
                        {
                            lastState = null;
                            newState  = new UnfocusedMouseState(new OpenTK.Input.MouseState(), host.IsActive, currentPosition);
                        }

                        PendingStates.Enqueue(new InputState {
                            Mouse = newState
                        });

                        FrameStatistics.Increment(StatisticsCounterType.MouseEvents);
                    }, 0, 0));
                }
                else
                {
                    scheduled?.Cancel();
                    lastState = null;
                }
            };
            Enabled.TriggerChange();
            return(true);
        }
        public override bool Initialize(GameHost host)
        {
            host.Window.MouseEnter += window_MouseEnter;
            host.Window.MouseLeave += window_MouseLeave;

            this.host = host;

            mouseInWindow = host.Window.CursorInWindow;

            // Get the bindables we need to determine whether to confine the mouse to window or not
            if (host.Window is DesktopGameWindow desktopWindow)
            {
                confineMode.BindTo(desktopWindow.ConfineMouseMode);
                windowMode.BindTo(desktopWindow.WindowMode);
                mapAbsoluteInputToWindow.BindTo(desktopWindow.MapAbsoluteInputToWindow);
            }

            Enabled.ValueChanged += enabled =>
            {
                if (enabled)
                {
                    host.InputThread.Scheduler.Add(scheduled = new ScheduledDelegate(delegate
                    {
                        if (!host.Window.Visible || host.Window.WindowState == WindowState.Minimized)
                        {
                            return;
                        }

                        if ((mouseInWindow || lastStates.Any(s => s.HasAnyButtonPressed)) && host.Window.Focused)
                        {
                            var newStates = new List <OpenTK.Input.MouseState>(mostSeenStates + 1);

                            for (int i = 0; i <= mostSeenStates + 1; i++)
                            {
                                var s = OpenTK.Input.Mouse.GetState(i);
                                if (s.IsConnected || i < mostSeenStates)
                                {
                                    newStates.Add(s);
                                    mostSeenStates = i;
                                }
                            }

                            while (lastStates.Count < newStates.Count)
                            {
                                lastStates.Add(null);
                            }

                            for (int i = 0; i < newStates.Count; i++)
                            {
                                if (newStates[i].IsConnected != true)
                                {
                                    lastStates[i] = null;
                                    continue;
                                }

                                var state     = newStates[i];
                                var lastState = lastStates[i];

                                if (lastState != null && state.Equals(lastState.RawState))
                                {
                                    continue;
                                }

                                var newState = new OpenTKPollMouseState(state, host.IsActive, getUpdatedPosition(state, lastState))
                                {
                                    LastState = lastState
                                };

                                lastStates[i] = newState;

                                if (lastState != null)
                                {
                                    PendingStates.Enqueue(new InputState {
                                        Mouse = newState
                                    });
                                    FrameStatistics.Increment(StatisticsCounterType.MouseEvents);
                                }
                            }
                        }
                        else
                        {
                            var state       = OpenTK.Input.Mouse.GetCursorState();
                            var screenPoint = host.Window.PointToClient(new Point(state.X, state.Y));
                            PendingStates.Enqueue(new InputState {
                                Mouse = new UnfocusedMouseState(new OpenTK.Input.MouseState(), host.IsActive, new Vector2(screenPoint.X, screenPoint.Y))
                            });
                            FrameStatistics.Increment(StatisticsCounterType.MouseEvents);

                            lastStates.Clear();
                        }
                    }, 0, 0));
                }
                else
                {
                    scheduled?.Cancel();
                    lastStates.Clear();
                }
            };

            Enabled.TriggerChange();
            return(true);
        }