Silk.NET icon indicating copy to clipboard operation
Silk.NET copied to clipboard

Keyboard events stops working after few Window Create/Dispose calls.

Open MarLupin opened this issue 2 years ago • 7 comments

Summary

It seems that in a scenario where we create and dispose a Window several times, at some point the keyboard event trigger stop working. I pointed this out when transferring several OpenGL examples into single project, where individual examples runs from the console menu. I'm not entirely sure if this is a bug in Windowing/Input, or maybe I'm doing something wrong ?

Steps to reproduce

  • Platform: Desktop
  • Framework Version: .NET 7
  • API: N/A

Below is an extracted code that shows the problem (console app).

  • When I use the KeyDown event to close the window, after few calls this stops working.
  • But when checking IsKeyPressed, closing works every time.

I noticed too, that when calling the ImGui Demo that way, keyboard events stop being passed to the controller, while mouse events continue to work.

Example

using Silk.NET.Windowing;
using Silk.NET.Input;

while (true)
{
    Console.WriteLine("Press any key to open window");
    Console.ReadKey(true);
    OpenWindow_WithEvent(); // <-- there is a problem
    // OpenWindow_WithoutEvent(); // <-- this is fine
    while (Console.KeyAvailable) Console.ReadKey(true);
    Console.WriteLine($"Window closed\n");
}

// Escape KeyDown event stops working after few calls.
static void OpenWindow_WithEvent()
{
    var window = Window.Create(WindowOptions.Default);
    window.Initialize();
    var input = window.CreateInput();
    Console.WriteLine("Window opened, press Escape key to close");
    input.Keyboards[0].KeyDown += (IKeyboard a1, Key a2, int a3)
       => { Console.WriteLine(a2); if (a2 == Key.Escape) window.Close(); };
    window.Run();
    input.Dispose();
    window.Dispose();
}

// Escape check by IsKeyPressed works every time.
static void OpenWindow_WithoutEvent()
{
    var window = Window.Create(WindowOptions.Default);
    window.Initialize();
    var input = window.CreateInput();
    Console.WriteLine("Window opened, press Escape key to close");
    window.Run(() => {
        if (input.Keyboards[0].IsKeyPressed(Key.Escape)) window.Close();
        window.DoEvents();
        window.SwapBuffers();
    });
    input.Dispose();
    window.Dispose();
}

MarLupin avatar Jun 12 '23 10:06 MarLupin

I'm having the same issue, but it appears that mouse events also do not work (alongside keyboard events). This happens after opening and closing the windows a seemingly random number of times.

BTW, were you able to eventually figure out the cause of the problem?

jk255 avatar Jul 12 '23 03:07 jk255

Unfortunately, I haven't found a solution. Eventually I gave up using the Windowing library and instead use GLFW API directly. This gives me more control over events and the message loop, plus as a bonus, unlike Windowing, does not throw trimming warnings with publishing to Native AOT.

MarLupin avatar Jul 12 '23 13:07 MarLupin

Keeping open so we can investigate

Perksey avatar Jul 12 '23 13:07 Perksey

I see. I did remember before, that when I accidentally double-disposed the GLFW API, that similar behavior emerged. Basically input would stop working. I fixed that up on my end, but it looks like this issue exists even on a MRE.

jk255 avatar Jul 13 '23 01:07 jk255

Because of this code in GlfwInputPlatform.cs

internal static unsafe void RegisterWindow(
...
GlfwEvents events = _subs.ContainsKey
     ((nint) handle)
     ? _subs[(nint) handle]
     : _subs[(nint) handle] = new GlfwEvents(handle);

SetCallbacks methods will never be called for a window with the same handle. Every time a new window is created, you need to call SetCallbacks methods from GlfwEvents.cs, for example, as is done in GlfwWindow.cs.

_glfw.SetWindowPosCallback(_glfwWindow, _onMove)
...

A simple solution is to edit GlfwInputPlatform.cs, and create new GlfwEvents each time.

internal static unsafe void RegisterWindow(
...
GlfwEvents events = _subs[(nint) handle] = new GlfwEvents(handle);
...

Donzasto avatar Nov 03 '23 10:11 Donzasto

У меня вообще ошибка после вызова и наведения мыши на окно: Silk.NET.Input.IInputContext input = window.CreateInput(); Возможно из-за того, что использую SDL2.dll version 2.28.50

image

BuslikDrev avatar Dec 05 '23 04:12 BuslikDrev

@BuslikDrev please do not add unrelated information to existing issues or discussions, instead open a new discussion. In addition, none of us can read Russian so it would be best to use English if you would like us to help.

Perksey avatar Dec 05 '23 04:12 Perksey

Reproduced & fixed in #2115

Perksey avatar Apr 15 '24 18:04 Perksey