8000 fix and expand the support of the window_minimized_event by InnocentusLime · Pull Request #552 · not-fl3/miniquad · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

fix and expand the support of the window_minimized_event #552

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

Merged
merged 1 commit into from
May 15, 2025

Conversation

InnocentusLime
Copy link
Contributor
@InnocentusLime InnocentusLime commented May 3, 2025

Why?

macroquad has a bug: not-fl3/macroquad#547.
There is a good fix we can implement, that has been suggested by @profan - the same issue, but in godot (godotengine/godot#28061). Essentially, this PR part 1 of the fix.

Context

miniquad already has some ready-to-use handlers for a potential fix. There is window_minimized_event. Despite the name, on X Window system and WASM it gets fired when a window loses focus.

I decided not to change that and instead focus on the following:

  • Adding a similar support for OSX (special thanks to @jonatino for the help!)
  • Adding a similar support for Windows
  • Fixing a related bug on WASM

Bug Reproduction

The following application is sufficient to catch the bug

use macroquad::prelude::*;

#[macroquad::main("Catching Keys")]
async fn main() {
    loop {
        clear_background(WHITE);

        let col = if is_key_down(KeyCode::A) {
            GREEN
        } else {
            RED
        };
        draw_re
8000
ctangle(0.0, 0.0, 32.0, 32.0, col);

        next_frame().await
    }
}

The steps are simple:

  1. Run the app
  2. Hold the A key
  3. While still holding the key -- focus on a different window
  4. Release the A key
  5. Focus again on the window
  6. The square remains green (because is_key_down is still returning true)

Testing The Fix

  1. Use the same setup
  2. Add the following lines to your Cargo.toml
  3. Repeat the same steps
  4. The square will now turn red on step (6)!
[patch.crates-io]
# hosts the second part of the fix
macroquad = { git = "https://github.com/InnocentusLime/macroquad.git", branch="lab-repeat-keys" }
# This branch with the fix
miniquad = { git = "https://github.com/InnocentusLime/miniquad.git", branch="fix-window-minimized" }

Tests:

  • Works on Windows
  • Works on MacOS/OsX (tested by @birhburh)
  • Works on WASM
  • Works on X11 (tested by @profan)

Technical Notes About the fixed js/gl.js

There were a few things that did not make the minimized events fire correctly:

  1. lastFocus == hasFocus caused the app being notified of focus only when it didn't change (fixed in 8d7cb80)
  2. the visibilitychange listener had a mistake. Elements do not lose focus when the browser changes tabs of the browser window becomes inactive. Instead document.visibilityState becomes not equal to "visible"

@jonatino
Copy link
Contributor
jonatino commented May 3, 2025

I've also made similar changes here for reference:

Miniquad commits:
windows & wasm: VoltaSoftware@59549b6
android & linux: VoltaSoftware@5a87f41
macos: VoltaSoftware@3e32633
ios: VoltaSoftware@9a8af70

Macroquad commit:
VoltaSoftware/macroquad@49972d9?w=1#diff-b1a35a68f14e696205874893c07fd24fdb88882b47c23cc0e0c80a30c7d53759

@InnocentusLime
Copy link
Contributor Author

I've also made similar changes here for reference:

Miniquad commits: windows & wasm: VoltaSoftware@59549b6 android & linux: VoltaSoftware@5a87f41 macos: VoltaSoftware@3e32633 ios: VoltaSoftware@9a8af70

Macroquad commit: VoltaSoftware/macroquad@49972d9?w=1#diff-b1a35a68f14e696205874893c07fd24fdb88882b47c23cc0e0c80a30c7d53759

Thank you! Gives me more confidence, that this fix is on the right track :D

@profan
Copy link
profan commented May 3, 2025

Verified on X11 with Ubuntu 24.04.2 LTS (with a somewhat esoteric window manager to be fair, running awesomewm, a tiling wm), not sure if we want/need someone running Wayland to try it as well or if it's fine with just X11?

Seems to be working as expected :)

edit: had a friend try it under Hyprland (Wayland) on Arch as well and it seems to be working there too

@InnocentusLime
Copy link
Contributor Author

Verified on X11 with Ubuntu 24.04.2 LTS (with a somewhat esoteric window manager to be fair, running awesomewm, a tiling wm), not sure if we want/need someone running Wayland to try it as well or if it's fine with just X11?

Seems to be working as expected :)

edit: had a friend try it under Hyprland (Wayland) on Arch as well and it seems to be working there too

Good question. I have no idea what policy macroquad has towards Wayland. Last time I checked the support was "unstable". So technically speaking, bugs for Wayland are to be expected are not required to be fixed by this PR.

That said, if Wayland does get fixed too -- good!

@InnocentusLime
Copy link
Contributor Author

@not-fl3 the PR has been tested on all declared platforms and seems to work! Any chance of it getting merged? :)

@InnocentusLime InnocentusLime force-pushed the fix-window-minimized branch from 1ff3c7f to a33b678 Compare May 4, 2025 16:29
@jonatino
Copy link
Contributor
jonatino commented May 4, 2025

@InnocentusLime I think your osx changes are missing the event for when the window gets reactivated.

You should use this instead because these are the actual activated/deactivated windows events for macos: VoltaSoftware@3e32633

https://developer.apple.com/documentation/appkit/nswindowdelegate/windowdidbecomekey(_:)
https://developer.apple.com/documentation/appkit/nswindowdelegate/windowdidresignkey(_:)

@InnocentusLime
Copy link
Contributor Author

@InnocentusLime I think your osx changes are missing the event for when the window gets reactivated.

You should use this instead because these are the actual activated/deactivated windows events for macos: VoltaSoftware@3e32633

https://developer.apple.com/documentation/appkit/nswindowdelegate/windowdidbecomekey(_:)
https://developer.apple.com/documentation/appkit/nswindowdelegate/windowdidresignkey(_:)

Interesting. I just did what Godot did in their PR. I suppose I can just alter the commit to use those instead. Thx! :)

@InnocentusLime
Copy link
Contributor Author

@jonatino
Although, it looks like DidMove should trigger the minimized event too just in case.
I will add the handlers instead.

@InnocentusLime InnocentusLime force-pushed the fix-window-minimized branch from a33b678 to 6a00a94 Compare May 4, 2025 17:57
@narodnik
Copy link
Contributor
narodnik commented May 5, 2025

Hey this is the same as this issue: #517

While your fix should be applied probably, it doesn't fix the overall issue with the key APIs. For that we should copy what Qt does with making available the actual scancodes, as well as merging the char and various key events into a unified API.

@InnocentusLime
Copy link
Contributor Author
InnocentusLime commented May 5, 2025

Hey this is the same as this issue: #517

While your fix should be applied probably, it doesn't fix the overall issue with the key APIs. For that we should copy what Qt does with making available the actual scancodes, as well as merging the char and various key events into a unified API.

The API might be a bit confusing right now, but KeyCode is actually the key scancode. It is why not-fl3/macroquad#686 exists actually

@narodnik
Copy link
Contributor
narodnik commented May 5, 2025

KeyCode is not the scan code. It changes between key presses. For example Colon and Semicolon. With scancodes they have the same value.

@profan
Copy link
profan commented May 5, 2025

@narodnik that's odd, considering there's this issue: not-fl3/macroquad#686 which seems to imply all the key codes are unrelated to the keyboard layout, so we have some awkward middleground right now then?

@InnocentusLime
Copy link
Contributor Author

KeyCode is not the scan code. It changes between key presses. For example Colon and Semicolon. With scancodes they have the same value.

This is factually incorrect. There is no Colon in the KeyCode enum.

https://github.com/not-fl3/miniquad/blob/master/src/event.rs#L21-L145

I have reviewed the windows implementation. I can vouch that it works with scancodes.
Yes, KeyCode is not exactly a raw scancode value. That is true, but it behaves exactly like it

@narodnik
8000 Copy link
Contributor
narodnik commented May 5, 2025

Linux wayland does not use scancodes. It converts them to key syms, then converts the key syms to key codes. For tracking key state, you should use the raw key passed in (which it does), but this does not match the key codes used in miniquad. The miniquad KeyCode does not work for key repeat.

Check unsafe extern "C" fn keyboard_handle_key() in src/native/linux_wayland.rs.

unsafe extern "C" fn keyboard_handle_key(
    ...
    key: u32,
    ...
) {
    // ...

    // https://wayland-book.com/seat/keyboard.html
    // To translate this to an XKB scancode, you must add 8 to the evdev scancode.
    let keysym = libxkb.keymap_key_get_sym_without_mod(xkb_keymap, key + 8);
    let keycode = keycodes::translate_keysym(keysym);
    let keymods = display.keymap.get_keymods(libxkb, xkb_state);
    match state {
        0 => {
            display.keyboard_context.track_key_up(key);
            display.events.push(WaylandEvent::KeyUp(keycode, keymods));
        }

@bolphen
Copy link
Contributor
bolphen commented May 5, 2025

Just to weigh in on this: as I understand, what this PR does is to fire the window_minimized_event / window_restored_event upon focus lost / gain, and has nothing to do with keyboard input. Moreover these events are already being fired on Linux (both X11 and Wayland) before this PR; the PR just implements them on the other platforms (which btw is a good indication that the Wayland backend is actually pretty on a par with the other platforms).

There's also a related issue by Fedor himself #28 although I think we can all agree that this is basically window_minimized now.

@InnocentusLime
Copy link
Contributor Author
InnocentusLime commented May 5, 2025

Just to weigh in on this: as I understand, what this PR does is to fire the window_minimized_event / window_restored_event upon focus lost / gain, and has nothing to do with keyboard input. Moreover these events are already being fired on Linux (both X11 and Wayland) before this PR; the PR just implements them on the other platforms (which btw is a good indication that the Wayland backend is actually pretty on a par with the other platforms).

There's also a related issue by Fedor himself #28 although I think we can all agree that this is basically window_minimized now.

You are absolutely correct.

  1. Yes, the key mapping is completely unrelated to this PR.
  2. Yes, this PR makes window_minimized_event and window_restored_event properly cross-platform

@InnocentusLime
Copy link
Contributor Author

@narodnik

Linux wayland does not use scancodes. It converts them to key syms, then converts the key syms to key codes. For tracking key state, you should use the raw key passed in (which it does), but this does not match the key codes used in miniquad. The miniquad KeyCode does not work for key repeat.

Apologies. I may not have a good grasp of how wayland works.

Regardless, I believe KeyCode should remain related to physical key locations and nothing else. Otherwise it becomes difficult to use for gamedev purposes.

This PR is also in fact unrelated to #517, despite what you said. So I would suggest moving the keyboard processing related discussion there

@InnocentusLime
Copy link
Contributor Author

@not-fl3

@not-fl3
Copy link
Owner
not-fl3 commented May 15, 2025

Oh, thanks for PR, missed it!

@not-fl3 not-fl3 merged commit 52bdf3f into not-fl3:master May 15, 2025
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants
0