Add a popover menu to switch languages
This commit is contained in:
264
Cargo.lock
generated
264
Cargo.lock
generated
@ -1,15 +1,224 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
|
[[package]]
|
||||||
|
name = "atk-sys"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cairo-rs"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cairo-sys-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glib 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cairo-sys-rs"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"glib 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.0.45"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dtoa"
|
name = "dtoa"
|
||||||
version = "0.4.4"
|
version = "0.4.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fragile"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gdk"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cairo-rs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cairo-sys-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gdk-pixbuf 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gdk-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gio-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glib 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"pango 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gdk-pixbuf"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"gdk-pixbuf-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gio-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glib 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gdk-pixbuf-sys"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"gio-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gdk-sys"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cairo-sys-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gdk-pixbuf-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gio-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"pango-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gio"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"fragile 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gio-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glib 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gio-sys"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "glib"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "glib-sys"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gobject-sys"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gtk"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cairo-rs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cairo-sys-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gdk 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gdk-pixbuf 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gdk-pixbuf-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gdk-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gio-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glib 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gtk-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"pango 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gtk-sys"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"atk-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cairo-sys-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gdk-pixbuf-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gdk-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gio-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"pango-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.62"
|
version = "0.2.62"
|
||||||
@ -34,6 +243,36 @@ dependencies = [
|
|||||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pango"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glib 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"pango-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pango-sys"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pkg-config"
|
||||||
|
version = "0.3.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
@ -55,6 +294,11 @@ name = "rs"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glib 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gtk 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"gtk-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -142,12 +386,32 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
"checksum atk-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7017e53393e713212aed7aea336b6553be4927f58c37070a56c2fe3d107e489"
|
||||||
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
|
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
|
||||||
|
"checksum cairo-rs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd940f0d609699e343ef71c4af5f66423afbf30d666f796dabd8fd15229cf5b6"
|
||||||
|
"checksum cairo-sys-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d25596627380be4381247dba06c69ad05ca21b3b065bd9827e416882ac41dcd2"
|
||||||
|
"checksum cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "4fc9a35e1f4290eb9e5fc54ba6cf40671ed2a2514c3eeb2b2a908dda2ea5a1be"
|
||||||
"checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e"
|
"checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e"
|
||||||
|
"checksum fragile 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f8140122fa0d5dcb9fc8627cfce2b37cc1500f752636d46ea28bc26785c2f9"
|
||||||
|
"checksum gdk 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc52c7244046df9d959df87289f1fc5cca23f9f850bab0c967963e2ecb83a96"
|
||||||
|
"checksum gdk-pixbuf 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc3aa730cb4df3de5d9fed59f43afdf9e5fb2d3d10bfcbd04cec031435ce87f5"
|
||||||
|
"checksum gdk-pixbuf-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08284f16ce4d909b10d785a763ba190e222d2c1557b29908bf0a661e27a8ac3b"
|
||||||
|
"checksum gdk-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "108548ebf5329b551f2b97ab356908d14627905abb74b936c3372de1535aee81"
|
||||||
|
"checksum gio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "29a44b051990573448edc80b1995237f8b97b5734d2aec05105b9242aa10af11"
|
||||||
|
"checksum gio-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6975ada29f7924dc1c90b30ed3b32d777805a275556c05e420da4fbdc22eb250"
|
||||||
|
"checksum glib 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a333edf5b9f1411c246ef14e7881b087255f04c56dbef48c64a0cb039b4b340"
|
||||||
|
"checksum glib-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3573351e846caed9f11207b275cd67bc07f0c2c94fb628e5d7c92ca056c7882d"
|
||||||
|
"checksum gobject-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08475e4a08f27e6e2287005950114735ed61cec2cb8c1187682a5aec8c69b715"
|
||||||
|
"checksum gtk 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "56a6b30f194f09a17bb7ffa95c3ecdb405abd3b75ff981f831b1f6d18fe115ff"
|
||||||
|
"checksum gtk-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d487d333a4b87072e6bf9f2e55befa0ebef01b9496c2e263c0f4a1ff3d6c04b1"
|
||||||
|
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
|
"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
|
||||||
"checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83"
|
"checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83"
|
||||||
"checksum maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
|
"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 memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
|
||||||
|
"checksum pango 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4c2cb169402a3eb1ba034a7cc7d95b8b1c106e9be5ba4be79a5a93dc1a2795f4"
|
||||||
|
"checksum pango-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6eb49268e69dd0c1da5d3001a61aac08e2e9d2bfbe4ae4b19b9963c998f6453"
|
||||||
|
"checksum pkg-config 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "72d5370d90f49f70bd033c3d75e87fc529fbfff9d6f7cccef07d6170079d91ea"
|
||||||
"checksum proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afdc77cc74ec70ed262262942ebb7dac3d479e9e5cfa2da1841c0806f6cdabcc"
|
"checksum proc-macro2 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afdc77cc74ec70ed262262942ebb7dac3d479e9e5cfa2da1841c0806f6cdabcc"
|
||||||
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
|
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
|
||||||
"checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd"
|
"checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd"
|
||||||
|
|||||||
22
Cargo.toml
22
Cargo.toml
@ -9,6 +9,28 @@ serde = { version = "1.0.*", features = ["derive"] }
|
|||||||
serde_yaml = "0.8.*"
|
serde_yaml = "0.8.*"
|
||||||
xkbcommon = { version = "0.4.*", features = ["wayland"] }
|
xkbcommon = { version = "0.4.*", features = ["wayland"] }
|
||||||
|
|
||||||
|
[dependencies.gio]
|
||||||
|
version = ""
|
||||||
|
features = ["v2_44"]
|
||||||
|
|
||||||
|
[dependencies.glib]
|
||||||
|
version = ""
|
||||||
|
features = ["v2_44"]
|
||||||
|
|
||||||
|
[dependencies.glib-sys]
|
||||||
|
version = ""
|
||||||
|
features = ["v2_44"]
|
||||||
|
|
||||||
|
|
||||||
|
[dependencies.gtk]
|
||||||
|
version = "0.5.*"
|
||||||
|
features = ["v3_22"]
|
||||||
|
|
||||||
|
[dependencies.gtk-sys]
|
||||||
|
version = ""
|
||||||
|
features = ["v3_22"]
|
||||||
|
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "rs"
|
name = "rs"
|
||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|||||||
19
data/popup.ui
Normal file
19
data/popup.ui
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- Generated with glade 3.22.1 -->
|
||||||
|
<interface>
|
||||||
|
<requires lib="gtk+" version="3.16"/>
|
||||||
|
<object class="GtkPopoverMenu" id="main_menu">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox" id="box">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="submenu">main</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</interface>
|
||||||
@ -29,6 +29,7 @@
|
|||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ua.xml</file>
|
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ua.xml</file>
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ug.xml</file>
|
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/ug.xml</file>
|
||||||
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/zh-bopomofo.xml</file>
|
<file compressed="true" preprocess="xml-stripblanks">keyboards/symbols/zh-bopomofo.xml</file>
|
||||||
|
<file compressed="true" preprocess="xml-stripblanks">popup.ui</file>
|
||||||
<file>icons/key-enter.svg</file>
|
<file>icons/key-enter.svg</file>
|
||||||
<file>icons/key-shift.svg</file>
|
<file>icons/key-shift.svg</file>
|
||||||
<file>icons/keyboard-mode-symbolic.svg</file>
|
<file>icons/keyboard-mode-symbolic.svg</file>
|
||||||
|
|||||||
5
debian/control
vendored
5
debian/control
vendored
@ -12,6 +12,11 @@ Build-Depends:
|
|||||||
libgtk-3-dev,
|
libgtk-3-dev,
|
||||||
libcroco3-dev,
|
libcroco3-dev,
|
||||||
librust-bitflags-1-dev (>= 1.0),
|
librust-bitflags-1-dev (>= 1.0),
|
||||||
|
librust-gio+v2-44-dev,
|
||||||
|
librust-glib+v2-44-dev,
|
||||||
|
librust-glib-sys-dev,
|
||||||
|
librust-gtk+v3-22-dev (>= 0.5),
|
||||||
|
librust-gtk-sys-dev,
|
||||||
librust-maplit-1-dev (>= 1.0),
|
librust-maplit-1-dev (>= 1.0),
|
||||||
librust-serde-derive-1-dev (>= 1.0),
|
librust-serde-derive-1-dev (>= 1.0),
|
||||||
librust-serde-yaml-0.8-dev (>= 0.8),
|
librust-serde-yaml-0.8-dev (>= 0.8),
|
||||||
|
|||||||
@ -145,7 +145,7 @@ static void release(EekGtkKeyboard *self, guint32 time)
|
|||||||
{
|
{
|
||||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||||
|
|
||||||
squeek_layout_release(priv->keyboard->layout, priv->keyboard->manager->virtual_keyboard, time, self);
|
squeek_layout_release(priv->keyboard->layout, priv->keyboard->manager->virtual_keyboard, eek_renderer_get_transformation(priv->renderer), time, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|||||||
@ -36,4 +36,5 @@ pub enum Action {
|
|||||||
/// The key events this symbol submits when submitting text is not possible
|
/// The key events this symbol submits when submitting text is not possible
|
||||||
keys: Vec<KeySym>,
|
keys: Vec<KeySym>,
|
||||||
},
|
},
|
||||||
|
ShowPreferences,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -509,10 +509,7 @@ fn create_action(
|
|||||||
&view_names
|
&view_names
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
Some(Action::ShowPrefs) => ::action::Action::Submit {
|
Some(Action::ShowPrefs) => ::action::Action::ShowPreferences,
|
||||||
text: None,
|
|
||||||
keys: Vec::new(),
|
|
||||||
},
|
|
||||||
None => ::action::Action::Submit {
|
None => ::action::Action::Submit {
|
||||||
text: None,
|
text: None,
|
||||||
keys: keysyms.into_iter().map(::action::KeySym).collect(),
|
keys: keysyms.into_iter().map(::action::KeySym).collect(),
|
||||||
|
|||||||
@ -62,7 +62,10 @@ 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*);
|
||||||
|
|
||||||
void squeek_layout_release(struct squeek_layout *layout, struct zwp_virtual_keyboard_v1 *virtual_keyboard, uint32_t timestamp, EekGtkKeyboard *ui_keyboard);
|
void squeek_layout_release(struct squeek_layout *layout, struct zwp_virtual_keyboard_v1 *virtual_keyboard,
|
||||||
|
struct transformation widget_to_layout,
|
||||||
|
uint32_t timestamp,
|
||||||
|
EekGtkKeyboard *ui_keyboard);
|
||||||
void squeek_layout_release_all_only(struct squeek_layout *layout, struct zwp_virtual_keyboard_v1 *virtual_keyboard, uint32_t timestamp);
|
void squeek_layout_release_all_only(struct squeek_layout *layout, struct zwp_virtual_keyboard_v1 *virtual_keyboard, uint32_t timestamp);
|
||||||
void squeek_layout_depress(struct squeek_layout *layout, struct zwp_virtual_keyboard_v1 *virtual_keyboard,
|
void squeek_layout_depress(struct squeek_layout *layout, struct zwp_virtual_keyboard_v1 *virtual_keyboard,
|
||||||
double x_widget, double y_widget,
|
double x_widget, double y_widget,
|
||||||
|
|||||||
159
src/layout.rs
159
src/layout.rs
@ -37,6 +37,7 @@ pub mod c {
|
|||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::os::raw::{ c_char, c_void };
|
use std::os::raw::{ c_char, c_void };
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
use gtk_sys;
|
||||||
|
|
||||||
// The following defined in C
|
// The following defined in C
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ pub mod c {
|
|||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct EekGtkKeyboard(*const c_void);
|
pub struct EekGtkKeyboard(pub *const gtk_sys::GtkWidget);
|
||||||
|
|
||||||
/// Defined in eek-types.h
|
/// Defined in eek-types.h
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
@ -245,7 +246,7 @@ pub mod c {
|
|||||||
origin_y: f64,
|
origin_y: f64,
|
||||||
scale: f64,
|
scale: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Transformation {
|
impl Transformation {
|
||||||
fn forward(&self, p: Point) -> Point {
|
fn forward(&self, p: Point) -> Point {
|
||||||
Point {
|
Point {
|
||||||
@ -253,6 +254,25 @@ pub mod c {
|
|||||||
y: (p.y - self.origin_y) / self.scale,
|
y: (p.y - self.origin_y) / self.scale,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn reverse(&self, p: Point) -> Point {
|
||||||
|
Point {
|
||||||
|
x: p.x * self.scale + self.origin_x,
|
||||||
|
y: p.y * self.scale + self.origin_y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn reverse_bounds(&self, b: Bounds) -> Bounds {
|
||||||
|
let start = self.reverse(Point { x: b.x, y: b.y });
|
||||||
|
let end = self.reverse(Point {
|
||||||
|
x: b.x + b.width,
|
||||||
|
y: b.y + b.height,
|
||||||
|
});
|
||||||
|
Bounds {
|
||||||
|
x: start.x,
|
||||||
|
y: start.y,
|
||||||
|
width: end.x - start.x,
|
||||||
|
height: end.y - start.y,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is constructed only in C, no need for warnings
|
// This is constructed only in C, no need for warnings
|
||||||
@ -319,28 +339,30 @@ pub mod c {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Release pointer in the specified position
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C"
|
pub extern "C"
|
||||||
fn squeek_layout_release(
|
fn squeek_layout_release(
|
||||||
layout: *mut Layout,
|
layout: *mut Layout,
|
||||||
virtual_keyboard: ZwpVirtualKeyboardV1, // TODO: receive a reference to the backend
|
virtual_keyboard: ZwpVirtualKeyboardV1, // TODO: receive a reference to the backend
|
||||||
|
widget_to_layout: Transformation,
|
||||||
time: u32,
|
time: u32,
|
||||||
ui_keyboard: EekGtkKeyboard,
|
ui_keyboard: EekGtkKeyboard,
|
||||||
) {
|
) {
|
||||||
|
let time = Timestamp(time);
|
||||||
let layout = unsafe { &mut *layout };
|
let layout = unsafe { &mut *layout };
|
||||||
let virtual_keyboard = VirtualKeyboard(virtual_keyboard);
|
let virtual_keyboard = VirtualKeyboard(virtual_keyboard);
|
||||||
// The list must be copied,
|
// The list must be copied,
|
||||||
// because it will be mutated in the loop
|
// because it will be mutated in the loop
|
||||||
for key in layout.pressed_keys.clone() {
|
for key in layout.pressed_keys.clone() {
|
||||||
let key: &Rc<RefCell<KeyState>> = key.borrow();
|
let key: &Rc<RefCell<KeyState>> = key.borrow();
|
||||||
layout.release_key(
|
ui::release_key(
|
||||||
|
layout,
|
||||||
&virtual_keyboard,
|
&virtual_keyboard,
|
||||||
&mut key.clone(),
|
&widget_to_layout,
|
||||||
Timestamp(time)
|
time,
|
||||||
);
|
ui_keyboard,
|
||||||
let view = layout.get_current_view();
|
key
|
||||||
::layout::procedures::release_ui_buttons(
|
|
||||||
&view, key, ui_keyboard,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -418,6 +440,7 @@ pub mod c {
|
|||||||
time: u32,
|
time: u32,
|
||||||
ui_keyboard: EekGtkKeyboard,
|
ui_keyboard: EekGtkKeyboard,
|
||||||
) {
|
) {
|
||||||
|
let time = Timestamp(time);
|
||||||
let layout = unsafe { &mut *layout };
|
let layout = unsafe { &mut *layout };
|
||||||
let virtual_keyboard = VirtualKeyboard(virtual_keyboard);
|
let virtual_keyboard = VirtualKeyboard(virtual_keyboard);
|
||||||
|
|
||||||
@ -442,36 +465,30 @@ pub mod c {
|
|||||||
if Rc::ptr_eq(&state, &wrapped_key.0) {
|
if Rc::ptr_eq(&state, &wrapped_key.0) {
|
||||||
found = true;
|
found = true;
|
||||||
} else {
|
} else {
|
||||||
layout.release_key(
|
ui::release_key(
|
||||||
|
layout,
|
||||||
&virtual_keyboard,
|
&virtual_keyboard,
|
||||||
&mut key.clone(),
|
&widget_to_layout,
|
||||||
Timestamp(time),
|
time,
|
||||||
);
|
ui_keyboard,
|
||||||
let view = layout.get_current_view();
|
key,
|
||||||
::layout::procedures::release_ui_buttons(
|
|
||||||
&view, key, ui_keyboard,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !found {
|
if !found {
|
||||||
layout.press_key(
|
layout.press_key(&virtual_keyboard, &mut state, time);
|
||||||
&virtual_keyboard,
|
|
||||||
&mut state,
|
|
||||||
Timestamp(time),
|
|
||||||
);
|
|
||||||
unsafe { eek_gtk_on_button_pressed(c_place, ui_keyboard) };
|
unsafe { eek_gtk_on_button_pressed(c_place, ui_keyboard) };
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for wrapped_key in pressed {
|
for wrapped_key in pressed {
|
||||||
let key: &Rc<RefCell<KeyState>> = wrapped_key.borrow();
|
let key: &Rc<RefCell<KeyState>> = wrapped_key.borrow();
|
||||||
layout.release_key(
|
ui::release_key(
|
||||||
|
layout,
|
||||||
&virtual_keyboard,
|
&virtual_keyboard,
|
||||||
&mut key.clone(),
|
&widget_to_layout,
|
||||||
Timestamp(time),
|
time,
|
||||||
);
|
ui_keyboard,
|
||||||
let view = layout.get_current_view();
|
key,
|
||||||
::layout::procedures::release_ui_buttons(
|
|
||||||
&view, key, ui_keyboard,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -503,6 +520,28 @@ pub mod c {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
fn near(a: f64, b: f64) -> bool {
|
||||||
|
(a - b).abs() < ((a + b) * 0.001f64).abs()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn transform_back() {
|
||||||
|
let transform = Transformation {
|
||||||
|
origin_x: 10f64,
|
||||||
|
origin_y: 11f64,
|
||||||
|
scale: 12f64,
|
||||||
|
};
|
||||||
|
let point = Point { x: 1f64, y: 1f64 };
|
||||||
|
let transformed = transform.reverse(transform.forward(point.clone()));
|
||||||
|
assert!(near(point.x, transformed.x));
|
||||||
|
assert!(near(point.y, transformed.y));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -717,6 +756,12 @@ pub struct Layout {
|
|||||||
pub keymap_str: 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.
|
||||||
|
// The renderer doesn't need the list of pressed keys any more,
|
||||||
|
// because it needs to iterate
|
||||||
|
// through all buttons of the current view anyway.
|
||||||
|
// When the list tracks actual location,
|
||||||
|
// it becomes possible to place popovers and other UI accurately.
|
||||||
pub pressed_keys: HashSet<::util::Pointer<RefCell<KeyState>>>,
|
pub pressed_keys: HashSet<::util::Pointer<RefCell<KeyState>>>,
|
||||||
pub locked_keys: HashSet<::util::Pointer<RefCell<KeyState>>>,
|
pub locked_keys: HashSet<::util::Pointer<RefCell<KeyState>>>,
|
||||||
}
|
}
|
||||||
@ -949,6 +994,64 @@ mod procedures {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_button_bounds(
|
||||||
|
view: &View,
|
||||||
|
row: &Row,
|
||||||
|
button: &Button
|
||||||
|
) -> Option<c::Bounds> {
|
||||||
|
match &row.bounds {
|
||||||
|
Some(row) => Some(c::Bounds {
|
||||||
|
x: view.bounds.x + row.x + button.bounds.x,
|
||||||
|
y: view.bounds.y + row.y + button.bounds.y,
|
||||||
|
width: button.bounds.width,
|
||||||
|
height: button.bounds.height,
|
||||||
|
}),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Top level UI procedures
|
||||||
|
mod ui {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
// TODO: turn into release_button
|
||||||
|
pub fn release_key(
|
||||||
|
layout: &mut Layout,
|
||||||
|
virtual_keyboard: &VirtualKeyboard,
|
||||||
|
widget_to_layout: &c::procedures::Transformation,
|
||||||
|
time: Timestamp,
|
||||||
|
ui_keyboard: c::EekGtkKeyboard,
|
||||||
|
key: &Rc<RefCell<KeyState>>,
|
||||||
|
) {
|
||||||
|
layout.release_key(virtual_keyboard, &mut key.clone(), time);
|
||||||
|
|
||||||
|
let view = layout.get_current_view();
|
||||||
|
let action = RefCell::borrow(key).action.clone();
|
||||||
|
if let Action::ShowPreferences = action {
|
||||||
|
let paths = ::layout::procedures::find_key_paths(
|
||||||
|
view, key
|
||||||
|
);
|
||||||
|
// getting first item will cause mispositioning
|
||||||
|
// with more than one button with the same key
|
||||||
|
// on the keyboard
|
||||||
|
if let Some((row, button)) = paths.get(0) {
|
||||||
|
let bounds = ::layout::procedures::get_button_bounds(
|
||||||
|
view, row, button
|
||||||
|
).unwrap_or_else(|| {
|
||||||
|
eprintln!("BUG: Clicked button has no position?");
|
||||||
|
c::Bounds { x: 0f64, y: 0f64, width: 0f64, height: 0f64 }
|
||||||
|
});
|
||||||
|
::popover::show(
|
||||||
|
ui_keyboard,
|
||||||
|
widget_to_layout.reverse_bounds(bounds)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
procedures::release_ui_buttons(view, key, ui_keyboard);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@ -1,5 +1,10 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate bitflags;
|
extern crate bitflags;
|
||||||
|
extern crate gio;
|
||||||
|
extern crate glib;
|
||||||
|
extern crate glib_sys;
|
||||||
|
extern crate gtk;
|
||||||
|
extern crate gtk_sys;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
#[macro_use] // only for tests
|
#[macro_use] // only for tests
|
||||||
extern crate maplit;
|
extern crate maplit;
|
||||||
@ -13,6 +18,7 @@ pub mod imservice;
|
|||||||
mod keyboard;
|
mod keyboard;
|
||||||
mod layout;
|
mod layout;
|
||||||
mod outputs;
|
mod outputs;
|
||||||
|
mod popover;
|
||||||
mod resources;
|
mod resources;
|
||||||
mod submission;
|
mod submission;
|
||||||
mod util;
|
mod util;
|
||||||
|
|||||||
9
src/popover.h
Normal file
9
src/popover.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#ifndef POPOVER_H__
|
||||||
|
#define POPOVER_H__
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include "eek/eek-keyboard.h"
|
||||||
|
|
||||||
|
void squeek_popover_show(GtkWidget*, struct button_place);
|
||||||
|
|
||||||
|
#endif
|
||||||
158
src/popover.rs
Normal file
158
src/popover.rs
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
/*! The layout chooser popover */
|
||||||
|
|
||||||
|
use gio;
|
||||||
|
use gtk;
|
||||||
|
use ::layout::c::EekGtkKeyboard;
|
||||||
|
|
||||||
|
use gio::ActionExt;
|
||||||
|
use gio::ActionMapExt;
|
||||||
|
use gio::SettingsExt;
|
||||||
|
use glib::translate::FromGlibPtrNone;
|
||||||
|
use glib::variant::ToVariant;
|
||||||
|
use gtk::PopoverExt;
|
||||||
|
use gtk::WidgetExt;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
mod variants {
|
||||||
|
use glib;
|
||||||
|
use glib_sys;
|
||||||
|
|
||||||
|
use glib::translate::FromGlibPtrFull;
|
||||||
|
use glib::translate::ToGlibPtr;
|
||||||
|
|
||||||
|
/// Unpacks tuple & array variants
|
||||||
|
fn get_items(items: glib::Variant) -> Vec<glib::Variant> {
|
||||||
|
let variant_naked = items.to_glib_none().0;
|
||||||
|
let count = unsafe { glib_sys::g_variant_n_children(variant_naked) };
|
||||||
|
(0..count).map(|index|
|
||||||
|
unsafe {
|
||||||
|
glib::Variant::from_glib_full(
|
||||||
|
glib_sys::g_variant_get_child_value(variant_naked, index)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Unpacks "a(ss)" variants
|
||||||
|
pub fn get_tuples(items: glib::Variant) -> Vec<(String, String)> {
|
||||||
|
get_items(items)
|
||||||
|
.into_iter()
|
||||||
|
.map(get_items)
|
||||||
|
.map(|v| {
|
||||||
|
(
|
||||||
|
v[0].get::<String>().unwrap(),
|
||||||
|
v[1].get::<String>().unwrap(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_menu_builder(inputs: Vec<&str>) -> gtk::Builder {
|
||||||
|
let mut xml: Vec<u8> = Vec::new();
|
||||||
|
writeln!(
|
||||||
|
xml,
|
||||||
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>
|
||||||
|
<interface>
|
||||||
|
<menu id=\"app-menu\">
|
||||||
|
<section>"
|
||||||
|
).unwrap();
|
||||||
|
for input in inputs {
|
||||||
|
writeln!(
|
||||||
|
xml,
|
||||||
|
"
|
||||||
|
<item>
|
||||||
|
<attribute name=\"label\" translatable=\"yes\">{}</attribute>
|
||||||
|
<attribute name=\"action\">layout</attribute>
|
||||||
|
<attribute name=\"target\">{0}</attribute>
|
||||||
|
</item>",
|
||||||
|
input,
|
||||||
|
).unwrap();
|
||||||
|
}
|
||||||
|
writeln!(
|
||||||
|
xml,
|
||||||
|
"
|
||||||
|
</section>
|
||||||
|
</menu>
|
||||||
|
</interface>"
|
||||||
|
).unwrap();
|
||||||
|
gtk::Builder::new_from_string(
|
||||||
|
&String::from_utf8(xml).expect("Bad menu definition")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_layout(kind: String, name: String) {
|
||||||
|
let settings = gio::Settings::new("org.gnome.desktop.input-sources");
|
||||||
|
let inputs = settings.get_value("sources").unwrap();
|
||||||
|
let inputs = variants::get_tuples(inputs).into_iter();
|
||||||
|
for (index, (ikind, iname)) in inputs.enumerate() {
|
||||||
|
if (&ikind, &iname) == (&kind, &name) {
|
||||||
|
settings.set_uint("current", index as u32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
settings.apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn show(window: EekGtkKeyboard, position: ::layout::c::Bounds) {
|
||||||
|
unsafe { gtk::set_initialized() };
|
||||||
|
let window = unsafe { gtk::Widget::from_glib_none(window.0) };
|
||||||
|
|
||||||
|
let settings = gio::Settings::new("org.gnome.desktop.input-sources");
|
||||||
|
let inputs = settings.get_value("sources").unwrap();
|
||||||
|
let current = settings.get_uint("current") as usize;
|
||||||
|
let inputs = variants::get_tuples(inputs);
|
||||||
|
|
||||||
|
let input_names: Vec<&str> = inputs.iter()
|
||||||
|
.map(|(_kind, name)| name.as_str())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let builder = make_menu_builder(input_names.clone());
|
||||||
|
// Much more debuggable to populate the model & menu
|
||||||
|
// from a string representation
|
||||||
|
// than add items imperatively
|
||||||
|
let model: gio::MenuModel = builder.get_object("app-menu").unwrap();
|
||||||
|
|
||||||
|
let menu = gtk::Popover::new_from_model(Some(&window), &model);
|
||||||
|
menu.set_pointing_to(>k::Rectangle {
|
||||||
|
x: position.x.ceil() as i32,
|
||||||
|
y: position.y.ceil() as i32,
|
||||||
|
width: position.width.floor() as i32,
|
||||||
|
height: position.width.floor() as i32,
|
||||||
|
});
|
||||||
|
|
||||||
|
let initial_state = input_names[current].to_variant();
|
||||||
|
|
||||||
|
let layout_action = gio::SimpleAction::new_stateful(
|
||||||
|
"layout",
|
||||||
|
Some(initial_state.type_()),
|
||||||
|
&initial_state,
|
||||||
|
);
|
||||||
|
|
||||||
|
let action_group = gio::SimpleActionGroup::new();
|
||||||
|
action_group.add_action(&layout_action);
|
||||||
|
|
||||||
|
menu.insert_action_group("popup", Some(&action_group));
|
||||||
|
menu.bind_model(Some(&model), Some("popup"));
|
||||||
|
|
||||||
|
menu.connect_closed(move |_menu| {
|
||||||
|
let state = match layout_action.get_state() {
|
||||||
|
Some(v) => {
|
||||||
|
let s = v.get::<String>().or_else(|| {
|
||||||
|
eprintln!("Variant is not string: {:?}", v);
|
||||||
|
None
|
||||||
|
});
|
||||||
|
// FIXME: the `get_state` docs call for unrefing,
|
||||||
|
// but the function is nowhere to be found
|
||||||
|
// glib::Variant::unref(v);
|
||||||
|
s
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
eprintln!("No variant selected");
|
||||||
|
None
|
||||||
|
},
|
||||||
|
};
|
||||||
|
set_layout("xkb".into(), state.unwrap_or("us".into()));
|
||||||
|
});
|
||||||
|
|
||||||
|
menu.popup();
|
||||||
|
}
|
||||||
@ -23,6 +23,7 @@ pub mod c {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct Timestamp(pub u32);
|
pub struct Timestamp(pub u32);
|
||||||
|
|
||||||
/// Layout-independent backend. TODO: Have one instance per program or seat
|
/// Layout-independent backend. TODO: Have one instance per program or seat
|
||||||
|
|||||||
Reference in New Issue
Block a user