AndyObtiva / glimmer-dsl-libui

Glimmer DSL for LibUI - Prerequisite-Free Ruby Desktop Development Cross-Platform Native GUI Library - The Quickest Way From Zero To GUI - If You Liked Shoes, You'll Love Glimmer! - No need to pre-install any prerequisites. Just install the gem and have platform-independent GUI that just works on Mac, Windows, and Linux.
MIT License
497 stars 15 forks source link

Tell mac that the key_down event is handled? #47

Closed phuongnd08 closed 1 year ago

phuongnd08 commented 1 year ago

I'm making a game controlled by keyboard using scrolling_area. I use this syntax:

scrolling_area {
    on_key_down do |key_event|
      if key_event[:ext_key] == :escape
        LibUI.quit
      else
        case key_event[:key]
        when "a", "b" then controller.check_answer(key_event[:key])
        when "\n" then controller.toggle_game_mode!
        end
      end

      nil
    end
}

This works fine, but my mac keep producing the "fonk" sound whenever the key is pressed. Return either true, false, nil from the on_key_down event doesn't change anything. I wonder how can I tell that my scrolling_area already handle the keydown event and there is no need for my Mac OSX to produce "fonk" sound?

AndyObtiva commented 1 year ago

Thank you for reporting.

I know what you're talking about. I get that "fonk" sound in examples/tetris.rb too.

Right now, I believe that is just a glitch in the underlying libui C library.

I just reported this as a bug to libui: https://github.com/libui-ng/libui-ng/issues/204

Once they fix it, and I update Glimmer DSL for LibUI to use their fix, I will notify you over here about it.

AndyObtiva commented 1 year ago

OK, I just figured out from the underlying C libui project owner how to tell the Mac that a key down event is handled, and I implemented this as automatic behavior in version 0.7.6: https://rubygems.org/gems/glimmer-dsl-libui/versions/0.7.6

As a result, the Tetris example does not make that "fonk" sound anymore while moving Tetris blocks with arrow keys. So, if you build games with a on_key_down listener, you should not have the problem anymore.

That should resolve your issue completely, so I am closing this issue.

If you have any further questions, feel free to reply to this issue, or even re-open if needed.

Cheers!

AndyObtiva commented 1 year ago

It just occurred to me that it would be useful to offer the library user the option to specify if a key event is handled or not in addition to the smart default automation. I am going to work on that and report back here once I have another release that enables it.

AndyObtiva commented 1 year ago

Version 0.7.7 just got released with the ability to return an explicit boolean value for whether a key event has been handled or not if needed (or otherwise if nothing (nil) or non-boolean non-1/0 value was returned, the assumption is the key event was handled):

https://rubygems.org/gems/glimmer-dsl-libui/versions/0.7.7

Change Log:

0.7.7

Example code from Tetris:

      on_key_down do |key_event|
        handled = true # assume it is handled for all cases except the else clause below
        case key_event
        in ext_key: :down
          if OS.windows?
            # rate limit downs in Windows as they go too fast when key is held
            @queued_downs ||= 0
            if @queued_downs < 2
              @queued_downs += 1
              Glimmer::LibUI.timer(0.01, repeat: false) do
                @game.down! if @queued_downs < 2
                @queued_downs -= 1
              end
            end
          else
            @game.down!
          end
        in key: ' '
          @game.down!(instant: true)
        in ext_key: :up
          case @game.up_arrow_action
          when :instant_down
            @game.down!(instant: true)
          when :rotate_right
            @game.rotate!(:right)
          when :rotate_left
            @game.rotate!(:left)
          end
        in ext_key: :left
          @game.left!
        in ext_key: :right
          @game.right!
        in modifier: :shift
          @game.rotate!(:right)
        in modifier: :control
          @game.rotate!(:left)
        else
          # returning false explicitly means the key event was not handled, which
          # propagates the event to other handlers, like the quit menu item, which
          # can handle COMMAND+Q on the Mac to quit an application
          handled = false
        end
        handled
      end

Cheers!