emoon / rust_minifb

Cross platfrom window and framebuffer crate for Rust
MIT License
980 stars 92 forks source link

F10 does not work on windows #310

Closed loudjanilef closed 1 year ago

loudjanilef commented 1 year ago

I defined a InputCallback for a window and every key seem to be recognized properly, except for the F10 key. After pressing F10, the other inputs are not recognized anymore and I have to click on the window to restore the keys recognition. Did I miss something in the setup ?

emoon commented 1 year ago

Not that I know of. If you do if window.is_key_down(Key::F10) { ... } in the window update loop (not callback) does that work as expected?

loudjanilef commented 1 year ago

Thank you for your answer I tested your snippet with F9 and F10 and it works properly with F9 but not with F10. I guess it does not comes from my keyboard as I reproduced this problem on two different computers (and so keyboards)

emoon commented 1 year ago

I see. Which OS do you see this behavior on?

loudjanilef commented 1 year ago

I am running on windows 10 for both computers

emoon commented 1 year ago

Alright. I will try on a Windows 10 machine here and see if the same thing happens for me.

emoon commented 1 year ago

I get the same behavior here. When searching around I found this https://gamedev.net/forums/topic/644254-pressing-f10-pause-main-loop/5069517 and the suggestion here is to

switch(message)
    {
    case WM_SYSCOMMAND:
        {
            switch (wParam)
            {    
                // Disables System Menu (F10 Key)       
                case SC_KEYMENU:
                {
                    return 0;
                }//SC_KEYMENU
                break;

So I tried to add this code inside the minifb code:

        winuser::WM_SYSCOMMAND => {
            if wparam == winuser::SC_KEYMENU {
                return 0;
            }
        }

And that indeed gets rid of the "freezing" of the application, but it still don't get the F10 key sent to the application so something more needs to be changed.

emoon commented 1 year ago

Ok, I have a potential fix if you want to test it locally

index 2ea0511..fc11588 100644
--- a/src/os/windows/mod.rs
+++ b/src/os/windows/mod.rs
@@ -207,6 +207,12 @@ unsafe extern "system" fn wnd_proc(
     let mut wnd: &mut Window = mem::transmute(user_data);

     match msg {
+        winuser::WM_SYSCOMMAND => {
+            if wparam == winuser::SC_KEYMENU {
+                return 0;
+            }
+        }
+
         winuser::WM_MOUSEWHEEL => {
             let scroll = ((((wparam as u32) >> 16) & 0xffff) as i16) as f32 * 0.1;
             wnd.mouse.scroll = scroll;
@@ -269,6 +275,11 @@ unsafe extern "system" fn wnd_proc(
             return 0;
         }

+        winuser::WM_SYSKEYUP => {
+            update_key_state(wnd, (lparam as u32) >> 16, false);
+            return 0;
+        }
+
         winuser::WM_COMMAND => {
             if lparam == 0 {
                 wnd.accel_key = (wparam & 0xffff) as usize;
loudjanilef commented 1 year ago

I tried this and did it seem to work, although i only receive the state false events. With this patch I receive both :

index 2ea0511..1aec629 100644
--- a/src/os/windows/mod.rs
+++ b/src/os/windows/mod.rs
@@ -207,6 +207,12 @@ unsafe extern "system" fn wnd_proc(
     let mut wnd: &mut Window = mem::transmute(user_data);

     match msg {
+        winuser::WM_SYSCOMMAND => {
+            if wparam == winuser::SC_KEYMENU {
+                return 0;
+            }
+        }
+
         winuser::WM_MOUSEWHEEL => {
             let scroll = ((((wparam as u32) >> 16) & 0xffff) as i16) as f32 * 0.1;
             wnd.mouse.scroll = scroll;
@@ -224,6 +230,11 @@ unsafe extern "system" fn wnd_proc(
             return 0;
         }

+        winuser::WM_SYSKEYDOWN => {
+            update_key_state(wnd, (lparam as u32) >> 16, true);
+            return 0;
+        }
+
         winuser::WM_CHAR => {
             char_down(wnd, wparam as u32);
         }
@@ -269,6 +280,11 @@ unsafe extern "system" fn wnd_proc(
             return 0;
         }

+        winuser::WM_SYSKEYUP => {
+            update_key_state(wnd, (lparam as u32) >> 16, false);
+            return 0;
+        }
+
         winuser::WM_COMMAND => {
             if lparam == 0 {
                 wnd.accel_key = (wparam & 0xffff) as usize;
emoon commented 1 year ago

Cool. I will make the change and try to release a new version with the fix today.

emoon commented 1 year ago

0.24 has been released and it includes this fix

loudjanilef commented 1 year ago

Thanks for your fast answers The lib is very helpful

emoon commented 1 year ago

Great to hear :)