Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Games receive joypad input even if the game window is not focused #16832

Open
BeayemX opened this issue Feb 19, 2018 · 15 comments

Comments

@BeayemX
Copy link
Contributor

commented Feb 19, 2018

Godot version:

3925e6a

OS/device including version:

Tested on Linux Mint 18.3 sylvia

Issue description:

When running multiple Godot games all games will receive the joypad input. It does not matter if the games are started from the editor or if they are run from the commandline.

Steps to reproduce:

  1. Run two godot games at the same time and use a joypad.
  2. See that both games will process the joypad input regardless of the window focus
@Ranoller

This comment has been minimized.

Copy link
Contributor

commented Feb 19, 2018

This is not a bug. If this was not intended... well... this bug turns into feature. What is the problem to allow user to play with joypad if focus was lost?. If you want not let user to play when focus was lost, maybe you should pause the game on focus lost.

Playing Ori and the blind forest... on focus lost: Pause.
Playing Shadows of war... on focus lost: pause, but if you enter in settings and see control type, if you lost focus with keyboard, game pauses, but if you touch the gamepad, game icon changes, so the game, in pause, is registering gamepad input.

So this is a standard behavior i think.

@Ranoller

This comment has been minimized.

Copy link
Contributor

commented Feb 19, 2018

Playing Hyper Light Drifter: On focus lost you can play the game. I´m playing now, and writing text... I open godot project, press play and both, my demo and hyper light drifter uses the joypad. This is expected behavior please.

The stanley parable: if you lost focus on windowed you can change options with gamepad.

@BeayemX

This comment has been minimized.

Copy link
Contributor Author

commented Feb 19, 2018

The problem I had was when testing network functionality of my game (locally) and both the server and client were reacting to the joypad input.

I am not quite convinced that this isn't a bug. Because I think it is strange that the game reacts to joypad input but not to keyboard input when not focused.

@Ranoller

This comment has been minimized.

Copy link
Contributor

commented Feb 19, 2018

I put some examples of that. All this games on focus lost don´t react to keyboard but react to gamepad.

@Ranoller

This comment has been minimized.

Copy link
Contributor

commented Feb 19, 2018

Why do you not filter joypad input on server?

@BeayemX

This comment has been minimized.

Copy link
Contributor Author

commented Feb 19, 2018

I could do that but the same thing applies when testing with multiple local clients. I could ignore input when not focused, but as I stated I think this is not the desired behavior.

I opened this issue because it was mentioned in #15199 by @akien-mga

The fact that multiple instances of a game all receive joypad events regardless of the focus would likely be worth keeping track of in a new issue (if not done already).

If this really is intended behavior this issue can be closed.

@Ranoller

This comment has been minimized.

Copy link
Contributor

commented Feb 19, 2018

I don´t know if is intended, but for me is dessired because is the normal behavior of PC games. Some games pauses in focus lost, others allows you to play with gamepad input. See this, i open stanley parable and don´t starve:
gamepadfocuslost
Same controler in menu...
A workaround for your problem can be an option in settings to only allow one window to handle input in preview... but in release i think that this can be a mistake.

@vnen

This comment has been minimized.

Copy link
Member

commented Feb 19, 2018

I don't think this has any "intention", it's all based on the underlying OS API. Usually the OS only send key and mouse events to the focused window (or to window directly under the cursor, for mouse wheel events). But gamepad events are usually sent to all windows that are listening to it, regardless of focus.

I don't know if we want to override the system behavior. But maybe there could be an easy way for the game dev to decide whether the input should be stopped or not when the window is out of focus.

@Ranoller

This comment has been minimized.

Copy link
Contributor

commented Feb 19, 2018

There are some constants defined in MainLoop called:

NOTIFICATION_WM_MOUSE_ENTER = 2

NOTIFICATION_WM_MOUSE_EXIT = 3

NOTIFICATION_WM_FOCUS_IN = 4

NOTIFICATION_WM_FOCUS_OUT = 5

But there in no notify() method in this class to use that, and i can´t find any documented method that allow to do that... so maybe is needed and easy way to notify focus_lost / focus_gain or something like this...

But for the problem of @BeayemX there is a bool method in Scenetree: Scenetree.is_network_server() that returns true if the scenetree is in server mode, so maybe can incorporate that to _input(event) to filter all the inputs if this is true (Not tested, only an idea)

@BeayemX

This comment has been minimized.

Copy link
Contributor Author

commented Feb 19, 2018

The function you are looking for is this

'''
func _notification(what):
if what == MainLoop.NOTIFICATION_WM_QUIT_REQUEST:
get_tree().quit()

'''

@Ranoller

This comment has been minimized.

Copy link
Contributor

commented Feb 19, 2018

And works!. So with a little tutorial in docs handle focus in window is easy...

@vnen

This comment has been minimized.

Copy link
Member

commented Feb 19, 2018

You can use notifications to check the focus change, that is not much the problem. The thing is that if you want to disable input, there's no way to do it globally, so you'd have to add a lot of ifs in every place you are using input.

@Ranoller

This comment has been minimized.

Copy link
Contributor

commented Feb 19, 2018

I see... i don´t think in that because i handle all input in unique global script, but is true that if using _input(event) in a lot of scripts this can be cumbersome.

@Ranoller

This comment has been minimized.

Copy link
Contributor

commented Feb 20, 2018

If you do a singleton with:

var Unfocused = false

func _notification(what):
    if what == MainLoop.NOTIFICATION_WM_FOCUS_OUT: 
        Unfocused = true
    elif what == MainLoop.NOTIFICATION_WM_FOCUS_IN: 
        Unfocused = false

func _input(event):
if Unfocused: get_tree().set_input_as_handled()

It can handle all input in focus lost?... Other idea (But i agree that this should be more intuitive/friendly to do)

Edit2: Works well, but only with _input(event). It stop propagation to all scripts, but if you use Input in _process or _fixed/physics_process that solution doesn´t work.

@Zylann

This comment has been minimized.

Copy link
Contributor

commented Feb 20, 2018

It's a common issue that usually happens with game vs GUI in games. When you poll input using "direct global" functions like Input.get_axis, you explicitely bypass any focus barrier (contrary to event based approach) so it's expected. Solution is indeed either use event approach, or use ifs to filter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.