Compare commits

..

3 Commits

55 changed files with 619 additions and 2428 deletions

View File

@ -136,10 +136,7 @@ test:
- build_meson - build_meson
script: script:
- apt-get -y build-dep . - apt-get -y build-dep .
- apt-get -y install clang-tidy
- ninja -C _build test - ninja -C _build test
- cd _build
- clang-tidy --checks=-clang-diagnostic-missing-braces,readability-braces-around-statements, --warnings-as-errors=readability-braces-around-statements -extra-arg=-Wno-unknown-warning-option ../src/*.c ../eek/*.c ../eekboard/*.c
check_release: check_release:
<<: *tags <<: *tags

430
Cargo.lock generated
View File

@ -4,481 +4,483 @@
name = "atk" name = "atk"
version = "0.7.0" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b7499272acf036bb5820c6e346bbfb5acc5dceb104bc2c4fd7e6e33dfcde6a"
dependencies = [ dependencies = [
"atk-sys", "atk-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags", "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glib", "glib 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys", "glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys", "gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc", "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "atk-sys" name = "atk-sys"
version = "0.9.1" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e552c1776737a4c80110d06b36d099f47c727335f9aaa5d942a72b6863a8ec6f"
dependencies = [ dependencies = [
"glib-sys", "glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys", "gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc", "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config", "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.2.1" version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]] [[package]]
name = "cairo-rs" name = "cairo-rs"
version = "0.7.1" version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e05db47de3b0f09a222fa4bba2eab957d920d4243962a86b2d77ab401e4a359c"
dependencies = [ dependencies = [
"bitflags", "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cairo-sys-rs", "cairo-sys-rs 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"glib", "glib 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys", "glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys", "gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc", "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "cairo-sys-rs" name = "cairo-sys-rs"
version = "0.9.2" version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff65ba02cac715be836f63429ab00a767d48336efc5497c5637afb53b4f14d63"
dependencies = [ dependencies = [
"glib-sys", "glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc", "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config", "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.66" version = "1.0.54"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"
[[package]] [[package]]
name = "clap" name = "clap"
version = "2.33.3" version = "2.33.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
dependencies = [ dependencies = [
"bitflags", "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"textwrap", "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width", "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "dtoa" name = "dtoa"
version = "0.4.7" version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88d7ed2934d741c6b37e33e3832298e8850b53fd2d2bea03873375596c7cea4e"
[[package]] [[package]]
name = "fragile" name = "fragile"
version = "0.3.0" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f8140122fa0d5dcb9fc8627cfce2b37cc1500f752636d46ea28bc26785c2f9"
[[package]] [[package]]
name = "gdk" name = "gdk"
version = "0.11.0" version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6243e995f41f3a61a31847e54cc719edce93dd9140c89dca3b9919be1cfe22d5"
dependencies = [ dependencies = [
"bitflags", "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cairo-rs", "cairo-rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cairo-sys-rs", "cairo-sys-rs 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"gdk-pixbuf", "gdk-pixbuf 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gdk-sys", "gdk-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gio", "gio 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gio-sys", "gio-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glib", "glib 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys", "glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys", "gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc", "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"pango", "pango 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "gdk-pixbuf" name = "gdk-pixbuf"
version = "0.7.0" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9726408ee1bbada83094326a99b9c68fea275f9dbb515de242a69e72051f4fcc"
dependencies = [ dependencies = [
"gdk-pixbuf-sys", "gdk-pixbuf-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gio", "gio 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gio-sys", "gio-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glib", "glib 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys", "glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys", "gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc", "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "gdk-pixbuf-sys" name = "gdk-pixbuf-sys"
version = "0.9.1" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8991b060a9e9161bafd09bf4a202e6fd404f5b4dd1a08d53a1e84256fb34ab0"
dependencies = [ dependencies = [
"gio-sys", "gio-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys", "glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys", "gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc", "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config", "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "gdk-sys" name = "gdk-sys"
version = "0.9.1" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6adf679e91d1bff0c06860287f80403e7db54c2d2424dce0a470023b56c88fbb"
dependencies = [ dependencies = [
"cairo-sys-rs", "cairo-sys-rs 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"gdk-pixbuf-sys", "gdk-pixbuf-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gio-sys", "gio-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys", "glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys", "gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc", "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"pango-sys", "pango-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config", "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "gio" name = "gio"
version = "0.7.0" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6261b5d34c30c2d59f879e643704cf54cb44731f3a2038000b68790c03e360e3"
dependencies = [ dependencies = [
"bitflags", "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fragile", "fragile 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gio-sys", "gio-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glib", "glib 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys", "glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys", "gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc", "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "gio-sys" name = "gio-sys"
version = "0.9.1" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fad225242b9eae7ec8a063bb86974aca56885014672375e5775dc0ea3533911"
dependencies = [ dependencies = [
"glib-sys", "glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys", "gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc", "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config", "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "glib" name = "glib"
version = "0.8.2" version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be27232841baa43e0fd5ae003f7941925735b2f733a336dc75f07b9eff415e7b"
dependencies = [ dependencies = [
"bitflags", "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys", "glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys", "gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc", "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "glib-sys" name = "glib-sys"
version = "0.9.1" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95856f3802f446c05feffa5e24859fe6a183a7cb849c8449afc35c86b1e316e2"
dependencies = [ dependencies = [
"libc", "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config", "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "gobject-sys" name = "gobject-sys"
version = "0.9.1" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31d1a804f62034eccf370006ccaef3708a71c31d561fee88564abe71177553d9"
dependencies = [ dependencies = [
"glib-sys", "glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc", "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config", "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "gtk" name = "gtk"
version = "0.7.0" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "709f1074259d4685b96133f92b75c7f35b504715b0fcdc96ec95de2607296a60"
dependencies = [ dependencies = [
"atk", "atk 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags", "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cairo-rs", "cairo-rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cairo-sys-rs", "cairo-sys-rs 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"cc", "cc 1.0.54 (registry+https://github.com/rust-lang/crates.io-index)",
"gdk", "gdk 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gdk-pixbuf", "gdk-pixbuf 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gdk-pixbuf-sys", "gdk-pixbuf-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gdk-sys", "gdk-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gio", "gio 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gio-sys", "gio-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glib", "glib 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys", "glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys", "gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gtk-sys", "gtk-sys 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc", "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"pango", "pango 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pango-sys", "pango-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "gtk-sys" name = "gtk-sys"
version = "0.9.2" version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53def660c7b48b00b510c81ef2d2fbd3c570f1527081d8d7947f471513e1a4c1"
dependencies = [ dependencies = [
"atk-sys", "atk-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cairo-sys-rs", "cairo-sys-rs 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"gdk-pixbuf-sys", "gdk-pixbuf-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gdk-sys", "gdk-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gio-sys", "gio-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys", "glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys", "gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc", "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"pango-sys", "pango-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config", "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.4.0" version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.82" version = "0.2.71"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929"
[[package]] [[package]]
name = "linked-hash-map" name = "linked-hash-map"
version = "0.5.4" version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
[[package]] [[package]]
name = "maplit" name = "maplit"
version = "1.0.2" version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
[[package]] [[package]]
name = "memmap" name = "memmap"
version = "0.7.0" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
dependencies = [ dependencies = [
"libc", "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "pango" name = "pango"
version = "0.7.0" version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "393fa071b144f8ffb83ede273758983cf414ca3c0b1d2a5a9ce325b3ba3dd786"
dependencies = [ dependencies = [
"bitflags", "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glib", "glib 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys", "glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys", "gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc", "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"pango-sys", "pango-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "pango-sys" name = "pango-sys"
version = "0.9.1" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b93d84907b3cf0819bff8f13598ba72843bee579d5ebc2502e4b0367b4be7d"
dependencies = [ dependencies = [
"glib-sys", "glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gobject-sys", "gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc", "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config", "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "pkg-config" name = "pkg-config"
version = "0.3.19" version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.24" version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [ dependencies = [
"unicode-xid", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.8" version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.3.9" version = "1.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6"
dependencies = [ dependencies = [
"regex-syntax", "regex-syntax 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "regex-syntax" name = "regex-syntax"
version = "0.6.22" version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
[[package]] [[package]]
name = "rs" name = "rs"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bitflags", "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cairo-rs", "cairo-rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cairo-sys-rs", "cairo-sys-rs 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"clap", "clap 2.33.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gdk", "gdk 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gio", "gio 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"glib", "glib 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"glib-sys", "glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gtk", "gtk 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gtk-sys", "gtk-sys 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"maplit", "maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"regex", "regex 1.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"serde", "serde 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_yaml", "serde_yaml 0.8.13 (registry+https://github.com/rust-lang/crates.io-index)",
"xkbcommon", "xkbcommon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.118" version = "1.0.111"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800"
dependencies = [ dependencies = [
"serde_derive", "serde_derive 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.118" version = "1.0.111"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
"quote", "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syn", "syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "serde_yaml" name = "serde_yaml"
version = "0.8.15" version = "0.8.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "971be8f6e4d4a47163b405a3df70d14359186f9ab0f3a3ec37df144ca1ce089f"
dependencies = [ dependencies = [
"dtoa", "dtoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"linked-hash-map", "linked-hash-map 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde", "serde 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
"yaml-rust", "yaml-rust 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.58" version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc60a3d73ea6594cd712d830cc1f0390fd71542d8c8cd24e70cc54cdfd5e05d5"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
"quote", "quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "textwrap" name = "textwrap"
version = "0.11.0" version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [ dependencies = [
"unicode-width", "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "unicode-width" name = "unicode-width"
version = "0.1.8" version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-xid"
version = "0.2.1" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]] [[package]]
name = "winapi" name = "winapi"
version = "0.3.9" version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [ dependencies = [
"winapi-i686-pc-windows-gnu", "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-x86_64-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "winapi-i686-pc-windows-gnu" name = "winapi-i686-pc-windows-gnu"
version = "0.4.0" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]] [[package]]
name = "winapi-x86_64-pc-windows-gnu" name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]] [[package]]
name = "xkbcommon" name = "xkbcommon"
version = "0.4.0" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fda0ea5f7ddabd51deeeda7799bee06274112f577da7dd3d954b8eda731b2fce"
dependencies = [ dependencies = [
"libc", "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap", "memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "yaml-rust" name = "yaml-rust"
version = "0.4.5" version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [ dependencies = [
"linked-hash-map", "linked-hash-map 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[metadata]
"checksum atk 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "86b7499272acf036bb5820c6e346bbfb5acc5dceb104bc2c4fd7e6e33dfcde6a"
"checksum atk-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e552c1776737a4c80110d06b36d099f47c727335f9aaa5d942a72b6863a8ec6f"
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
"checksum cairo-rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e05db47de3b0f09a222fa4bba2eab957d920d4243962a86b2d77ab401e4a359c"
"checksum cairo-sys-rs 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ff65ba02cac715be836f63429ab00a767d48336efc5497c5637afb53b4f14d63"
"checksum cc 1.0.54 (registry+https://github.com/rust-lang/crates.io-index)" = "7bbb73db36c1246e9034e307d0fba23f9a2e251faa47ade70c1bd252220c8311"
"checksum clap 2.33.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129"
"checksum dtoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4358a9e11b9a09cf52383b451b49a169e8d797b68aa02301ff586d70d9661ea3"
"checksum fragile 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f8140122fa0d5dcb9fc8627cfce2b37cc1500f752636d46ea28bc26785c2f9"
"checksum gdk 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6243e995f41f3a61a31847e54cc719edce93dd9140c89dca3b9919be1cfe22d5"
"checksum gdk-pixbuf 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9726408ee1bbada83094326a99b9c68fea275f9dbb515de242a69e72051f4fcc"
"checksum gdk-pixbuf-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d8991b060a9e9161bafd09bf4a202e6fd404f5b4dd1a08d53a1e84256fb34ab0"
"checksum gdk-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6adf679e91d1bff0c06860287f80403e7db54c2d2424dce0a470023b56c88fbb"
"checksum gio 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6261b5d34c30c2d59f879e643704cf54cb44731f3a2038000b68790c03e360e3"
"checksum gio-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4fad225242b9eae7ec8a063bb86974aca56885014672375e5775dc0ea3533911"
"checksum glib 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "be27232841baa43e0fd5ae003f7941925735b2f733a336dc75f07b9eff415e7b"
"checksum glib-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "95856f3802f446c05feffa5e24859fe6a183a7cb849c8449afc35c86b1e316e2"
"checksum gobject-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31d1a804f62034eccf370006ccaef3708a71c31d561fee88564abe71177553d9"
"checksum gtk 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "709f1074259d4685b96133f92b75c7f35b504715b0fcdc96ec95de2607296a60"
"checksum gtk-sys 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53def660c7b48b00b510c81ef2d2fbd3c570f1527081d8d7947f471513e1a4c1"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)" = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49"
"checksum linked-hash-map 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a"
"checksum maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
"checksum pango 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "393fa071b144f8ffb83ede273758983cf414ca3c0b1d2a5a9ce325b3ba3dd786"
"checksum pango-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "86b93d84907b3cf0819bff8f13598ba72843bee579d5ebc2502e4b0367b4be7d"
"checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
"checksum proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa"
"checksum quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
"checksum regex 1.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6"
"checksum regex-syntax 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)" = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
"checksum serde 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)" = "c9124df5b40cbd380080b2cc6ab894c040a3070d995f5c9dc77e18c34a8ae37d"
"checksum serde_derive 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)" = "3f2c3ac8e6ca1e9c80b8be1023940162bf81ae3cffbb1809474152f2ce1eb250"
"checksum serde_yaml 0.8.13 (registry+https://github.com/rust-lang/crates.io-index)" = "ae3e2dd40a7cdc18ca80db804b7f461a39bb721160a85c9a1fa30134bf3c02a5"
"checksum syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "b5304cfdf27365b7585c25d4af91b35016ed21ef88f17ced89c7093b43dba8b6"
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
"checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479"
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
"checksum xkbcommon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fda0ea5f7ddabd51deeeda7799bee06274112f577da7dd3d954b8eda731b2fce"
"checksum yaml-rust 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "39f0c922f1a334134dc2f7a8b67dc5d25f0735263feec974345ff706bcf20b0d"

View File

@ -19,7 +19,6 @@ path = "@path@/examples/test_layout.rs"
[features] [features]
gio_v0_5 = [] gio_v0_5 = []
gtk_v0_5 = [] gtk_v0_5 = []
rustc_less_1_36 = []
# Dependencies which don't change based on build flags # Dependencies which don't change based on build flags
[dependencies.cairo-sys-rs] [dependencies.cairo-sys-rs]

View File

@ -1,49 +0,0 @@
#!/usr/bin/env python3
"""This script manages Cargo builds
while keeping the artifact directory within the build tree
instead of the source tree.
"""
from pathlib import Path
import shlex
import subprocess
import sys
source_dir = Path(__file__).absolute().parent
args = sys.argv[1:]
binary_dir = "debug"
if '--release' in args:
binary_dir = "release"
# The file produced by Cargo will have a special name
try:
i = args.index('--rename')
except ValueError:
filename = None
else:
args.pop(i)
filename = args.pop(i)
# The target destination of the produced file is a positional argument
out_path = [arg for arg in args if not arg.startswith('--')]
if out_path:
out_path = out_path[0]
i = args.index(out_path)
args.pop(i)
subprocess.run(['sh', "{}/cargo.sh".format(shlex.quote(source_dir.as_posix())), 'build']
+ args,
check=True)
if out_path:
out_path = Path(out_path).absolute()
out_basename = out_path.name
filename = filename or out_basename
subprocess.run(['cp', '-a',
'./{}/{}'.format(shlex.quote(binary_dir), shlex.quote(filename)),
out_path],
check=True)

34
cargo_build.sh Executable file
View File

@ -0,0 +1,34 @@
#!/bin/sh
# This script manages Cargo builds
# while keeping the artifact directory within the build tree
# instead of the source tree
set -e
SCRIPT_PATH="$(realpath "$0")"
SOURCE_DIR="$(dirname "$SCRIPT_PATH")"
RELEASE=""
BINARY_DIR="debug"
if [ "${1}" = "--release" ]; then
shift
BINARY_DIR="release"
RELEASE="--release"
fi
if [ "${1}" = "--rename" ]; then
shift
FILENAME="${1}"
shift
fi
OUT_PATH="$(realpath "${1}")"
shift
OUT_BASENAME="$(basename "${OUT_PATH}")"
FILENAME="${FILENAME:-"${OUT_BASENAME}"}"
sh "$SOURCE_DIR"/cargo.sh build $RELEASE "$@"
if [ -n "${OUT_PATH}" ]; then
cp -a ./"${BINARY_DIR}"/"${FILENAME}" "${OUT_PATH}"
fi

View File

@ -1,78 +0,0 @@
---
outlines:
default: { width: 32.72, height: 52 }
altline: { width: 47, height: 52 }
wide: { width: 49.09, height: 52 }
spaceline: { width: 185, height: 52 }
special: { width: 44, height: 52 }
views:
base:
- "я в е р т ъ у и о п ю"
- "а с д ф г х й к л ш щ"
- "Shift_L з ь ц ж б н м ч BackSpace"
- "show_numbers preferences space . Return"
upper:
- В Е Р Т Ъ У И О П Ю"
- "А С Д Ф Г Х Й К Л Ш Щ"
- "Shift_L З Ь Ц Ж Б Н М Ч BackSpace"
- "show_numbers preferences space , Return"
numbers:
- "1 2 3 4 5 6 7 8 9 0"
- "@ # € % & - _ + ( )"
- "show_symbols , \" ' colon ; ! ? BackSpace"
- "show_letters preferences space Return"
symbols:
- "~ ` | · √ π τ ÷ × ¶"
- "© ® £ $ ¥ ^ ° * { }"
- "show_numbers_from_symbols \\ / < > = [ ] BackSpace"
- "show_letters preferences space Return"
buttons:
Shift_L:
action:
locking:
lock_view: "upper"
unlock_view: "base"
outline: "altline"
icon: "key-shift"
BackSpace:
outline: "altline"
icon: "edit-clear-symbolic"
action: erase
preferences:
action: "show_prefs"
outline: "special"
icon: "keyboard-mode-symbolic"
show_numbers:
action:
set_view: "numbers"
outline: "wide"
label: "123"
show_numbers_from_symbols:
action:
set_view: "numbers"
outline: "altline"
label: "123"
show_letters:
action:
set_view: "base"
outline: "wide"
label: "abc"
show_symbols:
action:
set_view: "symbols"
outline: "altline"
label: "*/="
space:
outline: "spaceline"
text: " "
Return:
outline: "wide"
icon: "key-enter"
keysym: "Return"
colon:
text: ":"
"\"":
keysym: "quotedbl"

View File

@ -1,106 +0,0 @@
---
outlines:
default: { width: 35.33, height: 52 }
altline: { width: 52.67, height: 52 }
wide: { width: 52.67, height: 52 }
spaceline: { width: 106, height: 52 }
special: { width: 35.33, height: 52 }
views:
base:
- "q w e r t y u i o p"
- "a s d f g h j k l"
- "Shift_L z x c v b n m BackSpace"
- "show_numbers preferences show_accents space , . Return"
upper:
- "Q W E R T Y U I O P"
- "A S D F G H J K L"
- "Shift_L Z X C V B N M BackSpace"
- "show_numbers preferences show_upper_accents space ! ? Return"
numbers:
- "1 2 3 4 5 6 7 8 9 0"
- "@ # $ % & - _ + ( )"
- "show_symbols , \" ' colon ; ! ? BackSpace"
- "show_letters preferences show_accents space , . Return"
symbols:
- "~ ` | · √ π τ ÷ × ¶"
- "© ® £ € ¥ ^ ° * { }"
- "show_numbers_from_symbols \\ / < > = [ ] BackSpace"
- "show_letters preferences show_accents space , . Return"
accents:
- "ä ě é ř ť ý ů í ó ö"
- "á š ď ë ŕ ú ü ô ľ"
- "accents_Shift_L ž ß č ç ñ ň ĺ BackSpace"
- "show_letters preferences show_accents space , . Return"
upper_accents:
- "Ä Ě É Ř Ť Ý Ů Í Ó Ö"
- "Á Š Ď Ë Ŕ Ú Ü Ô Ľ"
- "accents_Shift_L Ž ẞ Č Ç Ñ Ň Ĺ BackSpace"
- "show_letters preferences show_upper_accents space , . Return"
buttons:
Shift_L:
action:
locking:
lock_view: "upper"
unlock_view: "base"
outline: "altline"
icon: "key-shift"
accents_Shift_L:
action:
locking:
lock_view: "upper_accents"
unlock_view: "base"
outline: "altline"
icon: "key-shift"
BackSpace:
outline: "altline"
icon: "edit-clear-symbolic"
action: erase
preferences:
action: show_prefs
outline: "special"
icon: "keyboard-mode-symbolic"
show_numbers:
action:
set_view: "numbers"
outline: "wide"
label: "123"
show_numbers_from_symbols:
action:
set_view: "numbers"
outline: "altline"
label: "123"
show_letters:
action:
set_view: "base"
outline: "wide"
label: "abc"
show_symbols:
action:
set_view: "symbols"
outline: "altline"
label: "*/="
show_accents:
action:
locking:
lock_view: "accents"
unlock_view: "base"
outline: "special"
label: "á"
show_upper_accents:
action:
locking:
lock_view: "upper_accents"
unlock_view: "base"
outline: "special"
label: "Á"
space:
outline: "spaceline"
text: " "
Return:
outline: "wide"
icon: "key-enter"
keysym: "Return"
colon:
text: ":"

View File

@ -1,106 +0,0 @@
---
outlines:
default: { width: 54, height: 42 }
altline: { width: 81, height: 42 }
wide: { width: 81, height: 42 }
spaceline: { width: 162, height: 42 }
special: { width: 54, height: 42 }
views:
base:
- "q w e r t y u i o p"
- "a s d f g h j k l"
- "Shift_L z x c v b n m BackSpace"
- "show_numbers preferences show_accents space , . Return"
upper:
- "Q W E R T Y U I O P"
- "A S D F G H J K L"
- "Shift_L Z X C V B N M BackSpace"
- "show_numbers preferences show_upper_accents space ! ? Return"
numbers:
- "1 2 3 4 5 6 7 8 9 0"
- "@ # $ % & - _ + ( )"
- "show_symbols , \" ' colon ; ! ? BackSpace"
- "show_letters preferences show_accents space , . Return"
symbols:
- "~ ` | · √ π τ ÷ × ¶"
- "© ® £ € ¥ ^ ° * { }"
- "show_numbers_from_symbols \\ / < > = [ ] BackSpace"
- "show_letters preferences show_accents space , . Return"
accents:
- "ä ě é ř ť ý ů í ó ö"
- "á š ď ë ŕ ú ü ô ľ"
- "accents_Shift_L ž ß č ç ñ ň ĺ BackSpace"
- "show_letters preferences show_accents space , . Return"
upper_accents:
- "Ä Ě É Ř Ť Ý Ů Í Ó Ö"
- "Á Š Ď Ë Ŕ Ú Ü Ô Ľ"
- "accents_Shift_L Ž ẞ Č Ç Ñ Ň Ĺ BackSpace"
- "show_letters preferences show_upper_accents space , . Return"
buttons:
Shift_L:
action:
locking:
lock_view: "upper"
unlock_view: "base"
outline: "altline"
icon: "key-shift"
accents_Shift_L:
action:
locking:
lock_view: "upper_accents"
unlock_view: "base"
outline: "altline"
icon: "key-shift"
BackSpace:
outline: "altline"
icon: "edit-clear-symbolic"
action: erase
preferences:
action: show_prefs
outline: "special"
icon: "keyboard-mode-symbolic"
show_numbers:
action:
set_view: "numbers"
outline: "wide"
label: "123"
show_numbers_from_symbols:
action:
set_view: "numbers"
outline: "altline"
label: "123"
show_letters:
action:
set_view: "base"
outline: "wide"
label: "abc"
show_symbols:
action:
set_view: "symbols"
outline: "altline"
label: "*/="
show_accents:
action:
locking:
lock_view: "accents"
unlock_view: "base"
outline: "special"
label: "á"
show_upper_accents:
action:
locking:
lock_view: "upper_accents"
unlock_view: "base"
outline: "special"
label: "Á"
space:
outline: "spaceline"
text: " "
Return:
outline: "wide"
icon: "key-enter"
keysym: "Return"
colon:
text: ":"

View File

@ -1,106 +0,0 @@
---
outlines:
default: { width: 35.33, height: 52 }
altline: { width: 52.67, height: 52 }
wide: { width: 52.67, height: 52 }
spaceline: { width: 106, height: 52 }
special: { width: 35.33, height: 52 }
views:
base:
- "q w e r t z u i o p"
- "a s d f g h j k l"
- "Shift_L y x c v b n m BackSpace"
- "show_numbers preferences show_accents space , . Return"
upper:
- "Q W E R T Z U I O P"
- "A S D F G H J K L"
- "Shift_L Y X C V B N M BackSpace"
- "show_numbers preferences show_upper_accents space ! ? Return"
numbers:
- "1 2 3 4 5 6 7 8 9 0"
- "@ # $ % & - _ + ( )"
- "show_symbols , \" ' colon ; ! ? BackSpace"
- "show_letters preferences show_accents space , . Return"
symbols:
- "~ ` | · √ π τ ÷ × ¶"
- "© ® £ € ¥ ^ ° * { }"
- "show_numbers_from_symbols \\ / < > = [ ] BackSpace"
- "show_letters preferences show_accents space , . Return"
accents:
- "ä ě é ř ť ž ů í ó ö"
- "á š ď ë ŕ ú ü ô ľ"
- "accents_Shift_L ý ß č ç ñ ň ĺ BackSpace"
- "show_letters preferences show_accents space , . Return"
upper_accents:
- "Ä Ě É Ř Ť Ž Ů Í Ó Ö"
- "Á Š Ď Ë Ŕ Ú Ü Ô Ľ"
- "accents_Shift_L Ý ẞ Č Ç Ñ Ň Ĺ BackSpace"
- "show_letters preferences show_upper_accents space , . Return"
buttons:
Shift_L:
action:
locking:
lock_view: "upper"
unlock_view: "base"
outline: "altline"
icon: "key-shift"
accents_Shift_L:
action:
locking:
lock_view: "upper_accents"
unlock_view: "base"
outline: "altline"
icon: "key-shift"
BackSpace:
outline: "altline"
icon: "edit-clear-symbolic"
action: erase
preferences:
action: show_prefs
outline: "special"
icon: "keyboard-mode-symbolic"
show_numbers:
action:
set_view: "numbers"
outline: "wide"
label: "123"
show_numbers_from_symbols:
action:
set_view: "numbers"
outline: "altline"
label: "123"
show_letters:
action:
set_view: "base"
outline: "wide"
label: "abc"
show_symbols:
action:
set_view: "symbols"
outline: "altline"
label: "*/="
show_accents:
action:
locking:
lock_view: "accents"
unlock_view: "base"
outline: "special"
label: "á"
show_upper_accents:
action:
locking:
lock_view: "upper_accents"
unlock_view: "base"
outline: "special"
label: "Á"
space:
outline: "spaceline"
text: " "
Return:
outline: "wide"
icon: "key-enter"
keysym: "Return"
colon:
text: ":"

View File

@ -1,106 +0,0 @@
---
outlines:
default: { width: 54, height: 42 }
altline: { width: 81, height: 42 }
wide: { width: 81, height: 42 }
spaceline: { width: 162, height: 42 }
special: { width: 54, height: 42 }
views:
base:
- "q w e r t z u i o p"
- "a s d f g h j k l"
- "Shift_L y x c v b n m BackSpace"
- "show_numbers preferences show_accents space , . Return"
upper:
- "Q W E R T Z U I O P"
- "A S D F G H J K L"
- "Shift_L Y X C V B N M BackSpace"
- "show_numbers preferences show_upper_accents space ! ? Return"
numbers:
- "1 2 3 4 5 6 7 8 9 0"
- "@ # $ % & - _ + ( )"
- "show_symbols , \" ' colon ; ! ? BackSpace"
- "show_letters preferences show_accents space , . Return"
symbols:
- "~ ` | · √ π τ ÷ × ¶"
- "© ® £ € ¥ ^ ° * { }"
- "show_numbers_from_symbols \\ / < > = [ ] BackSpace"
- "show_letters preferences show_accents space , . Return"
accents:
- "ä ě é ř ť ž ů í ó ö"
- "á š ď ë ŕ ú ü ô ľ"
- "accents_Shift_L ý ß č ç ñ ň ĺ BackSpace"
- "show_letters preferences show_accents space , . Return"
upper_accents:
- "Ä Ě É Ř Ť Ž Ů Í Ó Ö"
- "Á Š Ď Ë Ŕ Ú Ü Ô Ľ"
- "accents_Shift_L Ý ẞ Č Ç Ñ Ň Ĺ BackSpace"
- "show_letters preferences show_upper_accents space , . Return"
buttons:
Shift_L:
action:
locking:
lock_view: "upper"
unlock_view: "base"
outline: "altline"
icon: "key-shift"
accents_Shift_L:
action:
locking:
lock_view: "upper_accents"
unlock_view: "base"
outline: "altline"
icon: "key-shift"
BackSpace:
outline: "altline"
icon: "edit-clear-symbolic"
action: erase
preferences:
action: show_prefs
outline: "special"
icon: "keyboard-mode-symbolic"
show_numbers:
action:
set_view: "numbers"
outline: "wide"
label: "123"
show_numbers_from_symbols:
action:
set_view: "numbers"
outline: "altline"
label: "123"
show_letters:
action:
set_view: "base"
outline: "wide"
label: "abc"
show_symbols:
action:
set_view: "symbols"
outline: "altline"
label: "*/="
show_accents:
action:
locking:
lock_view: "accents"
unlock_view: "base"
outline: "special"
label: "á"
show_upper_accents:
action:
locking:
lock_view: "upper_accents"
unlock_view: "base"
outline: "special"
label: "Á"
space:
outline: "spaceline"
text: " "
Return:
outline: "wide"
icon: "key-enter"
keysym: "Return"
colon:
text: ":"

View File

@ -21,7 +21,7 @@ views:
numbers: numbers:
- "1 2 3 4 5 6 7 8 9 0" - "1 2 3 4 5 6 7 8 9 0"
- "@ # € % & - _ + ( )" - "@ # € % & - _ + ( )"
- "show_symbols ; \" ' : = < > BackSpace" - "show_symbols , \" ' : = < > BackSpace"
- "show_letters show_eschars preferences space , . Return" - "show_letters show_eschars preferences space , . Return"
symbols: symbols:
- "~ ` ´ | · √ µ ÷ × ¶" - "~ ` ´ | · √ µ ÷ × ¶"

View File

@ -21,7 +21,7 @@ views:
numbers: numbers:
- "1 2 3 4 5 6 7 8 9 0" - "1 2 3 4 5 6 7 8 9 0"
- "@ # % & - _ + ( ) ß" - "@ # % & - _ + ( ) ß"
- "show_symbols ; \" ' : = < > BackSpace" - "show_symbols , \" ' : = < > BackSpace"
- "show_letters preferences space , . Return" - "show_letters preferences space , . Return"
symbols: symbols:
- "~ ` ´ · © ® ÷ × ¶" - "~ ` ´ · © ® ÷ × ¶"

View File

@ -1,81 +0,0 @@
---
outlines:
default: { width: 35.33, height: 52 }
altline: { width: 52.67, height: 52 }
wide: { width: 62, height: 52 }
spaceline: { width: 99.67, height: 52 }
special: { width: 35.33, height: 52 }
views:
base:
- "q w e r t y u i o p"
- "a s d f g h j k l"
- "Shift_L z x c v b n m BackSpace"
- "show_numbers show_eschars preferences space , . Return"
upper:
- "Q W E R T Y U I O P"
- "A S D F G H J K L"
- "Shift_L Z X C V B N M BackSpace"
- "show_numbers show_eschars preferences space ! ? Return"
numbers:
- "1 2 3 4 5 6 7 8 9 0"
- "@ # $ % & - _ + ( )"
- "show_symbols , \" ' : ; ! ? BackSpace"
- "show_letters preferences space . Return"
symbols:
- "~ ` | · √ π τ ÷ × ¶"
- "© ® £ € ¥ ^ ° * { }"
- "show_numbers_from_symbols \\ / < > = [ ] BackSpace"
- "show_letters preferences space . Return"
eschars:
- "ĉ ĝ ĥ ĵ ŝ ŭ ?"
- "Ĉ Ĝ Ĥ Ĵ Ŝ Ŭ !"
- "show_numbers ' - 🐊 💚 🌐 . BackSpace"
- "show_letters show_eschars preferences space „ “ Return"
buttons:
Shift_L:
action:
locking:
lock_view: "upper"
unlock_view: "base"
outline: "altline"
icon: "key-shift"
BackSpace:
outline: "altline"
icon: "edit-clear-symbolic"
action: "erase"
preferences:
action: "show_prefs"
outline: "special"
icon: "keyboard-mode-symbolic"
show_numbers:
action:
set_view: "numbers"
outline: "altline"
label: "123"
show_letters:
action:
set_view: "base"
outline: "altline"
label: "abc"
show_symbols:
action:
set_view: "symbols"
outline: "altline"
label: "*/="
show_eschars:
action:
locking:
lock_view: "eschars"
unlock_view: "base"
outline: "altline"
label: "ŭŜ"
space:
outline: "spaceline"
label: " "
text: " "
Return:
outline: "altline"
icon: "key-enter"
keysym: "Return"

View File

@ -1,78 +0,0 @@
---
outlines:
default: { width: 35.33, height: 52 }
altline: { width: 52.67, height: 52 }
wide: { width: 62, height: 52 }
spaceline: { width: 142, height: 52 }
special: { width: 44, height: 52 }
views:
base:
- "ض ص ق ف غ ع ه خ ح ج"
- "ش س ی ب ل ا ت ن م ک"
- "Shift_L ظ ط ز ر ذ د و BackSpace"
- "show_numbers preferences space period Return"
upper:
- "پ { } [ ] ّ َ ِ ُ چ"
- "ؤ‌ ئ ي‌ إ أ آ ة‌ » « گ"
- "Shift_L ك ٓ ژ ء > < ؟ BackSpace"
- "show_numbers preferences space period Return"
numbers:
- "۱ ۲ ۳ ۴ ۵ ۶ ۷ ۸ ۹ ۰"
- "@ # ﷼ % & - _ + ( )"
- "show_symbols , \" ' colon ؛ ! ? BackSpace"
- "show_letters preferences space period Return"
symbols:
- "~ ` | · √ π τ ÷ × ¶"
- "© ® £ € ¥ ^ ° * { }"
- "show_numbers_from_symbols \\ / < > = [ ] BackSpace"
- "show_letters preferences space period Return"
buttons:
Shift_L:
action:
locking:
lock_view: "upper"
unlock_view: "base"
outline: "altline"
icon: "key-shift"
BackSpace:
outline: "altline"
icon: "edit-clear-symbolic"
action: erase
preferences:
action: show_prefs
outline: "special"
icon: "keyboard-mode-symbolic"
show_numbers:
action:
set_view: "numbers"
outline: "wide"
label: "123"
show_numbers_from_symbols:
action:
set_view: "numbers"
outline: "altline"
label: "123"
show_letters:
action:
set_view: "base"
outline: "wide"
label: "ABC"
show_symbols:
action:
set_view: "symbols"
outline: "altline"
label: "*/="
period:
outline: "special"
text: "."
space:
outline: "spaceline"
text: " "
Return:
outline: "wide"
icon: "key-enter"
keysym: "Return"
colon:
text: ":"

View File

@ -1,78 +0,0 @@
---
outlines:
default: { width: 54, height: 42 }
altline: { width: 81, height: 42 }
wide: { width: 108, height: 42 }
spaceline: { width: 216, height: 42 }
special: { width: 54, height: 42 }
views:
base:
- "ض ص ق ف غ ع ه خ ح ج"
- "ش س ی ب ل ا ت ن م ک"
- "Shift_L ظ ط ز ر ذ د و BackSpace"
- "show_numbers preferences space period Return"
upper:
- "پ { } [ ] ّ َ ِ ُ چ"
- "ؤ‌ ئ ي‌ إ أ آ ة‌ » « گ"
- "Shift_L ك ٓ ژ ء > < ؟ BackSpace"
- "show_numbers preferences space period Return"
numbers:
- "۱ ۲ ۳ ۴ ۵ ۶ ۷ ۸ ۹ ۰"
- "@ # ﷼ % & - _ + ( )"
- "show_symbols , \" ' colon ؛ ! ? BackSpace"
- "show_letters preferences space period Return"
symbols:
- "~ ` | · √ π τ ÷ × ¶"
- "© ® £ € ¥ ^ ° * { }"
- "show_numbers_from_symbols \\ / < > = [ ] BackSpace"
- "show_letters preferences space period Return"
buttons:
Shift_L:
action:
locking:
lock_view: "upper"
unlock_view: "base"
outline: "altline"
icon: "key-shift"
BackSpace:
outline: "altline"
icon: "edit-clear-symbolic"
action: "erase"
preferences:
action: "show_prefs"
outline: "special"
icon: "keyboard-mode-symbolic"
show_numbers:
action:
set_view: "numbers"
outline: "wide"
label: "123"
show_numbers_from_symbols:
action:
set_view: "numbers"
outline: "altline"
label: "123"
show_letters:
action:
set_view: "base"
outline: "wide"
label: "ABC"
show_symbols:
action:
set_view: "symbols"
outline: "altline"
label: "*/="
".":
outline: "special"
text: "."
space:
outline: "spaceline"
text: " "
Return:
outline: "wide"
icon: "key-enter"
keysym: "Return"
colon:
text: ":"

View File

@ -1,92 +0,0 @@
# Friulian layout created by Fabio Tomat
# 14 october 2020
---
outlines:
default: { width: 35.33, height: 52 }
altline: { width: 52.67, height: 52 }
wide: { width: 62, height: 52 }
spaceline: { width: 99.67, height: 52 }
special: { width: 44, height: 52 }
views:
base:
- "q w e r t y u i o p"
- "a s d f g h j k l"
- "Shift_L z x c v b n m BackSpace"
- "show_numbers show_eschars preferences space , . Return"
upper:
- "Q W E R T Y U I O P"
- "A S D F G H J K L"
- "Shift_L Z X C V B N M BackSpace"
- "show_numbers show_eschars preferences space “ ” Return"
numbers:
- "1 2 3 4 5 6 7 8 9 0"
- "@ # € % & - _ + ( )"
- "show_symbols , \" ' colon ; ! = BackSpace"
- "show_letters show_eschars preferences space ? . Return"
symbols:
- "~ ` | · √ π τ ÷ × ¶"
- "© ® £ $ ¥ ^ ° * { }"
- "show_numbers \\ / < > = [ ] BackSpace"
- "show_letters show_eschars preferences space ? . Return"
eschars:
- "â ê î ô û Â Ê Î Ô Û"
- "à è ì ò ù À È Ì Ò Ù"
- "show_numbers ç Ç ᶜ ᵐ ⁿ ᵉ ᵗ BackSpace"
- "show_letters show_eschars preferences space ᶠ . Return"
buttons:
Shift_L:
action:
locking:
lock_view: "upper"
unlock_view: "base"
outline: "altline"
icon: "key-shift"
BackSpace:
outline: "altline"
icon: "edit-clear-symbolic"
action: "erase"
preferences:
action: "show_prefs"
outline: "special"
icon: "keyboard-mode-symbolic"
show_numbers:
action:
set_view: "numbers"
outline: "altline"
label: "123"
show_numbers_from_symbols:
action:
set_view: "numbers"
outline: "altline"
label: "123"
show_letters:
action:
set_view: "base"
outline: "altline"
label: "abc"
show_symbols:
action:
set_view: "symbols"
outline: "altline"
label: "*/="
show_eschars:
action:
locking:
lock_view: "eschars"
unlock_view: "base"
outline: "altline"
label: "àê"
space:
outline: "spaceline"
label: " "
text: " "
Return:
outline: "altline"
icon: "key-enter"
keysym: "Return"
colon:
label: ":"
"\"":
keysym: "quotedbl"

View File

@ -2,9 +2,9 @@
outlines: outlines:
default: { width: 32, height: 52 } default: { width: 32, height: 52 }
altline: { width: 48.39024, height: 52 } altline: { width: 48.39024, height: 52 }
wide: { width: 64, height: 52 } wide: { width: 62, height: 52 }
spaceline: { width: 142, height: 52 } outline7: { width: 88.97561, height: 52 }
special: { width: 44, height: 52 } spaceline: { width: 150.5853, height: 52 }
views: views:
base: base:
@ -25,7 +25,7 @@ views:
symbols: symbols:
- "~ ` | U00B7 squareroot Greek_pi Greek_tau division multiply paragraph" - "~ ` | U00B7 squareroot Greek_pi Greek_tau division multiply paragraph"
- "copyright U00AE U00A3 EuroSign U00A5 asciicircum degree * { }" - "copyright U00AE U00A3 EuroSign U00A5 asciicircum degree * { }"
- "show_numbers_from_symbols \\ / < > = [ ] BackSpace" - "show_numbers \\ / < > = [ ] BackSpace"
- "show_letters preferences space . Return" - "show_letters preferences space . Return"
buttons: buttons:
@ -42,22 +42,17 @@ buttons:
action: erase action: erase
preferences: preferences:
action: "show_prefs" action: "show_prefs"
outline: "special" outline: "altline"
icon: "keyboard-mode-symbolic" icon: "keyboard-mode-symbolic"
show_numbers: show_numbers:
action: action:
set_view: "numbers" set_view: "numbers"
outline: "wide" outline: "altline"
label: "123"
show_numbers_from_symbols:
action:
set_view: "numbers"
outline: altline
label: "123" label: "123"
show_letters: show_letters:
action: action:
set_view: "base" set_view: "base"
outline: "wide" outline: "altline"
label: "ABC" label: "ABC"
show_symbols: show_symbols:
action: action:
@ -65,7 +60,7 @@ buttons:
outline: "altline" outline: "altline"
label: "*/=" label: "*/="
".": ".":
outline: "special" outline: altline
space: space:
outline: spaceline outline: spaceline
text: " " text: " "

View File

@ -1,80 +0,0 @@
---
outlines:
default: { width: 35.33, height: 52 }
altline: { width: 52.67, height: 52 }
wide: { width: 62, height: 52 }
spaceline: { width: 142, height: 52 }
special: { width: 44, height: 52 }
views:
base:
- "ๅ / _ ภ ถ ุ ึ ค ต จ ข ช"
- "ๆ ไ ำ พ ะ ั ี ร น ย บ ล"
- "ฟ ห ก ด เ ้ ่ า ส ว ง ฃ"
- "Shift_L ผ ป แ อ ิ ื ท ม ใ ฝ BackSpace"
- "show_numbers preferences space period Return"
upper:
- "+ ๑ ๒ ๓ ๔ ู ฿ ๕ ๖ ๗ ๘ ๙"
- " \" ฎ ฑ ธ ํ ๊ ณ ฯ ญ ฐ ,"
- "ฤ ฆ ฏ โ ฌ ็ ๋ ษ ศ ซ . ฅ"
- "Shift_L ( ) ฉ ฮ ฺ ์ ? ฒ ฬ ฦ BackSpace"
- "show_numbers preferences space period Return"
numbers:
- "1 2 3 4 5 6 7 8 9 0"
- "@ # $ % & - _ + ( )"
- "show_symbols , \" ' colon ; ! ? BackSpace"
- "show_letters preferences space period Return"
symbols:
- "~ ` | · √ π τ ÷ × ¶"
- "© ® £ € ¥ ^ ° * { }"
- "show_numbers_from_symbols \\ / < > = [ ] BackSpace"
- "show_letters preferences space period Return"
buttons:
Shift_L:
action:
locking:
lock_view: "upper"
unlock_view: "base"
outline: "altline"
icon: "key-shift"
BackSpace:
outline: "altline"
icon: "edit-clear-symbolic"
action: erase
preferences:
action: show_prefs
outline: "special"
icon: "keyboard-mode-symbolic"
show_numbers:
action:
set_view: "numbers"
outline: "wide"
label: "123"
show_numbers_from_symbols:
action:
set_view: "numbers"
outline: "altline"
label: "123"
show_letters:
action:
set_view: "base"
outline: "wide"
label: "กขค"
show_symbols:
action:
set_view: "symbols"
outline: "altline"
label: "*/="
period:
outline: "special"
text: "."
space:
outline: "spaceline"
text: " "
Return:
outline: "wide"
icon: "key-enter"
keysym: "Return"
colon:
text: ":"

View File

@ -1,78 +0,0 @@
---
outlines:
default: { width: 35.33, height: 52 }
altline: { width: 52.67, height: 52 }
wide: { width: 62, height: 52 }
spaceline: { width: 142, height: 52 }
special: { width: 44, height: 52 }
views:
base:
- "q w f p g j l u y"
- "a r s t d h n e i o"
- "Shift_L z x c v b k m BackSpace"
- "show_numbers preferences space period Return"
upper:
- "Q W F P G J L U Y"
- "A R S T D H N E I O"
- "Shift_L Z X C V B K M BackSpace"
- "show_numbers preferences space period Return"
numbers:
- "1 2 3 4 5 6 7 8 9 0"
- "@ # $ % & - _ + ( )"
- "show_symbols , \" ' colon ; ! ? BackSpace"
- "show_letters preferences space period Return"
symbols:
- "~ ` | · √ π τ ÷ × ¶"
- "© ® £ € ¥ ^ ° * { }"
- "show_numbers_from_symbols \\ / < > = [ ] BackSpace"
- "show_letters preferences space period Return"
buttons:
Shift_L:
action:
locking:
lock_view: "upper"
unlock_view: "base"
outline: "altline"
icon: "key-shift"
BackSpace:
outline: "altline"
icon: "edit-clear-symbolic"
action: erase
preferences:
action: show_prefs
outline: "special"
icon: "keyboard-mode-symbolic"
show_numbers:
action:
set_view: "numbers"
outline: "wide"
label: "123"
show_numbers_from_symbols:
action:
set_view: "numbers"
outline: "altline"
label: "123"
show_letters:
action:
set_view: "base"
outline: "wide"
label: "ABC"
show_symbols:
action:
set_view: "symbols"
outline: "altline"
label: "*/="
period:
outline: "special"
text: "."
space:
outline: "spaceline"
text: " "
Return:
outline: "wide"
icon: "key-enter"
keysym: "Return"
colon:
text: ":"

View File

@ -1,13 +0,0 @@
bg Български
de Немски
es Испански
emoji Емоджи
fi Френски
gr Гръцки
it Италянски
no Норевежки
pl Полски
ru Руски
se Шведски
terminal Терминал
us Английски (САЩ)

View File

@ -1,21 +0,0 @@
be Belgická
cz Česká
cz+qwerty Česká (QWERTY)
de Německá
dk Dánská
emoji Emoji
es Španělská
fi Finská
fr Francouzská
gr Řecká
it Italská
jp Japonská
jp+kana Japonská (Kana)
no Norská
pl Polská
ru Ruská
se Švédská
terminal Terminál
th Thajská
ua Ukrajinská
us Anglická (USA)

View File

@ -1,2 +0,0 @@
emoji ایموجی
terminal ترمینال

View File

@ -1,18 +0,0 @@
be Belgjic
br Brasilian
de Todesc
dk Danês
es Spagnûl
fi Finlandês
fr Francês
it+fur Furlan
gr Grêc
it Talian
jp+kana Gjaponês (Kana)
no Norvegjês
pl Polac
ru Rus
se Svedês
terminal Terminâl
ua Ucrain
us American (USA)

159
debian/changelog vendored
View File

@ -1,162 +1,3 @@
squeekboard (1.12.0pureos0~amber0) amber-phone; urgency=medium
[ Dorota Czaplejewicz ]
* docs: Correct Cargo update instructions
* visibility: Centralize keyboard panel visibility policy and handling
* build: Fix release
* tests: Prefer the env var for finding test layouts
* tests: Explicitly pass source directory to tests
* debian: Build reproducibly
* tests: Allow legacy mode to have much longer tests.
* build: Enable unused warnings in C
* build: Enable wformat to remove warnings about missing wformat
* build: Fail on any C warnings when strict
* data: Made data flow in fallback clearer
* data: Flattened layout fallback function
* layouts: Use base as fallback for alternative layouts
* layouts: Simplify the main flow of source list
* tests: Add some description to the list of tested layouts
* layout_names: Unmess the list of builtin layouts
* dbus: Reset hints if text input missing
* visibility: Stop calling GTK functions from the visibility manager
[ Wannaphong Phatthiyaphaibun ]
* Add thai keyboard
* Update resources.rs
* Update meson.build
* escape " on thai keyboard
[ clonex10100 ]
* Added US Colemak Keyboard Layout
[ Henry-Nicolas Tourneur ]
* d/rules: fix an FTBFS on mips64el with GOT > 64kb
* d/rules: export RUSTFLAGS only on architecture that needs it
* d/rules: export RUSTFLAGS only on architecture that needs it
[ Jiří Stránský ]
* Add Czech keyboard layouts
[ Stefan Grotz ]
* Esperanto keyboard
[ Vladimir ]
* Bulgarian language keyboard layout
[ Vladimir Stoilov ]
* bulgarian add translation and to needed lists
* Fix bulgarian layout size
[ Andreas Rönnquist ]
* no: Use wide button switching between numbers, symbols and base
[ jranaraki ]
* Farsi/Persian keyboard layout
* Farsi/Persian keyboard layout
* Added requirements to resources.rs and meson.build
* Updated the layout to provide more convenient and faster typing experience
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Sun, 10 Jan 2021 09:43:42 +0000
squeekboard (1.11.1) amber-phone; urgency=medium
[ Mark Müller ]
* keyboard: Fix semicolon in German layout
* keyboard: Move semicolon in German layout to numbers view replacing redundant comma key
[ Dorota Czaplejewicz ]
* imservice: Set up UI according to current needs when it shows up
* UI: Keep visibility factors in a central place
* cargo: Update deps
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Sat, 21 Nov 2020 11:08:06 +0000
squeekboard (1.11.0) amber-phone; urgency=medium
[ Dorota Czaplejewicz ]
* UI: Delay hiding only when leaving a text field
* ui: Cancel hiding delay when activity requested again
* Update dependencies
[ Fabio Tomat ]
* Update fur-IT.txt fix typo for Spanish
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Sat, 14 Nov 2020 06:46:28 +0000
squeekboard (1.10.0) amber-phone; urgency=medium
[ Dorota Czaplejewicz ]
* virtual_keyboard: Fix desynced modifiers state
* rust: Fix deprecation warnings
* docs: Tutorial syntax cleanups
* docs: Reorganize tutorial
* build: Error on repeating declarations
* keymap: Generate from symbol map, not layout
* data: Restore testability of action->keysym conversion
* syntax: Let older rustc understand symbolmap's lifetime
* debian: Insert a "breaks" for librem5-base < 24
* keymap: Keep keymap fd management in one place
* vkeyboard: Use a generic slice instead of a vector
* tests: Check for missing return in builtin layouts except emoji
* keymap: Concentrate special handling of BackSpace, which is implicit in Erase action
* keymaps: Use multiple key maps, each within the limit of what Xorg can accept.
* build: Avoid MaybeUninit on older Debian
* tests: Fix bad field access
* cargo: Update dependencies
[ Guido Günther ]
* eekboard-context-service: Return early if schema is unavailable
* treewide: Use new style function definitions
* build: Enable '-Wold-style-definition' '-Wstrict-prototypes'
* build: Enable '-Wunused-function'
* eekboard-context-service: Drop EEKBOARD_CONTEXT_SERVICE_GET_PRIVATE
* keyboard: Fix warning
* layout: Fix warning
* gitlab-ci: Enable --Werror
* eek-keyboard: Don't ignore return value
* build: Enable -Winit-self
* build: Enable -Wformat-security
* build: Enable -Wmaybe-uninitialized
* treewide: Drop redundant declarations
* build: Enable -Wredundant-declarations
* ServerContextService: Drop GObject boilerplate
* build: Enable '-Wformat-nonliteral'
* eekboad-context-service: Drop signal class handler
* eekboard-context-service: Drop docstrings for inexistent functions
* eekboard-context-service: Drop the GObject boilerplate
* eekboard-context-service: Drop private struct
* server-context-service: Consistenty name self argument 'self'
* server-context-service: swap signal arguments
* server-context-service: Don't show keyboard when disabled (Closes: #222)
[ Nazarii Kretovych ]
* Add Ukrainian keyboard layout.
[ Benjamin Schaaf ]
* Fix spelling mistakes in doc/hacking.md
* Expand the development documentation in the readme
* Expand key press detection to the edges of the view's bounding box
* Sort layouts by type before sorting by name
* Fix leak in level_keyboard_new
* Fix leak endlessly adding a resource path to the default theme
* Add settings option to popover
[ Al ]
* proposal for belgian layout (copy of fr)
* alphabetical order for src/resources.rs tests/meson.build
[ Arnaud Ferraris ]
* eek-gtk-keyboard: use virtual resolution to check arrangement kind
* server-context-service: optimize height calculation
* keyboards: add wide French layout
* keyboards: add wide Belgian layout
* keyboards: add wide terminal layout
[ Fabio Tomat ]
* Revert "Add friulian keyboard"
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Mon, 19 Oct 2020 14:07:01 +0000
squeekboard (1.9.3) amber-phone; urgency=medium squeekboard (1.9.3) amber-phone; urgency=medium
[ Björn Tantau ] [ Björn Tantau ]

1
debian/control vendored
View File

@ -26,7 +26,6 @@ Build-Depends:
librust-xkbcommon-0.4+wayland-dev (>= 0.4), librust-xkbcommon-0.4+wayland-dev (>= 0.4),
libwayland-dev (>= 1.16), libwayland-dev (>= 1.16),
lsb-release, lsb-release,
python3,
rustc, rustc,
wayland-protocols (>= 1.14), wayland-protocols (>= 1.14),
Standards-Version: 4.1.3 Standards-Version: 4.1.3

21
debian/rules vendored
View File

@ -2,27 +2,6 @@
export CARGO_HOME = $(CURDIR)/debian/cargo export CARGO_HOME = $(CURDIR)/debian/cargo
export DEB_BUILD_MAINT_OPTIONS = hardening=+all export DEB_BUILD_MAINT_OPTIONS = hardening=+all
# the below avoids an FTBFS on mips64el with a GOT > 64kb
DEB_HOST_ARCH := $(shell dpkg-architecture -qDEB_HOST_ARCH)
ifeq ($(DEB_HOST_ARCH),mips64el)
export RUSTFLAGS = -Ctarget-feature=+xgot
endif
# the below avoids an FTBFS on mips64el with a GOT > 64kb
DEB_HOST_ARCH := $(shell dpkg-architecture -qDEB_HOST_ARCH)
ifeq ($(DEB_HOST_ARCH),mips64el)
xgot = -Ctarget-feature=+xgot
else
xgot =
endif
# Don't use paths that may change between builds.
# No need to care about $HOME
# because Cargo will not place any source in ~/.cargo.
# The build directory is a subdirectory of the source directory,
# so it doesn't need to be explicitly taken care of.
export RUSTFLAGS = --remap-path-prefix=$(CURDIR)=/remap-pwd $(xgot)
distrel := $(shell lsb_release --codename --short) distrel := $(shell lsb_release --codename --short)
ifneq (,$(filter $(distrel),buster amber)) ifneq (,$(filter $(distrel),buster amber))

View File

@ -113,7 +113,7 @@ User interface modules should:
Code submitted should roughly match the style of surrounding code. Things that will *not* be accepted are ones that often lead to errors: Code submitted should roughly match the style of surrounding code. Things that will *not* be accepted are ones that often lead to errors:
- skipping brackets `{}` after every `if()`, `else`, and similar ([SCI CERT C: EXP19-C](https://wiki.sei.cmu.edu/confluence/display/c/EXP19-C.+Use+braces+for+the+body+of+an+if%2C+for%2C+or+while+statement)) - skipping brackets `{}` after every `if()`, `else`, and similar
Bad example: Bad example:
@ -179,10 +179,7 @@ Dependencies must be specified in `Cargo.toml` with 2 numbers: "major.minor". Si
``` ```
cd build_dir cd build_dir
ninja ./Cargo.toml ninja build src/Cargo.toml
sh /source_path/cargo.sh update sh /source_path/cargo.sh update
ninja test ninja test
cp ./Cargo.lock /source_path/
``` ```
Since version 1.9.3, `Cargo.lock` is not actually used by the build system, due to `Cargo.toml` being generated at every build.

View File

@ -129,12 +129,11 @@ eek_gtk_keyboard_real_size_allocate (GtkWidget *self,
eekboard_context_service_use_layout(priv->eekboard_context, priv->layout, time); eekboard_context_service_use_layout(priv->eekboard_context, priv->layout, time);
} }
if (priv->renderer) { if (priv->renderer)
eek_renderer_set_allocation_size (priv->renderer, eek_renderer_set_allocation_size (priv->renderer,
priv->keyboard->layout, priv->keyboard->layout,
allocation->width, allocation->width,
allocation->height); allocation->height);
}
GTK_WIDGET_CLASS (eek_gtk_keyboard_parent_class)-> GTK_WIDGET_CLASS (eek_gtk_keyboard_parent_class)->
size_allocate (self, allocation); size_allocate (self, allocation);
@ -356,11 +355,10 @@ eek_gtk_keyboard_init (EekGtkKeyboard *self)
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self)); EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (EEK_GTK_KEYBOARD (self));
g_autoptr(GError) err = NULL; g_autoptr(GError) err = NULL;
if (lfb_init(SQUEEKBOARD_APP_ID, &err)) { if (lfb_init(SQUEEKBOARD_APP_ID, &err))
priv->event = lfb_event_new ("button-pressed"); priv->event = lfb_event_new ("button-pressed");
} else { else
g_warning ("Failed to init libfeedback: %s", err->message); g_warning ("Failed to init libfeedback: %s", err->message);
}
GtkIconTheme *theme = gtk_icon_theme_get_default (); GtkIconTheme *theme = gtk_icon_theme_get_default ();

View File

@ -28,12 +28,19 @@
#include <sys/random.h> // TODO: this is Linux-specific #include <sys/random.h> // TODO: this is Linux-specific
#include <xkbcommon/xkbcommon.h> #include <xkbcommon/xkbcommon.h>
#include "eek-keyboard.h" #include "eek-keyboard.h"
/// External linkage for Rust.
/// The corresponding deinit is implemented in vkeyboard::KeyMap::drop static void eek_key_map_deinit(struct keymap *self) {
struct keymap squeek_key_map_from_str(const char *keymap_str) { if (self->fd < 0) {
g_error("Deinit called multiple times on KeyMap");
} else {
close(self->fd);
}
self->fd = -1;
}
static struct keymap eek_key_map_from_str(const char *keymap_str) {
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
if (!context) { if (!context) {
g_error("No context created"); g_error("No context created");
@ -42,9 +49,8 @@ struct keymap squeek_key_map_from_str(const char *keymap_str) {
struct xkb_keymap *keymap = xkb_keymap_new_from_string(context, keymap_str, struct xkb_keymap *keymap = xkb_keymap_new_from_string(context, keymap_str,
XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS); XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
if (!keymap) { if (!keymap)
g_error("Bad keymap:\n%s", keymap_str); g_error("Bad keymap:\n%s", keymap_str);
}
xkb_context_unref(context); xkb_context_unref(context);
@ -53,9 +59,8 @@ struct keymap squeek_key_map_from_str(const char *keymap_str) {
g_autofree char *path = strdup("/eek_keymap-XXXXXX"); g_autofree char *path = strdup("/eek_keymap-XXXXXX");
char *r = &path[strlen(path) - 6]; char *r = &path[strlen(path) - 6];
if (getrandom(r, 6, GRND_NONBLOCK) < 0) { if (getrandom(r, 6, GRND_NONBLOCK) < 0)
g_error("Failed to get random numbers: %s", strerror(errno)); g_error("Failed to get random numbers: %s", strerror(errno));
}
for (unsigned i = 0; i < 6; i++) { for (unsigned i = 0; i < 6; i++) {
r[i] = (r[i] & 0b1111111) | 0b1000000; // A-z r[i] = (r[i] & 0b1111111) | 0b1000000; // A-z
r[i] = r[i] > 'z' ? '?' : r[i]; // The randomizer doesn't need to be good... r[i] = r[i] > 'z' ? '?' : r[i]; // The randomizer doesn't need to be good...
@ -86,6 +91,7 @@ struct keymap squeek_key_map_from_str(const char *keymap_str) {
} }
void level_keyboard_free(LevelKeyboard *self) { void level_keyboard_free(LevelKeyboard *self) {
eek_key_map_deinit(&self->keymap);
squeek_layout_free(self->layout); squeek_layout_free(self->layout);
g_free(self); g_free(self);
} }
@ -98,5 +104,7 @@ level_keyboard_new (struct squeek_layout *layout)
g_error("Failed to create a keyboard"); g_error("Failed to create a keyboard");
} }
keyboard->layout = layout; keyboard->layout = layout;
const gchar *keymap_str = squeek_layout_get_keymap(keyboard->layout);
keyboard->keymap = eek_key_map_from_str(keymap_str);
return keyboard; return keyboard;
} }

View File

@ -41,7 +41,7 @@ struct keymap {
/// Keyboard state holder /// Keyboard state holder
struct _LevelKeyboard { struct _LevelKeyboard {
struct squeek_layout *layout; // owned struct squeek_layout *layout; // owned
// FIXME: This no longer needs to exist, keymap was folded into layout. struct keymap keymap; // owned
}; };
typedef struct _LevelKeyboard LevelKeyboard; typedef struct _LevelKeyboard LevelKeyboard;

View File

@ -590,33 +590,28 @@ phosh_layer_surface_set_size(PhoshLayerSurface *self, gint width, gint height)
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self)); g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
priv = phosh_layer_surface_get_instance_private (self); priv = phosh_layer_surface_get_instance_private (self);
if (priv->height == height && priv->width == width) { if (priv->height == height && priv->width == width)
return; return;
}
old_width = priv->width; old_width = priv->width;
old_height = priv->height; old_height = priv->height;
if (width != -1) { if (width != -1)
priv->width = width; priv->width = width;
}
if (height != -1) { if (height != -1)
priv->height = height; priv->height = height;
}
if (gtk_widget_get_mapped (GTK_WIDGET (self))) { if (gtk_widget_get_mapped (GTK_WIDGET (self))) {
zwlr_layer_surface_v1_set_size(priv->layer_surface, priv->width, priv->height); zwlr_layer_surface_v1_set_size(priv->layer_surface, priv->width, priv->height);
} }
if (priv->height != old_height) { if (priv->height != old_height)
g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT]); g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_LAYER_HEIGHT]);
}
if (priv->width != old_width) { if (priv->width != old_width)
g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH]); g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_LAYER_WIDTH]);
} }
}
/** /**
* phosh_layer_surface_set_margins: * phosh_layer_surface_set_margins:
@ -637,32 +632,26 @@ phosh_layer_surface_set_margins(PhoshLayerSurface *self, gint top, gint right, g
old_right = priv->margin_right; old_right = priv->margin_right;
old_bottom = priv->margin_bottom; old_bottom = priv->margin_bottom;
if (old_top == top && old_left == left && old_right == right && old_bottom == bottom) { if (old_top == top && old_left == left && old_right == right && old_bottom == bottom)
return; return;
}
priv->margin_top = top; priv->margin_top = top;
priv->margin_left = left; priv->margin_left = left;
priv->margin_right = right; priv->margin_right = right;
priv->margin_bottom = bottom; priv->margin_bottom = bottom;
if (priv->layer_surface) { if (priv->layer_surface)
zwlr_layer_surface_v1_set_margin(priv->layer_surface, top, right, bottom, left); zwlr_layer_surface_v1_set_margin(priv->layer_surface, top, right, bottom, left);
}
if (old_top != top) { if (old_top != top)
g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_MARGIN_TOP]); g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_MARGIN_TOP]);
} if (old_bottom != bottom)
if (old_bottom != bottom) {
g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_MARGIN_BOTTOM]); g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_MARGIN_BOTTOM]);
} if (old_left != left)
if (old_left != left) {
g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_MARGIN_LEFT]); g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_MARGIN_LEFT]);
} if (old_right != right)
if (old_right != right) {
g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_MARGIN_RIGHT]); g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_MARGIN_RIGHT]);
} }
}
/** /**
* phosh_layer_surface_set_exclusive_zone: * phosh_layer_surface_set_exclusive_zone:
@ -680,15 +669,13 @@ phosh_layer_surface_set_exclusive_zone(PhoshLayerSurface *self, gint zone)
old_zone = priv->exclusive_zone; old_zone = priv->exclusive_zone;
if (old_zone == zone) { if (old_zone == zone)
return; return;
}
priv->exclusive_zone = zone; priv->exclusive_zone = zone;
if (priv->layer_surface) { if (priv->layer_surface)
zwlr_layer_surface_v1_set_exclusive_zone(priv->layer_surface, zone); zwlr_layer_surface_v1_set_exclusive_zone(priv->layer_surface, zone);
}
g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_EXCLUSIVE_ZONE]); g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_EXCLUSIVE_ZONE]);
} }
@ -706,14 +693,13 @@ phosh_layer_surface_set_kbd_interactivity (PhoshLayerSurface *self, gboolean int
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self)); g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
priv = phosh_layer_surface_get_instance_private (self); priv = phosh_layer_surface_get_instance_private (self);
if (priv->kbd_interactivity == interactivity) { if (priv->kbd_interactivity == interactivity)
return; return;
}
priv->kbd_interactivity = interactivity; priv->kbd_interactivity = interactivity;
if (priv->layer_surface) { if (priv->layer_surface)
zwlr_layer_surface_v1_set_keyboard_interactivity (priv->layer_surface, interactivity); zwlr_layer_surface_v1_set_keyboard_interactivity (priv->layer_surface, interactivity);
}
g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_KBD_INTERACTIVITY]); g_object_notify_by_pspec (G_OBJECT (self), props[PHOSH_LAYER_SURFACE_PROP_KBD_INTERACTIVITY]);
} }
@ -731,7 +717,6 @@ phosh_layer_surface_wl_surface_commit (PhoshLayerSurface *self)
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self)); g_return_if_fail (PHOSH_IS_LAYER_SURFACE (self));
priv = phosh_layer_surface_get_instance_private (self); priv = phosh_layer_surface_get_instance_private (self);
if (priv->wl_surface) { if (priv->wl_surface)
wl_surface_commit (priv->wl_surface); wl_surface_commit (priv->wl_surface);
} }
}

View File

@ -159,7 +159,7 @@ eekboard_context_service_use_layout(EekboardContextService *context, struct sque
// Update the keymap if necessary. // Update the keymap if necessary.
// TODO: Update submission on change event // TODO: Update submission on change event
if (context->submission) { if (context->submission) {
submission_use_layout(context->submission, keyboard->layout, timestamp); submission_set_keyboard(context->submission, keyboard, timestamp);
} }
// Update UI // Update UI
@ -345,7 +345,7 @@ void eekboard_context_service_set_submission(EekboardContextService *context, st
context->submission = submission; context->submission = submission;
if (context->submission) { if (context->submission) {
uint32_t time = gdk_event_get_time(NULL); uint32_t time = gdk_event_get_time(NULL);
submission_use_layout(context->submission, context->keyboard->layout, time); submission_set_keyboard(context->submission, context->keyboard, time);
} }
} }

View File

@ -1,7 +1,7 @@
project( project(
'squeekboard', 'squeekboard',
'c', 'rust', 'c', 'rust',
version: '1.12.0', version: '1.9.3',
license: 'GPLv3', license: 'GPLv3',
meson_version: '>=0.51.0', meson_version: '>=0.51.0',
default_options: [ default_options: [
@ -20,16 +20,14 @@ add_project_arguments(
'-Werror=incompatible-pointer-types', '-Werror=incompatible-pointer-types',
'-Werror=int-conversion', '-Werror=int-conversion',
'-Werror=redundant-decls', '-Werror=redundant-decls',
'-Werror=parentheses',
'-Wformat-nonliteral', '-Wformat-nonliteral',
'-Wformat-security', '-Wformat-security',
'-Wformat',
'-Winit-self', '-Winit-self',
'-Wmaybe-uninitialized', '-Wmaybe-uninitialized',
'-Wold-style-definition', '-Wold-style-definition',
'-Wredundant-decls', '-Wredundant-decls',
'-Wstrict-prototypes', '-Wstrict-prototypes',
'-Wunused', '-Wunused-function',
], ],
language: 'c' language: 'c'
) )
@ -41,16 +39,6 @@ conf_data = configuration_data()
if get_option('buildtype').startswith('debug') if get_option('buildtype').startswith('debug')
add_project_arguments('-DDEBUG=1', language : 'c') add_project_arguments('-DDEBUG=1', language : 'c')
endif endif
if get_option('strict')
add_project_arguments(
[
'-Werror',
],
language: 'c'
)
endif
if get_option('buildtype') != 'plain' if get_option('buildtype') != 'plain'
add_project_arguments('-fstack-protector-strong', language: 'c') add_project_arguments('-fstack-protector-strong', language: 'c')
endif endif
@ -83,7 +71,6 @@ summary = [
message('\n'.join(summary)) message('\n'.join(summary))
# Rust deps are changing, depending on compile flags. Cargo can't handle it alone. # Rust deps are changing, depending on compile flags. Cargo can't handle it alone.
# As a side effect, Cargo.toml never gets used.
cargo_toml_in = files('Cargo.toml.in') cargo_toml_in = files('Cargo.toml.in')
path_data = configuration_data() path_data = configuration_data()
path_data.set('path', meson.source_root()) path_data.set('path', meson.source_root())
@ -97,7 +84,7 @@ cargo_toml_base = configure_file(
cargo_deps = files('Cargo.deps') cargo_deps = files('Cargo.deps')
if get_option('legacy') == true if get_option('legacy') == true
cargo_build_flags += ['--features', 'gtk_v0_5,gio_v0_5,rustc_less_1_36'] cargo_build_flags += ['--features', 'gtk_v0_5,gio_v0_5']
cargo_deps = files('Cargo.deps.legacy') cargo_deps = files('Cargo.deps.legacy')
endif endif
@ -111,7 +98,7 @@ cargo_toml = custom_target(
dep_cargo = find_program('cargo') dep_cargo = find_program('cargo')
cargo_script = find_program('cargo.sh') cargo_script = find_program('cargo.sh')
cargo_build = find_program('cargo_build.py') cargo_build = find_program('cargo_build.sh')
subdir('data') subdir('data')
subdir('protocols') subdir('protocols')

View File

@ -10,7 +10,3 @@ option('tests',
option('legacy', option('legacy',
type: 'boolean', value: false, type: 'boolean', value: false,
description: 'Build with Deban Buster versions of dependencies') description: 'Build with Deban Buster versions of dependencies')
option('strict',
type: 'boolean', value: true,
description: 'Turn more warnings into errors')

View File

@ -18,7 +18,7 @@ use xkbcommon::xkb;
use ::action; use ::action;
use ::keyboard::{ use ::keyboard::{
KeyState, PressType, KeyState, PressType,
generate_keymaps, generate_keycodes, KeyCode, FormattingError generate_keymap, generate_keycodes, FormattingError
}; };
use ::layout; use ::layout;
use ::layout::ArrangementKind; use ::layout::ArrangementKind;
@ -97,8 +97,6 @@ impl fmt::Display for DataSource {
} }
} }
type LayoutSource = (ArrangementKind, DataSource);
/// Lists possible sources, with 0 as the most preferred one /// Lists possible sources, with 0 as the most preferred one
/// Trying order: native lang of the right kind, native base, /// Trying order: native lang of the right kind, native base,
/// fallback lang of the right kind, fallback base /// fallback lang of the right kind, fallback base
@ -106,13 +104,19 @@ fn list_layout_sources(
name: &str, name: &str,
kind: ArrangementKind, kind: ArrangementKind,
keyboards_path: Option<PathBuf>, keyboards_path: Option<PathBuf>,
) -> Vec<LayoutSource> { ) -> Vec<(ArrangementKind, DataSource)> {
// Just a simplification of often called code. let mut ret = Vec::new();
let add_by_name = | {
mut ret: Vec<LayoutSource>, fn name_with_arrangement(name: String, kind: &ArrangementKind)
name: &str, -> String
kind: &ArrangementKind, {
| -> Vec<LayoutSource> { match kind {
ArrangementKind::Base => name,
ArrangementKind::Wide => name + "_wide",
}
}
let mut add_by_name = |name: &str, kind: &ArrangementKind| {
if let Some(path) = keyboards_path.clone() { if let Some(path) = keyboards_path.clone() {
ret.push(( ret.push((
kind.clone(), kind.clone(),
@ -126,57 +130,30 @@ fn list_layout_sources(
kind.clone(), kind.clone(),
DataSource::Resource(name.into()) DataSource::Resource(name.into())
)); ));
ret
}; };
// Another grouping. match &kind {
let add_by_kind = |ret, name: &str, kind| { ArrangementKind::Base => {},
let ret = match kind {
&ArrangementKind::Base => ret,
kind => add_by_name( kind => add_by_name(
ret, &name_with_arrangement(name.into(), &kind),
&name_with_arrangement(name.into(), kind), &kind,
kind,
), ),
}; };
add_by_name(ret, name, &ArrangementKind::Base) add_by_name(name, &ArrangementKind::Base);
match &kind {
ArrangementKind::Base => {},
kind => add_by_name(
&name_with_arrangement(FALLBACK_LAYOUT_NAME.into(), &kind),
&kind,
),
}; };
fn name_with_arrangement(name: String, kind: &ArrangementKind) -> String { add_by_name(FALLBACK_LAYOUT_NAME, &ArrangementKind::Base);
match kind {
ArrangementKind::Base => name,
ArrangementKind::Wide => name + "_wide",
} }
}
let ret = Vec::new();
// Name as given takes priority.
let ret = add_by_kind(ret, name, &kind);
// Then try non-alternative name if applicable (`us` for `us+colemak`).
let ret = {
let mut parts = name.splitn(2, '+');
match parts.next() {
Some(base) => {
// The name is already equal to base, so it was already added.
if base == name { ret }
else {
add_by_kind(ret, base, &kind)
}
},
// The layout's base name starts with a "+". Weird but OK.
None => {
log_print!(logging::Level::Surprise, "Base layout name is empty: {}", name);
ret ret
} }
}
};
// No other choices left, so give anything.
add_by_kind(ret, FALLBACK_LAYOUT_NAME.into(), &kind)
}
fn load_layout_data(source: DataSource) fn load_layout_data(source: DataSource)
-> Result<::layout::LayoutData, LoadError> -> Result<::layout::LayoutData, LoadError>
@ -405,7 +382,7 @@ impl Layout {
) )
)}).collect(); )}).collect();
let symbolmap: HashMap<String, KeyCode> = generate_keycodes( let symbolmap: HashMap<String, u32> = generate_keycodes(
extract_symbol_names(&button_actions) extract_symbol_names(&button_actions)
); );
@ -414,7 +391,7 @@ impl Layout {
let keycodes = match &action { let keycodes = match &action {
::action::Action::Submit { text: _, keys } => { ::action::Action::Submit { text: _, keys } => {
keys.iter().map(|named_keysym| { keys.iter().map(|named_keysym| {
symbolmap.get(named_keysym.0.as_str()) *symbolmap.get(named_keysym.0.as_str())
.expect( .expect(
format!( format!(
"keysym {} in key {} missing from symbol map", "keysym {} in key {} missing from symbol map",
@ -422,13 +399,11 @@ impl Layout {
name name
).as_str() ).as_str()
) )
.clone()
}).collect() }).collect()
}, },
action::Action::Erase => vec![ action::Action::Erase => vec![
symbolmap.get("BackSpace") *symbolmap.get("BackSpace")
.expect(&format!("BackSpace missing from symbol map")) .expect(&format!("BackSpace missing from symbol map")),
.clone(),
], ],
_ => Vec::new(), _ => Vec::new(),
}; };
@ -443,7 +418,7 @@ impl Layout {
}) })
); );
let keymaps = match generate_keymaps(symbolmap) { let keymap_str = match generate_keymap(symbolmap) {
Err(e) => { return (Err(e), warning_handler) }, Err(e) => { return (Err(e), warning_handler) },
Ok(v) => v, Ok(v) => v,
}; };
@ -507,10 +482,10 @@ impl Layout {
( (
Ok(::layout::LayoutData { Ok(::layout::LayoutData {
views: views, views: views,
keymaps: keymaps.into_iter().map(|keymap_str| keymap_str: {
CString::new(keymap_str) CString::new(keymap_str)
.expect("Invalid keymap string generated") .expect("Invalid keymap string generated")
).collect(), },
// FIXME: use a dedicated field // FIXME: use a dedicated field
margins: layout::Margins { margins: layout::Margins {
top: self.margins.top, top: self.margins.top,
@ -747,20 +722,19 @@ fn create_button<H: logging::Handler>(
} }
fn extract_symbol_names<'a>(actions: &'a [(&str, action::Action)]) fn extract_symbol_names<'a>(actions: &'a [(&str, action::Action)])
-> impl Iterator<Item=String> + 'a -> impl Iterator<Item=&'a str>
{ {
actions.iter() actions.iter()
.filter_map(|(_name, act)| { .filter_map(|(_name, act)| {
match act { match act {
action::Action::Submit { action::Action::Submit {
text: _, keys, text: _, keys,
} => Some(keys.clone()), } => Some(keys),
action::Action::Erase => Some(vec!(action::KeySym("BackSpace".into()))),
_ => None, _ => None,
} }
}) })
.flatten() .flatten()
.map(|named_keysym| named_keysym.0) .map(|named_keysym| named_keysym.0.as_str())
} }
#[cfg(test)] #[cfg(test)]
@ -769,21 +743,13 @@ mod tests {
use ::logging::ProblemPanic; use ::logging::ProblemPanic;
const THIS_FILE: &str = file!();
fn path_from_root(file: &'static str) -> PathBuf { fn path_from_root(file: &'static str) -> PathBuf {
let source_dir = env::var("SOURCE_DIR") PathBuf::from(THIS_FILE)
.map(PathBuf::from)
.unwrap_or_else(|e| {
if let env::VarError::NotPresent = e {
let this_file = file!();
PathBuf::from(this_file)
.parent().unwrap() .parent().unwrap()
.parent().unwrap() .parent().unwrap()
.into() .join(file)
} else {
panic!("{:?}", e);
}
});
source_dir.join(file)
} }
#[test] #[test]
@ -909,7 +875,7 @@ mod tests {
assert_eq!( assert_eq!(
out.views["base"].1 out.views["base"].1
.get_rows()[0].1 .get_rows()[0].1
.get_buttons()[0].1 .buttons[0].1
.state.borrow() .state.borrow()
.keycodes.len(), .keycodes.len(),
1 1
@ -941,25 +907,6 @@ mod tests {
); );
} }
/// If layout contains a "+", it should reach for what's in front of it too.
#[test]
fn fallbacks_order_base() {
let sources = list_layout_sources("nb+aliens", ArrangementKind::Base, None);
assert_eq!(
sources,
vec!(
(ArrangementKind::Base, DataSource::Resource("nb+aliens".into())),
(ArrangementKind::Base, DataSource::Resource("nb".into())),
(
ArrangementKind::Base,
DataSource::Resource(FALLBACK_LAYOUT_NAME.into())
),
)
);
}
#[test] #[test]
fn unicode_keysym() { fn unicode_keysym() {
let keysym = xkb::keysym_from_name( let keysym = xkb::keysym_from_name(
@ -1039,7 +986,7 @@ mod tests {
)]; )];
assert_eq!( assert_eq!(
extract_symbol_names(&actions[..]).collect::<Vec<_>>(), extract_symbol_names(&actions[..]).collect::<Vec<_>>(),
vec!["BackSpace"], Vec::<&str>::new(), //"BackSpace"], // TODO: centralize handling of BackSpace
); );
} }

View File

@ -59,7 +59,7 @@ handle_set_visible(SmPuriOSK0 *object, GDBusMethodInvocation *invocation,
if (service->context) { if (service->context) {
if (arg_visible) { if (arg_visible) {
server_context_service_force_show_keyboard (service->context); server_context_service_show_keyboard (service->context);
} else { } else {
server_context_service_hide_keyboard (service->context); server_context_service_hide_keyboard (service->context);
} }

View File

@ -25,7 +25,6 @@ static const struct zwp_input_method_v2_listener input_method_listener = {
struct submission* get_submission(struct zwp_input_method_manager_v2 *immanager, struct submission* get_submission(struct zwp_input_method_manager_v2 *immanager,
struct zwp_virtual_keyboard_manager_v1 *vkmanager, struct zwp_virtual_keyboard_manager_v1 *vkmanager,
struct vis_manager *vis_manager,
struct wl_seat *seat, struct wl_seat *seat,
EekboardContextService *state) { EekboardContextService *state) {
struct zwp_input_method_v2 *im = NULL; struct zwp_input_method_v2 *im = NULL;
@ -36,7 +35,7 @@ struct submission* get_submission(struct zwp_input_method_manager_v2 *immanager,
if (vkmanager) { if (vkmanager) {
vk = zwp_virtual_keyboard_manager_v1_create_virtual_keyboard(vkmanager, seat); vk = zwp_virtual_keyboard_manager_v1_create_virtual_keyboard(vkmanager, seat);
} }
return submission_new(im, vk, state, vis_manager); return submission_new(im, vk, state);
} }
/// Un-inlined /// Un-inlined

View File

@ -23,7 +23,7 @@ pub mod c {
use std::os::raw::{c_char, c_void}; use std::os::raw::{c_char, c_void};
pub use ::ui_manager::c::UIManager; pub use ::submission::c::UIManager;
pub use ::submission::c::StateManager; pub use ::submission::c::StateManager;
// The following defined in C // The following defined in C
@ -41,6 +41,8 @@ pub mod c {
pub fn eek_input_method_delete_surrounding_text(im: *mut InputMethod, before: u32, after: u32); pub fn eek_input_method_delete_surrounding_text(im: *mut InputMethod, before: u32, after: u32);
pub fn eek_input_method_commit(im: *mut InputMethod, serial: u32); pub fn eek_input_method_commit(im: *mut InputMethod, serial: u32);
fn eekboard_context_service_set_hint_purpose(state: *const StateManager, hint: u32, purpose: u32); fn eekboard_context_service_set_hint_purpose(state: *const StateManager, hint: u32, purpose: u32);
fn server_context_service_show_keyboard(imservice: *const UIManager);
fn server_context_service_hide_keyboard(imservice: *const UIManager);
} }
// The following defined in Rust. TODO: wrap naked pointers to Rust data inside RefCells to prevent multiple writers // The following defined in Rust. TODO: wrap naked pointers to Rust data inside RefCells to prevent multiple writers
@ -52,7 +54,7 @@ pub mod c {
im: *const InputMethod) im: *const InputMethod)
{ {
let imservice = check_imservice(imservice, im).unwrap(); let imservice = check_imservice(imservice, im).unwrap();
imservice.preedit_string = String::new(); imservice.preedit_string = String::new(); // I don't think this is ever used. Remove it?
imservice.pending = IMProtocolState { imservice.pending = IMProtocolState {
active: true, active: true,
..IMProtocolState::default() ..IMProtocolState::default()
@ -82,7 +84,7 @@ pub mod c {
surrounding_text: into_cstring(text) surrounding_text: into_cstring(text)
.expect("Received invalid string") .expect("Received invalid string")
.expect("Received null string"), .expect("Received null string"),
surrounding_cursor: cursor, cursor,
..imservice.pending.clone() ..imservice.pending.clone()
}; };
} }
@ -144,14 +146,12 @@ pub mod c {
let active_changed = imservice.current.active ^ imservice.pending.active; let active_changed = imservice.current.active ^ imservice.pending.active;
imservice.current = imservice.pending.clone(); imservice.current = imservice.pending.clone();
imservice.pending = IMProtocolState {
active: imservice.current.active,
..IMProtocolState::default()
};
if active_changed { if active_changed {
(imservice.active_callback)(imservice.current.active);
if imservice.current.active { if imservice.current.active {
if let Some(ui) = imservice.ui_manager {
unsafe { server_context_service_show_keyboard(ui); }
}
unsafe { unsafe {
eekboard_context_service_set_hint_purpose( eekboard_context_service_set_hint_purpose(
imservice.state_manager, imservice.state_manager,
@ -159,6 +159,10 @@ pub mod c {
imservice.current.content_purpose.clone() as u32, imservice.current.content_purpose.clone() as u32,
); );
} }
} else {
if let Some(ui) = imservice.ui_manager {
unsafe { server_context_service_hide_keyboard(ui); }
}
} }
} }
} }
@ -176,7 +180,9 @@ pub mod c {
// the keyboard is already decommissioned // the keyboard is already decommissioned
imservice.current.active = false; imservice.current.active = false;
(imservice.active_callback)(imservice.current.active); if let Some(ui) = imservice.ui_manager {
unsafe { server_context_service_hide_keyboard(ui); }
}
} }
// FIXME: destroy and deallocate // FIXME: destroy and deallocate
@ -304,7 +310,7 @@ impl TryFrom<u32> for ChangeCause {
#[derive(Clone)] #[derive(Clone)]
struct IMProtocolState { struct IMProtocolState {
surrounding_text: CString, surrounding_text: CString,
surrounding_cursor: u32, cursor: u32,
content_purpose: ContentPurpose, content_purpose: ContentPurpose,
content_hint: ContentHint, content_hint: ContentHint,
text_change_cause: ChangeCause, text_change_cause: ChangeCause,
@ -315,7 +321,7 @@ impl Default for IMProtocolState {
fn default() -> IMProtocolState { fn default() -> IMProtocolState {
IMProtocolState { IMProtocolState {
surrounding_text: CString::default(), surrounding_text: CString::default(),
surrounding_cursor: 0, // TODO: mark that there's no cursor cursor: 0, // TODO: mark that there's no cursor
content_hint: ContentHint::NONE, content_hint: ContentHint::NONE,
content_purpose: ContentPurpose::Normal, content_purpose: ContentPurpose::Normal,
text_change_cause: ChangeCause::InputMethod, text_change_cause: ChangeCause::InputMethod,
@ -329,11 +335,12 @@ pub struct IMService {
pub im: *mut c::InputMethod, pub im: *mut c::InputMethod,
/// Unowned reference. Be careful, it's shared with C at large /// Unowned reference. Be careful, it's shared with C at large
state_manager: *const c::StateManager, state_manager: *const c::StateManager,
active_callback: Box<dyn Fn(bool)>, /// Unowned reference. Be careful, it's shared with C at large
pub ui_manager: Option<*const c::UIManager>,
pending: IMProtocolState, pending: IMProtocolState,
current: IMProtocolState, // turn current into an idiomatic representation? current: IMProtocolState, // turn current into an idiomatic representation?
preedit_string: String, preedit_string: String, // I don't think this is ever used. Remove it?
serial: Wrapping<u32>, serial: Wrapping<u32>,
} }
@ -346,17 +353,16 @@ impl IMService {
pub fn new( pub fn new(
im: *mut c::InputMethod, im: *mut c::InputMethod,
state_manager: *const c::StateManager, state_manager: *const c::StateManager,
active_callback: Box<dyn Fn(bool)>,
) -> Box<IMService> { ) -> Box<IMService> {
// IMService will be referenced to by C, // IMService will be referenced to by C,
// so it needs to stay in the same place in memory via Box // so it needs to stay in the same place in memory via Box
let imservice = Box::new(IMService { let imservice = Box::new(IMService {
im, im,
active_callback, ui_manager: None,
state_manager, state_manager,
pending: IMProtocolState::default(), pending: IMProtocolState::default(),
current: IMProtocolState::default(), current: IMProtocolState::default(),
preedit_string: String::new(), preedit_string: String::new(), // I don't think this is ever used. Remove it?
serial: Wrapping(0u32), serial: Wrapping(0u32),
}); });
unsafe { unsafe {
@ -368,9 +374,14 @@ impl IMService {
imservice imservice
} }
pub fn commit_string(&self, text: &CString) -> Result<(), SubmitError> { pub fn commit_string(&mut self, text: &CString) -> Result<(), SubmitError> {
match self.current.active { match self.current.active {
true => { true => {
let cursor_position = self.pending.cursor.try_into().unwrap(); // Converts u32 of cursor to usize
self.pending
.surrounding_text
.insert_str(cursor_position, text);
self.pending.cursor += text.len() as u32;
unsafe { unsafe {
c::eek_input_method_commit_string(self.im, text.as_ptr()) c::eek_input_method_commit_string(self.im, text.as_ptr())
} }
@ -381,11 +392,16 @@ impl IMService {
} }
pub fn delete_surrounding_text( pub fn delete_surrounding_text(
&self, &mut self,
before: u32, after: u32, before: u32, after: u32,
) -> Result<(), SubmitError> { ) -> Result<(), SubmitError> {
match self.current.active { match self.current.active {
true => { true => {
let cursor_position: usize = self.pending.cursor.try_into().unwrap(); // Converts u32 of cursor to usize
self.pending.surrounding_text.replace_range(
cursor_position - (before as usize)..cursor_position + (after as usize),
"",
);
unsafe { unsafe {
c::eek_input_method_delete_surrounding_text( c::eek_input_method_delete_surrounding_text(
self.im, self.im,
@ -405,6 +421,7 @@ impl IMService {
c::eek_input_method_commit(self.im, self.serial.0) c::eek_input_method_commit(self.im, self.serial.0)
} }
self.serial += Wrapping(1u32); self.serial += Wrapping(1u32);
imservice_handle_done(self);
Ok(()) Ok(())
}, },
false => Err(SubmitError::NotActive), false => Err(SubmitError::NotActive),

View File

@ -5,13 +5,10 @@ use std::cell::RefCell;
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt; use std::fmt;
use std::io; use std::io;
use std::mem;
use std::ptr;
use std::rc::Rc; use std::rc::Rc;
use std::string::FromUtf8Error; use std::string::FromUtf8Error;
use ::action::Action; use ::action::Action;
use ::util;
// Traits // Traits
use std::io::Write; use std::io::Write;
@ -23,12 +20,7 @@ pub enum PressType {
Pressed = 1, Pressed = 1,
} }
/// The extended, unambiguous layout-keycode pub type KeyCode = u32;
#[derive(Debug, Clone)]
pub struct KeyCode {
pub code: u32,
pub keymap_idx: usize,
}
bitflags!{ bitflags!{
/// Map to `virtual_keyboard.modifiers` modifiers values /// Map to `virtual_keyboard.modifiers` modifiers values
@ -87,10 +79,10 @@ impl KeyState {
} }
/// Sorts an iterator by converting it to a Vector and back /// Sorts an iterator by converting it to a Vector and back
fn sorted<'a, I: Iterator<Item=String>>( fn sorted<'a, I: Iterator<Item=&'a str>>(
iter: I iter: I
) -> impl Iterator<Item=String> { ) -> impl Iterator<Item=&'a str> {
let mut v: Vec<String> = iter.collect(); let mut v: Vec<&'a str> = iter.collect();
v.sort(); v.sort();
v.into_iter() v.into_iter()
} }
@ -98,17 +90,15 @@ fn sorted<'a, I: Iterator<Item=String>>(
/// Generates a mapping where each key gets a keycode, starting from ~~8~~ /// Generates a mapping where each key gets a keycode, starting from ~~8~~
/// HACK: starting from 9, because 8 results in keycode 0, /// HACK: starting from 9, because 8 results in keycode 0,
/// which the compositor likes to discard /// which the compositor likes to discard
pub fn generate_keycodes<'a, C: IntoIterator<Item=String>>( pub fn generate_keycodes<'a, C: IntoIterator<Item=&'a str>>(
key_names: C, key_names: C,
) -> HashMap<String, KeyCode> { ) -> HashMap<String, u32> {
let special_keysyms = ["BackSpace", "Return"].iter().map(|&s| s);
HashMap::from_iter( HashMap::from_iter(
// Sort to remove a source of indeterminism in keycode assignment. // sort to remove a source of indeterminism in keycode assignment
sorted(key_names.into_iter()) sorted(key_names.into_iter().chain(special_keysyms))
.zip(util::cycle_count(9..255)) .map(|name| String::from(name))
.map(|(name, (code, keymap_idx))| ( .zip(9..)
String::from(name),
KeyCode { code, keymap_idx },
))
) )
} }
@ -133,54 +123,10 @@ impl From<io::Error> for FormattingError {
} }
} }
/// Index is the key code, String is the occupant.
/// Starts all empty.
/// https://gitlab.freedesktop.org/xorg/xserver/-/issues/260
type SingleKeyMap = [Option<String>; 256];
fn single_key_map_new() -> SingleKeyMap {
// Why can't we just initialize arrays without tricks -_- ?
unsafe {
// Inspired by
// https://www.reddit.com/r/rust/comments/5n7bh1/how_to_create_an_array_of_a_type_with_clone_but/
#[cfg(feature = "rustc_less_1_36")]
let mut array: SingleKeyMap = mem::uninitialized();
#[cfg(not(feature = "rustc_less_1_36"))]
let mut array: SingleKeyMap = mem::MaybeUninit::uninit().assume_init();
for element in array.iter_mut() {
ptr::write(element, None);
}
array
}
}
pub fn generate_keymaps(symbolmap: HashMap::<String, KeyCode>)
-> Result<Vec<String>, FormattingError>
{
let mut bins: Vec<SingleKeyMap> = Vec::new();
for (name, KeyCode { code, keymap_idx }) in symbolmap.into_iter() {
if keymap_idx >= bins.len() {
bins.resize_with(
keymap_idx + 1,
|| single_key_map_new(),
);
}
bins[keymap_idx][code as usize] = Some(name);
}
let mut out = Vec::new();
for bin in bins {
out.push(generate_keymap(&bin)?);
}
Ok(out)
}
/// Generates a de-facto single level keymap. /// Generates a de-facto single level keymap.
/// Key codes must not repeat and must remain between 9 and 255. /// Key codes must not repeat and should remain between 9 and 255.
fn generate_keymap( pub fn generate_keymap(
symbolmap: &SingleKeyMap, symbolmap: HashMap::<String, KeyCode>,
) -> Result<String, FormattingError> { ) -> Result<String, FormattingError> {
let mut buf: Vec<u8> = Vec::new(); let mut buf: Vec<u8> = Vec::new();
writeln!( writeln!(
@ -189,21 +135,14 @@ fn generate_keymap(
xkb_keycodes \"squeekboard\" {{ xkb_keycodes \"squeekboard\" {{
minimum = 8; minimum = 8;
maximum = 255;" maximum = 999;"
)?; )?;
let pairs: Vec<(&String, usize)> = symbolmap.iter()
// Attach a key code to each cell.
.enumerate()
// Get rid of empty keycodes.
.filter_map(|(code, name)| name.as_ref().map(|n| (n, code)))
.collect();
// Xorg can only consume up to 255 keys, so this may not work in Xwayland. // Xorg can only consume up to 255 keys, so this may not work in Xwayland.
// Two possible solutions: // Two possible solutions:
// - use levels to cram multiple characters into one key // - use levels to cram multiple characters into one key
// - swap layouts on key presses // - swap layouts on key presses
for (_name, keycode) in &pairs { for keycode in symbolmap.values() {
write!( write!(
buf, buf,
" "
@ -222,7 +161,7 @@ fn generate_keymap(
" "
)?; )?;
for (name, keycode) in pairs { for (name, keycode) in symbolmap.iter() {
write!( write!(
buf, buf,
" "
@ -280,15 +219,14 @@ mod tests {
use xkbcommon::xkb; use xkbcommon::xkb;
#[test] #[test]
fn test_keymap_single_resolve() { fn test_keymap_multi() {
let mut key_map = single_key_map_new();
key_map[9] = Some("a".into());
key_map[10] = Some("c".into());
let keymap_str = generate_keymap(&key_map).unwrap();
let context = xkb::Context::new(xkb::CONTEXT_NO_FLAGS); let context = xkb::Context::new(xkb::CONTEXT_NO_FLAGS);
let keymap_str = generate_keymap(hashmap!{
"a".into() => 9,
"c".into() => 10,
}).unwrap();
let keymap = xkb::Keymap::new_from_string( let keymap = xkb::Keymap::new_from_string(
&context, &context,
keymap_str.clone(), keymap_str.clone(),
@ -301,36 +239,4 @@ mod tests {
assert_eq!(state.key_get_one_sym(9), xkb::KEY_a); assert_eq!(state.key_get_one_sym(9), xkb::KEY_a);
assert_eq!(state.key_get_one_sym(10), xkb::KEY_c); assert_eq!(state.key_get_one_sym(10), xkb::KEY_c);
} }
#[test]
fn test_keymap_second_resolve() {
let keymaps = generate_keymaps(hashmap!(
"a".into() => KeyCode { keymap_idx: 1, code: 9 },
)).unwrap();
let context = xkb::Context::new(xkb::CONTEXT_NO_FLAGS);
let keymap = xkb::Keymap::new_from_string(
&context,
keymaps[1].clone(), // this index is part of the test
xkb::KEYMAP_FORMAT_TEXT_V1,
xkb::KEYMAP_COMPILE_NO_FLAGS,
).expect("Failed to create keymap");
let state = xkb::State::new(&keymap);
assert_eq!(state.key_get_one_sym(9), xkb::KEY_a);
}
#[test]
fn test_symbolmap_overflow() {
// The 257th key (U1101) is interesting.
// Use Unicode encoding for being able to use in xkb keymaps.
let keynames = (0..258).map(|num| format!("U{:04X}", 0x1000 + num));
let keycodes = generate_keycodes(keynames);
// test now
let code = keycodes.get("U1101").expect("Did not find the tested keysym");
assert_eq!(code.keymap_idx, 1);
}
} }

View File

@ -39,6 +39,7 @@ struct transformation squeek_layout_calculate_transformation(
double allocation_width, double allocation_size); double allocation_width, double allocation_size);
struct squeek_layout *squeek_load_layout(const char *name, uint32_t type); struct squeek_layout *squeek_load_layout(const char *name, uint32_t type);
const char *squeek_layout_get_keymap(const struct squeek_layout*);
enum squeek_arrangement_kind squeek_layout_get_kind(const struct squeek_layout *); enum squeek_arrangement_kind squeek_layout_get_kind(const struct squeek_layout *);
void squeek_layout_free(struct squeek_layout*); void squeek_layout_free(struct squeek_layout*);

View File

@ -237,6 +237,13 @@ pub mod c {
}) })
} }
#[no_mangle]
pub extern "C"
fn squeek_layout_get_keymap(layout: *const Layout) -> *const c_char {
let layout = unsafe { &*layout };
layout.keymap_str.as_ptr()
}
#[no_mangle] #[no_mangle]
pub extern "C" pub extern "C"
fn squeek_layout_get_kind(layout: *const Layout) -> u32 { fn squeek_layout_get_kind(layout: *const Layout) -> u32 {
@ -679,8 +686,8 @@ pub struct Layout {
pub views: HashMap<String, (c::Point, View)>, pub views: HashMap<String, (c::Point, View)>,
// Non-UI stuff // Non-UI stuff
/// xkb keymaps applicable to the contained keys. Unchangeable /// xkb keymap applicable to the contained keys. Unchangeable
pub keymaps: Vec<CString>, pub keymap_str: CString,
// Changeable state // Changeable state
// a Vec would be enough, but who cares, this will be small & fast enough // a Vec would be enough, but who cares, this will be small & fast enough
// TODO: turn those into per-input point *_buttons to track dragging. // TODO: turn those into per-input point *_buttons to track dragging.
@ -696,7 +703,7 @@ pub struct Layout {
pub struct LayoutData { pub struct LayoutData {
/// Point is the offset within layout /// Point is the offset within layout
pub views: HashMap<String, (c::Point, View)>, pub views: HashMap<String, (c::Point, View)>,
pub keymaps: Vec<CString>, pub keymap_str: CString,
pub margins: Margins, pub margins: Margins,
} }
@ -719,7 +726,7 @@ impl Layout {
kind, kind,
current_view: "base".to_owned(), current_view: "base".to_owned(),
views: data.views, views: data.views,
keymaps: data.keymaps, keymap_str: data.keymap_str,
pressed_keys: HashSet::new(), pressed_keys: HashSet::new(),
margins: data.margins, margins: data.margins,
} }
@ -1193,7 +1200,7 @@ mod test {
]); ]);
let layout = Layout { let layout = Layout {
current_view: String::new(), current_view: String::new(),
keymaps: Vec::new(), keymap_str: CString::new("").unwrap(),
kind: ArrangementKind::Base, kind: ArrangementKind::Base,
pressed_keys: HashSet::new(), pressed_keys: HashSet::new(),
// Lots of bottom margin // Lots of bottom margin

View File

@ -80,7 +80,6 @@ test(
'rstest', 'rstest',
cargo_script, cargo_script,
args: ['test'] + cargo_build_flags, args: ['test'] + cargo_build_flags,
env: ['SOURCE_DIR=' + meson.source_root()],
# this is a whole Carg-based test suite, let it run for a while # this is a whole Carg-based test suite, let it run for a while
timeout: 900, timeout: 900,
depends: [build_rstests, cargo_toml], depends: [build_rstests, cargo_toml],

View File

@ -10,70 +10,32 @@ use std::iter::FromIterator;
// TODO: keep a list of what is a language layout, // TODO: keep a list of what is a language layout,
// and what a convenience layout. "_wide" is not a layout, // and what a convenience layout. "_wide" is not a layout,
// neither is "number" // neither is "number"
/// List of builtin layouts
const KEYBOARDS: &[(*const str, *const str)] = &[ const KEYBOARDS: &[(*const str, *const str)] = &[
// layouts: us must be left as first, as it is the, // layouts: us must be left as first, as it is the,
// fallback layout. // fallback layout. The others should be alphabetical.
("us", include_str!("../data/keyboards/us.yaml")), ("us", include_str!("../data/keyboards/us.yaml")),
("us_wide", include_str!("../data/keyboards/us_wide.yaml")), ("us_wide", include_str!("../data/keyboards/us_wide.yaml")),
("br", include_str!("../data/keyboards/br.yaml")),
// Language layouts: keep alphabetical. ("de", include_str!("../data/keyboards/de.yaml")),
("be", include_str!("../data/keyboards/be.yaml")), ("be", include_str!("../data/keyboards/be.yaml")),
("be_wide", include_str!("../data/keyboards/be_wide.yaml")), ("be_wide", include_str!("../data/keyboards/be_wide.yaml")),
("bg", include_str!("../data/keyboards/bg.yaml")),
("br", include_str!("../data/keyboards/br.yaml")),
("de", include_str!("../data/keyboards/de.yaml")),
("de_wide", include_str!("../data/keyboards/de_wide.yaml")), ("de_wide", include_str!("../data/keyboards/de_wide.yaml")),
("cz", include_str!("../data/keyboards/cz.yaml")),
("cz_wide", include_str!("../data/keyboards/cz_wide.yaml")),
("cz+qwerty", include_str!("../data/keyboards/cz+qwerty.yaml")),
("cz+qwerty_wide", include_str!("../data/keyboards/cz+qwerty_wide.yaml")),
("dk", include_str!("../data/keyboards/dk.yaml")), ("dk", include_str!("../data/keyboards/dk.yaml")),
("epo", include_str!("../data/keyboards/epo.yaml")),
("es", include_str!("../data/keyboards/es.yaml")), ("es", include_str!("../data/keyboards/es.yaml")),
("fi", include_str!("../data/keyboards/fi.yaml")), ("fi", include_str!("../data/keyboards/fi.yaml")),
("fr", include_str!("../data/keyboards/fr.yaml")), ("fr", include_str!("../data/keyboards/fr.yaml")),
("fr_wide", include_str!("../data/keyboards/fr_wide.yaml")), ("fr_wide", include_str!("../data/keyboards/fr_wide.yaml")),
("gr", include_str!("../data/keyboards/gr.yaml")), ("gr", include_str!("../data/keyboards/gr.yaml")),
("ir", include_str!("../data/keyboards/ir.yaml")),
("ir_wide", include_str!("../data/keyboards/ir_wide.yaml")),
("it", include_str!("../data/keyboards/it.yaml")), ("it", include_str!("../data/keyboards/it.yaml")),
("it+fur", include_str!("../data/keyboards/it+fur.yaml")),
("jp+kana", include_str!("../data/keyboards/jp+kana.yaml")), ("jp+kana", include_str!("../data/keyboards/jp+kana.yaml")),
("jp+kana_wide", include_str!("../data/keyboards/jp+kana_wide.yaml")), ("jp+kana_wide", include_str!("../data/keyboards/jp+kana_wide.yaml")),
("no", include_str!("../data/keyboards/no.yaml")), ("no", include_str!("../data/keyboards/no.yaml")),
("number", include_str!("../data/keyboards/number.yaml")),
("pl", include_str!("../data/keyboards/pl.yaml")), ("pl", include_str!("../data/keyboards/pl.yaml")),
("pl_wide", include_str!("../data/keyboards/pl_wide.yaml")), ("pl_wide", include_str!("../data/keyboards/pl_wide.yaml")),
("ru", include_str!("../data/keyboards/ru.yaml")), ("ru", include_str!("../data/keyboards/ru.yaml")),
("se", include_str!("../data/keyboards/se.yaml")), ("se", include_str!("../data/keyboards/se.yaml")),
("th", include_str!("../data/keyboards/th.yaml")),
("ua", include_str!("../data/keyboards/ua.yaml")), ("ua", include_str!("../data/keyboards/ua.yaml")),
("us+colemak", include_str!("../data/keyboards/us+colemak.yaml")),
// Others
("number", include_str!("../data/keyboards/number.yaml")),
// layout+overlay // layout+overlay
("terminal", include_str!("../data/keyboards/terminal.yaml")), ("terminal", include_str!("../data/keyboards/terminal.yaml")),
("terminal_wide", include_str!("../data/keyboards/terminal_wide.yaml")), ("terminal_wide", include_str!("../data/keyboards/terminal_wide.yaml")),
@ -113,7 +75,6 @@ const LAYOUT_NAMES: &[(*const str, *const str)] = &[
("de-DE", include_str!("../data/langs/de-DE.txt")), ("de-DE", include_str!("../data/langs/de-DE.txt")),
("en-US", include_str!("../data/langs/en-US.txt")), ("en-US", include_str!("../data/langs/en-US.txt")),
("es-ES", include_str!("../data/langs/es-ES.txt")), ("es-ES", include_str!("../data/langs/es-ES.txt")),
("fur-IT", include_str!("../data/langs/fur-IT.txt")),
("ja-JP", include_str!("../data/langs/ja-JP.txt")), ("ja-JP", include_str!("../data/langs/ja-JP.txt")),
("pl-PL", include_str!("../data/langs/pl-PL.txt")), ("pl-PL", include_str!("../data/langs/pl-PL.txt")),
("ru-RU", include_str!("../data/langs/ru-RU.txt")), ("ru-RU", include_str!("../data/langs/ru-RU.txt")),

View File

@ -43,9 +43,9 @@ struct _ServerContextService {
struct submission *submission; // unowned struct submission *submission; // unowned
struct squeek_layout_state *layout; struct squeek_layout_state *layout;
struct ui_manager *manager; // unowned struct ui_manager *manager; // unowned
struct vis_manager *vis_manager; // owned
gboolean visible; gboolean visible;
gboolean enabled;
PhoshLayerSurface *window; PhoshLayerSurface *window;
GtkWidget *widget; // nullable GtkWidget *widget; // nullable
guint hiding; guint hiding;
@ -125,17 +125,14 @@ on_surface_configure(ServerContextService *self, PhoshLayerSurface *surface)
// we can use different algorithms for portrait and landscape mode. // we can use different algorithms for portrait and landscape mode.
// Note: this is a temporary fix until the size manager is complete. // Note: this is a temporary fix until the size manager is complete.
display = gdk_display_get_default (); display = gdk_display_get_default ();
if (display) { if (display)
window = gtk_widget_get_window (GTK_WIDGET (surface)); window = gtk_widget_get_window (GTK_WIDGET (surface));
} if (window)
if (window) {
monitor = gdk_display_get_monitor_at_window (display, window); monitor = gdk_display_get_monitor_at_window (display, window);
} if (monitor)
if (monitor) {
gdk_monitor_get_geometry (monitor, &geometry); gdk_monitor_get_geometry (monitor, &geometry);
} else { else
geometry.width = geometry.height = 0; geometry.width = geometry.height = 0;
}
// When the geometry event comes after surface.configure, // When the geometry event comes after surface.configure,
// this entire height calculation does nothing. // this entire height calculation does nothing.
@ -162,9 +159,8 @@ on_surface_configure(ServerContextService *self, PhoshLayerSurface *surface)
static void static void
make_window (ServerContextService *self) make_window (ServerContextService *self)
{ {
if (self->window) { if (self->window)
g_error("Window already present"); g_error("Window already present");
}
struct squeek_output_handle output = squeek_outputs_get_current(squeek_wayland->outputs); struct squeek_output_handle output = squeek_outputs_get_current(squeek_wayland->outputs);
squeek_uiman_set_output(self->manager, output); squeek_uiman_set_output(self->manager, output);
@ -226,75 +222,52 @@ make_widget (ServerContextService *self)
gtk_widget_show_all(self->widget); gtk_widget_show_all(self->widget);
} }
static void
server_context_service_real_show_keyboard (ServerContextService *self)
{
if (!self->window) {
make_window (self);
}
if (!self->widget) {
make_widget (self);
}
self->visible = TRUE;
gtk_widget_show (GTK_WIDGET(self->window));
}
static gboolean
show_keyboard_source_func(ServerContextService *context)
{
server_context_service_real_show_keyboard(context);
return G_SOURCE_REMOVE;
}
static void
server_context_service_real_hide_keyboard (ServerContextService *self)
{
gtk_widget_hide (GTK_WIDGET(self->window));
self->visible = FALSE;
}
static gboolean
hide_keyboard_source_func(ServerContextService *context)
{
server_context_service_real_hide_keyboard(context);
return G_SOURCE_REMOVE;
}
static gboolean static gboolean
on_hide (ServerContextService *self) on_hide (ServerContextService *self)
{ {
server_context_service_real_hide_keyboard(self); gtk_widget_hide (GTK_WIDGET(self->window));
self->hiding = 0; self->hiding = 0;
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
} }
static void static void
server_context_service_show_keyboard (ServerContextService *self) server_context_service_real_show_keyboard (ServerContextService *self)
{ {
g_return_if_fail (SERVER_IS_CONTEXT_SERVICE(self)); if (!self->enabled)
return;
if (self->hiding) { if (self->hiding) {
g_source_remove (self->hiding); g_source_remove (self->hiding);
self->hiding = 0; self->hiding = 0;
} }
if (!self->visible) { if (!self->window)
g_idle_add((GSourceFunc)show_keyboard_source_func, self); make_window (self);
if (!self->widget)
make_widget (self);
self->visible = TRUE;
gtk_widget_show (GTK_WIDGET(self->window));
} }
static void
server_context_service_real_hide_keyboard (ServerContextService *self)
{
if (!self->hiding)
self->hiding = g_timeout_add (200, (GSourceFunc) on_hide, self);
self->visible = FALSE;
} }
void void
server_context_service_force_show_keyboard (ServerContextService *self) server_context_service_show_keyboard (ServerContextService *self)
{ {
if (!submission_hint_available(self->submission)) { g_return_if_fail (SERVER_IS_CONTEXT_SERVICE(self));
eekboard_context_service_set_hint_purpose(
self->state, if (!self->visible) {
ZWP_TEXT_INPUT_V3_CONTENT_HINT_NONE, server_context_service_real_show_keyboard (self);
ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL
);
} }
server_context_service_show_keyboard(self);
} }
void void
@ -303,33 +276,10 @@ server_context_service_hide_keyboard (ServerContextService *self)
g_return_if_fail (SERVER_IS_CONTEXT_SERVICE(self)); g_return_if_fail (SERVER_IS_CONTEXT_SERVICE(self));
if (self->visible) { if (self->visible) {
g_idle_add((GSourceFunc)hide_keyboard_source_func, self); server_context_service_real_hide_keyboard (self);
} }
} }
/// Meant for use by the input-method handler:
/// the visible keyboard is no longer needed.
/// The implementation will delay it slightly,
/// because the release may be due to switching from one text field to another.
/// In this case, the user doesn't really need the keyboard surface
/// to disappear completely.
void
server_context_service_release_visibility (ServerContextService *self)
{
g_return_if_fail (SERVER_IS_CONTEXT_SERVICE(self));
if (!self->hiding && self->visible) {
self->hiding = g_timeout_add (200, (GSourceFunc) on_hide, self);
}
}
static void
server_context_service_set_physical_keyboard_present (ServerContextService *self, gboolean physical_keyboard_present)
{
g_return_if_fail (SERVER_IS_CONTEXT_SERVICE (self));
squeek_visman_set_keyboard_present(self->vis_manager, physical_keyboard_present);
}
static void static void
server_context_service_set_property (GObject *object, server_context_service_set_property (GObject *object,
guint prop_id, guint prop_id,
@ -343,7 +293,7 @@ server_context_service_set_property (GObject *object,
self->visible = g_value_get_boolean (value); self->visible = g_value_get_boolean (value);
break; break;
case PROP_ENABLED: case PROP_ENABLED:
server_context_service_set_physical_keyboard_present (self, !g_value_get_boolean (value)); server_context_service_set_enabled (self, g_value_get_boolean (value));
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -418,14 +368,12 @@ server_context_service_class_init (ServerContextServiceClass *klass)
} }
static void static void
server_context_service_init (ServerContextService *self) {} server_context_service_init (ServerContextService *self) {
static void
init (ServerContextService *self) {
const char *schema_name = "org.gnome.desktop.a11y.applications"; const char *schema_name = "org.gnome.desktop.a11y.applications";
GSettingsSchemaSource *ssrc = g_settings_schema_source_get_default(); GSettingsSchemaSource *ssrc = g_settings_schema_source_get_default();
g_autoptr(GSettingsSchema) schema = NULL; g_autoptr(GSettingsSchema) schema = NULL;
self->enabled = TRUE;
if (!ssrc) { if (!ssrc) {
g_warning("No gsettings schemas installed."); g_warning("No gsettings schemas installed.");
return; return;
@ -442,24 +390,27 @@ init (ServerContextService *self) {
} }
ServerContextService * ServerContextService *
server_context_service_new (EekboardContextService *self, struct submission *submission, struct squeek_layout_state *layout, struct ui_manager *uiman, struct vis_manager *visman) server_context_service_new (EekboardContextService *self, struct submission *submission, struct squeek_layout_state *layout, struct ui_manager *uiman)
{ {
ServerContextService *ui = g_object_new (SERVER_TYPE_CONTEXT_SERVICE, NULL); ServerContextService *ui = g_object_new (SERVER_TYPE_CONTEXT_SERVICE, NULL);
ui->submission = submission; ui->submission = submission;
ui->state = self; ui->state = self;
ui->layout = layout; ui->layout = layout;
ui->manager = uiman; ui->manager = uiman;
ui->vis_manager = visman;
init(ui);
return ui; return ui;
} }
void void
server_context_service_update_visible (ServerContextService *self, gboolean visible) { server_context_service_set_enabled (ServerContextService *self, gboolean enabled)
if (visible) { {
g_return_if_fail (SERVER_IS_CONTEXT_SERVICE (self));
if (enabled == self->enabled)
return;
self->enabled = enabled;
if (self->enabled)
server_context_service_show_keyboard (self); server_context_service_show_keyboard (self);
} else { else
server_context_service_hide_keyboard (self); server_context_service_hide_keyboard (self);
} }
}

View File

@ -29,10 +29,11 @@ G_BEGIN_DECLS
/** Manages the lifecycle of the window displaying layouts. */ /** Manages the lifecycle of the window displaying layouts. */
G_DECLARE_FINAL_TYPE (ServerContextService, server_context_service, SERVER, CONTEXT_SERVICE, GObject) G_DECLARE_FINAL_TYPE (ServerContextService, server_context_service, SERVER, CONTEXT_SERVICE, GObject)
ServerContextService *server_context_service_new(EekboardContextService *self, struct submission *submission, struct squeek_layout_state *layout, struct ui_manager *uiman, struct vis_manager *visman); ServerContextService *server_context_service_new(EekboardContextService *self, struct submission *submission, struct squeek_layout_state *layout, struct ui_manager *uiman);
enum squeek_arrangement_kind server_context_service_get_layout_type(ServerContextService *); enum squeek_arrangement_kind server_context_service_get_layout_type(ServerContextService *);
void server_context_service_force_show_keyboard (ServerContextService *self); void server_context_service_show_keyboard (ServerContextService *self);
void server_context_service_hide_keyboard (ServerContextService *self); void server_context_service_hide_keyboard (ServerContextService *self);
void server_context_service_set_enabled (ServerContextService *self, gboolean enabled);
G_END_DECLS G_END_DECLS
#endif /* SERVER_CONTEXT_SERVICE_H */ #endif /* SERVER_CONTEXT_SERVICE_H */

View File

@ -213,13 +213,12 @@ main (int argc, char **argv)
// dbus is not strictly necessary for the useful operation // dbus is not strictly necessary for the useful operation
// if text-input is used, as it can bring the keyboard in and out // if text-input is used, as it can bring the keyboard in and out
GBusType bus_type; GBusType bus_type;
if (opt_system) { if (opt_system)
bus_type = G_BUS_TYPE_SYSTEM; bus_type = G_BUS_TYPE_SYSTEM;
} else if (opt_address) { else if (opt_address)
bus_type = G_BUS_TYPE_NONE; bus_type = G_BUS_TYPE_NONE;
} else { else
bus_type = G_BUS_TYPE_SESSION; bus_type = G_BUS_TYPE_SESSION;
}
GDBusConnection *connection = NULL; GDBusConnection *connection = NULL;
GError *error = NULL; GError *error = NULL;
@ -277,11 +276,8 @@ main (int argc, char **argv)
} }
} }
struct vis_manager *vis_manager = squeek_visman_new();
instance.submission = get_submission(instance.wayland.input_method_manager, instance.submission = get_submission(instance.wayland.input_method_manager,
instance.wayland.virtual_keyboard_manager, instance.wayland.virtual_keyboard_manager,
vis_manager,
instance.wayland.seat, instance.wayland.seat,
instance.settings_context); instance.settings_context);
@ -291,15 +287,15 @@ main (int argc, char **argv)
instance.settings_context, instance.settings_context,
instance.submission, instance.submission,
&instance.layout_choice, &instance.layout_choice,
instance.ui_manager, instance.ui_manager);
vis_manager);
if (!ui_context) { if (!ui_context) {
g_error("Could not initialize GUI"); g_error("Could not initialize GUI");
exit(1); exit(1);
} }
instance.ui_context = ui_context; instance.ui_context = ui_context;
squeek_visman_set_ui(vis_manager, instance.ui_context); if (instance.submission) {
submission_set_ui(instance.submission, instance.ui_context);
}
if (instance.dbus_handler) { if (instance.dbus_handler) {
dbus_handler_set_ui_context(instance.dbus_handler, instance.ui_context); dbus_handler_set_ui_context(instance.dbus_handler, instance.ui_context);
} }

View File

@ -4,20 +4,16 @@
#include "input-method-unstable-v2-client-protocol.h" #include "input-method-unstable-v2-client-protocol.h"
#include "virtual-keyboard-unstable-v1-client-protocol.h" #include "virtual-keyboard-unstable-v1-client-protocol.h"
#include "eek/eek-types.h" #include "eek/eek-types.h"
#include "src/ui_manager.h"
struct submission; struct submission;
struct squeek_layout;
struct submission* get_submission(struct zwp_input_method_manager_v2 *immanager, struct submission* get_submission(struct zwp_input_method_manager_v2 *immanager,
struct zwp_virtual_keyboard_manager_v1 *vkmanager, struct zwp_virtual_keyboard_manager_v1 *vkmanager,
struct vis_manager *vis_manager,
struct wl_seat *seat, struct wl_seat *seat,
EekboardContextService *state); EekboardContextService *state);
// Defined in Rust // Defined in Rust
struct submission* submission_new(struct zwp_input_method_v2 *im, struct zwp_virtual_keyboard_v1 *vk, EekboardContextService *state, struct vis_manager *vis_manager); struct submission* submission_new(struct zwp_input_method_v2 *im, struct zwp_virtual_keyboard_v1 *vk, EekboardContextService *state);
uint8_t submission_hint_available(struct submission *self);
void submission_set_ui(struct submission *self, ServerContextService *ui_context); void submission_set_ui(struct submission *self, ServerContextService *ui_context);
void submission_use_layout(struct submission *self, struct squeek_layout *layout, uint32_t time); void submission_set_keyboard(struct submission *self, LevelKeyboard *keyboard, uint32_t time);
#endif #endif

View File

@ -23,10 +23,8 @@ use ::action::Modifier;
use ::imservice; use ::imservice;
use ::imservice::IMService; use ::imservice::IMService;
use ::keyboard::{ KeyCode, KeyStateId, Modifiers, PressType }; use ::keyboard::{ KeyCode, KeyStateId, Modifiers, PressType };
use ::layout; use ::layout::c::LevelKeyboard;
use ::ui_manager::VisibilityManager;
use ::util::vec_remove; use ::util::vec_remove;
use ::vkeyboard;
use ::vkeyboard::VirtualKeyboard; use ::vkeyboard::VirtualKeyboard;
// traits // traits
@ -39,11 +37,14 @@ pub mod c {
use std::os::raw::c_void; use std::os::raw::c_void;
use ::imservice::c::InputMethod; use ::imservice::c::InputMethod;
use ::util::c::Wrapped;
use ::vkeyboard::c::ZwpVirtualKeyboardV1; use ::vkeyboard::c::ZwpVirtualKeyboardV1;
// The following defined in C // The following defined in C
/// ServerContextService*
#[repr(transparent)]
pub struct UIManager(*const c_void);
/// EekboardContextService* /// EekboardContextService*
#[repr(transparent)] #[repr(transparent)]
pub struct StateManager(*const c_void); pub struct StateManager(*const c_void);
@ -53,18 +54,12 @@ pub mod c {
fn submission_new( fn submission_new(
im: *mut InputMethod, im: *mut InputMethod,
vk: ZwpVirtualKeyboardV1, vk: ZwpVirtualKeyboardV1,
state_manager: *const StateManager, state_manager: *const StateManager
visibility_manager: Wrapped<VisibilityManager>,
) -> *mut Submission { ) -> *mut Submission {
let imservice = if im.is_null() { let imservice = if im.is_null() {
None None
} else { } else {
let visibility_manager = visibility_manager.clone_ref(); Some(IMService::new(im, state_manager))
Some(IMService::new(
im,
state_manager,
Box::new(move |active| visibility_manager.borrow_mut().set_im_active(active)),
))
}; };
// TODO: add vkeyboard too // TODO: add vkeyboard too
Box::<Submission>::into_raw(Box::new( Box::<Submission>::into_raw(Box::new(
@ -73,37 +68,39 @@ pub mod c {
modifiers_active: Vec::new(), modifiers_active: Vec::new(),
virtual_keyboard: VirtualKeyboard(vk), virtual_keyboard: VirtualKeyboard(vk),
pressed: Vec::new(), pressed: Vec::new(),
keymap_fds: Vec::new(),
keymap_idx: None,
} }
)) ))
} }
/// Use to initialize the UI reference
#[no_mangle] #[no_mangle]
pub extern "C" pub extern "C"
fn submission_use_layout( fn submission_set_ui(submission: *mut Submission, ui_manager: *const UIManager) {
if submission.is_null() {
panic!("Null submission pointer");
}
let submission: &mut Submission = unsafe { &mut *submission };
if let Some(ref mut imservice) = &mut submission.imservice {
imservice.ui_manager = if ui_manager.is_null() {
None
} else {
Some(ui_manager)
}
};
}
#[no_mangle]
pub extern "C"
fn submission_set_keyboard(
submission: *mut Submission, submission: *mut Submission,
layout: *const layout::Layout, keyboard: LevelKeyboard,
time: u32, time: u32,
) { ) {
if submission.is_null() { if submission.is_null() {
panic!("Null submission pointer"); panic!("Null submission pointer");
} }
let submission: &mut Submission = unsafe { &mut *submission }; let submission: &mut Submission = unsafe { &mut *submission };
let layout = unsafe { &*layout }; submission.update_keymap(keyboard, Timestamp(time));
submission.use_layout(layout, Timestamp(time));
}
#[no_mangle]
pub extern "C"
fn submission_hint_available(submission: *mut Submission) -> u8 {
if submission.is_null() {
panic!("Null submission pointer");
}
let submission: &mut Submission = unsafe { &mut *submission };
let active = submission.imservice.as_ref()
.map(|imservice| imservice.is_active());
(Some(true) == active) as u8
} }
} }
@ -122,8 +119,6 @@ pub struct Submission {
virtual_keyboard: VirtualKeyboard, virtual_keyboard: VirtualKeyboard,
modifiers_active: Vec<(KeyStateId, Modifier)>, modifiers_active: Vec<(KeyStateId, Modifier)>,
pressed: Vec<(KeyStateId, SubmittedAction)>, pressed: Vec<(KeyStateId, SubmittedAction)>,
keymap_fds: Vec<vkeyboard::c::KeyMap>,
keymap_idx: Option<usize>,
} }
pub enum SubmitData<'a> { pub enum SubmitData<'a> {
@ -182,34 +177,11 @@ impl Submission {
let submit_action = match was_committed_as_text { let submit_action = match was_committed_as_text {
true => SubmittedAction::IMService, true => SubmittedAction::IMService,
false => { false => {
let keycodes_count = keycodes.len();
for keycode in keycodes.iter() {
self.select_keymap(keycode.keymap_idx, time);
let keycode = keycode.code;
match keycodes_count {
// Pressing a key made out of a single keycode is simple:
// press on press, release on release.
1 => self.virtual_keyboard.switch(
keycode,
PressType::Pressed,
time,
),
// A key made of multiple keycodes
// has to submit them one after the other.
_ => {
self.virtual_keyboard.switch( self.virtual_keyboard.switch(
keycode.clone(), keycodes,
PressType::Pressed, PressType::Pressed,
time, time,
); );
self.virtual_keyboard.switch(
keycode.clone(),
PressType::Released,
time,
);
},
};
}
SubmittedAction::VirtualKeyboard(keycodes.clone()) SubmittedAction::VirtualKeyboard(keycodes.clone())
}, },
}; };
@ -227,21 +199,11 @@ impl Submission {
// no matter if the imservice got activated, // no matter if the imservice got activated,
// keys must be released // keys must be released
SubmittedAction::VirtualKeyboard(keycodes) => { SubmittedAction::VirtualKeyboard(keycodes) => {
let keycodes_count = keycodes.len();
match keycodes_count {
1 => {
let keycode = &keycodes[0];
self.select_keymap(keycode.keymap_idx, time);
self.virtual_keyboard.switch( self.virtual_keyboard.switch(
keycode.code, &keycodes,
PressType::Released, PressType::Released,
time, time,
); )
},
// Design choice here: submit multiple all at press time
// and do nothing at release time.
_ => {},
};
}, },
} }
}; };
@ -312,7 +274,6 @@ impl Submission {
} }
} }
/// Changes keymap and clears pressed keys and modifiers. /// Changes keymap and clears pressed keys and modifiers.
/// ///
/// It's not obvious if clearing is the right thing to do, /// It's not obvious if clearing is the right thing to do,
@ -322,28 +283,9 @@ impl Submission {
/// Alternatively, modifiers could be restored on the new keymap. /// Alternatively, modifiers could be restored on the new keymap.
/// That approach might be difficult /// That approach might be difficult
/// due to modifiers meaning different things in different keymaps. /// due to modifiers meaning different things in different keymaps.
fn select_keymap(&mut self, idx: usize, time: Timestamp) { pub fn update_keymap(&mut self, keyboard: LevelKeyboard, time: Timestamp) {
if self.keymap_idx != Some(idx) {
self.keymap_idx = Some(idx);
self.clear_all_modifiers(); self.clear_all_modifiers();
self.release_all_virtual_keys(time); self.release_all_virtual_keys(time);
let keymap = &self.keymap_fds[idx]; self.virtual_keyboard.update_keymap(keyboard);
self.virtual_keyboard.update_keymap(keymap);
}
}
pub fn use_layout(&mut self, layout: &layout::Layout, time: Timestamp) {
self.keymap_fds = layout.keymaps.iter()
.map(|keymap_str| vkeyboard::c::KeyMap::from_cstr(
keymap_str.as_c_str()
))
.collect();
self.keymap_idx = None;
// This can probably be eliminated,
// because key presses can trigger an update anyway.
// However, self.keymap_idx needs to become Option<>
// in order to force update on new layouts.
self.select_keymap(0, time);
} }
} }

View File

@ -40,29 +40,21 @@ pub fn check_layout_file(path: &str) {
) )
} }
fn check_sym_in_keymap(state: &xkb::State, sym_name: &str) -> bool { fn check_sym_presence(
state: &xkb::State,
sym_name: &str,
handler: &mut dyn logging::Handler,
) {
let sym = xkb::keysym_from_name(sym_name, xkb::KEYSYM_NO_FLAGS); let sym = xkb::keysym_from_name(sym_name, xkb::KEYSYM_NO_FLAGS);
if sym == xkb::KEY_NoSymbol { if sym == xkb::KEY_NoSymbol {
panic!(format!("Entered invalid keysym: {}", sym_name)); panic!(format!("Entered invalid keysym: {}", sym_name));
} }
let map = state.get_keymap(); let map = state.get_keymap();
let range = map.min_keycode()..=map.max_keycode(); let range = map.min_keycode()..=map.max_keycode();
range.flat_map(|code| state.key_get_syms(code)) let found = range.flat_map(|code| state.key_get_syms(code))
.find(|s| **s == sym) .find(|s| **s == sym)
.is_some() .is_some();
} if !found {
fn check_sym_presence(
states: &[xkb::State],
sym_name: &str,
handler: &mut dyn logging::Handler,
) {
let found = states.iter()
.position(|state| {
check_sym_in_keymap(&state, sym_name)
});
if let None = found {
handler.handle( handler.handle(
logging::Level::Surprise, logging::Level::Surprise,
&format!("There's no way to input the keysym {} on this layout", sym_name), &format!("There's no way to input the keysym {} on this layout", sym_name),
@ -80,26 +72,25 @@ fn check_layout(layout: Layout, allow_missing_return: bool) {
let layout = layout.expect("layout broken"); let layout = layout.expect("layout broken");
let xkb_states: Vec<xkb::State> = layout.keymaps.iter()
.map(|keymap_str| {
let context = xkb::Context::new(xkb::CONTEXT_NO_FLAGS); let context = xkb::Context::new(xkb::CONTEXT_NO_FLAGS);
let keymap_str = keymap_str
let keymap_str = layout.keymap_str
.clone() .clone()
.into_string().expect("Failed to decode keymap string"); .into_string().expect("Failed to decode keymap string");
let keymap = xkb::Keymap::new_from_string( let keymap = xkb::Keymap::new_from_string(
&context, &context,
keymap_str.clone(), keymap_str.clone(),
xkb::KEYMAP_FORMAT_TEXT_V1, xkb::KEYMAP_FORMAT_TEXT_V1,
xkb::KEYMAP_COMPILE_NO_FLAGS, xkb::KEYMAP_COMPILE_NO_FLAGS,
).expect("Failed to create keymap"); ).expect("Failed to create keymap");
xkb::State::new(&keymap)
})
.collect();
check_sym_presence(&xkb_states, "BackSpace", &mut handler); let state = xkb::State::new(&keymap);
check_sym_presence(&state, "BackSpace", &mut handler);
let mut printer = logging::Print; let mut printer = logging::Print;
check_sym_presence( check_sym_presence(
&xkb_states, &state,
"Return", "Return",
if allow_missing_return { &mut printer } if allow_missing_return { &mut printer }
else { &mut handler }, else { &mut handler },
@ -111,19 +102,10 @@ fn check_layout(layout: Layout, allow_missing_return: bool) {
for (_x, button) in row.get_buttons() { for (_x, button) in row.get_buttons() {
let keystate = button.state.borrow(); let keystate = button.state.borrow();
for keycode in &keystate.keycodes { for keycode in &keystate.keycodes {
match xkb_states[keycode.keymap_idx].key_get_one_sym(keycode.code) { match state.key_get_one_sym(*keycode) {
xkb::KEY_NoSymbol => { xkb::KEY_NoSymbol => {
eprintln!( eprintln!("{}", keymap_str);
"keymap {}: {}", panic!("Keysym {} on key {:?} can't be resolved", keycode, button.name);
keycode.keymap_idx,
layout.keymaps[keycode.keymap_idx].to_str().unwrap(),
);
panic!(
"Keysym for code {:?} on key {} ({:?}) can't be resolved",
keycode,
button.name.to_string_lossy(),
button.name,
);
}, },
_ => {}, _ => {},
} }

View File

@ -3,7 +3,6 @@
#include <inttypes.h> #include <inttypes.h>
#include "eek/eek-types.h"
#include "outputs.h" #include "outputs.h"
struct ui_manager; struct ui_manager;
@ -12,9 +11,4 @@ struct ui_manager *squeek_uiman_new(void);
void squeek_uiman_set_output(struct ui_manager *uiman, struct squeek_output_handle output); void squeek_uiman_set_output(struct ui_manager *uiman, struct squeek_output_handle output);
uint32_t squeek_uiman_get_perceptual_height(struct ui_manager *uiman); uint32_t squeek_uiman_get_perceptual_height(struct ui_manager *uiman);
struct vis_manager;
struct vis_manager *squeek_visman_new(void);
void squeek_visman_set_ui(struct vis_manager *visman, ServerContextService *ui_context);
void squeek_visman_set_keyboard_present(struct vis_manager *visman, uint32_t keyboard_present);
#endif #endif

View File

@ -10,50 +10,10 @@
use std::cmp::min; use std::cmp::min;
use ::outputs::c::OutputHandle; use ::outputs::c::OutputHandle;
pub mod c { mod c {
use super::*; use super::*;
use std::os::raw::c_void;
use ::util::c::Wrapped; use ::util::c::Wrapped;
/// ServerContextService*
#[repr(transparent)]
pub struct UIManager(*const c_void);
#[no_mangle]
extern "C" {
pub fn server_context_service_update_visible(imservice: *const UIManager, active: u32);
pub fn server_context_service_release_visibility(imservice: *const UIManager);
}
#[no_mangle]
pub extern "C"
fn squeek_visman_new() -> Wrapped<VisibilityManager> {
Wrapped::new(VisibilityManager {
ui_manager: None,
visibility_state: VisibilityFactors {
im_active: false,
physical_keyboard_present: false,
}
})
}
/// Use to initialize the UI reference
#[no_mangle]
pub extern "C"
fn squeek_visman_set_ui(visman: Wrapped<VisibilityManager>, ui_manager: *const UIManager) {
let visman = visman.clone_ref();
let mut visman = visman.borrow_mut();
visman.set_ui_manager(Some(ui_manager))
}
#[no_mangle]
pub extern "C"
fn squeek_visman_set_keyboard_present(visman: Wrapped<VisibilityManager>, present: u32) {
let visman = visman.clone_ref();
let mut visman = visman.borrow_mut();
visman.set_keyboard_present(present != 0)
}
#[no_mangle] #[no_mangle]
pub extern "C" pub extern "C"
fn squeek_uiman_new() -> Wrapped<Manager> { fn squeek_uiman_new() -> Wrapped<Manager> {
@ -119,131 +79,3 @@ impl Manager {
} }
} }
} }
#[derive(PartialEq, Debug)]
enum Visibility {
Hidden,
Visible,
}
#[derive(Debug)]
enum VisibilityTransition {
/// Hide immediately
Hide,
/// Hide if no show request comes soon
Release,
/// Show instantly
Show,
/// Don't do anything
NoTransition,
}
/// Contains visibility policy
#[derive(Clone, Debug)]
struct VisibilityFactors {
im_active: bool,
physical_keyboard_present: bool,
}
impl VisibilityFactors {
/// Static policy.
/// Use when transitioning from an undefined state (e.g. no UI before).
fn desired(&self) -> Visibility {
match self {
VisibilityFactors {
im_active: true,
physical_keyboard_present: false,
} => Visibility::Visible,
_ => Visibility::Hidden,
}
}
/// Stateful policy
fn transition_to(&self, next: &Self) -> VisibilityTransition {
use self::Visibility::*;
let im_deactivation = self.im_active && !next.im_active;
match (self.desired(), next.desired(), im_deactivation) {
(Visible, Hidden, true) => VisibilityTransition::Release,
(Visible, Hidden, _) => VisibilityTransition::Hide,
(Hidden, Visible, _) => VisibilityTransition::Show,
_ => VisibilityTransition::NoTransition,
}
}
}
// Temporary struct for migration. Should be integrated with Manager eventually.
pub struct VisibilityManager {
/// Owned reference. Be careful, it's shared with C at large
ui_manager: Option<*const c::UIManager>,
visibility_state: VisibilityFactors,
}
impl VisibilityManager {
fn set_ui_manager(&mut self, ui_manager: Option<*const c::UIManager>) {
let new = VisibilityManager {
ui_manager,
..unsafe { self.clone() }
};
self.apply_changes(new);
}
fn apply_changes(&mut self, new: Self) {
if let Some(ui) = &new.ui_manager {
if self.ui_manager.is_none() {
// Previous state was never applied, so effectively undefined.
// Just apply the new one.
let new_state = new.visibility_state.desired();
unsafe {
c::server_context_service_update_visible(
*ui,
(new_state == Visibility::Visible) as u32,
);
}
} else {
match self.visibility_state.transition_to(&new.visibility_state) {
VisibilityTransition::Hide => unsafe {
c::server_context_service_update_visible(*ui, 0);
},
VisibilityTransition::Show => unsafe {
c::server_context_service_update_visible(*ui, 1);
},
VisibilityTransition::Release => unsafe {
c::server_context_service_release_visibility(*ui);
},
VisibilityTransition::NoTransition => {}
}
}
}
*self = new;
}
pub fn set_im_active(&mut self, im_active: bool) {
let new = VisibilityManager {
visibility_state: VisibilityFactors {
im_active,
..self.visibility_state.clone()
},
..unsafe { self.clone() }
};
self.apply_changes(new);
}
pub fn set_keyboard_present(&mut self, keyboard_present: bool) {
let new = VisibilityManager {
visibility_state: VisibilityFactors {
physical_keyboard_present: keyboard_present,
..self.visibility_state.clone()
},
..unsafe { self.clone() }
};
self.apply_changes(new);
}
/// The struct is not really safe to clone due to the ui_manager reference.
/// This is only a helper for getting desired visibility.
unsafe fn clone(&self) -> Self {
VisibilityManager {
ui_manager: self.ui_manager.clone(),
visibility_state: self.visibility_state.clone(),
}
}
}

View File

@ -203,23 +203,6 @@ pub fn vec_remove<T, F: FnMut(&T) -> bool>(v: &mut Vec<T>, pred: F) -> Option<T>
idx.map(|idx| v.remove(idx)) idx.map(|idx| v.remove(idx))
} }
/// Repeats all the items of the iterator forever,
/// but returns the cycle number alongside.
/// Inefficient due to all the vectors, but doesn't have to be fast.
pub fn cycle_count<T, I: Clone + Iterator<Item=T>>(iter: I)
-> impl Iterator<Item=(T, usize)>
{
let numbered_copies = vec![iter].into_iter()
.cycle()
.enumerate();
numbered_copies.flat_map(|(idx, cycle)|
// Pair each element from the cycle with a copy of the index.
cycle.zip(
vec![idx].into_iter().cycle() // Repeat the index forever.
)
)
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@ -234,12 +217,4 @@ mod tests {
assert_eq!(s.insert(Pointer(Rc::new(2u32))), true); assert_eq!(s.insert(Pointer(Rc::new(2u32))), true);
assert_eq!(s.remove(&Pointer(first)), true); assert_eq!(s.remove(&Pointer(first)), true);
} }
#[test]
fn check_count() {
assert_eq!(
cycle_count(5..8).take(7).collect::<Vec<_>>(),
vec![(5, 0), (6, 0), (7, 0), (5, 1), (6, 1), (7, 1), (5, 2)]
);
}
} }

View File

@ -1,47 +1,20 @@
/*! Managing the events belonging to virtual-keyboard interface. */ /*! Managing the events belonging to virtual-keyboard interface. */
use ::keyboard::{ Modifiers, PressType }; use ::keyboard::{ KeyCode, Modifiers, PressType };
use ::layout::c::LevelKeyboard;
use ::submission::Timestamp; use ::submission::Timestamp;
/// Standard xkb keycode
type KeyCode = u32;
/// Gathers stuff defined in C or called by C /// Gathers stuff defined in C or called by C
pub mod c { pub mod c {
use std::ffi::CStr; use super::*;
use std::os::raw::{ c_char, c_void }; use std::os::raw::c_void;
#[repr(transparent)] #[repr(transparent)]
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct ZwpVirtualKeyboardV1(*const c_void); pub struct ZwpVirtualKeyboardV1(*const c_void);
#[repr(C)]
pub struct KeyMap {
fd: u32,
fd_len: usize,
}
impl KeyMap {
pub fn from_cstr(s: &CStr) -> KeyMap {
unsafe {
squeek_key_map_from_str(s.as_ptr())
}
}
}
impl Drop for KeyMap {
fn drop(&mut self) {
unsafe {
close(self.fd as u32);
}
}
}
#[no_mangle] #[no_mangle]
extern "C" { extern "C" {
// From libc, to let KeyMap get deallocated.
fn close(fd: u32);
pub fn eek_virtual_keyboard_v1_key( pub fn eek_virtual_keyboard_v1_key(
virtual_keyboard: ZwpVirtualKeyboardV1, virtual_keyboard: ZwpVirtualKeyboardV1,
timestamp: u32, timestamp: u32,
@ -51,15 +24,13 @@ pub mod c {
pub fn eek_virtual_keyboard_update_keymap( pub fn eek_virtual_keyboard_update_keymap(
virtual_keyboard: ZwpVirtualKeyboardV1, virtual_keyboard: ZwpVirtualKeyboardV1,
keymap: *const KeyMap, keyboard: LevelKeyboard,
); );
pub fn eek_virtual_keyboard_set_modifiers( pub fn eek_virtual_keyboard_set_modifiers(
virtual_keyboard: ZwpVirtualKeyboardV1, virtual_keyboard: ZwpVirtualKeyboardV1,
modifiers: u32, modifiers: u32,
); );
pub fn squeek_key_map_from_str(keymap_str: *const c_char) -> KeyMap;
} }
} }
@ -70,15 +41,35 @@ impl VirtualKeyboard {
// TODO: error out if keymap not set // TODO: error out if keymap not set
pub fn switch( pub fn switch(
&self, &self,
keycode: KeyCode, keycodes: &[KeyCode],
action: PressType, action: PressType,
timestamp: Timestamp, timestamp: Timestamp,
) { ) {
let keycodes_count = keycodes.len();
for keycode in keycodes.iter() {
let keycode = keycode - 8; let keycode = keycode - 8;
unsafe { match (action, keycodes_count) {
// Pressing a key made out of a single keycode is simple:
// press on press, release on release.
(_, 1) => unsafe {
c::eek_virtual_keyboard_v1_key( c::eek_virtual_keyboard_v1_key(
self.0, timestamp.0, keycode, action.clone() as u32 self.0, timestamp.0, keycode, action.clone() as u32
); );
},
// A key made of multiple keycodes
// has to submit them one after the other
(PressType::Pressed, _) => unsafe {
c::eek_virtual_keyboard_v1_key(
self.0, timestamp.0, keycode, PressType::Pressed as u32
);
c::eek_virtual_keyboard_v1_key(
self.0, timestamp.0, keycode, PressType::Released as u32
);
},
// Design choice here: submit multiple all at press time
// and do nothing at release time
(PressType::Released, _) => {},
}
} }
} }
@ -89,12 +80,9 @@ impl VirtualKeyboard {
} }
} }
pub fn update_keymap(&self, keymap: &c::KeyMap) { pub fn update_keymap(&self, keyboard: LevelKeyboard) {
unsafe { unsafe {
c::eek_virtual_keyboard_update_keymap( c::eek_virtual_keyboard_update_keymap(self.0, keyboard);
self.0,
keymap as *const c::KeyMap,
);
} }
} }
} }

View File

@ -14,10 +14,10 @@ eek_virtual_keyboard_v1_key(struct zwp_virtual_keyboard_v1 *zwp_virtual_keyboard
} }
void eek_virtual_keyboard_update_keymap(struct zwp_virtual_keyboard_v1 *zwp_virtual_keyboard_v1, struct keymap *keymap) { void eek_virtual_keyboard_update_keymap(struct zwp_virtual_keyboard_v1 *zwp_virtual_keyboard_v1, const LevelKeyboard *keyboard) {
zwp_virtual_keyboard_v1_keymap(zwp_virtual_keyboard_v1, zwp_virtual_keyboard_v1_keymap(zwp_virtual_keyboard_v1,
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
keymap->fd, keymap->fd_len); keyboard->keymap.fd, keyboard->keymap.fd_len);
} }
void void

View File

@ -46,68 +46,40 @@ endforeach
# The layout test is in the examples directory # The layout test is in the examples directory
# due to the way Cargo builds executables # due to the way Cargo builds executables
# and the need to call it manually. # and the need to call it manually
# This is the list of tested builtin layouts.
# Please keep each block alphabetical!
# Please keep shapes (with _) on the same line,
# variants (with +) on separate lines.
foreach layout : [ foreach layout : [
# This is the fallback layout,
# so stays first to make sure it never goes missing.
'us', 'us_wide', 'us', 'us_wide',
# Block: Languages
'be', 'be_wide',
'bg',
'br', 'br',
'cz', 'cz_wide', 'be', 'be_wide',
'cz+qwerty', 'cz+qwerty_wide',
'de', 'de_wide', 'de', 'de_wide',
'dk', 'dk',
'epo',
'es', 'es',
'fi', 'fi',
'fr', 'fr_wide', 'fr', 'fr_wide',
'gr', 'gr',
'ir',
'it', 'it',
'it+fur',
'jp+kana','jp+kana_wide', 'jp+kana','jp+kana_wide',
'no', 'no',
'number',
'pl', 'pl_wide', 'pl', 'pl_wide',
'ru', 'ru',
'se', 'se',
'th',
'ua', 'ua',
'us+colemak',
# Block: Not languages.
'emoji',
'number',
'terminal', 'terminal_wide', 'terminal', 'terminal_wide',
'emoji',
] ]
extra = [] extra = []
if layout == 'emoji' if layout == 'emoji'
extra += ['allow_missing_return'] extra += ['allow_missing_return']
endif endif
# Older Cargo seens to be sensitive to something
# about the RUST_FLAGS env var, and rebuilds all tests when it's set,
# increasing test time by 2 orders of magnitude.
# Let it have its way.
if get_option('legacy') == true
timeout = 300
else
timeout = 30
endif
test( test(
'test_layout_' + layout, 'test_layout_' + layout,
cargo_script, cargo_script,
args: ['run'] + cargo_build_flags args: ['run'] + cargo_build_flags
+ ['--example', 'test_layout', '--', layout] + ['--example', 'test_layout', '--', layout]
+ extra, + extra,
timeout: timeout,
workdir: meson.build_root(), workdir: meson.build_root(),
) )
endforeach endforeach