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

In-game, clicking the mouse sometimes causes all pressed buttons to be cleared after using EditText.IsSelectionActive #2084

Closed
adrsch opened this issue Dec 17, 2023 · 5 comments
Assignees
Labels
bug Something isn't working

Comments

@adrsch
Copy link
Contributor

adrsch commented Dec 17, 2023

Release Type: Github

Version: Main branch from yesterday, but it has been happening for months. Since I first started using the engine in 4.1.

Platform(s): Windows

Describe the bug
Sometimes, when clicking, all the currently down keys are cleared (I'm still holding the key down physically on my keyboard)

To Reproduce
The InputSourceBase for my keyboard is InputSourceWinforms.

For a UI page, I am forcing selection of an EditText with myEditTextElement.IsSelectionActive = true; in the update function for a period, then collapsing the page. After collapsing the page, the bug occurs.

Once it starts happening, it will occur repeatedly. Adding myEditTextElement.IsSelectionActive = false; when it is hidden, makes it occur only once. That behavior seems fine.

Expected behavior
The pressed keys remain pressed.

Additional context
I have a fix for this that seems to work: deleting InputSourceWinforms.UIControlOnLostFocus. I'm not sure what that's even supposed to do in the first place! So I have low confidence for just submitting a PR with that... may break something I don't know about.

That function has a comment on it:
// Release keys/buttons when control focus is lost (this prevents some keys getting stuck when a focus loss happens when moving the camera)
But I haven't seen this occur ingame since I removed the code earlier today, although I'm not sure what its referring to specifically.

@adrsch adrsch added the bug Something isn't working label Dec 17, 2023
@Doprez
Copy link
Contributor

Doprez commented Dec 17, 2023

@Eideren is this at all related to #1897 or #94?

@Eideren
Copy link
Collaborator

Eideren commented Dec 17, 2023

UIControlOnLostFocus is for when you tab out of the application, or when another application takes the focus away by itself, we don't want to have the game thinking that keys are still held down when they aren't, it may already be taken care of though.

From what I understand, this issue occurs in game, and the lines I added only affects the editor, while those I removed were never activated as the preprocessor is never defined. Though you could validate this just to be sure.

@adrsch
Copy link
Contributor Author

adrsch commented Dec 17, 2023

Okay, I was wondering if that was for the application as a whole or something like input fields. Testing out a few code changes for fullscreen, mouse locking, and the way I get input in my console UI page (since using it seems to make the bug occur)

I do vaguely remember pulling that fix for the editor camera stuttering! The bug felt very similar, I thought it was the same thing until that got fixed and my ingame problem still occurred. But it's been so long all that was left was a vague memory of something happened in editor, too. I will edit my first post to make it more clear it is exclusively ingame.

@adrsch
Copy link
Contributor Author

adrsch commented Dec 17, 2023

I figured out what causes it to occur! In a UI component, I am forcing selection with myEditTextElement.IsSelectionActive = true; in the update function for a period, then collapsing the page. After collapsing the page, the bug occurs.

Adding myEditTextElement.IsSelectionActive = false; when it is hidden, makes the problem occur only once, instead of repeatedly. That behavior seems fine.

@adrsch adrsch changed the title In-game, clicking the mouse sometimes causes all pressed buttons to be cleared In-game, clicking the mouse sometimes causes all pressed buttons to be cleared after using EditText.IsSelectionActive Dec 17, 2023
@TranquilAbyss
Copy link
Contributor

The way I ended handling a similar problem where I have multiple edit texts and want to left click off off them to deselected while managing which one is selected and change the game state to prevent hotkey presses while typing:

To Reproduce
Make a new Windows Stride Project
Add a Page with a EditText named "EditText", to the Scene
Add a SyncScript with the following code to the Scence

using Stride.Engine;
using Stride.UI;
using Stride.UI.Controls;
using System.Diagnostics;
using Stride.Input;

public class Script : SyncScript
{
    public UIComponent page;
    EditText editText;

    public override void Start()
    {
        editText = page.Page.RootElement.FindVisualChildOfType<EditText>("EditText");
    }

    public override void Update()
    {
        if (Input.IsMouseButtonPressed(MouseButton.Left))
        {
            editText.IsSelectionActive = false;
        }
        else if (Input.IsMouseButtonReleased(MouseButton.Left)) 
        {
            Debug.WriteLine("Mouse Button Released");
        }
    }
}

Set the Script in the scene's page object

Run the build and run, then Press and hold Left Click in game, if using visual studio, the Immediate window will Show "Mouse Button Released" while the mouse left button is still down.

The Expected Behavior is the mouse release state is not triggered when editText.IsSelectionActive = false;

Imperfect Workaround

The short of what is happening, I am trying to prevent hotkeys from triggering when typing, But Input.IsMouseButtonReleased(MouseButton.Left) is getting triggered too soon, so I need delay lastSelectedEditText.IsSelectionActive = false later in the Update loop. This still does not work the way I want it too.
Below is part of the Update loop to better manage the timing of event changes.

if (selectedEditText != null && gameStateController.state != GameState.TEXTINPUT)
{
    gameStateController.SetGameState(GameState.TEXTINPUT);
}
else if (gameStateController.state == GameState.TEXTINPUT && Input.IsMouseButtonReleased(MouseButton.Left))
{
    gameStateController.SetGameState(GameState.MENU);
}

In a class used to track UI elements I have the following, these functions are triggered during EditText or other Click Events.

public EditText selectedEditText { get; private set; }
public EditText lastSelectedEditText;
bool workAroundEditTextFlag = false; // "IsSelectionActive = false" is cuasing IsMouseButton to be Release when mouse button is down.
public void SelectEditText(EditText editText)
{
    if (editText != selectedEditText)
    {
        if (selectedEditText != null)
        {
            lastSelectedEditText = selectedEditText;
            workAroundEditTextFlag = true;
        }

        selectedEditText = editText;
    }
}

public void DeselectEditText()
{
    if (selectedEditText != null)
    {
        lastSelectedEditText = selectedEditText;
        workAroundEditTextFlag = true;
    } 
     
    selectedEditText = null;
}

The workaround is to have this at the end of the Update function handling UI States. It delays the .IsSelectionActive = false; so that it does not trigger Input.IsMouseButtonReleased(MouseButton.Left) Stuff too early.

 if (workAroundEditTextFlag && Input.IsMouseButtonReleased(MouseButton.Left))
 {
     // IsSelectionActive = false retrigers mouse button release 
     if (lastSelectedEditText != null)
     {
         lastSelectedEditText.IsSelectionActive = false;
         lastSelectedEditText = null;
     }
     else selectedEditText.IsSelectionActive = false;
     workAroundEditTextFlag = false;
 }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants