Mouse temporarily leaves window at right and bottom screen edges

I am developing a small FPS and am having some issues with mouse input at the screen edges. Specifically, when I turn right or down long enough, the (invisible) mouse cursor will hit either the right or botton screen edge. When this happens it seems to be leaving the window, but only by a few pixels. I can actually move it around and when it fullscreen it doesn’t tab me out, but mouse clicks of any kind aren’t registered anymore. When in windowed mode, the cursor occasionally becomes visible, and I can resize the window by clicking and dragging the window edge. This happens both in my game as well as with the unmodified C++ FPS example that comes with the engine. This also appears to happen when I use “Launch game” from the editor.

This video demonstrates the problem: Desktop 2018 03 24 13 42 32 04 - YouTube

Everything works fine for me in the editor, but I’m getting this exact problem in packaged builds in 4.19.2, as well as when running “Standalone Game” (separate process) via the editor.

This happens in fullscreen, borderless fullscreen, as well as windowed.

There are a lot of FPS-type games made in Unreal that don’t have this problem, so it seems like there must be some kind of workaround? Or maybe this issue only occurs with certain setups?

(By the way, should this be posted in bug reports?)

Doesn’t happen on my end (also using 4.19.2). Tested both default Blueprint and C++ “First Person” template projects.

Maybe you have a window manager extension or something that causes the cursor to lose focus? Windows 10 up to date?

After testing it again I think it may have something to do with multiple monitors. I couldn’t get it to happen on my laptop (using 4.17, I don’t have 4.19 installed on my machines yet, but I will try it with that as well as soon as possible) while it does happen on both of my desktop PCs with two monitors. Other than the amount of monitors there’s no difference between the laptop and the desktops, no window manager extension and win 10 is up to date.

How many monitors do you have?

Some more detail:

The specific undesirable behavior that occurs in my environment is as follows:

  • When dragging the mouse diagonally and clicking, mouse clicks will register as clicking on the window border. This only occurs when the mouse cursor is located at coordinates corresponding with one of the corners of the screen. As such, it is easiest to reproduce by clicking while dragging diagonally. If you let go of the mouse before clicking, the mouse often leaves the exact corner position and normal behavior occurs.

  • In windowed mode, this will result in dragging the corner of the screen and changing the window size.

  • In fullscreen mode, the click on the corner of the screen simply doesn’t register with the game (so if left-click were to trigger an attack action, the action wouldn’t trigger)

  • Even if the mouse cursor is properly captured by the application, this still occurs when the position that the mouse would be at (if the cursor were visible) was at the corner of the screen.

I have the latest version of Windows 10, and have actually noticed this issue in UE4 for the last few months (or more). I think before it was actually worse in previous engine versions and happened with all the edges of the screen, and now it only seems to happen when the mouse is exactly on one of the screen corners.

I am not using any particular extensions that cause my mouse to lose focus in any other situations whatsoever. Again, this behavior occurs with very specific input on full screen or windowed Unreal applications.

One particularity of my environment is that I am using a single 4k TV as a monitor (3840x2160 resolution), but I don’t notice any issues in other games or applications.

I am using a single 4k TV as a monitor (3840x2160 resolution)

UE4 version 4.19.2 (also noticed this issue on previous engine versions)

Strangely, after testing this a few more times (opening my project’s built package a few times and going back and forth between the various screen modes), the issue suddenly stopped occurring. I didn’t change anything, so there might be specific conditions for this issue to occur.

Even more strangely, although the issue was temporarily fixed with my package build, the issue still occurs as I described when running “Standalone Game” (separate process) via the editor. Actually, in this case the bug is occurring with the edges of the screen as well (particularly the right edge)

So when trying to reproduce the bug, I would recommend checking both Standalone Game from the editor as well as packaged builds.

One workaround is to set the position of the mouse every frame while the viewport is captured so as to prevent the mouse from getting near the edge of the screen. You could constantly set the mouse to be in the center of the screen (as below), or alternatively remember the cursor’s last position and keep it there while the mouse is captured by the viewport.

Adding the below code to your PlayerController’s Tick function should do the trick:

FViewport* viewPort = CastChecked<ULocalPlayer>(this->Player)->ViewportClient->Viewport;
if ( viewport->HasMouseCapture() ) // alternatively, could use viewport->HasFocus() based on what you are doing
{
	FIntPoint sizeXY = viewport->GetSizeXY();
	viewport->SetMouse( sizeXY.X/2, sizeXY.Y/2 );
}

Edit: When trying to implement the second method I described above (saving the mouse position and setting the saved position while the cursor is captured), I noticed that strangely, SetMouse has different behavior for PIE windows and standalone windows.

For standalone windows, everything works correctly, but when setting the saved position in editor windows, the result would be drastically offset.

Looking through the answerhub, it didn’t seem like there was a solution, but after a lot of debugging I found that multiplying the saved mouse coordinates by the viewport resolution’s Y/X ratio would give extremely good results (maybe not 100% perfect? or maybe it’s just rounding?)

If anyone else has the same issue, try out something like the below code:

if (viewport->HasMouseCapture())
	{
		viewport->SetMouse(m_lastMousePosition.X, m_lastMousePosition.Y);
	}
	else
	{
		// remember last mouse pos
		FIntPoint lastMousePosition;
		viewport->GetMousePos(lastMousePosition, true);

		if (lastMousePosition.X >= 0 && lastMousePosition.Y >= 0)
		{
			// skip if mouse is outside window (when outside window, X and Y become -1)

			float viewportRatio = 1.0f; // use 1.0 for standalone builds etc    			
			if (viewport->IsPlayInEditorViewport())
			{
				FIntPoint screenResolutionViewport(GSystemResolution.ResX, GSystemResolution.ResY);
				viewportRatio = (float)screenResolutionViewport.Y / (float)screenResolutionViewport.X;
			}

			m_lastMousePosition.X = (float)lastMousePosition.X * viewportRatio;
			m_lastMousePosition.Y = (float)lastMousePosition.Y * viewportRatio;
		}
}

Edit 2: I noticed that with the above code active, ejecting from the player character and moving environment data around with the mouse in PIE mode no longer functions because the mouse cursor will get stuck in one position when clicking on the viewport. I couldn’t find a way of checking if the editor is in “Possess” or “Eject” mode, so instead I temporarily resolved this by disabling the functionality when in PIE mode. Note that the original bug doesn’t seem to occur in PIE mode anyway, so this is a decent enough workaround, I guess.