Control and Alt are special in that they aren't expected to switch levels, and so don't need to change what characters are output.
Use in layouts by adding `modifier: Control` or `modifier: Alt` in place of `text: "foo"`.
The latching of the modifier will force the keyboard to emit raw key presses and prevent it from outputting text.
In order to do that, an additional piece of state (layout switcher) was exposed to the event handlers, a separation between squeekboard-only and system layouts was introduced, along with a Translation structure to prevent mixing up strings.
Sizes of widgets can be derived, so storing them was only for C compatibility. Similar with storing position inside of widgets.
Some layout margin and scaling changes could be introduced, meaning a possibility of visual differences.
Moved Cairo context usage to Rust, and rearranged ctx setup (position) to happen in one place.
Removed render calls that were overwritten on each draw call anyway.
This fixes some rendering things which would happen with multiple state-sharing buttons. It also removes some interfaces exposing rows, views, layouts, and buttons, bringing the code closer to removing them from the FFI entirely.
WIP
WIP: keymap generation test passes
meta: Update features and version
WiP: cargo.lock
WIP: don't crash
WIP: no outlines
parsing: New tests
WIP: base level works
WIP: remove old keyboard
symbols correctly input
WIP: lodaing files
WIP: fallback works
Valid fallback
The check against fitting inside the Layout was removed: as an optimization it is unneeded, as the actual search must be optimized to be quick. In addition, the view bounds don't correspond to anything physical as long as negative offsets are allowed.
The C version of looping over buttons and other items was weakly typed, causing runtime errors, and also C doesn't know how to iterate in abstract, so it was full of callbacks with user-defined data. Moving this to Rust, iteration is made of simple loops, and compile-time type-checked, at the cost of some more verbose code.
Each Button has a KeyState, which may be shared with other buttons. The list of pressed and locked buttons is used as a list of keys, causing a search for the button in the current view.