Mouse lock leaves window

hello the mouse lock works the first time when game launches in packaged game . but i have found that if you alt tab out from the game it breaks the mouse lock and then it seems unable to capture the mouse again .

ok so just discovered the culprit, it has somethinng to do with using multiple screens . if i just use one screen then the mouse lock behaves as you expect, but with multiple screen setup mouse lock will only work the first time game opens. is there any way to make this work with multiple screen seup? thanks

Hello EniGmaa,

I was unable to reproduce your issue on our end. I have a couple of questions that will help me narrow down your issue.

  1. Can you reproduce this issue in a new project?
  2. If so, could you provide a detailed list of steps so I can reproduce your issue on our end?
  3. Could you provide screenshots of your issue?

Thanks!

yep i can reproduce it in any project.
here is a video showing the bug
[Mouse Bug Report Vid][1]

I simply took a brand new thirdperson template. created my own gamemode and player controller. inside the player controller im using the game settings node to make the game windowed and then adding the test widget to the screen and locking the mouse to the test widget ui.

then launching game in standalone, as you can see from the video everything works as expected the first time you launch. But then if you press ALT TAB for instance to tab out of the game or do anything that looses the capture on the game window, then the window and mouse capture never works again no mattter what you do. only restarting the game makes it work again.

This also happens when i set the mode to fullscreen, i was just showing it as windowed because it is easier to see the mouse escaping the window to the desktop etc.

It is also the same in packaged games.

i am uploading the test project
here [bug report download][2]

after doing further testing
windowed mode ONLY WORKS the first time and doesnt recapture mouse .

fullscreen mode ONLY WORKS on single monitor setup.
if i have multiple monitors with exstend display setting, it breaks the mouse lock.
eg this breaks lock

Which i can kind of understand because when you exstend displays the mouse can leave one screen and go into the next screen.

BUT i have lots of games that i play even with my screens exstended and the mouse always stays within these games.

if i switch off exstend display like this

or simply switch the power off to the other screen .
then the mouse lock behaves as excpected

, I believe this is working as intended, Your event is running on Begin Play and once you alt+tab out and back in the event won’t lock. You can work around this issue by having the set Input of your choice to run off another event after the Begin play (such as an event tick); however, I have put in a feature request about your issue which can be viewed here:

Please be aware that this issue may not be prioritized or worked on soon.

Thankyou for you’re quick and detailed response . Ok will just add it to the event tick for now . I think the confusing bit for people is that it’s labelled ‘lock always’ so that’s why I thought it wasn’t working as intended but you’re explanation makes sense.

I saw the ticket and that feature sounds good.

Thanks for the help

Try something like this:

  1. Create a your custom UMyGameViewportClient class

  2. Override a default one within DefaultEngine.ini GameUserSettingsClassName=/Script/MyModule.UMyGameViewportClient

  3. Then put this code in UMyGameViewportClient

    virtual bool ShouldAlwaysLockMouse() override
    {
    return true;// MouseLockMode == EMouseLockMode::LockAlways;
    }

    virtual void ReceivedFocus(FViewport* InViewport) override
    {
    	Super::ReceivedFocus(InViewport);
    	InViewport->LockMouseToViewport(true);
    }
    
    virtual void LostFocus(FViewport* InViewport) override
    {
    	Super::LostFocus(InViewport);
    	InViewport->LockMouseToViewport(false);
    }
    

Hope it will help you :0

First off, this isn’t “GameUserSettings…”, but “GameViewportClientClassName”.
Second, this can be done in the editor UI :slight_smile:
Third, this doesn’t work unfortunately :frowning:

Doing a little digging with “ReceivedFocus” and “LostFocus” from an overload of UGameViewportClient, it appears as though the “ReceivedFocus” event happens after an alt+tab (or the press of the Windows key) as soon as you click on something (say, the OS bar at the very bottom of your screen).

So, of course after losing focus, you can click inside the game window and get a “legitimate” ReceivedFocus (even though that doesn’t fix our mouse lock issue), but you can also randomly click OUTSIDE the game window instead, and that too will trigger the ReceivedFocus.

I have a temporary solution that, while a bit bruteforce and kinda hacky, does work for nearly all use-cases, in editor (all modes) and packaged, fullscreen or not.

Exception 1: If you alt/tab too much (multiple times a second) while moving the cursor at the edge of the window.

Exception 2: If you use the combo Windows Key + Tab (but who uses that)

Tested on windows 7 only.


Solution:

  1. Create a custom GameViewportClient class in C++
  2. Set it as the default GameViewportClient (either in editor or using the DefaultEngine.ini following modification: “GameViewportClientClassName=/Path/To/Class/Module.NameOfClass”)
  3. Use the following code:

.h:

    virtual void MouseMove(FViewport* InViewport, int32 InMouseX, int32 InMouseY) override;
	bool PastIsForeground;

.cpp:

void UMainGameViewportClient::MouseMove(FViewport* InViewport, int32 InMouseX, int32 InMouseY)
{
	Super::MouseMove(InViewport, InMouseX, InMouseY);

	bool currentIsForeground = InViewport->IsForegroundWindow();
	if (currentIsForeground != PastIsForeground && currentIsForeground) {
		InViewport->LockMouseToViewport(true);
	}
	PastIsForeground = currentIsForeground;
}

I hope this helps!