Figuring Out Raw-Key Support: Experimentation

So, as detailed elsewhere, I’m trying to implement support for international keyboards via the use of raw-events.

I think that I’ve made some progress: I’ve managed to get what seem to be international keys picked up by Panda.

However, I’m facing something odd: the keys that I’m getting don’t always seem to match what I’m expecting, based on both typing in other programs and the OS-provided keyboard-layout image.

For example, if I select a Czech keyboard, the layout indicates that the “3”-key should produce the “š”-character. And in most places, it does–that’s how I entered it in that sentence, in fact.

In a Panda-program, however, that key is only recognised as “3”, even after application of “getMappedButtonLabel”.

Conversely, the “0”-key correctly produces the “é”-character, both in places like this text-entry box and in Panda.

So, am I doing something wrong? Is it an issue with the default font?

Here is the code that I’m using right now, more or less:

from direct.showbase.ShowBase import ShowBase

from panda3d.core import TextNode
from direct.gui.DirectGui import *

from panda3d import __version__ as pandaVersion
print (pandaVersion)

import sys
print (sys.version)

class Game(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        self.disableMouse()

        self.accept("escape", base.userExit)

        self.txt = DirectLabel(text = "Mew",
                               scale = 0.15)

        self.buttonThrower = base.buttonThrowers[0].node()
        
        self.buttonThrower.setRawButtonDownEvent("keyInterception")

        self.accept("keyInterception", self.keyInterception)

        self.keyMap = base.win.get_keyboard_map()

    def keyInterception(self, key):
        self.accept("raw-" + key, self.keyEvent, extraArgs = [key])
        self.updateKeyText("KEY BOUND!\nKey: {0}\nHaving label: {1}", key)
        self.buttonThrower.setRawButtonDownEvent("")

    def keyEvent(self, key):
        self.updateKeyText("A key was pressed!\nThat being: {0}\nWith label: {1}", key)

    def updateKeyText(self, message, key):
        mew = self.keyMap.getMappedButtonLabel(key)
        if len(mew) == 0:
            mew = key

        self.txt.show()
        self.txt["text"] = message.format(key, mew)
        self.txt.resetFrameSize()

app = Game()
app.run()

In short, it first listens for any key, then, on a key being pressed, clears the “any key” event and binds a raw-event for the key in question. Both the binding and subsequent presses of the bound key display messages to indicate that they were enacted, and with what data.

(This won’t work for things like mouse-buttons, of course, but right now I’m concentrating on the keyboard.)

When I print(mew) it prints the correct characters on my system. In the application (for some) it displays some similar version of them but that must be because the font lacks the czech subset.

1 Like

It’s not quite clear from your description what you are observing as incorrect. That the mapped button label for the raw “3” key is “3”? That is what is printed on a Czech keyboard:
image

“getMappedButtonLabel” is meant to be used to tell the user what to press; it is a localised name assigned by the operating system (GetKeyNameTextW on Windows). If a user with a Czech keyboard is told to press the “3” key, I assume there will not be confusion, given that there is a “3” printed on that key. Under different circumstances, that key may produce different letters when typed into a text box, but getMappedButtonLabel is not intended to disambiguate between that.

What operating system are you testing on, also? And which Panda version?

1 Like

If you happen to be on Linux, on the other hand, it looks like there is currently a limitation that certain extended Latin character sets are not mapped to button labels, which I can address in the next Panda version.

1 Like

Ah, interesting. Okay, so at least we know that the correct characters are being generated–that’s good, at least!

It may well be that the font lacks the relevant characters–although I’m surprised at that happening on your system, where I would expect the default font to have those characters!

As far as I understand it–and based both on what I’ve seen from telling the OS to treat my keyboard as a Czech keyboard and from user report–a single press of the “3” key, with no modifiers, produces not a “3”, but a “š” (which is visible next to the “3” on the button in the image above). Thus I’m inclined to expect the mapping to report “š” instead of “3”.

Aahh, I am indeed on Linux. Okay, at least I know that it’s not something that I’m doing wrong, and I’m glad to know that it might be addressed! :slight_smile:

A character in a font not being supported will not cause a completely different character to be selected in Panda. Panda may try to emulate an accented character using a combining character, but if it fails to do so, it will display a box (or some other character-not-found symbol).

We don’t use the system default font in Panda.

I just want to say that the mapping is not guaranteed to give you a printable character that would be pressed if that key is pressed. For many keyboard layouts, it isn’t that simple, because printable characters may be produced based on a modifier key, a toggleable state, whether a dead key was recently pressed, or something else entirely.

The label is supposed to indicate something you can communicate to the user; a Czech user will likely understand which key to press regardless of whether you tell them to press “3” or “š” because both are printed on the key.

(In fact, I would say for consistency it should produce “3”, because we also produce a label of “A” for the A key, even though that is in fact the shift-modified character.)

Ah, fair enough.

Funnily enough, I did have a report of something that may be this: it was reported that in one case, the character produced was almost right, but had the incorrect accent (specifically, a vertically-flipped version of the accent, I think that it was).

That’s fair. I suppose that I was just expecting that the character produced would be the character printed if the key were pressed in the keyboard’s default state. However, whether that’s reasonable or not:

That’s very fair, and a good argument, I feel. Fair enough, then!

Do you happen to know which character that was?

I believe that it was in fact the aforementioned “š” character.

Here’s the report:

ě š č ř ž had the ˇ fliped, I guess as rdb explained its because panda tried to find the closest match.

And I want to point out that you shouldnt probably use 3, yeah 1-0 wont confuse probably anyone but then the keys around Enter would get very confusing if you didnt use the label.

1 Like

Ah, it’s Panda’s “cheesy accent fallback code” failing to find a caron in the font and deciding to just grab the ^ and put it upside-down over the character. Except it’s failing to flip it upside-down. Will investigate.

However, this is no substitute for just loading in a font with a caron (U+030C) or the proper composed character.

1 Like

Of course. But this was just in the example-game for the KeyMapper module, so I haven’t been too worried about getting a good font–I’ve just been using whatever it is that Panda defaults to.

(However, given that this is for a key-mapping module, perhaps this is one case in which a good font, and thus a good representation of what the module does, is in fact a good idea…)

Also for ý it uses some weird ´ but éíá seem correct. Tho I wouldnt bother much with it, its still readable.

It probably suggests we need to ship a better font with Panda. :slight_smile:

1 Like

On which note, I’ve just found the font “Aileron”. While I can’t speak to its completeness or accuracy, it looks to my layman’s eye like it has a lot of glyphs. On top of that, it’s released under Creative Commons 0!

See here:

1 Like

That looks like a nice font. :slight_smile: When evaluating a font we should probably try to pick one that has metrics close to the current default font, so that people don’t have to change their UI sizing significantly.

I have fixed the bug that labels aren’t provided for many international keys in the X11 implementation, and I have fixed the bug that the synthesized caron appears upside-down. These fixes will be in 1.10.9.

Thanks for helping to uncover these issues!

That’s fair. And given the presence of this font, there may be others available that have the features offered by this one and the desired metrics. It may just be a matter of trawling the free font sites for a bit! (Or even just the site of the maker of the above font, come to that.)

Ah, excellent! That’s good to know, and thank you for your work on this! :slight_smile:

It’s my pleasure, for my part. :slight_smile: