Skip to content

Commit 0348094

Browse files
committed
Editor updates mouse position while game widget is unfocused
1 parent b5ce772 commit 0348094

3 files changed

Lines changed: 47 additions & 15 deletions

File tree

engine/Sandbox.Engine/Systems/Input/InputRouter.Input.cs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -87,30 +87,34 @@ internal static void OnMouseMotion( float dx, float dy )
8787
/// </summary>
8888
internal static void OnMousePositionChange( float x, float y, float dx, float dy )
8989
{
90-
var delta = new Vector2( 0, 0 );
90+
ApplyAbsoluteMousePosition( new Vector2( x, y ), new Vector2( dx, dy ) );
91+
}
92+
93+
/// <summary>
94+
/// Shared absolute-position path for native and editor-driven mouse updates.
95+
/// </summary>
96+
internal static void ApplyAbsoluteMousePosition( Vector2 pos, Vector2 delta )
97+
{
98+
MouseCursorPosition = pos;
9199

92-
// if we're not in relative mode - take the delta from this
93-
if ( !NativeEngine.InputSystem.GetRelativeMouseMode() )
100+
if ( InputSystem.GetRelativeMouseMode() )
94101
{
95-
delta = new Vector2( dx, dy );
96-
MouseCursorDelta += delta;
102+
delta = Vector2.Zero;
97103
}
98104

99-
MouseCursorPosition = new Vector2( x, y );
100-
101-
// if this is set, we're in capture mode - so just update the position
102-
// which will update the position of the cursor when we come out of it
105+
// If this is set, we're in capture mode - so just update the position
106+
// cache we restore when capture ends. This intentionally records the
107+
// latest absolute position without moving the OS cursor.
103108
if ( mouseCapturePosition is not null )
104109
{
105110
mouseCapturePosition = MouseCursorPosition;
106111
return;
107112
}
108113

114+
MouseCursorDelta += delta;
115+
109116
var mouse = Contexts.FirstOrDefault( x => x.MouseState != InputContext.InputState.Ignore );
110-
if ( mouse is not null )
111-
{
112-
mouse.In_MousePosition( MouseCursorPosition, delta );
113-
}
117+
mouse?.In_MousePosition( MouseCursorPosition, delta );
114118
}
115119

116120
internal static void OnGameControllerButton( int deviceId, GameControllerCode button, bool down )

engine/Sandbox.Tools/GameMode.cs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
using Native;
1+
using Sandbox.Engine;
22

33
namespace Editor;
44

55
/// <summary>
6-
/// Registers a widget with the input system, so it uses SDL.
6+
/// Registers a widget with the input system to use SDL and manages
7+
/// inputs and focus as it relates to the editor's game widget.
78
/// </summary>
89
public static class GameMode
910
{
@@ -50,6 +51,9 @@ public static void ClearPlayMode()
5051
/// </summary>
5152
private static void WidgetFocused( FocusChangeReason reason )
5253
{
54+
if ( _inPlay is null )
55+
return;
56+
5357
NativeEngine.InputSystem.OnEditorGameFocusChange( _inPlay._widget.winId(), true );
5458
}
5559

@@ -58,6 +62,28 @@ private static void WidgetFocused( FocusChangeReason reason )
5862
/// </summary>
5963
private static void WidgetBlurred( FocusChangeReason reason )
6064
{
65+
if ( _inPlay is null )
66+
return;
67+
6168
NativeEngine.InputSystem.OnEditorGameFocusChange( _inPlay._widget.winId(), false );
6269
}
70+
71+
internal static void Tick()
72+
{
73+
// Keep game mouse position updated while the play widget is unfocused.
74+
var playWidget = _inPlay;
75+
if ( playWidget is null || playWidget.IsFocused )
76+
return;
77+
78+
var local = playWidget.FromScreen( Application.CursorPosition );
79+
80+
// Don't snap to borders if cursor isn't over the widget.
81+
if ( local.x < 0 || local.y < 0 || local.x >= playWidget.Size.x || local.y >= playWidget.Size.y )
82+
return;
83+
84+
var pos = new Vector2( (int)local.x, (int)local.y );
85+
var delta = pos - InputRouter.MouseCursorPosition;
86+
87+
InputRouter.ApplyAbsoluteMousePosition( pos, delta );
88+
}
6389
}

engine/Sandbox.Tools/ToolsDll.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,8 @@ public void Tick()
260260
Time.Update( scene.TimeNow, scene.TimeDelta );
261261
}
262262

263+
GameMode.Tick();
264+
263265
// Escape was pressed in game and wasn't swallowed
264266
// so lets change focus from the game window to the main editor
265267
// window, which is going to free the mouse cursor from being captured

0 commit comments

Comments
 (0)