Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cb338129ca | |||
| 9e8a243439 | |||
| d3e0ee8c0d | |||
| 2e2c8ab2cb | |||
| 36474d3e9d | |||
| e6438503a5 | |||
| 58c7fe98b8 | |||
| 6867f48bf9 | |||
| 71942f7221 | |||
| c486ad1eb3 | |||
| 05e7cde8fa | |||
| 9adb593e8e | |||
| 073326f31b | |||
| dae324f86d | |||
| 2eec3372f3 | |||
| f6724c0948 | |||
| af8b688d94 | |||
| d21dba6a8f | |||
| 0e2d459d5a | |||
| 89ad302255 | |||
| 494f9442c4 | |||
| 68087a125c | |||
| 323fd7ea14 | |||
| 3167cfce9c | |||
| 8ea6f6d5c1 | |||
| 3b70116a15 | |||
| 397f5e126e | |||
| 14d7d5d4e0 | |||
| 6528879fed | |||
| 57aeeaa882 | |||
| bbceba7e9b | |||
| 5a210712f6 | |||
| bb8bba163e | |||
| 83b0d1553f | |||
| a1664630ed | |||
| 529ac89150 | |||
| 479f1befc9 | |||
| 29b30fbe22 | |||
| 1ccc663c48 | |||
| 7c43528ebf | |||
| 7f4c823c1e | |||
| d19050e06d | |||
| b5142ac765 | |||
| b456889fe9 | |||
| 3fdbcf905b | |||
| 8a2de2fdf2 | |||
| bd390894c5 | |||
| 04018a8c06 | |||
| b4cd5659cb | |||
| 59c3da0344 | |||
| c5eb41292c |
@ -3,6 +3,7 @@ image: pureos/byzantium
|
|||||||
stages:
|
stages:
|
||||||
- build
|
- build
|
||||||
- test
|
- test
|
||||||
|
- deploy
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- apt-get -y update
|
- apt-get -y update
|
||||||
@ -74,6 +75,7 @@ build_deb:arm64:
|
|||||||
|
|
||||||
build_deb:future:
|
build_deb:future:
|
||||||
image: debian:sid
|
image: debian:sid
|
||||||
|
allow_failure: true
|
||||||
tags:
|
tags:
|
||||||
- aarch64
|
- aarch64
|
||||||
stage: build
|
stage: build
|
||||||
@ -93,6 +95,22 @@ build_deb:future:
|
|||||||
- debuild -i -us -uc -b
|
- debuild -i -us -uc -b
|
||||||
- cp ../*.deb .
|
- cp ../*.deb .
|
||||||
|
|
||||||
|
build_reference:
|
||||||
|
stage: build
|
||||||
|
needs:
|
||||||
|
- job: build_meson
|
||||||
|
artifacts: true
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- _build/doc
|
||||||
|
script:
|
||||||
|
- apt-get -y install cargo
|
||||||
|
- cd _build
|
||||||
|
- ../cargo.sh doc --no-deps --document-private-items
|
||||||
|
except:
|
||||||
|
variables:
|
||||||
|
- $PKG_ONLY == "1"
|
||||||
|
|
||||||
test_lintian:
|
test_lintian:
|
||||||
stage: test
|
stage: test
|
||||||
needs:
|
needs:
|
||||||
@ -141,3 +159,17 @@ check_release:
|
|||||||
except:
|
except:
|
||||||
variables:
|
variables:
|
||||||
- $PKG_ONLY == "1"
|
- $PKG_ONLY == "1"
|
||||||
|
|
||||||
|
pages:
|
||||||
|
stage: deploy
|
||||||
|
needs:
|
||||||
|
- build_docs
|
||||||
|
- build_reference
|
||||||
|
script:
|
||||||
|
- mv _build/ public/
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- public
|
||||||
|
only:
|
||||||
|
refs:
|
||||||
|
- master
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
# Dependencies which change based on build flags
|
# Dependencies which change based on build flags
|
||||||
bitflags = "1.2.*"
|
bitflags = "1.2.*"
|
||||||
clap = { version = "2.33.*", default-features = false }
|
clap = { version = "2.33.*", default-features = false }
|
||||||
|
zbus = "1.0.*"
|
||||||
|
zvariant = "2.0.*"
|
||||||
|
# Newer versions seem to confuse the version of Cargo on Debian Bullseye
|
||||||
|
zvariant_derive = "2.0.*"
|
||||||
|
|
||||||
[dependencies.cairo-rs]
|
[dependencies.cairo-rs]
|
||||||
version = "0.7.*"
|
version = "0.7.*"
|
||||||
@ -29,4 +33,4 @@ features = ["v3_22"]
|
|||||||
|
|
||||||
[dependencies.gtk-sys]
|
[dependencies.gtk-sys]
|
||||||
version = "0.9"
|
version = "0.9"
|
||||||
features = ["v3_22"]
|
features = ["v3_22"]
|
||||||
@ -1,7 +1,11 @@
|
|||||||
# Dependencies which change based on build flags
|
# Dependencies which change based on build flags
|
||||||
# For the newer-than-Byzantium config
|
# For the newer-than-Byzantium config
|
||||||
bitflags = "1.3.*"
|
bitflags = "1.3.*"
|
||||||
clap = { version = "2.33.*", default-features = false }
|
clap = { version = "3.1.*", features=["std"], default-features = false }
|
||||||
|
zbus = "1.9.*"
|
||||||
|
zvariant = "2.10.*"
|
||||||
|
# Newer versions seem to confuse the version of Cargo on Debian Bullseye
|
||||||
|
zvariant_derive = "2.10.*"
|
||||||
|
|
||||||
[dependencies.cairo-rs]
|
[dependencies.cairo-rs]
|
||||||
version = "0.14.*"
|
version = "0.14.*"
|
||||||
|
|||||||
4
Cargo.deps.online
Normal file
4
Cargo.deps.online
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# Dependencies which are only used with online, crates.io builds.
|
||||||
|
[patch.crates-io]
|
||||||
|
# Dependency was yanked, but gio 0.7 needs it.
|
||||||
|
fragile = { git = "https://source.puri.sm/dorota.czaplejewicz/fragile.git", tag = "0.3.0" }
|
||||||
205
Cargo.lock
generated
205
Cargo.lock
generated
@ -40,6 +40,12 @@ 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"
|
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cairo-rs"
|
name = "cairo-rs"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
@ -71,6 +77,18 @@ version = "1.0.73"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "2.33.4"
|
version = "2.33.4"
|
||||||
@ -82,11 +100,51 @@ dependencies = [
|
|||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "derivative"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enumflags2"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "83c8d82922337cd23a15f88b70d8e4ef5f11da38dd7cdb55e84dd5de99695da0"
|
||||||
|
dependencies = [
|
||||||
|
"enumflags2_derive",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enumflags2_derive"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fastrand"
|
||||||
|
version = "1.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
|
||||||
|
dependencies = [
|
||||||
|
"instant",
|
||||||
|
]
|
||||||
|
|
||||||
[[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 = "git+https://source.puri.sm/dorota.czaplejewicz/fragile.git?tag=0.3.0#51048ca11824279c2114c77fef5bcb950838fc09"
|
||||||
checksum = "05f8140122fa0d5dcb9fc8627cfce2b37cc1500f752636d46ea28bc26785c2f9"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gdk"
|
name = "gdk"
|
||||||
@ -267,14 +325,23 @@ checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "1.8.0"
|
version = "1.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223"
|
checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "instant"
|
||||||
|
version = "0.1.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
@ -283,9 +350,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.119"
|
version = "0.2.124"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4"
|
checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linked-hash-map"
|
name = "linked-hash-map"
|
||||||
@ -309,6 +376,19 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nix"
|
||||||
|
version = "0.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"cc",
|
||||||
|
"cfg-if 0.1.10",
|
||||||
|
"libc",
|
||||||
|
"void",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pango"
|
name = "pango"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@ -338,24 +418,33 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pkg-config"
|
name = "pkg-config"
|
||||||
version = "0.3.24"
|
version = "0.3.25"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
|
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-crate"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785"
|
||||||
|
dependencies = [
|
||||||
|
"toml",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.36"
|
version = "1.0.37"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
|
checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.15"
|
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 = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
|
checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
@ -378,6 +467,9 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
"xkbcommon",
|
"xkbcommon",
|
||||||
|
"zbus",
|
||||||
|
"zvariant",
|
||||||
|
"zvariant_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -386,6 +478,12 @@ version = "1.0.9"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
|
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scoped-tls"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.136"
|
version = "1.0.136"
|
||||||
@ -406,6 +504,17 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_repr"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_yaml"
|
name = "serde_yaml"
|
||||||
version = "0.8.23"
|
version = "0.8.23"
|
||||||
@ -420,9 +529,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.86"
|
version = "1.0.91"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
|
checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -438,6 +547,15 @@ dependencies = [
|
|||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.5.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-width"
|
name = "unicode-width"
|
||||||
version = "0.1.9"
|
version = "0.1.9"
|
||||||
@ -450,6 +568,12 @@ version = "0.2.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "void"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
@ -490,3 +614,56 @@ checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"linked-hash-map",
|
"linked-hash-map",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zbus"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1cb97c72cbfd5c7537ca730eeb810da7348f345ba67ab7673bcbe0d81c076427"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"derivative",
|
||||||
|
"enumflags2",
|
||||||
|
"fastrand",
|
||||||
|
"nix",
|
||||||
|
"scoped-tls",
|
||||||
|
"serde",
|
||||||
|
"serde_repr",
|
||||||
|
"zbus_macros",
|
||||||
|
"zvariant",
|
||||||
|
"zvariant_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zbus_macros"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c0c1f2a20a4cb90922b44d3bebd232b246e52b3dd95ed5bea8aec83cde3a5a8a"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-crate",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zvariant"
|
||||||
|
version = "2.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0bf85e67d1a3780cb1c56c80227532354f21907cba14805a773eb507b444580"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"enumflags2",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zvariant_derive"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d68726e8c12757384a8d1485080527e263dea67d91f19e97cd71b9292f22d7c5"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|||||||
@ -86,4 +86,4 @@ It's strongly recommended to support:
|
|||||||
Developing
|
Developing
|
||||||
----------
|
----------
|
||||||
|
|
||||||
See [`doc/hacking.md`](doc/hacking.md) for this copy, or the [official documentation](https://developer.puri.sm/projects/squeekboard/) for the current release.
|
See [`doc/hacking.md`](doc/hacking.md) for this copy, or the [official documentation](https://world.pages.gitlab.gnome.org/Phosh/squeekboard) for the current release.
|
||||||
|
|||||||
326
data/keyboards/gr+polytonic.yaml
Normal file
326
data/keyboards/gr+polytonic.yaml
Normal file
@ -0,0 +1,326 @@
|
|||||||
|
# Greek polytonic layout by Antonis Tsolomitis
|
||||||
|
# University of the Aegean, Department of Mathematics, atsol@aegean.gr
|
||||||
|
# March 2022
|
||||||
|
#
|
||||||
|
---
|
||||||
|
outlines:
|
||||||
|
default: { width: 40, height: 60 }
|
||||||
|
altline: { width: 52.67, height: 60 }
|
||||||
|
wide: { width: 62, height: 60 }
|
||||||
|
extrawide: { width: 66, height: 60 }
|
||||||
|
spaceline: { width: 140, height: 60 }
|
||||||
|
special: { width: 44, height: 60 }
|
||||||
|
|
||||||
|
views:
|
||||||
|
base:
|
||||||
|
- "semicolon ς ε ρ τ υ θ ι ο π"
|
||||||
|
- "α σ δ φ γ η ξ κ λ show_accents"
|
||||||
|
- "Shift_L ζ χ ψ ω β ν μ BackSpace"
|
||||||
|
- "show_numbers preferences space period comma Return"
|
||||||
|
upper:
|
||||||
|
- "colon EuroSign Ε Ρ Τ Υ Θ Ι Ο Π"
|
||||||
|
- "Α Σ Δ Φ Γ Η Ξ Κ Λ show_accents"
|
||||||
|
- "Shift_L Ζ Χ Ψ Ω Β Ν Μ BackSpace"
|
||||||
|
- "show_numbers preferences space exclam period_upper Return"
|
||||||
|
accents:
|
||||||
|
- "show_psiliordasiaandvaria show_psiliordasiaandoxia show_psiliordasia show_bariaorperispomeni show_oxia"
|
||||||
|
- "show_PsiliOrDasiaAndVaria show_PsiliOrDasiaAndOxia show_PsiliOrDasia show_BariaOrPerispomeni show_Oxia show_base"
|
||||||
|
- "show_PsiliOrDasiaAndPerispomeni show_psiliordasiaandperispomeni ᾿ BackSpace"
|
||||||
|
- "show_numbers preferences space Return"
|
||||||
|
oxia:
|
||||||
|
- "ά έ ή ί ϊ ΐ ό ύ ϋ ώ"
|
||||||
|
- "show_Oxia ᾳ ᾴ ῃ ῄ ῳ ῴ show_base"
|
||||||
|
- "Ϗ ϐ ϑ ϗ ϖ ΰ ϕ – — BackSpace"
|
||||||
|
- "show_numbers preferences space eis_l eis_r Return"
|
||||||
|
Oxia:
|
||||||
|
- "Ά Έ Ή Ί Ϊ Ό Ύ Ϋ Ώ"
|
||||||
|
- "show_oxia ᾼ ῌ ῼ show_base"
|
||||||
|
- "Ϗ ϐ ϑ ϗ ϖ ϕ – — BackSpace"
|
||||||
|
- "show_numbers preferences space eis_l eis_r Return"
|
||||||
|
bariaorperispomeni:
|
||||||
|
- "ὰ ὲ ὴ ὶ ῒ ὸ ὺ ὼ ῐ ῑ"
|
||||||
|
- "show_BariaOrPerispomeni ᾳ ᾲ ῃ ῂ ῳ ῲ ῠ show_base"
|
||||||
|
- "ᾶ ᾷ ῆ ῖ ῗ ῦ ῧ ῶ ῡ BackSpace"
|
||||||
|
- "show_numbers preferences space ῇ ῷ Return"
|
||||||
|
BariaOrPerispomeni:
|
||||||
|
- "Ὰ Ὲ Ὴ Ὶ Ὸ Ὺ Ὼ"
|
||||||
|
- "show_bariaorperispomeni ᾼ ῌ ῼ show_base"
|
||||||
|
- "show_numbers preferences space BackSpace Return"
|
||||||
|
psiliordasia:
|
||||||
|
- "ἀ ἐ ἠ ἰ ὀ ὐ ὠ ᾀ ᾐ ᾠ"
|
||||||
|
- "show_PsiliOrDasia ἁ ἑ ἡ ἱ ὁ ὑ ὡ show_base"
|
||||||
|
- "ᾁ ᾑ ᾡ ῤ ῥ BackSpace"
|
||||||
|
- "show_numbers preferences space Return"
|
||||||
|
PsiliOrDasia:
|
||||||
|
- "Ἀ Ἐ Ἠ Ἰ Ὀ Ὠ ᾈ ᾘ ᾨ"
|
||||||
|
- "show_psiliordasia Ἁ Ἑ Ἡ Ἱ Ὁ Ὑ Ὡ show_base"
|
||||||
|
- "ᾉ ᾙ ᾩ Ῥ BackSpace"
|
||||||
|
- "show_numbers preferences space Return"
|
||||||
|
psiliordasiaandoxia:
|
||||||
|
- "ἄ ἔ ἤ ἴ ὄ ὔ ὤ ᾄ ᾔ ᾤ"
|
||||||
|
- "show_PsiliOrDasiaAndOxia ἅ ἕ ἥ ἵ ὅ ὕ ὥ show_base"
|
||||||
|
- "ᾅ ᾕ ᾥ BackSpace"
|
||||||
|
- "show_numbers preferences space Return"
|
||||||
|
PsiliOrDasiaAndOxia:
|
||||||
|
- "Ἄ Ἔ Ἤ Ἴ Ὄ Ὤ ᾌ ᾜ ᾬ"
|
||||||
|
- "show_psiliordasiaandoxia Ἅ Ἕ Ἥ Ἵ Ὅ Ὕ Ὥ show_base"
|
||||||
|
- "ᾍ ᾝ ᾭ BackSpace"
|
||||||
|
- "show_numbers preferences space Return"
|
||||||
|
psiliordasiaandvaria:
|
||||||
|
- "ἂ ἒ ἢ ἲ ὂ ὒ ὢ ᾂ ᾒ ᾢ"
|
||||||
|
- "show_PsiliOrDasiaAndVaria ἃ ἓ ἣ ἳ ὃ ὓ ὣ show_base"
|
||||||
|
- "ᾃ ᾓ ᾣ BackSpace"
|
||||||
|
- "show_numbers preferences space Return"
|
||||||
|
PsiliOrDasiaAndVaria:
|
||||||
|
- "Ἂ Ἒ Ἢ Ἲ Ὂ Ὢ ᾊ ᾚ ᾪ"
|
||||||
|
- "show_psiliordasiaandvaria Ἃ Ἓ Ἣ Ἳ Ὃ Ὓ Ὣ show_base"
|
||||||
|
- "ᾋ ᾛ ᾫ BackSpace"
|
||||||
|
- "show_numbers preferences space Return"
|
||||||
|
psiliordasiaandperispomeni:
|
||||||
|
- "ἆ ἦ ἶ ὖ ὦ ᾆ ᾖ ᾦ"
|
||||||
|
- "show_PsiliOrDasiaAndPerispomeni ἇ ἧ ἷ ὗ ὧ show_base"
|
||||||
|
- "ᾇ ᾗ ᾧ BackSpace"
|
||||||
|
- "show_numbers preferences space Return"
|
||||||
|
PsiliOrDasiaAndPerispomeni:
|
||||||
|
- "Ἆ Ἦ Ἶ Ὦ ᾎ ᾞ ᾮ"
|
||||||
|
- "show_psiliordasiaandperispomeni Ἇ Ἧ Ἷ Ὗ Ὧ show_base"
|
||||||
|
- "ᾏ ᾟ ᾯ BackSpace"
|
||||||
|
- "show_numbers preferences space Return"
|
||||||
|
numbers:
|
||||||
|
- "1 2 3 4 5 6 7 8 9 0"
|
||||||
|
- "at numbersign dollar percent ampersand minus underscore plus parenleft parenright"
|
||||||
|
- "show_symbols comma quotedbl quoteright colon semicolon exclam question BackSpace"
|
||||||
|
- "show_letters preferences space period comma Return"
|
||||||
|
symbols:
|
||||||
|
- "asciitilde quoteleft bar U00B7 squareroot Greek_pi Greek_tau division multiply paragraph"
|
||||||
|
- "copyright U00AE U00A3 EuroSign U00A5 asciicircum degree asterisk braceleft braceright"
|
||||||
|
- "show_numbers backslash slash less greater equal bracketleft bracketright BackSpace"
|
||||||
|
- "show_letters preferences space period comma 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: "altline"
|
||||||
|
icon: "keyboard-mode-symbolic"
|
||||||
|
show_oxia:
|
||||||
|
action:
|
||||||
|
set_view: "oxia"
|
||||||
|
outline: "extrawide"
|
||||||
|
label: "´ ΅"
|
||||||
|
show_Oxia:
|
||||||
|
action:
|
||||||
|
set_view: "Oxia"
|
||||||
|
outline: "extrawide"
|
||||||
|
label: "´¨↑"
|
||||||
|
show_bariaorperispomeni:
|
||||||
|
action:
|
||||||
|
set_view: "bariaorperispomeni"
|
||||||
|
outline: "extrawide"
|
||||||
|
label: "` ῀"
|
||||||
|
show_BariaOrPerispomeni:
|
||||||
|
action:
|
||||||
|
set_view: "BariaOrPerispomeni"
|
||||||
|
outline: "extrawide"
|
||||||
|
label: "`῀↑"
|
||||||
|
show_psiliordasia:
|
||||||
|
action:
|
||||||
|
set_view: "psiliordasia"
|
||||||
|
outline: "extrawide"
|
||||||
|
label: "᾿ ῾"
|
||||||
|
show_PsiliOrDasia:
|
||||||
|
action:
|
||||||
|
set_view: "PsiliOrDasia"
|
||||||
|
outline: "extrawide"
|
||||||
|
label: "᾿῾↑"
|
||||||
|
show_psiliordasiaandoxia:
|
||||||
|
action:
|
||||||
|
set_view: "psiliordasiaandoxia"
|
||||||
|
outline: "extrawide"
|
||||||
|
label: "῎ ῞"
|
||||||
|
show_PsiliOrDasiaAndOxia:
|
||||||
|
action:
|
||||||
|
set_view: "PsiliOrDasiaAndOxia"
|
||||||
|
outline: "extrawide"
|
||||||
|
label: "῎῞↑"
|
||||||
|
show_psiliordasiaandvaria:
|
||||||
|
action:
|
||||||
|
set_view: "psiliordasiaandvaria"
|
||||||
|
outline: "extrawide"
|
||||||
|
label: "῍ ῝"
|
||||||
|
show_PsiliOrDasiaAndVaria:
|
||||||
|
action:
|
||||||
|
set_view: "PsiliOrDasiaAndVaria"
|
||||||
|
outline: "extrawide"
|
||||||
|
label: "῍῝↑"
|
||||||
|
show_psiliordasiaandperispomeni:
|
||||||
|
action:
|
||||||
|
set_view: "psiliordasiaandperispomeni"
|
||||||
|
outline: "extrawide"
|
||||||
|
label: "῏ ῟"
|
||||||
|
show_PsiliOrDasiaAndPerispomeni:
|
||||||
|
action:
|
||||||
|
set_view: "PsiliOrDasiaAndPerispomeni"
|
||||||
|
outline: "extrawide"
|
||||||
|
label: "῏῟↑"
|
||||||
|
show_numbers:
|
||||||
|
action:
|
||||||
|
set_view: "numbers"
|
||||||
|
outline: "wide"
|
||||||
|
label: "123"
|
||||||
|
show_letters:
|
||||||
|
action:
|
||||||
|
set_view: "base"
|
||||||
|
outline: "wide"
|
||||||
|
label: "ΑΒΓ"
|
||||||
|
show_symbols:
|
||||||
|
action:
|
||||||
|
set_view: "symbols"
|
||||||
|
outline: "altline"
|
||||||
|
label: "*/="
|
||||||
|
show_accents:
|
||||||
|
action:
|
||||||
|
locking:
|
||||||
|
lock_view: "accents"
|
||||||
|
unlock_view: "base"
|
||||||
|
outline: "altline"
|
||||||
|
label: "ᾦ"
|
||||||
|
show_base:
|
||||||
|
action:
|
||||||
|
set_view: "base"
|
||||||
|
outline: "altline"
|
||||||
|
label: "αι"
|
||||||
|
space:
|
||||||
|
outline: "spaceline"
|
||||||
|
text: " "
|
||||||
|
Return:
|
||||||
|
outline: "wide"
|
||||||
|
icon: "key-enter"
|
||||||
|
keysym: "Return"
|
||||||
|
period:
|
||||||
|
outline: "special"
|
||||||
|
text: "."
|
||||||
|
period_upper:
|
||||||
|
outline: "special"
|
||||||
|
text: "·"
|
||||||
|
comma:
|
||||||
|
outline: "special"
|
||||||
|
text: ","
|
||||||
|
colon:
|
||||||
|
outline: "special"
|
||||||
|
text: ":"
|
||||||
|
semicolon:
|
||||||
|
outline: "special"
|
||||||
|
text: ";"
|
||||||
|
exclam:
|
||||||
|
outline: "special"
|
||||||
|
text: "!"
|
||||||
|
eis_l:
|
||||||
|
outline: "special"
|
||||||
|
text: "«"
|
||||||
|
eis_r:
|
||||||
|
outline: "special"
|
||||||
|
text: "»"
|
||||||
|
aring:
|
||||||
|
text: "å"
|
||||||
|
Aring:
|
||||||
|
text: "Å"
|
||||||
|
oslash:
|
||||||
|
text: "ø"
|
||||||
|
Oslash:
|
||||||
|
text: "Ø"
|
||||||
|
ae:
|
||||||
|
text: "æ"
|
||||||
|
AE:
|
||||||
|
text: "Æ"
|
||||||
|
asterisk:
|
||||||
|
text: "*"
|
||||||
|
asciitilde:
|
||||||
|
text: "~"
|
||||||
|
quoteleft:
|
||||||
|
text: "`"
|
||||||
|
bar:
|
||||||
|
text: "|"
|
||||||
|
U00B7:
|
||||||
|
text: "·"
|
||||||
|
squareroot:
|
||||||
|
text: "√"
|
||||||
|
Greek_pi:
|
||||||
|
text: "π"
|
||||||
|
division:
|
||||||
|
text: "÷"
|
||||||
|
multiply:
|
||||||
|
text: "×"
|
||||||
|
paragraph:
|
||||||
|
text: "¶"
|
||||||
|
Greek_tau:
|
||||||
|
text: "τ"
|
||||||
|
copyright:
|
||||||
|
text: "©"
|
||||||
|
numbersign:
|
||||||
|
text: "#"
|
||||||
|
U00AE:
|
||||||
|
text: "®"
|
||||||
|
at:
|
||||||
|
text: "@"
|
||||||
|
dollar:
|
||||||
|
text: "$"
|
||||||
|
U00A3:
|
||||||
|
text: "£"
|
||||||
|
percent:
|
||||||
|
text: "%"
|
||||||
|
EuroSign:
|
||||||
|
outline: "special"
|
||||||
|
text: "€"
|
||||||
|
ampersand:
|
||||||
|
text: "&"
|
||||||
|
U00A5:
|
||||||
|
text: "¥"
|
||||||
|
minus:
|
||||||
|
text: "-"
|
||||||
|
asciicircum:
|
||||||
|
text: "^"
|
||||||
|
underscore:
|
||||||
|
text: "_"
|
||||||
|
degree:
|
||||||
|
text: "°"
|
||||||
|
plus:
|
||||||
|
text: "+"
|
||||||
|
equal:
|
||||||
|
text: "="
|
||||||
|
parenleft:
|
||||||
|
text: "("
|
||||||
|
parenright:
|
||||||
|
text: ")"
|
||||||
|
braceleft:
|
||||||
|
text: "{"
|
||||||
|
braceright:
|
||||||
|
text: "}"
|
||||||
|
backslash:
|
||||||
|
text: "\\"
|
||||||
|
slash:
|
||||||
|
text: "/"
|
||||||
|
quotedbl:
|
||||||
|
text: "\""
|
||||||
|
quoteright:
|
||||||
|
text: "'"
|
||||||
|
less:
|
||||||
|
text: "<"
|
||||||
|
greater:
|
||||||
|
text: ">"
|
||||||
|
question:
|
||||||
|
text: "?"
|
||||||
|
bracketleft:
|
||||||
|
text: "["
|
||||||
|
bracketright:
|
||||||
|
text: "]"
|
||||||
|
|
||||||
@ -1,40 +1,41 @@
|
|||||||
# Greek layout created by Antonis Tsolomitis
|
# Greek layout originally created by Antonis Tsolomitis
|
||||||
# University of the Aegean, Department of Mathematics, atsol@aegean.gr
|
# University of the Aegean, Department of Mathematics, atsol@aegean.gr
|
||||||
# Sep 2019
|
# Sep 2019
|
||||||
|
# Edited by Sotiris Papadopoulos, sotirios.papadopoulos@inserm.fr
|
||||||
---
|
---
|
||||||
outlines:
|
outlines:
|
||||||
default: { width: 32, height: 52 }
|
default: { width: 40, height: 60 }
|
||||||
altline: { width: 48.39024, height: 52 }
|
altline: { width: 52.67, height: 60 }
|
||||||
wide: { width: 62, height: 52 }
|
wide: { width: 62, height: 60 }
|
||||||
outline7: { width: 88.97561, height: 52 }
|
spaceline: { width: 140, height: 60 }
|
||||||
spaceline: { width: 150.5853, height: 52 }
|
special: { width: 44, height: 60 }
|
||||||
|
|
||||||
views:
|
views:
|
||||||
base:
|
base:
|
||||||
- "; ς ε ρ τ υ θ ι ο π !"
|
- "semicolon ς ε ρ τ υ θ ι ο π"
|
||||||
- "α σ δ φ γ η ξ κ λ show_accented"
|
- "α σ δ φ γ η ξ κ λ show_accented"
|
||||||
- "Shift_L ζ χ ψ ω β ν μ , BackSpace"
|
- "Shift_L ζ χ ψ ω β ν μ BackSpace"
|
||||||
- "show_numbers preferences space period Return"
|
- "show_numbers preferences space period comma Return"
|
||||||
upper:
|
upper:
|
||||||
- ": EuroSign Ε Ρ Τ Υ Θ Ι Ο Π"
|
- "colon exclam Ε Ρ Τ Υ Θ Ι Ο Π"
|
||||||
- "Α Σ Δ Φ Γ Η Ξ Κ Λ show_accented"
|
- "Α Σ Δ Φ Γ Η Ξ Κ Λ show_accented"
|
||||||
- "Shift_L Ζ Χ Ψ Ω Β Ν Μ · BackSpace"
|
- "Shift_L Ζ Χ Ψ Ω Β Ν Μ BackSpace"
|
||||||
- "show_numbers preferences space « » Return"
|
- "show_numbers preferences space period_upper apostrophe Return"
|
||||||
accented:
|
accented:
|
||||||
- "ά έ ή ί ό ύ ώ ϊ ϋ ΐ"
|
- "ά έ ή ί ϊ ΐ ό ύ ϋ ώ "
|
||||||
- "ΰ Ά Έ Ή Ί Ό Ύ Ώ Ϊ show_base"
|
- "Ά Έ Ή Ί Ϊ Ό Ύ Ϋ Ώ show_base"
|
||||||
- "Ϋ Ϗ ϐ ϑ ϕ ϖ ϗ – — BackSpace"
|
- "Ϗ ϐ ϑ ϗ ϖ ΰ ϕ – — BackSpace"
|
||||||
- "show_numbers preferences space quoteleft quoteright Return"
|
- "show_numbers preferences space eis_l eis_r Return"
|
||||||
numbers:
|
numbers:
|
||||||
- "1 2 3 4 5 6 7 8 9 0"
|
- "1 2 3 4 5 6 7 8 9 0"
|
||||||
- "at numbersign dollar percent ampersand minus underscore plus parenleft parenright"
|
- "at numbersign dollar percent ampersand minus underscore plus parenleft parenright"
|
||||||
- "show_symbols comma quotedbl quoteright colon semicolon exclam question BackSpace"
|
- "show_symbols comma quotedbl quoteright colon semicolon exclam question BackSpace"
|
||||||
- "show_letters preferences space period Return"
|
- "show_letters preferences space period comma Return"
|
||||||
symbols:
|
symbols:
|
||||||
- "asciitilde quoteleft bar U00B7 squareroot Greek_pi Greek_tau division multiply paragraph"
|
- "asciitilde quoteleft bar U00B7 squareroot Greek_pi Greek_tau division multiply paragraph"
|
||||||
- "copyright U00AE U00A3 EuroSign U00A5 asciicircum degree asterisk braceleft braceright"
|
- "copyright U00AE U00A3 EuroSign U00A5 asciicircum degree asterisk braceleft braceright"
|
||||||
- "show_numbers backslash slash less greater equal bracketleft bracketright BackSpace"
|
- "show_numbers backslash slash less greater equal bracketleft bracketright BackSpace"
|
||||||
- "show_letters preferences space period Return"
|
- "show_letters preferences space period comma Return"
|
||||||
buttons:
|
buttons:
|
||||||
Shift_L:
|
Shift_L:
|
||||||
action:
|
action:
|
||||||
@ -54,12 +55,12 @@ buttons:
|
|||||||
show_numbers:
|
show_numbers:
|
||||||
action:
|
action:
|
||||||
set_view: "numbers"
|
set_view: "numbers"
|
||||||
outline: "altline"
|
outline: "wide"
|
||||||
label: "123"
|
label: "123"
|
||||||
show_letters:
|
show_letters:
|
||||||
action:
|
action:
|
||||||
set_view: "base"
|
set_view: "base"
|
||||||
outline: "altline"
|
outline: "wide"
|
||||||
label: "ΑΒΓ"
|
label: "ΑΒΓ"
|
||||||
show_symbols:
|
show_symbols:
|
||||||
action:
|
action:
|
||||||
@ -78,16 +79,40 @@ buttons:
|
|||||||
set_view: "base"
|
set_view: "base"
|
||||||
outline: "altline"
|
outline: "altline"
|
||||||
label: "αι"
|
label: "αι"
|
||||||
period:
|
|
||||||
outline: "altline"
|
|
||||||
text: "."
|
|
||||||
space:
|
space:
|
||||||
outline: spaceline
|
outline: "spaceline"
|
||||||
text: " "
|
text: " "
|
||||||
Return:
|
Return:
|
||||||
outline: "wide"
|
outline: "wide"
|
||||||
icon: "key-enter"
|
icon: "key-enter"
|
||||||
keysym: "Return"
|
keysym: "Return"
|
||||||
|
period:
|
||||||
|
outline: "special"
|
||||||
|
text: "."
|
||||||
|
period_upper:
|
||||||
|
outline: "special"
|
||||||
|
text: "·"
|
||||||
|
comma:
|
||||||
|
outline: "special"
|
||||||
|
text: ","
|
||||||
|
colon:
|
||||||
|
outline: "special"
|
||||||
|
text: ":"
|
||||||
|
semicolon:
|
||||||
|
outline: "special"
|
||||||
|
text: ";"
|
||||||
|
apostrophe:
|
||||||
|
outline: "special"
|
||||||
|
text: "᾿"
|
||||||
|
exclam:
|
||||||
|
outline: "special"
|
||||||
|
text: "!"
|
||||||
|
eis_l:
|
||||||
|
outline: "special"
|
||||||
|
text: "«"
|
||||||
|
eis_r:
|
||||||
|
outline: "special"
|
||||||
|
text: "»"
|
||||||
aring:
|
aring:
|
||||||
text: "å"
|
text: "å"
|
||||||
Aring:
|
Aring:
|
||||||
@ -162,8 +187,6 @@ buttons:
|
|||||||
text: "{"
|
text: "{"
|
||||||
braceright:
|
braceright:
|
||||||
text: "}"
|
text: "}"
|
||||||
comma:
|
|
||||||
text: ","
|
|
||||||
backslash:
|
backslash:
|
||||||
text: "\\"
|
text: "\\"
|
||||||
slash:
|
slash:
|
||||||
@ -176,12 +199,6 @@ buttons:
|
|||||||
text: "<"
|
text: "<"
|
||||||
greater:
|
greater:
|
||||||
text: ">"
|
text: ">"
|
||||||
colon:
|
|
||||||
text: ":"
|
|
||||||
semicolon:
|
|
||||||
text: ";"
|
|
||||||
exclam:
|
|
||||||
text: "!"
|
|
||||||
question:
|
question:
|
||||||
text: "?"
|
text: "?"
|
||||||
bracketleft:
|
bracketleft:
|
||||||
|
|||||||
204
data/keyboards/gr_wide.yaml
Normal file
204
data/keyboards/gr_wide.yaml
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
# Creaed by Sotiris Papadopoulos, sotirios.papadopoulos@inserm.fr
|
||||||
|
---
|
||||||
|
outlines:
|
||||||
|
default: { width: 80, height: 60 }
|
||||||
|
altline: { width: 110, height: 60 }
|
||||||
|
wide: { width: 120, height: 60 }
|
||||||
|
spaceline: { width: 250, height: 60 }
|
||||||
|
special: { width: 75, height: 60 }
|
||||||
|
|
||||||
|
views:
|
||||||
|
base:
|
||||||
|
- "semicolon ς ε ρ τ υ θ ι ο π"
|
||||||
|
- "α σ δ φ γ η ξ κ λ show_accented"
|
||||||
|
- "Shift_L ζ χ ψ ω β ν μ BackSpace"
|
||||||
|
- "show_numbers preferences space period comma Return"
|
||||||
|
upper:
|
||||||
|
- "colon exclam Ε Ρ Τ Υ Θ Ι Ο Π"
|
||||||
|
- "Α Σ Δ Φ Γ Η Ξ Κ Λ show_accented"
|
||||||
|
- "Shift_L Ζ Χ Ψ Ω Β Ν Μ BackSpace"
|
||||||
|
- "show_numbers preferences space period_upper apostrophe Return"
|
||||||
|
accented:
|
||||||
|
- "ά έ ή ί ϊ ΐ ό ύ ϋ ώ "
|
||||||
|
- "Ά Έ Ή Ί Ϊ Ό Ύ Ϋ Ώ show_base"
|
||||||
|
- "Ϗ ϐ ϑ ϗ ΰ ϕ ϖ – — BackSpace"
|
||||||
|
- "show_numbers preferences space eis_l eis_r Return"
|
||||||
|
numbers:
|
||||||
|
- "1 2 3 4 5 6 7 8 9 0"
|
||||||
|
- "at numbersign dollar percent ampersand minus underscore plus parenleft parenright"
|
||||||
|
- "show_symbols comma quotedbl quoteright colon semicolon exclam question BackSpace"
|
||||||
|
- "show_letters preferences space period comma Return"
|
||||||
|
symbols:
|
||||||
|
- "asciitilde quoteleft bar U00B7 squareroot Greek_pi Greek_tau division multiply paragraph"
|
||||||
|
- "copyright U00AE U00A3 EuroSign U00A5 asciicircum degree asterisk braceleft braceright"
|
||||||
|
- "show_numbers backslash slash less greater equal bracketleft bracketright BackSpace"
|
||||||
|
- "show_letters preferences space period comma 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_letters:
|
||||||
|
action:
|
||||||
|
set_view: "base"
|
||||||
|
outline: "wide"
|
||||||
|
label: "ΑΒΓ"
|
||||||
|
show_symbols:
|
||||||
|
action:
|
||||||
|
set_view: "symbols"
|
||||||
|
outline: "altline"
|
||||||
|
label: "*/="
|
||||||
|
show_accented:
|
||||||
|
action:
|
||||||
|
locking:
|
||||||
|
lock_view: "accented"
|
||||||
|
unlock_view: "base"
|
||||||
|
outline: "altline"
|
||||||
|
label: "άΐ"
|
||||||
|
show_base:
|
||||||
|
action:
|
||||||
|
set_view: "base"
|
||||||
|
outline: "altline"
|
||||||
|
label: "αι"
|
||||||
|
space:
|
||||||
|
outline: "spaceline"
|
||||||
|
text: " "
|
||||||
|
Return:
|
||||||
|
outline: "wide"
|
||||||
|
icon: "key-enter"
|
||||||
|
keysym: "Return"
|
||||||
|
period:
|
||||||
|
outline: "special"
|
||||||
|
text: "."
|
||||||
|
period_upper:
|
||||||
|
outline: "special"
|
||||||
|
text: "·"
|
||||||
|
comma:
|
||||||
|
outline: "special"
|
||||||
|
text: ","
|
||||||
|
colon:
|
||||||
|
outline: "special"
|
||||||
|
text: ":"
|
||||||
|
semicolon:
|
||||||
|
outline: "special"
|
||||||
|
text: ";"
|
||||||
|
apostrophe:
|
||||||
|
outline: "special"
|
||||||
|
text: "᾿"
|
||||||
|
exclam:
|
||||||
|
outline: "special"
|
||||||
|
text: "!"
|
||||||
|
eis_l:
|
||||||
|
outline: "special"
|
||||||
|
text: "«"
|
||||||
|
eis_r:
|
||||||
|
outline: "special"
|
||||||
|
text: "»"
|
||||||
|
aring:
|
||||||
|
text: "å"
|
||||||
|
Aring:
|
||||||
|
text: "Å"
|
||||||
|
oslash:
|
||||||
|
text: "ø"
|
||||||
|
Oslash:
|
||||||
|
text: "Ø"
|
||||||
|
ae:
|
||||||
|
text: "æ"
|
||||||
|
AE:
|
||||||
|
text: "Æ"
|
||||||
|
asterisk:
|
||||||
|
text: "*"
|
||||||
|
asciitilde:
|
||||||
|
text: "~"
|
||||||
|
quoteleft:
|
||||||
|
text: "`"
|
||||||
|
bar:
|
||||||
|
text: "|"
|
||||||
|
U00B7:
|
||||||
|
text: "·"
|
||||||
|
squareroot:
|
||||||
|
text: "√"
|
||||||
|
Greek_pi:
|
||||||
|
text: "π"
|
||||||
|
division:
|
||||||
|
text: "÷"
|
||||||
|
multiply:
|
||||||
|
text: "×"
|
||||||
|
paragraph:
|
||||||
|
text: "¶"
|
||||||
|
Greek_tau:
|
||||||
|
text: "τ"
|
||||||
|
copyright:
|
||||||
|
text: "©"
|
||||||
|
numbersign:
|
||||||
|
text: "#"
|
||||||
|
U00AE:
|
||||||
|
text: "®"
|
||||||
|
at:
|
||||||
|
text: "@"
|
||||||
|
dollar:
|
||||||
|
text: "$"
|
||||||
|
U00A3:
|
||||||
|
text: "£"
|
||||||
|
percent:
|
||||||
|
text: "%"
|
||||||
|
EuroSign:
|
||||||
|
text: "€"
|
||||||
|
ampersand:
|
||||||
|
text: "&"
|
||||||
|
U00A5:
|
||||||
|
text: "¥"
|
||||||
|
minus:
|
||||||
|
text: "-"
|
||||||
|
asciicircum:
|
||||||
|
text: "^"
|
||||||
|
underscore:
|
||||||
|
text: "_"
|
||||||
|
degree:
|
||||||
|
text: "°"
|
||||||
|
plus:
|
||||||
|
text: "+"
|
||||||
|
equal:
|
||||||
|
text: "="
|
||||||
|
parenleft:
|
||||||
|
text: "("
|
||||||
|
parenright:
|
||||||
|
text: ")"
|
||||||
|
braceleft:
|
||||||
|
text: "{"
|
||||||
|
braceright:
|
||||||
|
text: "}"
|
||||||
|
backslash:
|
||||||
|
text: "\\"
|
||||||
|
slash:
|
||||||
|
text: "/"
|
||||||
|
quotedbl:
|
||||||
|
text: "\""
|
||||||
|
quoteright:
|
||||||
|
text: "'"
|
||||||
|
less:
|
||||||
|
text: "<"
|
||||||
|
greater:
|
||||||
|
text: ">"
|
||||||
|
question:
|
||||||
|
text: "?"
|
||||||
|
bracketleft:
|
||||||
|
text: "["
|
||||||
|
bracketright:
|
||||||
|
text: "]"
|
||||||
1
debian/cargo/config
vendored
1
debian/cargo/config
vendored
@ -9,4 +9,3 @@ replace-with = 'vendored-sources'
|
|||||||
|
|
||||||
[source.vendored-sources]
|
[source.vendored-sources]
|
||||||
directory = '/usr/share/cargo/registry'
|
directory = '/usr/share/cargo/registry'
|
||||||
|
|
||||||
|
|||||||
66
debian/changelog
vendored
66
debian/changelog
vendored
@ -1,3 +1,69 @@
|
|||||||
|
squeekboard (1.18.0-1) experimental; urgency=medium
|
||||||
|
|
||||||
|
[ Hugo Carvalho ]
|
||||||
|
* Add Portuguese translation
|
||||||
|
|
||||||
|
[ Мирослав Николић ]
|
||||||
|
* Add Serbian translation
|
||||||
|
|
||||||
|
[ William Wold ]
|
||||||
|
* Do not reset pending state on zwp_input_method_v2.done
|
||||||
|
|
||||||
|
[ Balázs Úr ]
|
||||||
|
* Add Hungarian translation
|
||||||
|
|
||||||
|
[ Emin Tufan Çetin ]
|
||||||
|
* Add Turkish translation
|
||||||
|
|
||||||
|
[ Piotr Drąg ]
|
||||||
|
* Add Polish translation
|
||||||
|
|
||||||
|
[ Pablo Correa Gómez ]
|
||||||
|
* Add Spanish translation
|
||||||
|
|
||||||
|
[ Vittorio Monti ]
|
||||||
|
* Add Italian translation
|
||||||
|
|
||||||
|
[ Dorota Czaplejewicz ]
|
||||||
|
* build: Replace missing crates.io dependency with Purism-hosted one
|
||||||
|
* ci: Allow failure on sid
|
||||||
|
* build: Update clap on newer Debian
|
||||||
|
* panel: Use scaling to set height
|
||||||
|
* layouts: Add Greek Polytonic
|
||||||
|
* debug: Add dbus interface to control debug prints
|
||||||
|
* output: Store physical size
|
||||||
|
* state: Derive panel size from physical click target size
|
||||||
|
* Clean up size types
|
||||||
|
* state: Add sizing unit test
|
||||||
|
* layouts: Register gr_wide
|
||||||
|
* CI: Build Rust code reference
|
||||||
|
* CI: Add gitlab pages deployment
|
||||||
|
* panel: Split away panel handling
|
||||||
|
* cargo: Add zbus to newer Debian
|
||||||
|
* docs: Update location
|
||||||
|
* docs: Link to reference
|
||||||
|
* docs: Make index more logical
|
||||||
|
* Update Cargo lock
|
||||||
|
|
||||||
|
[ Sotiris Papadopoulos ]
|
||||||
|
* Update gr.yaml to take advantage of more space per symbol. Creation of a wide variant...
|
||||||
|
|
||||||
|
[ Arnaud Ferraris ]
|
||||||
|
* state: fix "wide mode" detection in portrait orientation
|
||||||
|
* layout: allow stretching the layout by a small amount
|
||||||
|
* layout: fix build on i386
|
||||||
|
|
||||||
|
[ Sungjoon Moon ]
|
||||||
|
* Add Korean translation
|
||||||
|
|
||||||
|
[ Quentin PAGÈS ]
|
||||||
|
* Add Occitan translation
|
||||||
|
|
||||||
|
[ Zurab Kargareteli ]
|
||||||
|
* Add Georgian translation
|
||||||
|
|
||||||
|
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Mon, 25 Apr 2022 13:12:36 +0000
|
||||||
|
|
||||||
squeekboard (1.17.0-1) experimental; urgency=medium
|
squeekboard (1.17.0-1) experimental; urgency=medium
|
||||||
|
|
||||||
[ Dorota Czaplejewicz ]
|
[ Dorota Czaplejewicz ]
|
||||||
|
|||||||
1
debian/control
vendored
1
debian/control
vendored
@ -23,6 +23,7 @@ Build-Depends:
|
|||||||
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),
|
||||||
librust-xkbcommon-0.4+wayland-dev (>= 0.4),
|
librust-xkbcommon-0.4+wayland-dev (>= 0.4),
|
||||||
|
librust-zbus-dev (>=1.0),
|
||||||
libwayland-dev (>= 1.16),
|
libwayland-dev (>= 1.16),
|
||||||
lsb-release,
|
lsb-release,
|
||||||
python3,
|
python3,
|
||||||
|
|||||||
1
debian/control-newer
vendored
1
debian/control-newer
vendored
@ -23,6 +23,7 @@ Build-Depends:
|
|||||||
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),
|
||||||
librust-xkbcommon-0.4+wayland-dev (>= 0.4),
|
librust-xkbcommon-0.4+wayland-dev (>= 0.4),
|
||||||
|
librust-zbus-dev (>= 1.9),
|
||||||
libwayland-dev (>= 1.16),
|
libwayland-dev (>= 1.16),
|
||||||
lsb-release,
|
lsb-release,
|
||||||
python3,
|
python3,
|
||||||
|
|||||||
2
debian/rules
vendored
2
debian/rules
vendored
@ -38,6 +38,6 @@ endif
|
|||||||
# causing Cargo to refuse to build with a crates.io copy
|
# causing Cargo to refuse to build with a crates.io copy
|
||||||
override_dh_auto_configure:
|
override_dh_auto_configure:
|
||||||
[ ! -f Cargo.lock ] || rm Cargo.lock
|
[ ! -f Cargo.lock ] || rm Cargo.lock
|
||||||
dh_auto_configure -- -Dnewer=$(newer)
|
dh_auto_configure -- -Dnewer=$(newer) -Donline=false
|
||||||
|
|
||||||
override_dh_autoreconf:
|
override_dh_autoreconf:
|
||||||
|
|||||||
@ -102,6 +102,17 @@ contain a comma separated list of:
|
|||||||
Coding
|
Coding
|
||||||
------
|
------
|
||||||
|
|
||||||
|
### Reference docs
|
||||||
|
|
||||||
|
Reference documentation can be generated using:
|
||||||
|
|
||||||
|
```
|
||||||
|
cd squeekboard_build/
|
||||||
|
../squeekboard_source/cargo.sh doc --no-deps --document-private-items
|
||||||
|
```
|
||||||
|
|
||||||
|
as well as found [online](https://world.pages.gitlab.gnome.org/Phosh/squeekboard/doc/rs/).
|
||||||
|
|
||||||
### Project structure
|
### Project structure
|
||||||
|
|
||||||
Rust modules should be split into 2 categories: libraries, and user interface. They differ in the way they do error handling.
|
Rust modules should be split into 2 categories: libraries, and user interface. They differ in the way they do error handling.
|
||||||
|
|||||||
13
doc/index.md
13
doc/index.md
@ -1,13 +1,6 @@
|
|||||||
Welcome to squeekboard's documentation!
|
Welcome to squeekboard's documentation!
|
||||||
=======================================
|
=======================================
|
||||||
|
|
||||||
Contents
|
|
||||||
--------
|
|
||||||
|
|
||||||
* [Tutorial](tutorial.md)
|
|
||||||
* [Contributing](hacking.md)
|
|
||||||
* [Switching views](views.md)
|
|
||||||
|
|
||||||
Introduction
|
Introduction
|
||||||
------------
|
------------
|
||||||
|
|
||||||
@ -22,9 +15,15 @@ Layouts are created using a text-based format, based on YAML.
|
|||||||
|
|
||||||
TODO: Provide a description of the format.
|
TODO: Provide a description of the format.
|
||||||
|
|
||||||
|
### Views
|
||||||
|
|
||||||
Squeekboard layouts are separated into *views* and use a *room metaphor* to [switch views](views.md).
|
Squeekboard layouts are separated into *views* and use a *room metaphor* to [switch views](views.md).
|
||||||
|
|
||||||
Contributions
|
Contributions
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
Anyone is free to modify *squeekboard*. See the [contributing document](hacking.md).
|
Anyone is free to modify *squeekboard*. See the [contributing document](hacking.md).
|
||||||
|
|
||||||
|
### Code documentation
|
||||||
|
|
||||||
|
To expose the structure of Squeekboard in detail, there's a [code reference](doc/rs).
|
||||||
@ -55,6 +55,8 @@ typedef struct _EekGtkKeyboardPrivate
|
|||||||
|
|
||||||
GdkEventSequence *sequence; // unowned reference
|
GdkEventSequence *sequence; // unowned reference
|
||||||
LfbEvent *event;
|
LfbEvent *event;
|
||||||
|
|
||||||
|
gulong kb_signal;
|
||||||
} EekGtkKeyboardPrivate;
|
} EekGtkKeyboardPrivate;
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (EekGtkKeyboard, eek_gtk_keyboard, GTK_TYPE_DRAWING_AREA)
|
G_DEFINE_TYPE_WITH_PRIVATE (EekGtkKeyboard, eek_gtk_keyboard, GTK_TYPE_DRAWING_AREA)
|
||||||
@ -307,12 +309,19 @@ eek_gtk_keyboard_set_property (GObject *object,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This may actually get called multiple times in a row
|
||||||
|
// if both a parent object and its parent get destroyed
|
||||||
static void
|
static void
|
||||||
eek_gtk_keyboard_dispose (GObject *object)
|
eek_gtk_keyboard_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (object);
|
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (object);
|
||||||
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
|
||||||
|
|
||||||
|
if (priv->kb_signal != 0) {
|
||||||
|
g_signal_handler_disconnect(priv->eekboard_context, priv->kb_signal);
|
||||||
|
priv->kb_signal = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (priv->renderer) {
|
if (priv->renderer) {
|
||||||
eek_renderer_free(priv->renderer);
|
eek_renderer_free(priv->renderer);
|
||||||
priv->renderer = NULL;
|
priv->renderer = NULL;
|
||||||
@ -418,12 +427,13 @@ eek_gtk_keyboard_new (EekboardContextService *eekservice,
|
|||||||
.widget_to_layout = {
|
.widget_to_layout = {
|
||||||
.origin_x = 0,
|
.origin_x = 0,
|
||||||
.origin_y = 0,
|
.origin_y = 0,
|
||||||
.scale = 1,
|
.scale_x = 1,
|
||||||
|
.scale_y = 1,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
priv->render_geometry = initial_geometry;
|
priv->render_geometry = initial_geometry;
|
||||||
|
|
||||||
g_signal_connect (eekservice,
|
priv->kb_signal = g_signal_connect (eekservice,
|
||||||
"notify::keyboard",
|
"notify::keyboard",
|
||||||
G_CALLBACK(on_notify_keyboard),
|
G_CALLBACK(on_notify_keyboard),
|
||||||
ret);
|
ret);
|
||||||
|
|||||||
@ -219,7 +219,7 @@ eek_renderer_render_keyboard (EekRenderer *self,
|
|||||||
|
|
||||||
cairo_save(cr);
|
cairo_save(cr);
|
||||||
cairo_translate (cr, geometry.widget_to_layout.origin_x, geometry.widget_to_layout.origin_y);
|
cairo_translate (cr, geometry.widget_to_layout.origin_x, geometry.widget_to_layout.origin_y);
|
||||||
cairo_scale (cr, geometry.widget_to_layout.scale, geometry.widget_to_layout.scale);
|
cairo_scale (cr, geometry.widget_to_layout.scale_x, geometry.widget_to_layout.scale_y);
|
||||||
|
|
||||||
squeek_draw_layout_base_view(keyboard->layout, self, cr);
|
squeek_draw_layout_base_view(keyboard->layout, self, cr);
|
||||||
squeek_layout_draw_all_changed(keyboard->layout, self, cr, submission);
|
squeek_layout_draw_all_changed(keyboard->layout, self, cr, submission);
|
||||||
|
|||||||
@ -87,7 +87,8 @@ void eek_bounds_free (EekBounds *bounds);
|
|||||||
struct transformation {
|
struct transformation {
|
||||||
gdouble origin_x;
|
gdouble origin_x;
|
||||||
gdouble origin_y;
|
gdouble origin_y;
|
||||||
gdouble scale;
|
gdouble scale_x;
|
||||||
|
gdouble scale_y;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|||||||
@ -60,10 +60,10 @@ struct _EekboardContextService {
|
|||||||
LevelKeyboard *keyboard; // currently used keyboard
|
LevelKeyboard *keyboard; // currently used keyboard
|
||||||
GSettings *settings; // Owned reference
|
GSettings *settings; // Owned reference
|
||||||
|
|
||||||
// Maybe TODO: it's used only for fetching layout type.
|
/// Needed for keymap changes after keyboard updates.
|
||||||
// Maybe let UI push the type to this structure?
|
// TODO: can the main loop access submission to change the key maps instead?
|
||||||
ServerContextService *ui; // unowned reference
|
// This should probably land together with passing buttons through state,
|
||||||
/// Needed for keymap changes after keyboard updates
|
// to avoid race conditions between setting buttons and key maps.
|
||||||
struct submission *submission; // unowned
|
struct submission *submission; // unowned
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -297,6 +297,8 @@ eekboard_context_service_get_keyboard (EekboardContextService *context)
|
|||||||
return context->keyboard;
|
return context->keyboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used from Rust.
|
||||||
|
// TODO: move hint management to Rust entirely
|
||||||
void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
|
void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
|
||||||
uint32_t hint, uint32_t purpose)
|
uint32_t hint, uint32_t purpose)
|
||||||
{
|
{
|
||||||
@ -340,7 +342,3 @@ void eekboard_context_service_set_submission(EekboardContextService *context, st
|
|||||||
submission_use_layout(context->submission, context->keyboard->layout, time);
|
submission_use_layout(context->submission, context->keyboard->layout, time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void eekboard_context_service_set_ui(EekboardContextService *context, ServerContextService *ui) {
|
|
||||||
context->ui = ui;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -39,16 +39,12 @@ G_DECLARE_FINAL_TYPE(EekboardContextService, eekboard_context_service, EEKBOARD,
|
|||||||
|
|
||||||
EekboardContextService *eekboard_context_service_new(struct squeek_layout_state *state);
|
EekboardContextService *eekboard_context_service_new(struct squeek_layout_state *state);
|
||||||
void eekboard_context_service_set_submission(EekboardContextService *context, struct submission *submission);
|
void eekboard_context_service_set_submission(EekboardContextService *context, struct submission *submission);
|
||||||
void eekboard_context_service_set_ui(EekboardContextService *context, ServerContextService *ui);
|
|
||||||
void eekboard_context_service_destroy (EekboardContextService *context);
|
void eekboard_context_service_destroy (EekboardContextService *context);
|
||||||
LevelKeyboard *eekboard_context_service_get_keyboard(EekboardContextService *context);
|
LevelKeyboard *eekboard_context_service_get_keyboard(EekboardContextService *context);
|
||||||
|
|
||||||
void eekboard_context_service_set_keymap(EekboardContextService *context,
|
void eekboard_context_service_set_keymap(EekboardContextService *context,
|
||||||
const LevelKeyboard *keyboard);
|
const LevelKeyboard *keyboard);
|
||||||
|
|
||||||
void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
|
|
||||||
uint32_t hint,
|
|
||||||
uint32_t purpose);
|
|
||||||
void
|
void
|
||||||
eekboard_context_service_use_layout(EekboardContextService *context, struct squeek_layout_state *layout, uint32_t timestamp);
|
eekboard_context_service_use_layout(EekboardContextService *context, struct squeek_layout_state *layout, uint32_t timestamp);
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|||||||
14
meson.build
14
meson.build
@ -1,7 +1,7 @@
|
|||||||
project(
|
project(
|
||||||
'squeekboard',
|
'squeekboard',
|
||||||
'c', 'rust',
|
'c', 'rust',
|
||||||
version: '1.17.0',
|
version: '1.18.0',
|
||||||
license: 'GPLv3',
|
license: 'GPLv3',
|
||||||
meson_version: '>=0.51.0',
|
meson_version: '>=0.51.0',
|
||||||
default_options: [
|
default_options: [
|
||||||
@ -96,19 +96,23 @@ cargo_toml_base = configure_file(
|
|||||||
configuration: path_data,
|
configuration: path_data,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
cargo_patch = []
|
||||||
cargo_deps = files('Cargo.deps')
|
|
||||||
|
|
||||||
if get_option('newer') == true
|
if get_option('newer') == true
|
||||||
cargo_build_flags += ['--features', 'glib_v0_14']
|
cargo_build_flags += ['--features', 'glib_v0_14']
|
||||||
cargo_deps = files('Cargo.deps.newer')
|
cargo_deps = files('Cargo.deps.newer')
|
||||||
|
else
|
||||||
|
cargo_deps = files('Cargo.deps')
|
||||||
|
if get_option('online') == true
|
||||||
|
cargo_patch = [files('Cargo.deps.online')]
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
cat = find_program('cat')
|
cat = find_program('cat')
|
||||||
cargo_toml = custom_target(
|
cargo_toml = custom_target(
|
||||||
'Cargo.toml',
|
'Cargo.toml',
|
||||||
output: 'Cargo.toml',
|
output: 'Cargo.toml',
|
||||||
command: [cat, cargo_toml_base, cargo_deps],
|
command: [cat, cargo_toml_base, cargo_deps] + cargo_patch,
|
||||||
capture: true,
|
capture: true,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,10 @@ option('newer',
|
|||||||
type: 'boolean', value: false,
|
type: 'boolean', value: false,
|
||||||
description: 'Build with dependencies newer than those of Byzantium')
|
description: 'Build with dependencies newer than those of Byzantium')
|
||||||
|
|
||||||
|
option('online',
|
||||||
|
type: 'boolean', value: true,
|
||||||
|
description: 'Pull packages from the internet while building, as opposed to a local regstry.')
|
||||||
|
|
||||||
option('strict',
|
option('strict',
|
||||||
type: 'boolean', value: true,
|
type: 'boolean', value: true,
|
||||||
description: 'Turn more warnings into errors')
|
description: 'Turn more warnings into errors')
|
||||||
|
|||||||
10
po/LINGUAS
10
po/LINGUAS
@ -1,13 +1,23 @@
|
|||||||
ca
|
ca
|
||||||
de
|
de
|
||||||
|
es
|
||||||
fa
|
fa
|
||||||
fi
|
fi
|
||||||
fur
|
fur
|
||||||
gl
|
gl
|
||||||
he
|
he
|
||||||
|
hu
|
||||||
|
it
|
||||||
|
ka
|
||||||
|
ko
|
||||||
nl
|
nl
|
||||||
|
oc
|
||||||
|
pl
|
||||||
|
pt
|
||||||
pt_BR
|
pt_BR
|
||||||
ro
|
ro
|
||||||
sl
|
sl
|
||||||
|
sr
|
||||||
|
tr
|
||||||
uk
|
uk
|
||||||
sv
|
sv
|
||||||
|
|||||||
47
po/es.po
Normal file
47
po/es.po
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# Spanish translation for squeekboard.
|
||||||
|
# Copyright (C) 2022 squeekboard's COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the squeekboard package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
# Pablo Correa Gómez <ablocorrea@hotmail.com>, 2022.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: squeekboard master\n"
|
||||||
|
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/Phosh/squeekboard/"
|
||||||
|
"issues\n"
|
||||||
|
"POT-Creation-Date: 2022-03-20 13:14+0000\n"
|
||||||
|
"PO-Revision-Date: 2022-03-22 21:33+0100\n"
|
||||||
|
"Last-Translator: Pablo Correa Gómez <ablocorrea@hotmail.com>\n"
|
||||||
|
"Language-Team: Spanish; Castilian <gnome-es-list@gnome.org>\n"
|
||||||
|
"Language: es\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||||
|
"X-Generator: Gtranslator 3.36.0\n"
|
||||||
|
|
||||||
|
#. translators: This is a emmoji keyboard layout
|
||||||
|
#: data/popover.ui:6
|
||||||
|
msgid "Emoji"
|
||||||
|
msgstr "Emoji"
|
||||||
|
|
||||||
|
#. translators: This is a terminal keyboard layout
|
||||||
|
#: data/popover.ui:12
|
||||||
|
msgid "Terminal"
|
||||||
|
msgstr "Terminal"
|
||||||
|
|
||||||
|
#: data/popover.ui:18
|
||||||
|
msgid "Keyboard Settings"
|
||||||
|
msgstr "Ajustes de teclado"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:3
|
||||||
|
msgid "Squeekboard"
|
||||||
|
msgstr "Squeekboard"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:4
|
||||||
|
msgid "On Screen Keyboard"
|
||||||
|
msgstr "Teclado en pantala"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:5
|
||||||
|
msgid "An on screen virtual keyboard"
|
||||||
|
msgstr "Un teclado virtual en pantalla"
|
||||||
46
po/hu.po
Normal file
46
po/hu.po
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# Hungarian translation for squeekboard.
|
||||||
|
# Copyright (C) 2022 Free Software Foundation, Inc.
|
||||||
|
# This file is distributed under the same license as the squeekboard package.
|
||||||
|
#
|
||||||
|
# Balázs Úr <ur.balazs at fsf dot hu>, 2022.
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: squeekboard master\n"
|
||||||
|
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/Phosh/squeekboard/issues"
|
||||||
|
"\n"
|
||||||
|
"POT-Creation-Date: 2022-03-12 12:04+0000\n"
|
||||||
|
"PO-Revision-Date: 2022-03-16 01:55+0100\n"
|
||||||
|
"Last-Translator: Balázs Úr <ur.balazs at fsf dot hu>\n"
|
||||||
|
"Language-Team: Hungarian <gnome-hu-list at gnome dot org>\n"
|
||||||
|
"Language: hu\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
"X-Generator: Lokalize 19.12.3\n"
|
||||||
|
|
||||||
|
#. translators: This is a emmoji keyboard layout
|
||||||
|
#: data/popover.ui:6
|
||||||
|
msgid "Emoji"
|
||||||
|
msgstr "Emodzsi"
|
||||||
|
|
||||||
|
#. translators: This is a terminal keyboard layout
|
||||||
|
#: data/popover.ui:12
|
||||||
|
msgid "Terminal"
|
||||||
|
msgstr "Terminál"
|
||||||
|
|
||||||
|
#: data/popover.ui:18
|
||||||
|
msgid "Keyboard Settings"
|
||||||
|
msgstr "Billentyűzetbeállítások"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:3
|
||||||
|
msgid "Squeekboard"
|
||||||
|
msgstr "Squeekboard"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:4
|
||||||
|
msgid "On Screen Keyboard"
|
||||||
|
msgstr "Képernyő-billentyűzet"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:5
|
||||||
|
msgid "An on screen virtual keyboard"
|
||||||
|
msgstr "Egy virtuális képernyő-billentyűzet"
|
||||||
47
po/it.po
Normal file
47
po/it.po
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# Italian translation for squeekboard.
|
||||||
|
# Copyright (C) 2021 squeekboard's COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the squeekboard package.
|
||||||
|
# Vittorio <postav@pm.me>, 2021.
|
||||||
|
# Vittorio Monti <postav@pm.me>, 2021.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: squeekboard master\n"
|
||||||
|
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/Phosh/squeekboard/"
|
||||||
|
"issues\n"
|
||||||
|
"POT-Creation-Date: 2021-12-22 19:14+0000\n"
|
||||||
|
"PO-Revision-Date: 2021-12-22 20:37+0100\n"
|
||||||
|
"Last-Translator: Vittorio Monti <postav@pm.me>\n"
|
||||||
|
"Language-Team: Italian <gnome-it-list@gnome.org>\n"
|
||||||
|
"Language: it\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
"X-Generator: Gtranslator 3.30.1\n"
|
||||||
|
|
||||||
|
#. translators: This is a emmoji keyboard layout
|
||||||
|
#: data/popover.ui:6
|
||||||
|
msgid "Emoji"
|
||||||
|
msgstr "Emoji"
|
||||||
|
|
||||||
|
#. translators: This is a terminal keyboard layout
|
||||||
|
#: data/popover.ui:12
|
||||||
|
msgid "Terminal"
|
||||||
|
msgstr "Terminale"
|
||||||
|
|
||||||
|
#: data/popover.ui:18
|
||||||
|
msgid "Keyboard Settings"
|
||||||
|
msgstr "Impostazioni tastiera"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:3
|
||||||
|
msgid "Squeekboard"
|
||||||
|
msgstr "Squeekboard"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:4
|
||||||
|
msgid "On Screen Keyboard"
|
||||||
|
msgstr "Tastiera su schermo"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:5
|
||||||
|
msgid "An on screen virtual keyboard"
|
||||||
|
msgstr "Una tastiera virtuale su schermo"
|
||||||
46
po/ka.po
Normal file
46
po/ka.po
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# SOME DESCRIPTIVE TITLE.
|
||||||
|
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: \n"
|
||||||
|
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/Phosh/squeekboard/"
|
||||||
|
"issues\n"
|
||||||
|
"POT-Creation-Date: 2022-02-04 15:22+0000\n"
|
||||||
|
"PO-Revision-Date: 2022-02-08 03:15+0100\n"
|
||||||
|
"Last-Translator: Temuri Doghonadze <temuri.doghonadze@gmail.com>\n"
|
||||||
|
"Language-Team: \n"
|
||||||
|
"Language: ka\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
"X-Generator: Poedit 3.0.1\n"
|
||||||
|
|
||||||
|
#. translators: This is a emmoji keyboard layout
|
||||||
|
#: data/popover.ui:6
|
||||||
|
msgid "Emoji"
|
||||||
|
msgstr "ემოჯი"
|
||||||
|
|
||||||
|
#. translators: This is a terminal keyboard layout
|
||||||
|
#: data/popover.ui:12
|
||||||
|
msgid "Terminal"
|
||||||
|
msgstr "ტერმინალი"
|
||||||
|
|
||||||
|
#: data/popover.ui:18
|
||||||
|
msgid "Keyboard Settings"
|
||||||
|
msgstr "კლავიატურის მორგება"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:3
|
||||||
|
msgid "Squeekboard"
|
||||||
|
msgstr "Squeekboard"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:4
|
||||||
|
msgid "On Screen Keyboard"
|
||||||
|
msgstr "ეკრანის კლავიატურა"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:5
|
||||||
|
msgid "An on screen virtual keyboard"
|
||||||
|
msgstr "ეკრანზე ვირტუალური კლავიატურის ჩვენება"
|
||||||
46
po/ko.po
Normal file
46
po/ko.po
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# Korean translation for squeekboard.
|
||||||
|
# Copyright (C) 2022 squeekboard'S COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the squeekboard package.
|
||||||
|
# Moon Sungjoon <sumoon@seoulsaram.org>, 2022.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: \n"
|
||||||
|
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/Phosh/squeekboard/"
|
||||||
|
"issues\n"
|
||||||
|
"POT-Creation-Date: 2022-04-09 18:43+0000\n"
|
||||||
|
"PO-Revision-Date: 2022-04-11 19:23+0900\n"
|
||||||
|
"Last-Translator: Moon Sungjoon <sumoon@seoulsaram.org>\n"
|
||||||
|
"Language-Team: \n"
|
||||||
|
"Language: ko\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||||
|
"X-Generator: Poedit 3.0.1\n"
|
||||||
|
|
||||||
|
#. translators: This is a emmoji keyboard layout
|
||||||
|
#: data/popover.ui:6
|
||||||
|
msgid "Emoji"
|
||||||
|
msgstr "이모지"
|
||||||
|
|
||||||
|
#. translators: This is a terminal keyboard layout
|
||||||
|
#: data/popover.ui:12
|
||||||
|
msgid "Terminal"
|
||||||
|
msgstr "터미널"
|
||||||
|
|
||||||
|
#: data/popover.ui:18
|
||||||
|
msgid "Keyboard Settings"
|
||||||
|
msgstr "키보드 설정"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:3
|
||||||
|
msgid "Squeekboard"
|
||||||
|
msgstr "스퀴크 보드"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:4
|
||||||
|
msgid "On Screen Keyboard"
|
||||||
|
msgstr "화상 키보드"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:5
|
||||||
|
msgid "An on screen virtual keyboard"
|
||||||
|
msgstr "가상 키보드"
|
||||||
45
po/oc.po
Normal file
45
po/oc.po
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# Occitan translation for squeekboard.
|
||||||
|
# Copyright (C) 2022 squeekboard's COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the squeekboard package.
|
||||||
|
# Quentin PAGÈS <pages_quentin@hotmail.com>, 2022.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: squeekboard master\n"
|
||||||
|
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/Phosh/squeekboard/"
|
||||||
|
"issues\n"
|
||||||
|
"POT-Creation-Date: 2022-04-17 06:24+0000\n"
|
||||||
|
"PO-Revision-Date: 2022-04-17 09:17+0200\n"
|
||||||
|
"Last-Translator: Quentin PAGÈS\n"
|
||||||
|
"Language-Team: Occitan <totenoc@gmail.com>\n"
|
||||||
|
"Language: oc\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Generator: Poedit 3.0.1\n"
|
||||||
|
|
||||||
|
#. translators: This is a emmoji keyboard layout
|
||||||
|
#: data/popover.ui:6
|
||||||
|
msgid "Emoji"
|
||||||
|
msgstr "Emoji"
|
||||||
|
|
||||||
|
#. translators: This is a terminal keyboard layout
|
||||||
|
#: data/popover.ui:12
|
||||||
|
msgid "Terminal"
|
||||||
|
msgstr "Terminal"
|
||||||
|
|
||||||
|
#: data/popover.ui:18
|
||||||
|
msgid "Keyboard Settings"
|
||||||
|
msgstr "Paramètres del clavièr"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:3
|
||||||
|
msgid "Squeekboard"
|
||||||
|
msgstr "Squeekboard"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:4
|
||||||
|
msgid "On Screen Keyboard"
|
||||||
|
msgstr "Clavièr visual"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:5
|
||||||
|
msgid "An on screen virtual keyboard"
|
||||||
|
msgstr "Un clavièr virtual sus l’ecran"
|
||||||
47
po/pl.po
Normal file
47
po/pl.po
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
# Polish translation for squeekboard.
|
||||||
|
# Copyright © 2022 the squeekboard authors.
|
||||||
|
# This file is distributed under the same license as the squeekboard package.
|
||||||
|
# Piotr Drąg <piotrdrag@gmail.com>, 2022.
|
||||||
|
# Aviary.pl <community-poland@mozilla.org>, 2022.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: squeekboard\n"
|
||||||
|
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/Phosh/squeekboard/"
|
||||||
|
"issues\n"
|
||||||
|
"POT-Creation-Date: 2022-03-19 09:34+0000\n"
|
||||||
|
"PO-Revision-Date: 2022-03-20 14:12+0100\n"
|
||||||
|
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||||
|
"Language-Team: Polish <community-poland@mozilla.org>\n"
|
||||||
|
"Language: pl\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
|
||||||
|
"|| n%100>=20) ? 1 : 2);\n"
|
||||||
|
|
||||||
|
#. translators: This is a emmoji keyboard layout
|
||||||
|
#: data/popover.ui:6
|
||||||
|
msgid "Emoji"
|
||||||
|
msgstr "Emoji"
|
||||||
|
|
||||||
|
#. translators: This is a terminal keyboard layout
|
||||||
|
#: data/popover.ui:12
|
||||||
|
msgid "Terminal"
|
||||||
|
msgstr "Terminal"
|
||||||
|
|
||||||
|
#: data/popover.ui:18
|
||||||
|
msgid "Keyboard Settings"
|
||||||
|
msgstr "Ustawienia klawiatury"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:3
|
||||||
|
msgid "Squeekboard"
|
||||||
|
msgstr "Squeekboard"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:4
|
||||||
|
msgid "On Screen Keyboard"
|
||||||
|
msgstr "Klawiatura ekranowa"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:5
|
||||||
|
msgid "An on screen virtual keyboard"
|
||||||
|
msgstr "Wirtualna klawiatura ekranowa"
|
||||||
46
po/pt.po
Normal file
46
po/pt.po
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# Portuguese translation for squeekboard.
|
||||||
|
# Copyright (C) 2022 squeekboard's COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the squeekboard package.
|
||||||
|
# Hugo Carvalho <hugokarvalho@hotmail.com>, 2022.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: squeekboard master\n"
|
||||||
|
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/Phosh/squeekboard/"
|
||||||
|
"issues\n"
|
||||||
|
"POT-Creation-Date: 2022-02-26 10:49+0000\n"
|
||||||
|
"PO-Revision-Date: 2022-02-26 18:27+0000\n"
|
||||||
|
"Last-Translator: Hugo Carvalho <hugokarvalho@hotmail.com>\n"
|
||||||
|
"Language-Team: Portuguese <pt@li.org>\n"
|
||||||
|
"Language: pt\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
"X-Generator: Poedit 3.0.1\n"
|
||||||
|
|
||||||
|
#. translators: This is a emmoji keyboard layout
|
||||||
|
#: data/popover.ui:6
|
||||||
|
msgid "Emoji"
|
||||||
|
msgstr "Emoji"
|
||||||
|
|
||||||
|
#. translators: This is a terminal keyboard layout
|
||||||
|
#: data/popover.ui:12
|
||||||
|
msgid "Terminal"
|
||||||
|
msgstr "Terminal"
|
||||||
|
|
||||||
|
#: data/popover.ui:18
|
||||||
|
msgid "Keyboard Settings"
|
||||||
|
msgstr "Definições do teclado"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:3
|
||||||
|
msgid "Squeekboard"
|
||||||
|
msgstr "Squeekboard"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:4
|
||||||
|
msgid "On Screen Keyboard"
|
||||||
|
msgstr "Teclado no ecrã"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:5
|
||||||
|
msgid "An on screen virtual keyboard"
|
||||||
|
msgstr "Um teclado virtual no ecrã"
|
||||||
45
po/sr.po
Normal file
45
po/sr.po
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# Serbian translation for squeekboard.
|
||||||
|
# Copyright © 2022 squeekboard's COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the squeekboard package.
|
||||||
|
# Мирослав Николић <miroslavnikolic@rocketmail.com>, 2022.
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: squeekboard master\n"
|
||||||
|
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/Phosh/squeekboard/"
|
||||||
|
"issues\n"
|
||||||
|
"POT-Creation-Date: 2022-03-08 10:15+0000\n"
|
||||||
|
"PO-Revision-Date: 2022-03-12 13:00+0200\n"
|
||||||
|
"Last-Translator: Мирослав Николић <miroslavnikolic@rocketmail.com>\n"
|
||||||
|
"Language-Team: Serbian <(nothing)>\n"
|
||||||
|
"Language: sr\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : n"
|
||||||
|
"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||||
|
|
||||||
|
#. translators: This is a emmoji keyboard layout
|
||||||
|
#: data/popover.ui:6
|
||||||
|
msgid "Emoji"
|
||||||
|
msgstr "Емоџи"
|
||||||
|
|
||||||
|
#. translators: This is a terminal keyboard layout
|
||||||
|
#: data/popover.ui:12
|
||||||
|
msgid "Terminal"
|
||||||
|
msgstr "Терминал"
|
||||||
|
|
||||||
|
#: data/popover.ui:18
|
||||||
|
msgid "Keyboard Settings"
|
||||||
|
msgstr "Поставке тастатуре"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:3
|
||||||
|
msgid "Squeekboard"
|
||||||
|
msgstr "Сквик-табла"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:4
|
||||||
|
msgid "On Screen Keyboard"
|
||||||
|
msgstr "Тастатура на екрану"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:5
|
||||||
|
msgid "An on screen virtual keyboard"
|
||||||
|
msgstr "Виртуелна тастатура на екрану"
|
||||||
46
po/tr.po
Normal file
46
po/tr.po
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# Turkish translation for squeekboard.
|
||||||
|
# Copyright (C) 2022 squeekboard's COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the squeekboard package.
|
||||||
|
# Emin Tufan Çetin <etcetin@gmail.com>, 2022.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: squeekboard master\n"
|
||||||
|
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/World/Phosh/squeekboard/"
|
||||||
|
"issues\n"
|
||||||
|
"POT-Creation-Date: 2022-03-16 00:57+0000\n"
|
||||||
|
"PO-Revision-Date: 2022-03-19 12:33+0300\n"
|
||||||
|
"Last-Translator: Emin Tufan Çetin <etcetin@gmail.com>\n"
|
||||||
|
"Language-Team: Turkish <gnometurk@gnome.org>\n"
|
||||||
|
"Language: tr\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||||
|
"X-Generator: Poedit 2.4.3\n"
|
||||||
|
|
||||||
|
#. translators: This is a emmoji keyboard layout
|
||||||
|
#: data/popover.ui:6
|
||||||
|
msgid "Emoji"
|
||||||
|
msgstr "Emoji"
|
||||||
|
|
||||||
|
#. translators: This is a terminal keyboard layout
|
||||||
|
#: data/popover.ui:12
|
||||||
|
msgid "Terminal"
|
||||||
|
msgstr "Uçbirim"
|
||||||
|
|
||||||
|
#: data/popover.ui:18
|
||||||
|
msgid "Keyboard Settings"
|
||||||
|
msgstr "Klavye Ayarları"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:3
|
||||||
|
msgid "Squeekboard"
|
||||||
|
msgstr "Squeekboard"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:4
|
||||||
|
msgid "On Screen Keyboard"
|
||||||
|
msgstr "Ekran Klavyesi"
|
||||||
|
|
||||||
|
#: data/sm.puri.Squeekboard.desktop.in.in:5
|
||||||
|
msgid "An on screen virtual keyboard"
|
||||||
|
msgstr "Sanal ekran klavyesi"
|
||||||
@ -7,6 +7,7 @@
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use crate::outputs::OutputId;
|
use crate::outputs::OutputId;
|
||||||
|
use crate::panel::PixelSize;
|
||||||
|
|
||||||
/// The keyboard should hide after this has elapsed to prevent flickering.
|
/// The keyboard should hide after this has elapsed to prevent flickering.
|
||||||
pub const HIDING_TIMEOUT: Duration = Duration::from_millis(200);
|
pub const HIDING_TIMEOUT: Duration = Duration::from_millis(200);
|
||||||
@ -16,7 +17,7 @@ pub const HIDING_TIMEOUT: Duration = Duration::from_millis(200);
|
|||||||
pub enum Outcome {
|
pub enum Outcome {
|
||||||
Visible {
|
Visible {
|
||||||
output: OutputId,
|
output: OutputId,
|
||||||
height: u32,
|
height: PixelSize,
|
||||||
},
|
},
|
||||||
Hidden,
|
Hidden,
|
||||||
}
|
}
|
||||||
|
|||||||
71
src/debug.rs
Normal file
71
src/debug.rs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 Purism SPC
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
use std::thread;
|
||||||
|
use zbus::{Connection, ObjectServer, dbus_interface, fdo};
|
||||||
|
|
||||||
|
use crate::event_loop;
|
||||||
|
use crate::state;
|
||||||
|
|
||||||
|
|
||||||
|
use std::convert::TryInto;
|
||||||
|
|
||||||
|
|
||||||
|
/// Accepts commands controlling the debug mode
|
||||||
|
struct Manager {
|
||||||
|
sender: event_loop::driver::Threaded,
|
||||||
|
enabled: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[dbus_interface(name = "sm.puri.SqueekDebug")]
|
||||||
|
impl Manager {
|
||||||
|
#[dbus_interface(property, name = "Enabled")]
|
||||||
|
fn get_enabled(&self) -> bool {
|
||||||
|
self.enabled
|
||||||
|
}
|
||||||
|
#[dbus_interface(property, name = "Enabled")]
|
||||||
|
fn set_enabled(&mut self, enabled: bool) {
|
||||||
|
self.enabled = enabled;
|
||||||
|
self.sender
|
||||||
|
.send(state::Event::Debug(
|
||||||
|
if enabled { Event::Enable }
|
||||||
|
else { Event::Disable }
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start(mgr: Manager) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let connection = Connection::new_session()?;
|
||||||
|
fdo::DBusProxy::new(&connection)?.request_name(
|
||||||
|
"sm.puri.SqueekDebug",
|
||||||
|
fdo::RequestNameFlags::ReplaceExisting.into(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let mut object_server = ObjectServer::new(&connection);
|
||||||
|
object_server.at(&"/sm/puri/SqueekDebug".try_into()?, mgr)?;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if let Err(err) = object_server.try_handle_next() {
|
||||||
|
eprintln!("{}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init(sender: event_loop::driver::Threaded) {
|
||||||
|
let mgr = Manager {
|
||||||
|
sender,
|
||||||
|
enabled: false,
|
||||||
|
};
|
||||||
|
thread::spawn(move || {
|
||||||
|
start(mgr).unwrap();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub enum Event {
|
||||||
|
Enable,
|
||||||
|
Disable,
|
||||||
|
}
|
||||||
@ -151,7 +151,7 @@ mod test {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::animation;
|
use crate::animation;
|
||||||
use crate::imservice::{ ContentHint, ContentPurpose };
|
use crate::imservice::{ ContentHint, ContentPurpose };
|
||||||
use crate::main::PanelCommand;
|
use crate::panel;
|
||||||
use crate::state::{ Application, InputMethod, InputMethodDetails, Presence, visibility };
|
use crate::state::{ Application, InputMethod, InputMethodDetails, Presence, visibility };
|
||||||
use crate::state::test::application_with_fake_output;
|
use crate::state::test::application_with_fake_output;
|
||||||
|
|
||||||
@ -176,13 +176,13 @@ mod test {
|
|||||||
|
|
||||||
let l = State::new(state, now);
|
let l = State::new(state, now);
|
||||||
let (l, commands) = handle_event(l, InputMethod::InactiveSince(now).into(), now);
|
let (l, commands) = handle_event(l, InputMethod::InactiveSince(now).into(), now);
|
||||||
assert_matches!(commands.panel_visibility, Some(PanelCommand::Show{..}));
|
assert_matches!(commands.panel_visibility, Some(panel::Command::Show{..}));
|
||||||
assert_eq!(l.scheduled_wakeup, Some(now + animation::HIDING_TIMEOUT));
|
assert_eq!(l.scheduled_wakeup, Some(now + animation::HIDING_TIMEOUT));
|
||||||
|
|
||||||
now += animation::HIDING_TIMEOUT;
|
now += animation::HIDING_TIMEOUT;
|
||||||
|
|
||||||
let (l, commands) = handle_event(l, Event::TimeoutReached(now), now);
|
let (l, commands) = handle_event(l, Event::TimeoutReached(now), now);
|
||||||
assert_eq!(commands.panel_visibility, Some(PanelCommand::Hide));
|
assert_eq!(commands.panel_visibility, Some(panel::Command::Hide));
|
||||||
assert_eq!(l.scheduled_wakeup, None);
|
assert_eq!(l.scheduled_wakeup, None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#include "submission.h"
|
#include "input-method-unstable-v2-client-protocol.h"
|
||||||
|
#include "virtual-keyboard-unstable-v1-client-protocol.h"
|
||||||
|
|
||||||
#include <glib.h>
|
#include "submission.h"
|
||||||
|
|
||||||
struct imservice;
|
struct imservice;
|
||||||
|
|
||||||
|
|||||||
@ -154,11 +154,6 @@ pub mod c {
|
|||||||
let imservice = check_imservice(imservice, im).unwrap();
|
let imservice = check_imservice(imservice, im).unwrap();
|
||||||
|
|
||||||
imservice.current = imservice.pending.clone();
|
imservice.current = imservice.pending.clone();
|
||||||
imservice.pending = IMProtocolState {
|
|
||||||
active: imservice.current.active,
|
|
||||||
..IMProtocolState::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
imservice.serial += Wrapping(1u32);
|
imservice.serial += Wrapping(1u32);
|
||||||
imservice.send_event();
|
imservice.send_event();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use std::cmp;
|
||||||
use std::collections::{ HashMap, HashSet };
|
use std::collections::{ HashMap, HashSet };
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -26,6 +27,7 @@ use std::vec::Vec;
|
|||||||
|
|
||||||
use ::action::Action;
|
use ::action::Action;
|
||||||
use ::drawing;
|
use ::drawing;
|
||||||
|
use ::float_ord::FloatOrd;
|
||||||
use ::keyboard::KeyState;
|
use ::keyboard::KeyState;
|
||||||
use ::logging;
|
use ::logging;
|
||||||
use ::manager;
|
use ::manager;
|
||||||
@ -117,28 +119,30 @@ pub mod c {
|
|||||||
pub struct Transformation {
|
pub struct Transformation {
|
||||||
pub origin_x: f64,
|
pub origin_x: f64,
|
||||||
pub origin_y: f64,
|
pub origin_y: f64,
|
||||||
pub scale: f64,
|
pub scale_x: f64,
|
||||||
|
pub scale_y: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Transformation {
|
impl Transformation {
|
||||||
/// Applies the new transformation after this one
|
/// Applies the new transformation after this one
|
||||||
pub fn chain(self, next: Transformation) -> Transformation {
|
pub fn chain(self, next: Transformation) -> Transformation {
|
||||||
Transformation {
|
Transformation {
|
||||||
origin_x: self.origin_x + self.scale * next.origin_x,
|
origin_x: self.origin_x + self.scale_x * next.origin_x,
|
||||||
origin_y: self.origin_y + self.scale * next.origin_y,
|
origin_y: self.origin_y + self.scale_y * next.origin_y,
|
||||||
scale: self.scale * next.scale,
|
scale_x: self.scale_x * next.scale_x,
|
||||||
|
scale_y: self.scale_y * next.scale_y,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn forward(&self, p: Point) -> Point {
|
fn forward(&self, p: Point) -> Point {
|
||||||
Point {
|
Point {
|
||||||
x: (p.x - self.origin_x) / self.scale,
|
x: (p.x - self.origin_x) / self.scale_x,
|
||||||
y: (p.y - self.origin_y) / self.scale,
|
y: (p.y - self.origin_y) / self.scale_y,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn reverse(&self, p: Point) -> Point {
|
fn reverse(&self, p: Point) -> Point {
|
||||||
Point {
|
Point {
|
||||||
x: p.x * self.scale + self.origin_x,
|
x: p.x * self.scale_x + self.origin_x,
|
||||||
y: p.y * self.scale + self.origin_y,
|
y: p.y * self.scale_y + self.origin_y,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn reverse_bounds(&self, b: Bounds) -> Bounds {
|
pub fn reverse_bounds(&self, b: Bounds) -> Bounds {
|
||||||
@ -394,7 +398,8 @@ pub mod c {
|
|||||||
let transform = Transformation {
|
let transform = Transformation {
|
||||||
origin_x: 10f64,
|
origin_x: 10f64,
|
||||||
origin_y: 11f64,
|
origin_y: 11f64,
|
||||||
scale: 12f64,
|
scale_x: 12f64,
|
||||||
|
scale_y: 13f64,
|
||||||
};
|
};
|
||||||
let point = Point { x: 1f64, y: 1f64 };
|
let point = Point { x: 1f64, y: 1f64 };
|
||||||
let transformed = transform.reverse(transform.forward(point.clone()));
|
let transformed = transform.reverse(transform.forward(point.clone()));
|
||||||
@ -755,16 +760,20 @@ impl Layout {
|
|||||||
let size = self.calculate_size();
|
let size = self.calculate_size();
|
||||||
let h_scale = available.width / size.width;
|
let h_scale = available.width / size.width;
|
||||||
let v_scale = available.height / size.height;
|
let v_scale = available.height / size.height;
|
||||||
let scale = if h_scale < v_scale { h_scale } else { v_scale };
|
// Allow up to 5% (and a bit more) horizontal stretching for filling up available space
|
||||||
|
let scale_x = if (h_scale / v_scale) < 1.055 { h_scale } else { v_scale };
|
||||||
|
let scale_y = cmp::min(FloatOrd(h_scale), FloatOrd(v_scale)).0;
|
||||||
let outside_margins = c::Transformation {
|
let outside_margins = c::Transformation {
|
||||||
origin_x: (available.width - (scale * size.width)) / 2.0,
|
origin_x: (available.width - (scale_x * size.width)) / 2.0,
|
||||||
origin_y: (available.height - (scale * size.height)) / 2.0,
|
origin_y: (available.height - (scale_y * size.height)) / 2.0,
|
||||||
scale: scale,
|
scale_x: scale_x,
|
||||||
|
scale_y: scale_y,
|
||||||
};
|
};
|
||||||
outside_margins.chain(c::Transformation {
|
outside_margins.chain(c::Transformation {
|
||||||
origin_x: self.margins.left,
|
origin_x: self.margins.left,
|
||||||
origin_y: self.margins.top,
|
origin_y: self.margins.top,
|
||||||
scale: 1.0,
|
scale_x: 1.0,
|
||||||
|
scale_y: 1.0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1471,8 +1480,63 @@ mod test {
|
|||||||
let transformation = layout.calculate_transformation(
|
let transformation = layout.calculate_transformation(
|
||||||
Size { width: 2.0, height: 2.0 }
|
Size { width: 2.0, height: 2.0 }
|
||||||
);
|
);
|
||||||
assert_eq!(transformation.scale, 1.0);
|
assert_eq!(transformation.scale_x, 1.0);
|
||||||
|
assert_eq!(transformation.scale_y, 1.0);
|
||||||
assert_eq!(transformation.origin_x, 0.5);
|
assert_eq!(transformation.origin_x, 0.5);
|
||||||
assert_eq!(transformation.origin_y, 0.0);
|
assert_eq!(transformation.origin_y, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_stretching() {
|
||||||
|
// just one button
|
||||||
|
let view = View::new(vec![
|
||||||
|
(
|
||||||
|
0.0,
|
||||||
|
Row::new(vec![(
|
||||||
|
0.0,
|
||||||
|
Box::new(Button {
|
||||||
|
size: Size { width: 1.0, height: 1.0 },
|
||||||
|
..*make_button_with_state("foo".into(), make_state())
|
||||||
|
}),
|
||||||
|
)]),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
let layout = Layout {
|
||||||
|
current_view: String::new(),
|
||||||
|
view_latched: LatchedState::Not,
|
||||||
|
keymaps: Vec::new(),
|
||||||
|
kind: ArrangementKind::Base,
|
||||||
|
pressed_keys: HashSet::new(),
|
||||||
|
margins: Margins {
|
||||||
|
top: 0.0,
|
||||||
|
left: 0.0,
|
||||||
|
right: 0.0,
|
||||||
|
bottom: 0.0,
|
||||||
|
},
|
||||||
|
views: hashmap! {
|
||||||
|
String::new() => (c::Point { x: 0.0, y: 0.0 }, view),
|
||||||
|
},
|
||||||
|
purpose: ContentPurpose::Normal,
|
||||||
|
};
|
||||||
|
let transformation = layout.calculate_transformation(
|
||||||
|
Size { width: 100.0, height: 100.0 }
|
||||||
|
);
|
||||||
|
assert_eq!(transformation.scale_x, 100.0);
|
||||||
|
assert_eq!(transformation.scale_y, 100.0);
|
||||||
|
let transformation = layout.calculate_transformation(
|
||||||
|
Size { width: 95.0, height: 100.0 }
|
||||||
|
);
|
||||||
|
assert_eq!(transformation.scale_x, 95.0);
|
||||||
|
assert_eq!(transformation.scale_y, 95.0);
|
||||||
|
let transformation = layout.calculate_transformation(
|
||||||
|
Size { width: 105.0, height: 100.0 }
|
||||||
|
);
|
||||||
|
assert_eq!(transformation.scale_x, 105.0);
|
||||||
|
assert_eq!(transformation.scale_y, 100.0);
|
||||||
|
let transformation = layout.calculate_transformation(
|
||||||
|
Size { width: 106.0, height: 100.0 }
|
||||||
|
);
|
||||||
|
assert_eq!(transformation.scale_x, 100.0);
|
||||||
|
assert_eq!(transformation.scale_y, 100.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,6 +13,8 @@ extern crate gtk_sys;
|
|||||||
extern crate maplit;
|
extern crate maplit;
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
extern crate xkbcommon;
|
extern crate xkbcommon;
|
||||||
|
extern crate zbus;
|
||||||
|
extern crate zvariant;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
@ -23,6 +25,7 @@ mod logging;
|
|||||||
mod action;
|
mod action;
|
||||||
mod animation;
|
mod animation;
|
||||||
pub mod data;
|
pub mod data;
|
||||||
|
mod debug;
|
||||||
mod drawing;
|
mod drawing;
|
||||||
mod event_loop;
|
mod event_loop;
|
||||||
pub mod float_ord;
|
pub mod float_ord;
|
||||||
@ -33,6 +36,7 @@ mod locale;
|
|||||||
mod main;
|
mod main;
|
||||||
mod manager;
|
mod manager;
|
||||||
mod outputs;
|
mod outputs;
|
||||||
|
mod panel;
|
||||||
mod popover;
|
mod popover;
|
||||||
mod resources;
|
mod resources;
|
||||||
mod state;
|
mod state;
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "eek/eek-types.h"
|
#include "eek/eek-types.h"
|
||||||
#include "dbus.h"
|
#include "dbus.h"
|
||||||
|
#include "panel.h"
|
||||||
|
|
||||||
|
|
||||||
struct receiver;
|
struct receiver;
|
||||||
@ -24,7 +25,7 @@ struct rsobjects {
|
|||||||
struct squeek_wayland *wayland;
|
struct squeek_wayland *wayland;
|
||||||
};
|
};
|
||||||
|
|
||||||
void register_ui_loop_handler(struct receiver *receiver, ServerContextService *ui, DBusHandler *dbus_handler);
|
void register_ui_loop_handler(struct receiver *receiver, struct panel_manager *panel, EekboardContextService *hint_manager, DBusHandler *dbus_handler);
|
||||||
|
|
||||||
struct rsobjects squeek_init(void);
|
struct rsobjects squeek_init(void);
|
||||||
|
|
||||||
|
|||||||
57
src/main.rs
57
src/main.rs
@ -3,7 +3,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*! Glue for the main loop. */
|
/*! Glue for the main loop. */
|
||||||
use crate::outputs::OutputId;
|
use crate::panel;
|
||||||
|
use crate::debug;
|
||||||
use crate::state;
|
use crate::state;
|
||||||
use glib::{Continue, MainContext, PRIORITY_DEFAULT, Receiver};
|
use glib::{Continue, MainContext, PRIORITY_DEFAULT, Receiver};
|
||||||
|
|
||||||
@ -19,19 +20,21 @@ mod c {
|
|||||||
use crate::imservice::IMService;
|
use crate::imservice::IMService;
|
||||||
use crate::imservice::c::InputMethod;
|
use crate::imservice::c::InputMethod;
|
||||||
use crate::outputs::Outputs;
|
use crate::outputs::Outputs;
|
||||||
use crate::outputs::c::WlOutput;
|
|
||||||
use crate::state;
|
use crate::state;
|
||||||
use crate::submission::Submission;
|
use crate::submission::Submission;
|
||||||
use crate::util::c::Wrapped;
|
use crate::util::c::Wrapped;
|
||||||
use crate::vkeyboard::c::ZwpVirtualKeyboardV1;
|
use crate::vkeyboard::c::ZwpVirtualKeyboardV1;
|
||||||
|
|
||||||
/// ServerContextService*
|
|
||||||
#[repr(transparent)]
|
|
||||||
pub struct UIManager(*const c_void);
|
|
||||||
|
|
||||||
/// DbusHandler*
|
/// DbusHandler*
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct DBusHandler(*const c_void);
|
pub struct DBusHandler(*const c_void);
|
||||||
|
|
||||||
|
/// EekboardContextService* in the role of a hint receiver
|
||||||
|
// The clone/copy is a concession to C style of programming.
|
||||||
|
// It would be hard to get rid of it.
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct HintManager(*const c_void);
|
||||||
|
|
||||||
/// Holds the Rust structures that are interesting from C.
|
/// Holds the Rust structures that are interesting from C.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
@ -75,9 +78,7 @@ mod c {
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#[allow(improper_ctypes)]
|
#[allow(improper_ctypes)]
|
||||||
fn init_wayland(wayland: *mut Wayland);
|
fn init_wayland(wayland: *mut Wayland);
|
||||||
fn server_context_service_update_keyboard(service: *const UIManager, output: WlOutput, height: u32);
|
fn eekboard_context_service_set_hint_purpose(service: HintManager, hint: u32, purpose: u32);
|
||||||
fn server_context_service_real_hide_keyboard(service: *const UIManager);
|
|
||||||
fn server_context_service_set_hint_purpose(service: *const UIManager, hint: u32, purpose: u32);
|
|
||||||
// This should probably only get called from the gtk main loop,
|
// This should probably only get called from the gtk main loop,
|
||||||
// given that dbus handler is using glib.
|
// given that dbus handler is using glib.
|
||||||
fn dbus_handler_set_visible(dbus: *const DBusHandler, visible: u8);
|
fn dbus_handler_set_visible(dbus: *const DBusHandler, visible: u8);
|
||||||
@ -94,6 +95,8 @@ mod c {
|
|||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
let state_manager = driver::Threaded::new(sender, state::Application::new(now));
|
let state_manager = driver::Threaded::new(sender, state::Application::new(now));
|
||||||
|
|
||||||
|
debug::init(state_manager.clone());
|
||||||
|
|
||||||
let outputs = Outputs::new(state_manager.clone());
|
let outputs = Outputs::new(state_manager.clone());
|
||||||
let mut wayland = Box::new(Wayland::new(outputs));
|
let mut wayland = Box::new(Wayland::new(outputs));
|
||||||
let wayland_raw = &mut *wayland as *mut _;
|
let wayland_raw = &mut *wayland as *mut _;
|
||||||
@ -121,18 +124,20 @@ mod c {
|
|||||||
pub extern "C"
|
pub extern "C"
|
||||||
fn register_ui_loop_handler(
|
fn register_ui_loop_handler(
|
||||||
receiver: Wrapped<Receiver<Commands>>,
|
receiver: Wrapped<Receiver<Commands>>,
|
||||||
ui_manager: *const UIManager,
|
panel_manager: panel::c::PanelManager,
|
||||||
|
hint_manager: HintManager,
|
||||||
dbus_handler: *const DBusHandler,
|
dbus_handler: *const DBusHandler,
|
||||||
) {
|
) {
|
||||||
let receiver = unsafe { receiver.unwrap() };
|
let receiver = unsafe { receiver.unwrap() };
|
||||||
let receiver = Rc::try_unwrap(receiver).expect("References still present");
|
let receiver = Rc::try_unwrap(receiver).expect("References still present");
|
||||||
let receiver = receiver.into_inner();
|
let receiver = receiver.into_inner();
|
||||||
|
let panel_manager = Wrapped::new(panel::Manager::new(panel_manager));
|
||||||
let ctx = MainContext::default();
|
let ctx = MainContext::default();
|
||||||
let _acqu = ctx.acquire();
|
let _acqu = ctx.acquire();
|
||||||
receiver.attach(
|
receiver.attach(
|
||||||
Some(&ctx),
|
Some(&ctx),
|
||||||
move |msg| {
|
move |msg| {
|
||||||
main_loop_handle_message(msg, ui_manager, dbus_handler);
|
main_loop_handle_message(msg, panel_manager.clone(), hint_manager, dbus_handler);
|
||||||
Continue(true)
|
Continue(true)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -146,18 +151,13 @@ mod c {
|
|||||||
/// and doesn't lend itself to testing other than integration.
|
/// and doesn't lend itself to testing other than integration.
|
||||||
fn main_loop_handle_message(
|
fn main_loop_handle_message(
|
||||||
msg: Commands,
|
msg: Commands,
|
||||||
ui_manager: *const UIManager,
|
panel_manager: Wrapped<panel::Manager>,
|
||||||
|
hint_manager: HintManager,
|
||||||
dbus_handler: *const DBusHandler,
|
dbus_handler: *const DBusHandler,
|
||||||
) {
|
) {
|
||||||
match msg.panel_visibility {
|
if let Some(visibility) = msg.panel_visibility {
|
||||||
Some(PanelCommand::Show { output, height }) => unsafe {
|
panel::Manager::update(panel_manager, visibility);
|
||||||
server_context_service_update_keyboard(ui_manager, output.0, height);
|
}
|
||||||
},
|
|
||||||
Some(PanelCommand::Hide) => unsafe {
|
|
||||||
server_context_service_real_hide_keyboard(ui_manager);
|
|
||||||
},
|
|
||||||
None => {},
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(visible) = msg.dbus_visible_set {
|
if let Some(visible) = msg.dbus_visible_set {
|
||||||
if dbus_handler != std::ptr::null() {
|
if dbus_handler != std::ptr::null() {
|
||||||
@ -167,8 +167,8 @@ mod c {
|
|||||||
|
|
||||||
if let Some(hints) = msg.layout_hint_set {
|
if let Some(hints) = msg.layout_hint_set {
|
||||||
unsafe {
|
unsafe {
|
||||||
server_context_service_set_hint_purpose(
|
eekboard_context_service_set_hint_purpose(
|
||||||
ui_manager,
|
hint_manager,
|
||||||
hints.hint.bits(),
|
hints.hint.bits(),
|
||||||
hints.purpose.clone() as u32,
|
hints.purpose.clone() as u32,
|
||||||
)
|
)
|
||||||
@ -177,20 +177,11 @@ mod c {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
|
||||||
pub enum PanelCommand {
|
|
||||||
Show {
|
|
||||||
output: OutputId,
|
|
||||||
height: u32,
|
|
||||||
},
|
|
||||||
Hide,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The commands consumed by the main loop,
|
/// The commands consumed by the main loop,
|
||||||
/// to be sent out to external components.
|
/// to be sent out to external components.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Commands {
|
pub struct Commands {
|
||||||
pub panel_visibility: Option<PanelCommand>,
|
pub panel_visibility: Option<panel::Command>,
|
||||||
pub layout_hint_set: Option<state::InputMethodDetails>,
|
pub layout_hint_set: Option<state::InputMethodDetails>,
|
||||||
pub dbus_visible_set: Option<bool>,
|
pub dbus_visible_set: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ sources = [
|
|||||||
config_h,
|
config_h,
|
||||||
'dbus.c',
|
'dbus.c',
|
||||||
'imservice.c',
|
'imservice.c',
|
||||||
|
'panel.c',
|
||||||
'popover.c',
|
'popover.c',
|
||||||
'server-context-service.c',
|
'server-context-service.c',
|
||||||
'wayland.c',
|
'wayland.c',
|
||||||
|
|||||||
118
src/outputs.rs
118
src/outputs.rs
@ -4,9 +4,11 @@
|
|||||||
|
|
||||||
/*! Managing Wayland outputs */
|
/*! Managing Wayland outputs */
|
||||||
|
|
||||||
|
use std::ops;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
use crate::event_loop;
|
use crate::event_loop;
|
||||||
use ::logging;
|
use ::logging;
|
||||||
|
use crate::util::DivCeil;
|
||||||
|
|
||||||
// traits
|
// traits
|
||||||
use ::logging::Warn;
|
use ::logging::Warn;
|
||||||
@ -126,7 +128,7 @@ pub mod c {
|
|||||||
outputs: COutputs,
|
outputs: COutputs,
|
||||||
wl_output: WlOutput,
|
wl_output: WlOutput,
|
||||||
_x: i32, _y: i32,
|
_x: i32, _y: i32,
|
||||||
_phys_width: i32, _phys_height: i32,
|
phys_width: i32, phys_height: i32,
|
||||||
_subpixel: i32,
|
_subpixel: i32,
|
||||||
_make: *const c_char, _model: *const c_char,
|
_make: *const c_char, _model: *const c_char,
|
||||||
transform: i32,
|
transform: i32,
|
||||||
@ -144,7 +146,19 @@ pub mod c {
|
|||||||
.find_output_mut(wl_output)
|
.find_output_mut(wl_output)
|
||||||
.map(|o| &mut o.pending);
|
.map(|o| &mut o.pending);
|
||||||
match output_state {
|
match output_state {
|
||||||
Some(state) => { state.transform = Some(transform) },
|
Some(state) => {
|
||||||
|
fn maybe_mm(value: i32) -> Option<Millimeter> {
|
||||||
|
if value == 0 { None }
|
||||||
|
else { Some(Millimeter(value)) }
|
||||||
|
}
|
||||||
|
state.geometry = Some(Geometry {
|
||||||
|
phys_size: Size {
|
||||||
|
width: maybe_mm(phys_width),
|
||||||
|
height: maybe_mm(phys_height),
|
||||||
|
},
|
||||||
|
transform,
|
||||||
|
});
|
||||||
|
},
|
||||||
None => log_print!(
|
None => log_print!(
|
||||||
logging::Level::Warning,
|
logging::Level::Warning,
|
||||||
"Got geometry on unknown output",
|
"Got geometry on unknown output",
|
||||||
@ -286,24 +300,51 @@ pub mod c {
|
|||||||
// TODO: handle unregistration
|
// TODO: handle unregistration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Generic size
|
/// Generic size
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct Size {
|
pub struct Size<Unit> {
|
||||||
pub width: u32,
|
pub width: Unit,
|
||||||
pub height: u32,
|
pub height: Unit,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type PixelSize = Size<u32>;
|
||||||
|
|
||||||
/// wl_output mode
|
/// wl_output mode
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct Mode {
|
pub struct Mode {
|
||||||
width: i32,
|
pub width: i32,
|
||||||
height: i32,
|
pub height: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub struct Millimeter(pub i32);
|
||||||
|
|
||||||
|
impl DivCeil<i32> for Millimeter {
|
||||||
|
type Output = Millimeter;
|
||||||
|
fn div_ceil(self, other: i32) -> Self {
|
||||||
|
Self(self.0.div_ceil(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ops::Mul<i32> for Millimeter {
|
||||||
|
type Output = Self;
|
||||||
|
fn mul(self, m: i32) -> Self {
|
||||||
|
Self(self.0 * m as i32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// All geometry parameters
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub struct Geometry {
|
||||||
|
pub transform: c::Transform,
|
||||||
|
pub phys_size: Size<Option<Millimeter>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct OutputState {
|
pub struct OutputState {
|
||||||
pub current_mode: Option<Mode>,
|
pub current_mode: Option<Mode>,
|
||||||
pub transform: Option<c::Transform>,
|
pub geometry: Option<Geometry>,
|
||||||
pub scale: i32,
|
pub scale: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,33 +358,56 @@ impl OutputState {
|
|||||||
fn uninitialized() -> OutputState {
|
fn uninitialized() -> OutputState {
|
||||||
OutputState {
|
OutputState {
|
||||||
current_mode: None,
|
current_mode: None,
|
||||||
transform: None,
|
geometry: None,
|
||||||
scale: 1,
|
scale: 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_pixel_size(&self) -> Option<Size> {
|
fn transform_size<T>(
|
||||||
|
width: T,
|
||||||
|
height: T,
|
||||||
|
transform: self::c::Transform,
|
||||||
|
) -> Size<T> {
|
||||||
use self::c::Transform;
|
use self::c::Transform;
|
||||||
|
|
||||||
|
match transform {
|
||||||
|
Transform::Normal
|
||||||
|
| Transform::Rotated180
|
||||||
|
| Transform::Flipped
|
||||||
|
| Transform::FlippedRotated180 => Size {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
},
|
||||||
|
_ => Size {
|
||||||
|
width: height,
|
||||||
|
height: width,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return resolution adjusted for current transform
|
||||||
|
pub fn get_pixel_size(&self) -> Option<PixelSize> {
|
||||||
match self {
|
match self {
|
||||||
OutputState {
|
OutputState {
|
||||||
current_mode: Some(Mode { width, height } ),
|
current_mode: Some(Mode { width, height } ),
|
||||||
transform: Some(transform),
|
geometry: Some(Geometry { transform, .. } ),
|
||||||
scale: _,
|
scale: _,
|
||||||
} => Some(
|
} => Some(Self::transform_size(*width as u32, *height as u32, *transform)),
|
||||||
match transform {
|
OutputState {
|
||||||
Transform::Normal
|
current_mode: Some(Mode { width, height } ),
|
||||||
| Transform::Rotated180
|
..
|
||||||
| Transform::Flipped
|
} => Some(PixelSize { width: *width as u32, height: *height as u32 } ),
|
||||||
| Transform::FlippedRotated180 => Size {
|
_ => None,
|
||||||
width: *width as u32,
|
}
|
||||||
height: *height as u32,
|
}
|
||||||
},
|
|
||||||
_ => Size {
|
/// Return physical dimensions adjusted for current transform
|
||||||
width: *height as u32,
|
pub fn get_physical_size(&self) -> Option<Size<Option<Millimeter>>> {
|
||||||
height: *width as u32,
|
match self {
|
||||||
},
|
OutputState {
|
||||||
}
|
geometry: Some(Geometry { transform, phys_size } ),
|
||||||
),
|
..
|
||||||
|
} => Some(Self::transform_size(phys_size.width, phys_size.height, *transform)),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
130
src/panel.c
Normal file
130
src/panel.c
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
#include "eekboard/eekboard-context-service.h"
|
||||||
|
#include "wayland.h"
|
||||||
|
#include "panel.h"
|
||||||
|
|
||||||
|
|
||||||
|
// Called from rust
|
||||||
|
/// Destroys the widget
|
||||||
|
void
|
||||||
|
panel_manager_hide(struct panel_manager *self)
|
||||||
|
{
|
||||||
|
if (self->window) {
|
||||||
|
gtk_widget_destroy (GTK_WIDGET (self->window));
|
||||||
|
}
|
||||||
|
if (self->widget) {
|
||||||
|
gtk_widget_destroy (GTK_WIDGET (self->widget));
|
||||||
|
}
|
||||||
|
self->window = NULL;
|
||||||
|
self->widget = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_destroy (struct panel_manager *self, GtkWidget *widget)
|
||||||
|
{
|
||||||
|
g_assert (widget == GTK_WIDGET(self->window));
|
||||||
|
panel_manager_hide(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// panel::Manager. Only needed for this callback
|
||||||
|
struct squeek_panel_manager;
|
||||||
|
|
||||||
|
/// Calls back into Rust
|
||||||
|
void squeek_panel_manager_configured(struct squeek_panel_manager *mgr, uint32_t width, uint32_t height);
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_surface_configure(struct squeek_panel_manager *self, PhoshLayerSurface *surface)
|
||||||
|
{
|
||||||
|
gint width;
|
||||||
|
gint height;
|
||||||
|
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (surface));
|
||||||
|
|
||||||
|
g_object_get(G_OBJECT(surface),
|
||||||
|
"configured-width", &width,
|
||||||
|
"configured-height", &height,
|
||||||
|
NULL);
|
||||||
|
squeek_panel_manager_configured(self, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
make_widget (struct panel_manager *self)
|
||||||
|
{
|
||||||
|
if (self->widget) {
|
||||||
|
g_error("Widget already present");
|
||||||
|
}
|
||||||
|
self->widget = eek_gtk_keyboard_new (self->state, self->submission, self->layout);
|
||||||
|
|
||||||
|
gtk_widget_set_has_tooltip (self->widget, TRUE);
|
||||||
|
gtk_container_add (GTK_CONTAINER(self->window), self->widget);
|
||||||
|
gtk_widget_show_all(self->widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Called from rust
|
||||||
|
/// Creates a new panel widget
|
||||||
|
void
|
||||||
|
panel_manager_request_widget (struct panel_manager *self, struct wl_output *output, uint32_t height, struct squeek_panel_manager *mgr)
|
||||||
|
{
|
||||||
|
if (self->window) {
|
||||||
|
g_error("Window already present");
|
||||||
|
}
|
||||||
|
|
||||||
|
self->window = g_object_new (
|
||||||
|
PHOSH_TYPE_LAYER_SURFACE,
|
||||||
|
"layer-shell", squeek_wayland->layer_shell,
|
||||||
|
"wl-output", output,
|
||||||
|
"height", height,
|
||||||
|
"anchor", ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM
|
||||||
|
| ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
|
||||||
|
| ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT,
|
||||||
|
"layer", ZWLR_LAYER_SHELL_V1_LAYER_TOP,
|
||||||
|
"kbd-interactivity", FALSE,
|
||||||
|
"exclusive-zone", height,
|
||||||
|
"namespace", "osk",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
g_object_connect (self->window,
|
||||||
|
"swapped-signal::destroy", G_CALLBACK(on_destroy), self,
|
||||||
|
"swapped-signal::configured", G_CALLBACK(on_surface_configure), mgr,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
// The properties below are just to make hacking easier.
|
||||||
|
// The way we use layer-shell overrides some,
|
||||||
|
// and there's no space in the protocol for others.
|
||||||
|
// Those may still be useful in the future,
|
||||||
|
// or for hacks with regular windows.
|
||||||
|
gtk_widget_set_can_focus (GTK_WIDGET(self->window), FALSE);
|
||||||
|
g_object_set (G_OBJECT(self->window), "accept_focus", FALSE, NULL);
|
||||||
|
gtk_window_set_title (GTK_WINDOW(self->window), "Squeekboard");
|
||||||
|
gtk_window_set_icon_name (GTK_WINDOW(self->window), "squeekboard");
|
||||||
|
gtk_window_set_keep_above (GTK_WINDOW(self->window), TRUE);
|
||||||
|
|
||||||
|
make_widget(self);
|
||||||
|
|
||||||
|
gtk_widget_show (GTK_WIDGET(self->window));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called from rust
|
||||||
|
/// Updates the size
|
||||||
|
void
|
||||||
|
panel_manager_resize (struct panel_manager *self, uint32_t height)
|
||||||
|
{
|
||||||
|
phosh_layer_surface_set_size(self->window, 0, height);
|
||||||
|
phosh_layer_surface_set_exclusive_zone(self->window, height);
|
||||||
|
phosh_layer_surface_wl_surface_commit(self->window);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct panel_manager panel_manager_new(EekboardContextService *state, struct submission *submission, struct squeek_layout_state *layout)
|
||||||
|
{
|
||||||
|
struct panel_manager mgr = {
|
||||||
|
.state = state,
|
||||||
|
.submission = submission,
|
||||||
|
.layout = layout,
|
||||||
|
.window = NULL,
|
||||||
|
.widget = NULL,
|
||||||
|
.current_output = NULL,
|
||||||
|
};
|
||||||
|
return mgr;
|
||||||
|
}
|
||||||
21
src/panel.h
Normal file
21
src/panel.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "eek/layersurface.h"
|
||||||
|
#include "src/layout.h"
|
||||||
|
#include "src/submission.h"
|
||||||
|
|
||||||
|
// Stores the objects that the panel and its widget will refer to
|
||||||
|
struct panel_manager {
|
||||||
|
EekboardContextService *state; // unowned
|
||||||
|
/// Needed for instantiating the widget
|
||||||
|
struct submission *submission; // unowned
|
||||||
|
struct squeek_layout_state *layout;
|
||||||
|
|
||||||
|
PhoshLayerSurface *window;
|
||||||
|
GtkWidget *widget; // nullable
|
||||||
|
|
||||||
|
// Those should be held in Rust
|
||||||
|
struct wl_output *current_output;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct panel_manager panel_manager_new(EekboardContextService *state, struct submission *submission, struct squeek_layout_state *layout);
|
||||||
248
src/panel.rs
Normal file
248
src/panel.rs
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
/* Copyright (C) 2022 Purism SPC
|
||||||
|
* SPDX-License-Identifier: GPL-3.0+
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! Panel state management.
|
||||||
|
*
|
||||||
|
* This is effectively a mirror of the previous C code,
|
||||||
|
* with an explicit state machine managing the panel size.
|
||||||
|
*
|
||||||
|
* It still relies on a callback from Wayland to accept the panel size,
|
||||||
|
* which makes this code somewhat prone to mistakes.
|
||||||
|
*
|
||||||
|
* An alternative to the callback would be
|
||||||
|
* to send a message all the way to `state::State`
|
||||||
|
* every time the allocated size changes.
|
||||||
|
* That would allow for a more holistic view
|
||||||
|
* of interactions of different pieces of state.
|
||||||
|
*
|
||||||
|
* However, `state::State` already has the potential to become a ball of mud,
|
||||||
|
* tightly coupling different functionality and making it difficult to see independent units.
|
||||||
|
*
|
||||||
|
* For this reason, I'm taking a light touch approach with the panel manager,
|
||||||
|
* and moving it just a bit closer to `state::State`.
|
||||||
|
* Hopefully ths still allows us to expose assumptions that were not stated yet
|
||||||
|
* (e.g. can the output disappear between size request andallocation?).
|
||||||
|
*
|
||||||
|
* Tight coupling, e.g. a future one between presented hints and layout size,
|
||||||
|
* will have to be taken into account later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use crate::logging;
|
||||||
|
use crate::outputs::OutputId;
|
||||||
|
use crate::util::c::Wrapped;
|
||||||
|
|
||||||
|
|
||||||
|
pub mod c {
|
||||||
|
use super::*;
|
||||||
|
use glib;
|
||||||
|
use gtk::Continue;
|
||||||
|
use std::os::raw::c_void;
|
||||||
|
|
||||||
|
use crate::outputs::c::WlOutput;
|
||||||
|
|
||||||
|
/// struct panel_manager*
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct PanelManager(*const c_void);
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#[allow(improper_ctypes)]
|
||||||
|
pub fn panel_manager_request_widget(
|
||||||
|
service: PanelManager,
|
||||||
|
output: WlOutput,
|
||||||
|
height: u32,
|
||||||
|
// for callbacks
|
||||||
|
panel: Wrapped<Manager>,
|
||||||
|
);
|
||||||
|
pub fn panel_manager_resize(service: PanelManager, height: u32);
|
||||||
|
pub fn panel_manager_hide(service: PanelManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C"
|
||||||
|
fn squeek_panel_manager_configured(panel: Wrapped<Manager>, width: u32, height: u32) {
|
||||||
|
// This is why this needs to be moved into state::State:
|
||||||
|
// it's getting too coupled to glib.
|
||||||
|
glib::idle_add_local(move || {
|
||||||
|
let panel = panel.clone_ref();
|
||||||
|
panel.borrow_mut().set_configured(Size{width, height});
|
||||||
|
Continue(false)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Size in pixels that is aware of scaling
|
||||||
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||||
|
pub struct PixelSize {
|
||||||
|
pub pixels: u32,
|
||||||
|
pub scale_factor: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn div_ceil(a: u32, b: u32) -> u32 {
|
||||||
|
// Given that it's for pixels on a screen, an overflow is unlikely.
|
||||||
|
(a + b - 1) / b
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PixelSize {
|
||||||
|
pub fn as_scaled_floor(&self) -> u32 {
|
||||||
|
self.pixels / self.scale_factor
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_scaled_ceiling(&self) -> u32 {
|
||||||
|
div_ceil(self.pixels, self.scale_factor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
struct Size {
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This state requests the Wayland layer shell protocol synchronization:
|
||||||
|
/// the application asks for some size,
|
||||||
|
/// and then receives a size that the compositor thought appropriate.
|
||||||
|
/// Stores raw values passed to Wayland, i.e. scaled dimensions.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
enum State {
|
||||||
|
Hidden,
|
||||||
|
SizeRequested {
|
||||||
|
output: OutputId,
|
||||||
|
height: u32,
|
||||||
|
//width: u32,
|
||||||
|
},
|
||||||
|
SizeAllocated {
|
||||||
|
output: OutputId,
|
||||||
|
wanted_height: u32,
|
||||||
|
allocated: Size,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
|
pub enum Command {
|
||||||
|
Show {
|
||||||
|
output: OutputId,
|
||||||
|
height: PixelSize,
|
||||||
|
},
|
||||||
|
Hide,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Tries to contain all the panel sizing duties.
|
||||||
|
pub struct Manager {
|
||||||
|
panel: c::PanelManager,
|
||||||
|
state: State,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Manager {
|
||||||
|
pub fn new(panel: c::PanelManager) -> Self {
|
||||||
|
Self {
|
||||||
|
panel,
|
||||||
|
state: State::Hidden,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO: mabe send the allocated size back to state::State,
|
||||||
|
// to perform layout adjustments
|
||||||
|
fn set_configured(&mut self, size: Size) {
|
||||||
|
self.state = match self.state.clone() {
|
||||||
|
State::Hidden => {
|
||||||
|
// This may happen if a hide is scheduled immediately after a show.
|
||||||
|
log_print!(
|
||||||
|
logging::Level::Surprise,
|
||||||
|
"Panel has been configured, but no request is pending. Ignoring",
|
||||||
|
);
|
||||||
|
State::Hidden
|
||||||
|
},
|
||||||
|
State::SizeAllocated{output, wanted_height, ..} => {
|
||||||
|
log_print!(
|
||||||
|
logging::Level::Surprise,
|
||||||
|
"Panel received new configuration without asking",
|
||||||
|
);
|
||||||
|
State::SizeAllocated{output, wanted_height, allocated: size}
|
||||||
|
},
|
||||||
|
State::SizeRequested{output, height} => State::SizeAllocated {
|
||||||
|
output,
|
||||||
|
wanted_height: height,
|
||||||
|
allocated: size,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(mgr: Wrapped<Manager>, cmd: Command) {
|
||||||
|
let copied = mgr.clone();
|
||||||
|
|
||||||
|
let mgr = mgr.clone_ref();
|
||||||
|
let mut mgr = mgr.borrow_mut();
|
||||||
|
|
||||||
|
(*mgr).state = match (cmd, mgr.state.clone()) {
|
||||||
|
(Command::Hide, State::Hidden) => State::Hidden,
|
||||||
|
(Command::Hide, State::SizeAllocated{..}) => {
|
||||||
|
unsafe { c::panel_manager_hide(mgr.panel); }
|
||||||
|
State::Hidden
|
||||||
|
},
|
||||||
|
(Command::Hide, State::SizeRequested{..}) => {
|
||||||
|
unsafe { c::panel_manager_hide(mgr.panel); }
|
||||||
|
State::Hidden
|
||||||
|
},
|
||||||
|
(Command::Show{output, height}, State::Hidden) => {
|
||||||
|
let height = height.as_scaled_ceiling();
|
||||||
|
unsafe { c::panel_manager_request_widget(mgr.panel, output.0, height, copied); }
|
||||||
|
State::SizeRequested{output, height}
|
||||||
|
},
|
||||||
|
(
|
||||||
|
Command::Show{output, height},
|
||||||
|
State::SizeRequested{output: req_output, height: req_height},
|
||||||
|
) => {
|
||||||
|
let height = height.as_scaled_ceiling();
|
||||||
|
if output == req_output && height == req_height {
|
||||||
|
State::SizeRequested{output: req_output, height: req_height}
|
||||||
|
} else if output == req_output {
|
||||||
|
// I'm not sure about that.
|
||||||
|
// This could cause a busy loop,
|
||||||
|
// when two requests are being processed at the same time:
|
||||||
|
// one message in the compositor to allocate size A,
|
||||||
|
// causing the state to update to height A'
|
||||||
|
// the other from the state wanting height B',
|
||||||
|
// causing the compositor to change size to B.
|
||||||
|
// So better cut this short here, despite artifacts.
|
||||||
|
// Out of simplicty, just ignore the new request.
|
||||||
|
// If that causes problems, the request in flight could be stored
|
||||||
|
// for the purpose of handling it better somehow.
|
||||||
|
State::SizeRequested{output: req_output, height: req_height}
|
||||||
|
} else {
|
||||||
|
// This looks weird, but should be safe.
|
||||||
|
// The stack seems to handle
|
||||||
|
// configure events on a dead surface.
|
||||||
|
unsafe {
|
||||||
|
c::panel_manager_hide(mgr.panel);
|
||||||
|
c::panel_manager_request_widget(mgr.panel, output.0, height, copied);
|
||||||
|
}
|
||||||
|
State::SizeRequested{output, height}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(
|
||||||
|
Command::Show{output, height},
|
||||||
|
State::SizeAllocated{output: alloc_output, allocated, wanted_height},
|
||||||
|
) => {
|
||||||
|
let height = height.as_scaled_ceiling();
|
||||||
|
if output == alloc_output && height == wanted_height {
|
||||||
|
State::SizeAllocated{output: alloc_output, wanted_height, allocated}
|
||||||
|
} else if output == alloc_output && height == allocated.height {
|
||||||
|
State::SizeAllocated{output: alloc_output, wanted_height: height, allocated}
|
||||||
|
} else if output == alloc_output {
|
||||||
|
// Should *all* other heights cause a resize?
|
||||||
|
// What about those between wanted and allocated?
|
||||||
|
unsafe { c::panel_manager_resize(mgr.panel, height); }
|
||||||
|
State::SizeRequested{output, height}
|
||||||
|
} else {
|
||||||
|
unsafe {
|
||||||
|
c::panel_manager_hide(mgr.panel);
|
||||||
|
c::panel_manager_request_widget(mgr.panel, output.0, height, copied);
|
||||||
|
}
|
||||||
|
State::SizeRequested{output, height}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -54,6 +54,8 @@ static KEYBOARDS: &[(&'static str, &'static str)] = &[
|
|||||||
("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")),
|
||||||
|
("gr_wide", include_str!("../data/keyboards/gr_wide.yaml")),
|
||||||
|
("gr+polytonic", include_str!("../data/keyboards/gr+polytonic.yaml")),
|
||||||
|
|
||||||
("il", include_str!("../data/keyboards/il.yaml")),
|
("il", include_str!("../data/keyboards/il.yaml")),
|
||||||
|
|
||||||
|
|||||||
@ -20,14 +20,7 @@
|
|||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
|
|
||||||
#include "eek/eek.h"
|
|
||||||
#include "eek/eek-gtk-keyboard.h"
|
|
||||||
#include "eek/layersurface.h"
|
|
||||||
#include "eekboard/eekboard-context-service.h"
|
|
||||||
#include "submission.h"
|
|
||||||
#include "wayland.h"
|
|
||||||
#include "server-context-service.h"
|
#include "server-context-service.h"
|
||||||
#include "wayland-client-protocol.h"
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
@ -37,148 +30,13 @@ enum {
|
|||||||
|
|
||||||
struct _ServerContextService {
|
struct _ServerContextService {
|
||||||
GObject parent;
|
GObject parent;
|
||||||
|
|
||||||
EekboardContextService *state; // unowned
|
|
||||||
/// Needed for instantiating the widget
|
|
||||||
struct submission *submission; // unowned
|
|
||||||
struct squeek_layout_state *layout;
|
|
||||||
struct squeek_state_manager *state_manager; // shared reference
|
struct squeek_state_manager *state_manager; // shared reference
|
||||||
|
|
||||||
PhoshLayerSurface *window;
|
|
||||||
GtkWidget *widget; // nullable
|
|
||||||
|
|
||||||
struct wl_output *current_output;
|
|
||||||
guint last_requested_height;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE(ServerContextService, server_context_service, G_TYPE_OBJECT);
|
G_DEFINE_TYPE(ServerContextService, server_context_service, G_TYPE_OBJECT);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_destroy (ServerContextService *self, GtkWidget *widget)
|
/// Height is in scaled units.
|
||||||
{
|
|
||||||
g_return_if_fail (SERVER_IS_CONTEXT_SERVICE (self));
|
|
||||||
|
|
||||||
g_assert (widget == GTK_WIDGET(self->window));
|
|
||||||
|
|
||||||
self->window = NULL;
|
|
||||||
self->widget = NULL;
|
|
||||||
|
|
||||||
//eekboard_context_service_destroy (EEKBOARD_CONTEXT_SERVICE (context));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
make_window (ServerContextService *self, struct wl_output *output, uint32_t height)
|
|
||||||
{
|
|
||||||
if (self->window) {
|
|
||||||
g_error("Window already present");
|
|
||||||
}
|
|
||||||
|
|
||||||
self->window = g_object_new (
|
|
||||||
PHOSH_TYPE_LAYER_SURFACE,
|
|
||||||
"layer-shell", squeek_wayland->layer_shell,
|
|
||||||
"wl-output", output,
|
|
||||||
"height", height,
|
|
||||||
"anchor", ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM
|
|
||||||
| ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
|
|
||||||
| ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT,
|
|
||||||
"layer", ZWLR_LAYER_SHELL_V1_LAYER_TOP,
|
|
||||||
"kbd-interactivity", FALSE,
|
|
||||||
"exclusive-zone", height,
|
|
||||||
"namespace", "osk",
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
g_object_connect (self->window,
|
|
||||||
"swapped-signal::destroy", G_CALLBACK(on_destroy), self,
|
|
||||||
//"swapped-signal::configured", G_CALLBACK(on_surface_configure), self,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
// The properties below are just to make hacking easier.
|
|
||||||
// The way we use layer-shell overrides some,
|
|
||||||
// and there's no space in the protocol for others.
|
|
||||||
// Those may still be useful in the future,
|
|
||||||
// or for hacks with regular windows.
|
|
||||||
gtk_widget_set_can_focus (GTK_WIDGET(self->window), FALSE);
|
|
||||||
g_object_set (G_OBJECT(self->window), "accept_focus", FALSE, NULL);
|
|
||||||
gtk_window_set_title (GTK_WINDOW(self->window), "Squeekboard");
|
|
||||||
gtk_window_set_icon_name (GTK_WINDOW(self->window), "squeekboard");
|
|
||||||
gtk_window_set_keep_above (GTK_WINDOW(self->window), TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
destroy_window (ServerContextService *self)
|
|
||||||
{
|
|
||||||
gtk_widget_destroy (GTK_WIDGET (self->window));
|
|
||||||
self->window = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
make_widget (ServerContextService *self)
|
|
||||||
{
|
|
||||||
if (self->widget) {
|
|
||||||
gtk_widget_destroy(self->widget);
|
|
||||||
self->widget = NULL;
|
|
||||||
}
|
|
||||||
self->widget = eek_gtk_keyboard_new (self->state, self->submission, self->layout);
|
|
||||||
|
|
||||||
gtk_widget_set_has_tooltip (self->widget, TRUE);
|
|
||||||
gtk_container_add (GTK_CONTAINER(self->window), self->widget);
|
|
||||||
gtk_widget_show_all(self->widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called from rust
|
|
||||||
/// Updates the type of hiddenness
|
|
||||||
void
|
|
||||||
server_context_service_real_hide_keyboard (ServerContextService *self)
|
|
||||||
{
|
|
||||||
//self->desired_height = 0;
|
|
||||||
self->current_output = NULL;
|
|
||||||
if (self->window) {
|
|
||||||
gtk_widget_hide (GTK_WIDGET(self->window));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called from rust
|
|
||||||
/// Updates the type of visibility
|
|
||||||
void
|
|
||||||
server_context_service_update_keyboard (ServerContextService *self, struct wl_output *output, uint32_t height)
|
|
||||||
{
|
|
||||||
if (output != self->current_output) {
|
|
||||||
// Recreate on a new output
|
|
||||||
server_context_service_real_hide_keyboard(self);
|
|
||||||
} else {
|
|
||||||
gint h;
|
|
||||||
PhoshLayerSurface *surface = self->window;
|
|
||||||
g_object_get(G_OBJECT(surface),
|
|
||||||
"configured-height", &h,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if ((uint32_t)h != height) {
|
|
||||||
|
|
||||||
//TODO: make sure that redrawing happens in the correct place (it doesn't now).
|
|
||||||
phosh_layer_surface_set_size(self->window, 0, height);
|
|
||||||
phosh_layer_surface_set_exclusive_zone(self->window, height);
|
|
||||||
phosh_layer_surface_wl_surface_commit(self->window);
|
|
||||||
|
|
||||||
self->current_output = output;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self->current_output = output;
|
|
||||||
|
|
||||||
if (!self->window) {
|
|
||||||
make_window (self, output, height);
|
|
||||||
}
|
|
||||||
if (!self->widget) {
|
|
||||||
make_widget (self);
|
|
||||||
}
|
|
||||||
gtk_widget_show (GTK_WIDGET(self->window));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
server_context_service_set_property (GObject *object,
|
server_context_service_set_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
const GValue *value,
|
const GValue *value,
|
||||||
@ -209,17 +67,6 @@ server_context_service_get_property (GObject *object,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
server_context_service_dispose (GObject *object)
|
|
||||||
{
|
|
||||||
ServerContextService *self = SERVER_CONTEXT_SERVICE(object);
|
|
||||||
|
|
||||||
destroy_window (self);
|
|
||||||
self->widget = NULL;
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (server_context_service_parent_class)->dispose (object);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
server_context_service_class_init (ServerContextServiceClass *klass)
|
server_context_service_class_init (ServerContextServiceClass *klass)
|
||||||
{
|
{
|
||||||
@ -228,7 +75,6 @@ server_context_service_class_init (ServerContextServiceClass *klass)
|
|||||||
|
|
||||||
gobject_class->set_property = server_context_service_set_property;
|
gobject_class->set_property = server_context_service_set_property;
|
||||||
gobject_class->get_property = server_context_service_get_property;
|
gobject_class->get_property = server_context_service_get_property;
|
||||||
gobject_class->dispose = server_context_service_dispose;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ServerContextServie:keyboard:
|
* ServerContextServie:keyboard:
|
||||||
@ -249,41 +95,29 @@ 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) {
|
ServerContextService *
|
||||||
|
server_context_service_new (struct squeek_state_manager *state_manager)
|
||||||
|
{
|
||||||
|
ServerContextService *holder = g_object_new (SERVER_TYPE_CONTEXT_SERVICE, NULL);
|
||||||
|
holder->state_manager = state_manager;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
if (!ssrc) {
|
if (!ssrc) {
|
||||||
g_warning("No gsettings schemas installed.");
|
g_warning("No gsettings schemas installed.");
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
schema = g_settings_schema_source_lookup(ssrc, schema_name, TRUE);
|
schema = g_settings_schema_source_lookup(ssrc, schema_name, TRUE);
|
||||||
if (schema) {
|
if (schema) {
|
||||||
g_autoptr(GSettings) settings = g_settings_new (schema_name);
|
g_autoptr(GSettings) settings = g_settings_new (schema_name);
|
||||||
g_settings_bind (settings, "screen-keyboard-enabled",
|
g_settings_bind (settings, "screen-keyboard-enabled",
|
||||||
self, "enabled", G_SETTINGS_BIND_GET);
|
holder, "enabled", G_SETTINGS_BIND_GET);
|
||||||
} else {
|
} else {
|
||||||
g_warning("Gsettings schema %s is not installed on the system. "
|
g_warning("Gsettings schema %s is not installed on the system. "
|
||||||
"Enabling by default.", schema_name);
|
"Enabling by default.", schema_name);
|
||||||
}
|
}
|
||||||
}
|
return holder;
|
||||||
|
|
||||||
ServerContextService *
|
|
||||||
server_context_service_new (EekboardContextService *self, struct submission *submission, struct squeek_layout_state *layout, struct squeek_state_manager *state_manager)
|
|
||||||
{
|
|
||||||
ServerContextService *ui = g_object_new (SERVER_TYPE_CONTEXT_SERVICE, NULL);
|
|
||||||
ui->submission = submission;
|
|
||||||
ui->state = self;
|
|
||||||
ui->layout = layout;
|
|
||||||
ui->state_manager = state_manager;
|
|
||||||
init(ui);
|
|
||||||
return ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Used from Rust
|
|
||||||
void server_context_service_set_hint_purpose(ServerContextService *self, uint32_t hint,
|
|
||||||
uint32_t purpose) {
|
|
||||||
eekboard_context_service_set_hint_purpose(self->state, hint, purpose);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,9 +17,9 @@
|
|||||||
*/
|
*/
|
||||||
#ifndef SERVER_CONTEXT_SERVICE_H
|
#ifndef SERVER_CONTEXT_SERVICE_H
|
||||||
#define SERVER_CONTEXT_SERVICE_H 1
|
#define SERVER_CONTEXT_SERVICE_H 1
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
#include "src/layout.h"
|
#include "main.h"
|
||||||
#include "src/submission.h"
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@ -28,8 +28,8 @@ 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 squeek_state_manager *state_manager);
|
ServerContextService *server_context_service_new(struct squeek_state_manager *state_manager);
|
||||||
enum squeek_arrangement_kind server_context_service_get_layout_type(ServerContextService *);
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* SERVER_CONTEXT_SERVICE_H */
|
#endif /* SERVER_CONTEXT_SERVICE_H */
|
||||||
|
|
||||||
|
|||||||
@ -31,6 +31,7 @@
|
|||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "outputs.h"
|
#include "outputs.h"
|
||||||
|
#include "panel.h"
|
||||||
#include "submission.h"
|
#include "submission.h"
|
||||||
#include "server-context-service.h"
|
#include "server-context-service.h"
|
||||||
#include "wayland.h"
|
#include "wayland.h"
|
||||||
@ -51,8 +52,10 @@ typedef enum _SqueekboardDebugFlags {
|
|||||||
struct squeekboard {
|
struct squeekboard {
|
||||||
struct squeek_wayland wayland; // Just hooks.
|
struct squeek_wayland wayland; // Just hooks.
|
||||||
DBusHandler *dbus_handler; // Controls visibility of the OSK.
|
DBusHandler *dbus_handler; // Controls visibility of the OSK.
|
||||||
EekboardContextService *settings_context; // Gsettings hooks.
|
EekboardContextService *settings_context; // Gsettings hooks for layouts.
|
||||||
ServerContextService *ui_context; // mess, includes the entire UI
|
/// Gsettings hook for visibility. TODO: this does not belong in gsettings.
|
||||||
|
ServerContextService *settings_handler;
|
||||||
|
struct panel_manager panel_manager; // Controls the shape of the panel.
|
||||||
/// Currently wanted layout. TODO: merge into state::Application
|
/// Currently wanted layout. TODO: merge into state::Application
|
||||||
struct squeek_layout_state layout_choice;
|
struct squeek_layout_state layout_choice;
|
||||||
};
|
};
|
||||||
@ -435,20 +438,21 @@ main (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
eekboard_context_service_set_submission(instance.settings_context, rsobjects.submission);
|
ServerContextService *setting_listener = server_context_service_new(
|
||||||
|
|
||||||
ServerContextService *ui_context = server_context_service_new(
|
|
||||||
instance.settings_context,
|
|
||||||
rsobjects.submission,
|
|
||||||
&instance.layout_choice,
|
|
||||||
rsobjects.state_manager);
|
rsobjects.state_manager);
|
||||||
if (!ui_context) {
|
if (!setting_listener) {
|
||||||
g_error("Could not initialize GUI");
|
g_warning ("could not connect to gsettings");
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.ui_context = ui_context;
|
instance.settings_handler = setting_listener;
|
||||||
register_ui_loop_handler(rsobjects.receiver, instance.ui_context, instance.dbus_handler);
|
|
||||||
|
eekboard_context_service_set_submission(instance.settings_context, rsobjects.submission);
|
||||||
|
|
||||||
|
instance.panel_manager = panel_manager_new(instance.settings_context,
|
||||||
|
rsobjects.submission,
|
||||||
|
&instance.layout_choice);
|
||||||
|
|
||||||
|
register_ui_loop_handler(rsobjects.receiver, &instance.panel_manager, instance.settings_context, instance.dbus_handler);
|
||||||
|
|
||||||
session_register();
|
session_register();
|
||||||
|
|
||||||
|
|||||||
169
src/state.rs
169
src/state.rs
@ -6,27 +6,32 @@
|
|||||||
* It's driven by the loop defined in the loop module. */
|
* It's driven by the loop defined in the loop module. */
|
||||||
|
|
||||||
use crate::animation;
|
use crate::animation;
|
||||||
|
use crate::debug;
|
||||||
use crate::imservice::{ ContentHint, ContentPurpose };
|
use crate::imservice::{ ContentHint, ContentPurpose };
|
||||||
use crate::main::{ Commands, PanelCommand };
|
use crate::main::Commands;
|
||||||
use crate::outputs;
|
use crate::outputs;
|
||||||
use crate::outputs::{OutputId, OutputState};
|
use crate::outputs::{Millimeter, OutputId, OutputState};
|
||||||
|
use crate::panel;
|
||||||
|
use crate::panel::PixelSize;
|
||||||
|
use crate::util::Rational;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum Presence {
|
pub enum Presence {
|
||||||
Present,
|
Present,
|
||||||
Missing,
|
Missing,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct InputMethodDetails {
|
pub struct InputMethodDetails {
|
||||||
pub hint: ContentHint,
|
pub hint: ContentHint,
|
||||||
pub purpose: ContentPurpose,
|
pub purpose: ContentPurpose,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum InputMethod {
|
pub enum InputMethod {
|
||||||
Active(InputMethodDetails),
|
Active(InputMethodDetails),
|
||||||
InactiveSince(Instant),
|
InactiveSince(Instant),
|
||||||
@ -34,12 +39,13 @@ pub enum InputMethod {
|
|||||||
|
|
||||||
/// Incoming events.
|
/// Incoming events.
|
||||||
/// This contains events that cause a change to the internal state.
|
/// This contains events that cause a change to the internal state.
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
InputMethod(InputMethod),
|
InputMethod(InputMethod),
|
||||||
Visibility(visibility::Event),
|
Visibility(visibility::Event),
|
||||||
PhysicalKeyboard(Presence),
|
PhysicalKeyboard(Presence),
|
||||||
Output(outputs::Event),
|
Output(outputs::Event),
|
||||||
|
Debug(debug::Event),
|
||||||
/// Event triggered because a moment in time passed.
|
/// Event triggered because a moment in time passed.
|
||||||
/// Use to animate state transitions.
|
/// Use to animate state transitions.
|
||||||
/// The value is the ideal arrival time.
|
/// The value is the ideal arrival time.
|
||||||
@ -59,7 +65,7 @@ impl From<outputs::Event> for Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub mod visibility {
|
pub mod visibility {
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
/// User requested the panel to show
|
/// User requested the panel to show
|
||||||
ForceVisible,
|
ForceVisible,
|
||||||
@ -79,7 +85,7 @@ pub mod visibility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The outwardly visible state.
|
/// The outwardly visible state.
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Outcome {
|
pub struct Outcome {
|
||||||
pub visibility: animation::Outcome,
|
pub visibility: animation::Outcome,
|
||||||
pub im: InputMethod,
|
pub im: InputMethod,
|
||||||
@ -114,8 +120,8 @@ impl Outcome {
|
|||||||
// FIXME: handle switching outputs
|
// FIXME: handle switching outputs
|
||||||
let (dbus_visible_set, panel_visibility) = match new_state.visibility {
|
let (dbus_visible_set, panel_visibility) = match new_state.visibility {
|
||||||
animation::Outcome::Visible{output, height}
|
animation::Outcome::Visible{output, height}
|
||||||
=> (Some(true), Some(PanelCommand::Show{output, height})),
|
=> (Some(true), Some(panel::Command::Show{output, height})),
|
||||||
animation::Outcome::Hidden => (Some(false), Some(PanelCommand::Hide)),
|
animation::Outcome::Hidden => (Some(false), Some(panel::Command::Hide)),
|
||||||
};
|
};
|
||||||
|
|
||||||
Commands {
|
Commands {
|
||||||
@ -137,11 +143,12 @@ impl Outcome {
|
|||||||
/// All state changes return the next state and the optimal time for the next check.
|
/// All state changes return the next state and the optimal time for the next check.
|
||||||
///
|
///
|
||||||
/// This state tracker can be driven by any event loop.
|
/// This state tracker can be driven by any event loop.
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Application {
|
pub struct Application {
|
||||||
pub im: InputMethod,
|
pub im: InputMethod,
|
||||||
pub visibility_override: visibility::State,
|
pub visibility_override: visibility::State,
|
||||||
pub physical_keyboard: Presence,
|
pub physical_keyboard: Presence,
|
||||||
|
pub debug_mode_enabled: bool,
|
||||||
/// The output on which the panel should appear.
|
/// The output on which the panel should appear.
|
||||||
/// This is stored as part of the state
|
/// This is stored as part of the state
|
||||||
/// because it's not clear how to derive the output from the rest of the state.
|
/// because it's not clear how to derive the output from the rest of the state.
|
||||||
@ -163,13 +170,29 @@ impl Application {
|
|||||||
im: InputMethod::InactiveSince(now),
|
im: InputMethod::InactiveSince(now),
|
||||||
visibility_override: visibility::State::NotForced,
|
visibility_override: visibility::State::NotForced,
|
||||||
physical_keyboard: Presence::Missing,
|
physical_keyboard: Presence::Missing,
|
||||||
|
debug_mode_enabled: false,
|
||||||
preferred_output: None,
|
preferred_output: None,
|
||||||
outputs: Default::default(),
|
outputs: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_event(self, event: Event, _now: Instant) -> Self {
|
pub fn apply_event(self, event: Event, now: Instant) -> Self {
|
||||||
match event {
|
if self.debug_mode_enabled {
|
||||||
|
println!(
|
||||||
|
"Received event:
|
||||||
|
{:#?}",
|
||||||
|
event,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let state = match event {
|
||||||
|
Event::Debug(dbg) => Self {
|
||||||
|
debug_mode_enabled: match dbg {
|
||||||
|
debug::Event::Enable => true,
|
||||||
|
debug::Event::Disable => false,
|
||||||
|
},
|
||||||
|
..self
|
||||||
|
},
|
||||||
|
|
||||||
Event::TimeoutReached(_) => self,
|
Event::TimeoutReached(_) => self,
|
||||||
|
|
||||||
Event::Visibility(visibility) => Self {
|
Event::Visibility(visibility) => Self {
|
||||||
@ -235,25 +258,88 @@ impl Application {
|
|||||||
..self
|
..self
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if state.debug_mode_enabled {
|
||||||
|
println!(
|
||||||
|
"State is now:
|
||||||
|
{:#?}
|
||||||
|
Outcome:
|
||||||
|
{:#?}",
|
||||||
|
state,
|
||||||
|
state.get_outcome(now),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
state
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_preferred_height(output: &OutputState) -> Option<u32> {
|
fn get_preferred_height(output: &OutputState) -> Option<PixelSize> {
|
||||||
output.get_pixel_size()
|
output.get_pixel_size()
|
||||||
.map(|px_size| {
|
.map(|px_size| {
|
||||||
let height = {
|
// Assume isotropy.
|
||||||
if px_size.width > px_size.height {
|
// Pixels/mm.
|
||||||
px_size.width / 5
|
let density = output.get_physical_size()
|
||||||
} else {
|
.and_then(|size| size.width)
|
||||||
if (px_size.width < 540) & (px_size.width > 0) {
|
.map(|width| Rational {
|
||||||
px_size.width * 7 / 12 // to match 360×210
|
numerator: px_size.width as i32,
|
||||||
} else {
|
denominator: width.0 as u32,
|
||||||
// Here we switch to wide layout, less height needed
|
})
|
||||||
px_size.width * 7 / 22
|
// Whatever the Librem 5 has,
|
||||||
}
|
// as a good default.
|
||||||
}
|
.unwrap_or(Rational {
|
||||||
|
numerator: 720,
|
||||||
|
denominator: 65,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Based on what works on the L5.
|
||||||
|
// Exceeding that probably wastes space. Reducing makes typing harder.
|
||||||
|
const IDEAL_TARGET_SIZE: Rational<Millimeter> = Rational {
|
||||||
|
numerator: Millimeter(948),
|
||||||
|
denominator: 100,
|
||||||
};
|
};
|
||||||
cmp::min(height, px_size.height / 2)
|
|
||||||
|
// TODO: calculate based on selected layout
|
||||||
|
const ROW_COUNT: u32 = 4;
|
||||||
|
|
||||||
|
let height = {
|
||||||
|
let ideal_height = IDEAL_TARGET_SIZE * ROW_COUNT as i32;
|
||||||
|
let ideal_height_px = (ideal_height * density).ceil().0 as u32;
|
||||||
|
|
||||||
|
// Reduce height to match what the layout can fill.
|
||||||
|
// For this, we need to guess if normal or wide will be picked up.
|
||||||
|
// This must match `eek_gtk_keyboard.c::get_type`.
|
||||||
|
// TODO: query layout database and choose one directly
|
||||||
|
let abstract_width
|
||||||
|
= PixelSize {
|
||||||
|
scale_factor: output.scale as u32,
|
||||||
|
pixels: px_size.width,
|
||||||
|
}
|
||||||
|
.as_scaled_ceiling();
|
||||||
|
|
||||||
|
let height_as_widths = {
|
||||||
|
if abstract_width < 540 {
|
||||||
|
// Normal
|
||||||
|
Rational {
|
||||||
|
numerator: 210,
|
||||||
|
denominator: 360,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Wide
|
||||||
|
Rational {
|
||||||
|
numerator: 172,
|
||||||
|
denominator: 540,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
cmp::min(
|
||||||
|
ideal_height_px,
|
||||||
|
(height_as_widths * px_size.width as i32).ceil() as u32,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
PixelSize {
|
||||||
|
scale_factor: output.scale as u32,
|
||||||
|
pixels: cmp::min(height, px_size.height / 2),
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,10 +351,10 @@ impl Application {
|
|||||||
Some(output) => {
|
Some(output) => {
|
||||||
// Hoping that this will get optimized out on branches not using `visible`.
|
// Hoping that this will get optimized out on branches not using `visible`.
|
||||||
let height = Self::get_preferred_height(self.outputs.get(&output).unwrap())
|
let height = Self::get_preferred_height(self.outputs.get(&output).unwrap())
|
||||||
.unwrap_or(0);
|
.unwrap_or(PixelSize{pixels: 0, scale_factor: 1});
|
||||||
// TODO: Instead of setting size to 0 when the output is invalid,
|
// TODO: Instead of setting size to 0 when the output is invalid,
|
||||||
// simply go invisible.
|
// simply go invisible.
|
||||||
let visible = animation::Outcome::Visible{output, height};
|
let visible = animation::Outcome::Visible{ output, height };
|
||||||
|
|
||||||
match (self.physical_keyboard, self.visibility_override) {
|
match (self.physical_keyboard, self.visibility_override) {
|
||||||
(_, visibility::State::ForcedHidden) => animation::Outcome::Hidden,
|
(_, visibility::State::ForcedHidden) => animation::Outcome::Hidden,
|
||||||
@ -332,7 +418,7 @@ pub mod test {
|
|||||||
id,
|
id,
|
||||||
OutputState {
|
OutputState {
|
||||||
current_mode: None,
|
current_mode: None,
|
||||||
transform: None,
|
geometry: None,
|
||||||
scale: 1,
|
scale: 1,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -514,4 +600,29 @@ pub mod test {
|
|||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn size_l5() {
|
||||||
|
use crate::outputs::{Mode, Geometry, c, Size};
|
||||||
|
assert_eq!(
|
||||||
|
Application::get_preferred_height(&OutputState {
|
||||||
|
current_mode: Some(Mode {
|
||||||
|
width: 720,
|
||||||
|
height: 1440,
|
||||||
|
}),
|
||||||
|
geometry: Some(Geometry{
|
||||||
|
transform: c::Transform::Normal,
|
||||||
|
phys_size: Size {
|
||||||
|
width: Some(Millimeter(65)),
|
||||||
|
height: Some(Millimeter(130)),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
scale: 2,
|
||||||
|
}),
|
||||||
|
Some(PixelSize {
|
||||||
|
scale_factor: 2,
|
||||||
|
pixels: 420,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
#ifndef __SUBMISSION_H
|
#ifndef __SUBMISSION_H
|
||||||
#define __SUBMISSION_H
|
#define __SUBMISSION_H
|
||||||
|
|
||||||
#include "input-method-unstable-v2-client-protocol.h"
|
#include "inttypes.h"
|
||||||
#include "virtual-keyboard-unstable-v1-client-protocol.h"
|
|
||||||
#include "eek/eek-types.h"
|
#include "eek/eek-types.h"
|
||||||
#include "main.h"
|
|
||||||
|
|
||||||
struct squeek_layout;
|
struct squeek_layout;
|
||||||
|
struct submission;
|
||||||
|
|
||||||
// Defined in Rust
|
// Defined in Rust
|
||||||
uint8_t submission_hint_available(struct submission *self);
|
uint8_t submission_hint_available(struct submission *self);
|
||||||
|
|||||||
49
src/util.rs
49
src/util.rs
@ -7,6 +7,7 @@ use ::float_ord::FloatOrd;
|
|||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
use std::hash::{ Hash, Hasher };
|
use std::hash::{ Hash, Hasher };
|
||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
|
use std::ops::Mul;
|
||||||
|
|
||||||
pub mod c {
|
pub mod c {
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -157,6 +158,54 @@ pub fn find_max_double<T, I, F>(iterator: I, get: F)
|
|||||||
.0
|
.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait DivCeil<Rhs = Self> {
|
||||||
|
type Output;
|
||||||
|
fn div_ceil(self, rhs: Rhs) -> Self::Output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Newer Rust introduces this natively,
|
||||||
|
/// but we don't always have newer Rust.
|
||||||
|
impl DivCeil for i32 {
|
||||||
|
type Output = Self;
|
||||||
|
fn div_ceil(self, other: i32) -> Self::Output {
|
||||||
|
let d = self / other;
|
||||||
|
let m = self % other;
|
||||||
|
if m == 0 { d } else { d + 1}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct Rational<T> {
|
||||||
|
pub numerator: T,
|
||||||
|
pub denominator: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<U, T: DivCeil<i32, Output=U>> Rational<T> {
|
||||||
|
pub fn ceil(self) -> U {
|
||||||
|
self.numerator.div_ceil(self.denominator as i32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Mul<i32, Output=T>> Mul<i32> for Rational<T> {
|
||||||
|
type Output = Self;
|
||||||
|
fn mul(self, m: i32) -> Self {
|
||||||
|
Self {
|
||||||
|
numerator: self.numerator * m,
|
||||||
|
denominator: self.denominator,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<U, T: Mul<U, Output=T>> Mul<Rational<U>> for Rational<T> {
|
||||||
|
type Output = Self;
|
||||||
|
fn mul(self, m: Rational<U>) -> Self {
|
||||||
|
Self {
|
||||||
|
numerator: self.numerator * m.numerator,
|
||||||
|
denominator: self.denominator * m.denominator,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Compares pointers but not internal values of Rc
|
/// Compares pointers but not internal values of Rc
|
||||||
pub struct Pointer<T>(pub Rc<T>);
|
pub struct Pointer<T>(pub Rc<T>);
|
||||||
|
|
||||||
|
|||||||
@ -76,7 +76,8 @@ foreach layout : [
|
|||||||
'es+cat',
|
'es+cat',
|
||||||
'fi',
|
'fi',
|
||||||
'fr', 'fr_wide',
|
'fr', 'fr_wide',
|
||||||
'gr',
|
'gr', 'gr_wide',
|
||||||
|
'gr+polytonic',
|
||||||
'il',
|
'il',
|
||||||
'ir',
|
'ir',
|
||||||
'it',
|
'it',
|
||||||
|
|||||||
Reference in New Issue
Block a user