Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a65332c2a9 | |||
| 2faa98d85f | |||
| b594fcf905 | |||
| 313dbdce33 | |||
| c51b001836 | |||
| bcbc9f7ba6 | |||
| b56500af0a |
@ -3,7 +3,6 @@ image: pureos/byzantium
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
- deploy
|
||||
|
||||
before_script:
|
||||
- apt-get -y update
|
||||
@ -23,14 +22,12 @@ build_docs:
|
||||
- $PKG_ONLY == "1"
|
||||
|
||||
build_meson:
|
||||
image: debian:bookworm
|
||||
stage: build
|
||||
artifacts:
|
||||
paths:
|
||||
- _build
|
||||
expire_in: 3h
|
||||
script:
|
||||
- mv debian/control-newer debian/control
|
||||
- apt-get -y build-dep .
|
||||
- meson . _build/ -Ddepdatadir=/usr/share --werror
|
||||
- ninja -C _build install
|
||||
@ -97,23 +94,6 @@ build_deb:future:
|
||||
- debuild -i -us -uc -b
|
||||
- cp ../*.deb .
|
||||
|
||||
build_reference:
|
||||
image: debian:bookworm
|
||||
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:
|
||||
stage: test
|
||||
needs:
|
||||
@ -127,13 +107,11 @@ test_lintian:
|
||||
- $PKG_ONLY == "1"
|
||||
|
||||
test:
|
||||
image: debian:bookworm
|
||||
stage: test
|
||||
needs:
|
||||
- job: build_meson
|
||||
artifacts: true
|
||||
script:
|
||||
- mv debian/control-newer debian/control
|
||||
- apt-get -y build-dep .
|
||||
- apt-get -y install clang-tidy
|
||||
- ninja -C _build test
|
||||
@ -164,17 +142,3 @@ check_release:
|
||||
except:
|
||||
variables:
|
||||
- $PKG_ONLY == "1"
|
||||
|
||||
pages:
|
||||
stage: deploy
|
||||
needs:
|
||||
- build_docs
|
||||
- build_reference
|
||||
script:
|
||||
- mv _build/ public/
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
only:
|
||||
refs:
|
||||
- master
|
||||
|
||||
@ -1,10 +1,6 @@
|
||||
# Dependencies which change based on build flags
|
||||
bitflags = "1.2.*"
|
||||
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]
|
||||
version = "0.7.*"
|
||||
|
||||
@ -1,11 +1,7 @@
|
||||
# Dependencies which change based on build flags
|
||||
# For the newer-than-Byzantium config
|
||||
bitflags = "1.3.*"
|
||||
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.*"
|
||||
clap = { version = "2.33.*", default-features = false }
|
||||
|
||||
[dependencies.cairo-rs]
|
||||
version = "0.14.*"
|
||||
|
||||
@ -1,4 +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" }
|
||||
fragile = { git = "https://source.puri.sm/dorota.czaplejewicz/fragile.git", tag = "0.3.0" }
|
||||
236
Cargo.lock
generated
236
Cargo.lock
generated
@ -40,12 +40,6 @@ version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cairo-rs"
|
||||
version = "0.7.1"
|
||||
@ -77,18 +71,6 @@ version = "1.0.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "clap"
|
||||
version = "2.33.4"
|
||||
@ -100,51 +82,11 @@ dependencies = [
|
||||
"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]]
|
||||
name = "fragile"
|
||||
version = "0.3.0"
|
||||
source = "git+https://source.puri.sm/dorota.czaplejewicz/fragile.git?tag=0.3.0#51048ca11824279c2114c77fef5bcb950838fc09"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05f8140122fa0d5dcb9fc8627cfce2b37cc1500f752636d46ea28bc26785c2f9"
|
||||
|
||||
[[package]]
|
||||
name = "gdk"
|
||||
@ -325,23 +267,14 @@ checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.8.2"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a"
|
||||
checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"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]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
@ -350,15 +283,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.126"
|
||||
version = "0.2.119"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
|
||||
checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4"
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
version = "0.5.6"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
|
||||
|
||||
[[package]]
|
||||
name = "maplit"
|
||||
@ -376,19 +309,6 @@ dependencies = [
|
||||
"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]]
|
||||
name = "pango"
|
||||
version = "0.7.0"
|
||||
@ -418,33 +338,24 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.25"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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",
|
||||
]
|
||||
checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.40"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
|
||||
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.20"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
|
||||
checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@ -463,53 +374,32 @@ dependencies = [
|
||||
"glib-sys",
|
||||
"gtk",
|
||||
"gtk-sys",
|
||||
"indexmap",
|
||||
"maplit",
|
||||
"serde",
|
||||
"serde_yaml",
|
||||
"xkbcommon",
|
||||
"zbus",
|
||||
"zvariant",
|
||||
"zvariant_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.10"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
|
||||
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.137"
|
||||
version = "1.0.136"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
|
||||
checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.137"
|
||||
version = "1.0.136"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_repr"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2ad84e47328a31223de7fed7a4f5087f2d6ddfe586cf3ca25b7a165bc0a5aed"
|
||||
checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -518,9 +408,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_yaml"
|
||||
version = "0.8.24"
|
||||
version = "0.8.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "707d15895415db6628332b737c838b88c598522e4dc70647e59b72312924aebc"
|
||||
checksum = "a4a521f2940385c165a24ee286aa8599633d162077a54bdcae2a6fd5a7bfa7a0"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"ryu",
|
||||
@ -530,13 +420,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.98"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
|
||||
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -548,21 +438,6 @@ dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.9"
|
||||
@ -570,10 +445,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
|
||||
|
||||
[[package]]
|
||||
name = "void"
|
||||
version = "1.0.2"
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
@ -615,56 +490,3 @@ checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
|
||||
dependencies = [
|
||||
"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",
|
||||
]
|
||||
|
||||
1142
Cargo.lock.newer
1142
Cargo.lock.newer
File diff suppressed because it is too large
Load Diff
@ -86,4 +86,4 @@ It's strongly recommended to support:
|
||||
Developing
|
||||
----------
|
||||
|
||||
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.
|
||||
See [`doc/hacking.md`](doc/hacking.md) for this copy, or the [official documentation](https://developer.puri.sm/projects/squeekboard/) for the current release.
|
||||
|
||||
@ -1,206 +0,0 @@
|
||||
---
|
||||
outlines:
|
||||
small: { width: 50, height: 30 }
|
||||
default: { width: 35.33, height: 52 }
|
||||
altline: { width: 35.33, height: 52 }
|
||||
wide: { width: 50, height: 52 }
|
||||
spaceline: { width: 150, height: 52 }
|
||||
special: { width: 35.33, height: 52 }
|
||||
|
||||
views:
|
||||
base:
|
||||
- "b é p o w v d l j z"
|
||||
- "a u i e c t s r n m"
|
||||
- "Shift_L y x k q g h f period BackSpace"
|
||||
- "show_numbers preferences space show_eschars Return"
|
||||
upper:
|
||||
- "B É P O W V D L J Z"
|
||||
- "A U I E C T S R N M"
|
||||
- "Shift_L Y X K Q G H F - BackSpace"
|
||||
- "show_numbers preferences space colon show_eschars Return"
|
||||
numbers:
|
||||
- "1 2 3 4 5 6 7 8 9 0"
|
||||
- "@ # € % & - _ + ( )"
|
||||
- "show_symbols , \" ' colon ; ! ? BackSpace"
|
||||
- "show_letters preferences space show_eschars Return"
|
||||
symbols:
|
||||
- "~ ` | · √ π τ ÷ × ¶"
|
||||
- "© ® £ $ ¥ ^ ° * { }"
|
||||
- "show_numbers_from_symbols \\ / < > = [ ] BackSpace"
|
||||
- "show_letters preferences space show_eschars Return"
|
||||
eschars:
|
||||
- "à â ç é è ê î ô ù û"
|
||||
- "À Â Ç É È Ê Î Ô Ù Û"
|
||||
- "show_numbers_from_symbols æ œ ä ë ï ö ü BackSpace"
|
||||
- "show_letters preferences space show_eschars Return"
|
||||
|
||||
buttons:
|
||||
F1:
|
||||
outline: "action"
|
||||
keysym: "F1"
|
||||
F2:
|
||||
outline: "action"
|
||||
keysym: "F2"
|
||||
F3:
|
||||
outline: "action"
|
||||
keysym: "F3"
|
||||
F4:
|
||||
outline: "action"
|
||||
keysym: "F4"
|
||||
F5:
|
||||
outline: "action"
|
||||
keysym: "F5"
|
||||
F6:
|
||||
outline: "action"
|
||||
keysym: "F6"
|
||||
F7:
|
||||
outline: "action"
|
||||
keysym: "F7"
|
||||
F8:
|
||||
outline: "action"
|
||||
keysym: "F8"
|
||||
F9:
|
||||
outline: "action"
|
||||
keysym: "F9"
|
||||
F10:
|
||||
outline: "action"
|
||||
keysym: "F10"
|
||||
F11:
|
||||
outline: "action"
|
||||
keysym: "F11"
|
||||
F12:
|
||||
outline: "action"
|
||||
keysym: "F12"
|
||||
Esc:
|
||||
outline: "action"
|
||||
keysym: "Escape"
|
||||
Tab:
|
||||
outline: "action"
|
||||
keysym: "Tab"
|
||||
Del:
|
||||
outline: "action"
|
||||
keysym: "Delete"
|
||||
Insert:
|
||||
outline: "action"
|
||||
keysym: "Insert"
|
||||
Menu:
|
||||
outline: "action"
|
||||
keysym: "Menu"
|
||||
Pause:
|
||||
outline: "action"
|
||||
keysym: "Pause"
|
||||
Break:
|
||||
outline: "action"
|
||||
keysym: "Break"
|
||||
Home:
|
||||
outline: "small"
|
||||
keysym: "Home"
|
||||
End:
|
||||
outline: "small"
|
||||
keysym: "End"
|
||||
PgUp:
|
||||
outline: "small"
|
||||
keysym: "Page_Up"
|
||||
PgDn:
|
||||
outline: "small"
|
||||
keysym: "Page_Down"
|
||||
"↑":
|
||||
outline: "small"
|
||||
keysym: "Up"
|
||||
"↓":
|
||||
outline: "small"
|
||||
keysym: "Down"
|
||||
"←":
|
||||
outline: "small"
|
||||
keysym: "Left"
|
||||
"→":
|
||||
outline: "small"
|
||||
keysym: "Right"
|
||||
Up:
|
||||
label: "↑"
|
||||
outline: "action"
|
||||
keysym: "Up"
|
||||
Left:
|
||||
label: "←"
|
||||
outline: "action"
|
||||
keysym: "Left"
|
||||
Down:
|
||||
label: "↓"
|
||||
outline: "action"
|
||||
keysym: "Down"
|
||||
Right:
|
||||
label: "→"
|
||||
outline: "action"
|
||||
keysym: "Right"
|
||||
Ctrl:
|
||||
modifier: "Control"
|
||||
outline: "small"
|
||||
label: "Ctrl"
|
||||
Alt:
|
||||
modifier: "Alt"
|
||||
outline: "small"
|
||||
label: "Alt"
|
||||
period:
|
||||
outline: "special"
|
||||
text: "."
|
||||
slash:
|
||||
outline: "special"
|
||||
text: "/"
|
||||
show_actions:
|
||||
action:
|
||||
set_view: "actions"
|
||||
outline: "special"
|
||||
label: ">_"
|
||||
Shift_L:
|
||||
action:
|
||||
locking:
|
||||
lock_view: "upper"
|
||||
unlock_view: "base"
|
||||
outline: "altline"
|
||||
icon: "key-shift"
|
||||
BackSpace:
|
||||
outline: "altline"
|
||||
icon: "edit-clear-symbolic"
|
||||
action: erase
|
||||
preferences:
|
||||
action: "show_prefs"
|
||||
outline: "special"
|
||||
icon: "keyboard-mode-symbolic"
|
||||
show_numbers:
|
||||
action:
|
||||
set_view: "numbers"
|
||||
outline: "wide"
|
||||
label: "123"
|
||||
show_numbers_from_symbols:
|
||||
action:
|
||||
set_view: "numbers"
|
||||
outline: "altline"
|
||||
label: "123"
|
||||
show_letters:
|
||||
action:
|
||||
set_view: "base"
|
||||
outline: "wide"
|
||||
label: "abc"
|
||||
show_symbols:
|
||||
action:
|
||||
set_view: "symbols"
|
||||
outline: "altline"
|
||||
label: "*/="
|
||||
show_eschars:
|
||||
action:
|
||||
locking:
|
||||
lock_view: "eschars"
|
||||
unlock_view: "base"
|
||||
outline: "altline"
|
||||
label: "âÂ"
|
||||
space:
|
||||
outline: "spaceline"
|
||||
text: " "
|
||||
Return:
|
||||
outline: "wide"
|
||||
icon: "key-enter"
|
||||
keysym: "Return"
|
||||
colon:
|
||||
text: ":"
|
||||
"\"":
|
||||
keysym: "quotedbl"
|
||||
@ -1,89 +0,0 @@
|
||||
---
|
||||
outlines:
|
||||
default: { width: 54, height: 42 }
|
||||
altline: { width: 81, height: 42 }
|
||||
wide: { width: 100, height: 42 }
|
||||
spaceline: { width: 205, height: 42 }
|
||||
special: { width: 54, height: 42 }
|
||||
|
||||
views:
|
||||
base:
|
||||
- "b é p o w v d l j z"
|
||||
- "a u i e c t s r n m"
|
||||
- "Shift_L y x k q g h f . BackSpace"
|
||||
- "show_numbers preferences space show_eschars Return"
|
||||
upper:
|
||||
- "B É P O W V D L J Z"
|
||||
- "A U I E C T S R N M"
|
||||
- "Shift_L Y X K Q G H F - BackSpace"
|
||||
- "show_numbers preferences space colon show_eschars Return"
|
||||
numbers:
|
||||
- "1 2 3 4 5 6 7 8 9 0"
|
||||
- "@ # € % & - _ + ( )"
|
||||
- "show_symbols , \" ' colon ; ! ? BackSpace"
|
||||
- "show_letters preferences space show_eschars Return"
|
||||
symbols:
|
||||
- "~ ` | · √ π τ ÷ × ¶"
|
||||
- "© ® £ $ ¥ ^ ° * { }"
|
||||
- "show_numbers_from_symbols \\ / < > = [ ] BackSpace"
|
||||
- "show_letters preferences space show_eschars Return"
|
||||
eschars:
|
||||
- "à â ç é è ê î ô ù û"
|
||||
- "À Â Ç É È Ê Î Ô Ù Û"
|
||||
- "show_numbers_from_symbols æ œ ä ë ï ö ü BackSpace"
|
||||
- "show_letters preferences space show_eschars Return"
|
||||
|
||||
buttons:
|
||||
Shift_L:
|
||||
action:
|
||||
locking:
|
||||
lock_view: "upper"
|
||||
unlock_view: "base"
|
||||
outline: "altline"
|
||||
icon: "key-shift"
|
||||
BackSpace:
|
||||
outline: "altline"
|
||||
icon: "edit-clear-symbolic"
|
||||
action: erase
|
||||
preferences:
|
||||
action: "show_prefs"
|
||||
outline: "special"
|
||||
icon: "keyboard-mode-symbolic"
|
||||
show_numbers:
|
||||
action:
|
||||
set_view: "numbers"
|
||||
outline: "wide"
|
||||
label: "123"
|
||||
show_numbers_from_symbols:
|
||||
action:
|
||||
set_view: "numbers"
|
||||
outline: "altline"
|
||||
label: "123"
|
||||
show_letters:
|
||||
action:
|
||||
set_view: "base"
|
||||
outline: "wide"
|
||||
label: "abc"
|
||||
show_symbols:
|
||||
action:
|
||||
set_view: "symbols"
|
||||
outline: "altline"
|
||||
label: "*/="
|
||||
show_eschars:
|
||||
action:
|
||||
locking:
|
||||
lock_view: "eschars"
|
||||
unlock_view: "base"
|
||||
outline: "altline"
|
||||
label: "âÂ"
|
||||
space:
|
||||
outline: "spaceline"
|
||||
text: " "
|
||||
Return:
|
||||
outline: "wide"
|
||||
icon: "key-enter"
|
||||
keysym: "Return"
|
||||
colon:
|
||||
text: ":"
|
||||
"\"":
|
||||
keysym: "quotedbl"
|
||||
@ -1,78 +0,0 @@
|
||||
---
|
||||
outlines:
|
||||
default: { width: 35.33, height: 52 }
|
||||
altline: { width: 52.67, height: 52 }
|
||||
wide: { width: 62, height: 52 }
|
||||
spaceline: { width: 142, height: 52 }
|
||||
special: { width: 44, height: 52 }
|
||||
|
||||
views:
|
||||
base:
|
||||
- "ქ წ ე რ ტ ყ უ ი ო პ"
|
||||
- "ა ს დ ფ გ ჰ ჯ კ ლ"
|
||||
- "Shift_L ზ ხ ც ვ ბ ნ მ BackSpace"
|
||||
- "show_numbers preferences space period Return"
|
||||
upper:
|
||||
- "ქ ჭ ე ღ თ ყ უ ი ო პ"
|
||||
- "ა შ დ ფ გ ჰ ჟ კ ლ"
|
||||
- "Shift_L ძ ხ ჩ ვ ბ ნ მ BackSpace"
|
||||
- "show_numbers preferences space period Return"
|
||||
numbers:
|
||||
- "1 2 3 4 5 6 7 8 9 0"
|
||||
- "! @ # $ % ^ & * ( )"
|
||||
- "show_symbols - ' \" colon ; , ? BackSpace"
|
||||
- "show_letters preferences space period Return"
|
||||
symbols:
|
||||
- "+ ⨯ ÷ = / _ € £ ¥ ₾"
|
||||
- "~ ` | · √ π τ ° { }"
|
||||
- "show_numbers_from_symbols \\ / < > = [ ] BackSpace"
|
||||
- "show_letters preferences space period Return"
|
||||
|
||||
buttons:
|
||||
Shift_L:
|
||||
action:
|
||||
locking:
|
||||
lock_view: "upper"
|
||||
unlock_view: "base"
|
||||
outline: "altline"
|
||||
icon: "key-shift"
|
||||
BackSpace:
|
||||
outline: "altline"
|
||||
icon: "edit-clear-symbolic"
|
||||
action: "erase"
|
||||
preferences:
|
||||
action: "show_prefs"
|
||||
outline: "special"
|
||||
icon: "keyboard-mode-symbolic"
|
||||
show_numbers:
|
||||
action:
|
||||
set_view: "numbers"
|
||||
outline: "wide"
|
||||
label: "123"
|
||||
show_numbers_from_symbols:
|
||||
action:
|
||||
set_view: "numbers"
|
||||
outline: "altline"
|
||||
label: "123"
|
||||
show_letters:
|
||||
action:
|
||||
set_view: "base"
|
||||
outline: "wide"
|
||||
label: "ABC"
|
||||
show_symbols:
|
||||
action:
|
||||
set_view: "symbols"
|
||||
outline: "altline"
|
||||
label: "*/="
|
||||
period:
|
||||
outline: "special"
|
||||
text: "."
|
||||
space:
|
||||
outline: "spaceline"
|
||||
text: " "
|
||||
Return:
|
||||
outline: "wide"
|
||||
icon: "key-enter"
|
||||
keysym: "Return"
|
||||
colon:
|
||||
text: ":"
|
||||
@ -1,326 +0,0 @@
|
||||
# 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,41 +1,40 @@
|
||||
# Greek layout originally created by Antonis Tsolomitis
|
||||
# Greek layout created by Antonis Tsolomitis
|
||||
# University of the Aegean, Department of Mathematics, atsol@aegean.gr
|
||||
# Sep 2019
|
||||
# Edited by Sotiris Papadopoulos, sotirios.papadopoulos@inserm.fr
|
||||
---
|
||||
outlines:
|
||||
default: { width: 40, height: 60 }
|
||||
altline: { width: 52.67, height: 60 }
|
||||
wide: { width: 62, height: 60 }
|
||||
spaceline: { width: 140, height: 60 }
|
||||
special: { width: 44, height: 60 }
|
||||
default: { width: 32, height: 52 }
|
||||
altline: { width: 48.39024, height: 52 }
|
||||
wide: { width: 62, height: 52 }
|
||||
outline7: { width: 88.97561, height: 52 }
|
||||
spaceline: { width: 150.5853, height: 52 }
|
||||
|
||||
views:
|
||||
base:
|
||||
- "semicolon ς ε ρ τ υ θ ι ο π"
|
||||
- "; ς ε ρ τ υ θ ι ο π !"
|
||||
- "α σ δ φ γ η ξ κ λ show_accented"
|
||||
- "Shift_L ζ χ ψ ω β ν μ BackSpace"
|
||||
- "show_numbers preferences space period comma Return"
|
||||
- "Shift_L ζ χ ψ ω β ν μ , BackSpace"
|
||||
- "show_numbers preferences space period Return"
|
||||
upper:
|
||||
- "colon exclam Ε Ρ Τ Υ Θ Ι Ο Π"
|
||||
- ": EuroSign Ε Ρ Τ Υ Θ Ι Ο Π"
|
||||
- "Α Σ Δ Φ Γ Η Ξ Κ Λ show_accented"
|
||||
- "Shift_L Ζ Χ Ψ Ω Β Ν Μ BackSpace"
|
||||
- "show_numbers preferences space period_upper apostrophe Return"
|
||||
- "Shift_L Ζ Χ Ψ Ω Β Ν Μ · BackSpace"
|
||||
- "show_numbers preferences space « » Return"
|
||||
accented:
|
||||
- "ά έ ή ί ϊ ΐ ό ύ ϋ ώ "
|
||||
- "Ά Έ Ή Ί Ϊ Ό Ύ Ϋ Ώ show_base"
|
||||
- "Ϗ ϐ ϑ ϗ ϖ ΰ ϕ – — BackSpace"
|
||||
- "show_numbers preferences space eis_l eis_r Return"
|
||||
- "ά έ ή ί ό ύ ώ ϊ ϋ ΐ"
|
||||
- "ΰ Ά Έ Ή Ί Ό Ύ Ώ Ϊ show_base"
|
||||
- "Ϋ Ϗ ϐ ϑ ϕ ϖ ϗ – — BackSpace"
|
||||
- "show_numbers preferences space quoteleft quoteright 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"
|
||||
- "show_letters preferences space period 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"
|
||||
- "show_letters preferences space period Return"
|
||||
buttons:
|
||||
Shift_L:
|
||||
action:
|
||||
@ -55,12 +54,12 @@ buttons:
|
||||
show_numbers:
|
||||
action:
|
||||
set_view: "numbers"
|
||||
outline: "wide"
|
||||
outline: "altline"
|
||||
label: "123"
|
||||
show_letters:
|
||||
action:
|
||||
set_view: "base"
|
||||
outline: "wide"
|
||||
outline: "altline"
|
||||
label: "ΑΒΓ"
|
||||
show_symbols:
|
||||
action:
|
||||
@ -79,40 +78,16 @@ buttons:
|
||||
set_view: "base"
|
||||
outline: "altline"
|
||||
label: "αι"
|
||||
period:
|
||||
outline: "altline"
|
||||
text: "."
|
||||
space:
|
||||
outline: "spaceline"
|
||||
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:
|
||||
@ -187,6 +162,8 @@ buttons:
|
||||
text: "{"
|
||||
braceright:
|
||||
text: "}"
|
||||
comma:
|
||||
text: ","
|
||||
backslash:
|
||||
text: "\\"
|
||||
slash:
|
||||
@ -199,6 +176,12 @@ buttons:
|
||||
text: "<"
|
||||
greater:
|
||||
text: ">"
|
||||
colon:
|
||||
text: ":"
|
||||
semicolon:
|
||||
text: ";"
|
||||
exclam:
|
||||
text: "!"
|
||||
question:
|
||||
text: "?"
|
||||
bracketleft:
|
||||
|
||||
@ -1,204 +0,0 @@
|
||||
# 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: "]"
|
||||
@ -30,10 +30,10 @@ views:
|
||||
- "show_numbers \\ / < > = [ ] BackSpace"
|
||||
- "show_letters show_eschars preferences space ? . Return"
|
||||
eschars:
|
||||
- "è é È É ù ú Ù Ú ò ó"
|
||||
- "à á À Á ì í Ì Í Ò Ó"
|
||||
- "show_numbers “ ” « » ≈ ≠ ‽ BackSpace"
|
||||
- "show_letters show_eschars preferences space , . Return"
|
||||
- "á é í ó ú Á É Í Ó Ú"
|
||||
- "à è ì ò « » ù ! { }"
|
||||
- "show_numbers \\ / < > = [ ] BackSpace"
|
||||
- "show_letters show_eschars preferences space « » Return"
|
||||
|
||||
buttons:
|
||||
Shift_L:
|
||||
|
||||
@ -1,223 +0,0 @@
|
||||
---
|
||||
outlines:
|
||||
action: { width: 59, height: 46 }
|
||||
small: { width: 50, height: 22 }
|
||||
default: { width: 35.33, height: 46 }
|
||||
altline: { width: 35.33, height: 46 }
|
||||
wide: { width: 50, height: 46 }
|
||||
spaceline: { width: 110, height: 46 }
|
||||
special: { width: 35.33, height: 46 }
|
||||
|
||||
views:
|
||||
base:
|
||||
- "Ctrl Alt Tabsmall ↑ ↓ ← →"
|
||||
- "b é p o w v d l j z"
|
||||
- "a u i e c t s r n m"
|
||||
- "Shift_L y x k q g h f period BackSpace"
|
||||
- "show_numbers preferences slash space show_eschars show_actions Return"
|
||||
upper:
|
||||
- "Ctrl Alt Tabsmall PgUp PgDn Home End"
|
||||
- "B É P O W V D L J Z"
|
||||
- "A U I E C T S R N M"
|
||||
- "Shift_L Y X K Q G H F - BackSpace"
|
||||
- "show_numbers preferences space colon show_eschars show_actions Return"
|
||||
numbers:
|
||||
- "Ctrl Alt Tabsmall ↑ ↓ ← →"
|
||||
- "1 2 3 4 5 6 7 8 9 0"
|
||||
- "@ # € % & - _ + ( )"
|
||||
- "show_symbols , \" ' colon ; ! ? BackSpace"
|
||||
- "show_letters preferences space show_eschars show_actions Return"
|
||||
symbols:
|
||||
- "Ctrl Alt Tabsmall ↑ ↓ ← →"
|
||||
- "~ ` | · √ π τ ÷ × ¶"
|
||||
- "© ® £ $ ¥ ^ ° * { }"
|
||||
- "show_numbers_from_symbols \\ / < > = [ ] BackSpace"
|
||||
- "show_letters preferences space show_eschars show_actions Return"
|
||||
eschars:
|
||||
- "Ctrl Alt Tabsmall ↑ ↓ ← →"
|
||||
- "à â ç é è ê î ô ù û"
|
||||
- "À Â Ç É È Ê Î Ô Ù Û"
|
||||
- "show_numbers_from_symbols æ œ ä ë ï ö ü BackSpace"
|
||||
- "show_letters preferences space show_eschars show_actions Return"
|
||||
actions:
|
||||
- "Ctrl Alt PgUp PgDn Home End"
|
||||
- "F1 F2 F3 F4 F5 F6"
|
||||
- "F7 F8 F9 F10 F11 F12"
|
||||
- "Esc Tab Pause Insert Up Del"
|
||||
- "show_letters Menu Break Left Down Right"
|
||||
|
||||
|
||||
buttons:
|
||||
F1:
|
||||
outline: "action"
|
||||
keysym: "F1"
|
||||
F2:
|
||||
outline: "action"
|
||||
keysym: "F2"
|
||||
F3:
|
||||
outline: "action"
|
||||
keysym: "F3"
|
||||
F4:
|
||||
outline: "action"
|
||||
keysym: "F4"
|
||||
F5:
|
||||
outline: "action"
|
||||
keysym: "F5"
|
||||
F6:
|
||||
outline: "action"
|
||||
keysym: "F6"
|
||||
F7:
|
||||
outline: "action"
|
||||
keysym: "F7"
|
||||
F8:
|
||||
outline: "action"
|
||||
keysym: "F8"
|
||||
F9:
|
||||
outline: "action"
|
||||
keysym: "F9"
|
||||
F10:
|
||||
outline: "action"
|
||||
keysym: "F10"
|
||||
F11:
|
||||
outline: "action"
|
||||
keysym: "F11"
|
||||
F12:
|
||||
outline: "action"
|
||||
keysym: "F12"
|
||||
Esc:
|
||||
outline: "action"
|
||||
keysym: "Escape"
|
||||
Tab:
|
||||
outline: "action"
|
||||
keysym: "Tab"
|
||||
Tabsmall:
|
||||
outline: "small"
|
||||
keysym: "Tab"
|
||||
label: "Tab"
|
||||
Del:
|
||||
outline: "action"
|
||||
keysym: "Delete"
|
||||
Insert:
|
||||
outline: "action"
|
||||
keysym: "Insert"
|
||||
Menu:
|
||||
outline: "action"
|
||||
keysym: "Menu"
|
||||
Pause:
|
||||
outline: "action"
|
||||
keysym: "Pause"
|
||||
Break:
|
||||
outline: "action"
|
||||
keysym: "Break"
|
||||
Home:
|
||||
outline: "small"
|
||||
keysym: "Home"
|
||||
End:
|
||||
outline: "small"
|
||||
keysym: "End"
|
||||
PgUp:
|
||||
outline: "small"
|
||||
keysym: "Page_Up"
|
||||
PgDn:
|
||||
outline: "small"
|
||||
keysym: "Page_Down"
|
||||
"↑":
|
||||
outline: "small"
|
||||
keysym: "Up"
|
||||
"↓":
|
||||
outline: "small"
|
||||
keysym: "Down"
|
||||
"←":
|
||||
outline: "small"
|
||||
keysym: "Left"
|
||||
"→":
|
||||
outline: "small"
|
||||
keysym: "Right"
|
||||
Up:
|
||||
label: "↑"
|
||||
outline: "action"
|
||||
keysym: "Up"
|
||||
Left:
|
||||
label: "←"
|
||||
outline: "action"
|
||||
keysym: "Left"
|
||||
Down:
|
||||
label: "↓"
|
||||
outline: "action"
|
||||
keysym: "Down"
|
||||
Right:
|
||||
label: "→"
|
||||
outline: "action"
|
||||
keysym: "Right"
|
||||
Ctrl:
|
||||
modifier: "Control"
|
||||
outline: "small"
|
||||
label: "Ctrl"
|
||||
Alt:
|
||||
modifier: "Alt"
|
||||
outline: "small"
|
||||
label: "Alt"
|
||||
period:
|
||||
outline: "special"
|
||||
text: "."
|
||||
slash:
|
||||
outline: "special"
|
||||
text: "/"
|
||||
show_actions:
|
||||
action:
|
||||
set_view: "actions"
|
||||
outline: "special"
|
||||
label: ">_"
|
||||
Shift_L:
|
||||
action:
|
||||
locking:
|
||||
lock_view: "upper"
|
||||
unlock_view: "base"
|
||||
outline: "altline"
|
||||
icon: "key-shift"
|
||||
BackSpace:
|
||||
outline: "altline"
|
||||
icon: "edit-clear-symbolic"
|
||||
action: erase
|
||||
preferences:
|
||||
action: "show_prefs"
|
||||
outline: "special"
|
||||
icon: "keyboard-mode-symbolic"
|
||||
show_numbers:
|
||||
action:
|
||||
set_view: "numbers"
|
||||
outline: "wide"
|
||||
label: "123"
|
||||
show_numbers_from_symbols:
|
||||
action:
|
||||
set_view: "numbers"
|
||||
outline: "wide"
|
||||
label: "123"
|
||||
show_letters:
|
||||
action:
|
||||
set_view: "base"
|
||||
outline: "wide"
|
||||
label: "abc"
|
||||
show_symbols:
|
||||
action:
|
||||
set_view: "symbols"
|
||||
outline: "wide"
|
||||
label: "*/="
|
||||
show_eschars:
|
||||
action:
|
||||
locking:
|
||||
lock_view: "eschars"
|
||||
unlock_view: "base"
|
||||
outline: "altline"
|
||||
label: "âÂ"
|
||||
space:
|
||||
outline: "spaceline"
|
||||
text: " "
|
||||
Return:
|
||||
outline: "wide"
|
||||
icon: "key-enter"
|
||||
keysym: "Return"
|
||||
colon:
|
||||
text: ":"
|
||||
"\"":
|
||||
keysym: "quotedbl"
|
||||
@ -1,227 +0,0 @@
|
||||
---
|
||||
outlines:
|
||||
action: { width: 90, height: 37 }
|
||||
small: { width: 67.4, height: 22 }
|
||||
default: { width: 54, height: 37 }
|
||||
altline: { width: 81, height: 37 }
|
||||
wide: { width: 100, height: 37 }
|
||||
spaceline: { width: 110, height: 37 }
|
||||
special: { width: 54, height: 37 }
|
||||
|
||||
views:
|
||||
base:
|
||||
- "EscSmall TabSmall Ctrl Alt ↑ ↓ ← →"
|
||||
- "b é p o w v d l j z"
|
||||
- "a u i e c t s r n m"
|
||||
- "Shift_L y x k q g h f period BackSpace"
|
||||
- "show_numbers preferences space slash show_eschars show_actions Return"
|
||||
upper:
|
||||
- "EscSmall TabSmall Ctrl Alt ↑ ↓ ← →"
|
||||
- "B É P O W V D L J Z"
|
||||
- "A U I E C T S R N M"
|
||||
- "Shift_L Y X K Q G H F - BackSpace"
|
||||
- "show_numbers preferences space colon show_eschars show_actions Return"
|
||||
numbers:
|
||||
- "EscSmall TabSmall Ctrl Alt ↑ ↓ ← →"
|
||||
- "1 2 3 4 5 6 7 8 9 0"
|
||||
- "@ # € % & - _ + ( )"
|
||||
- "show_symbols , \" ' colon ; ! ? BackSpace"
|
||||
- "show_letters preferences space show_eschars show_actions Return"
|
||||
symbols:
|
||||
- "EscSmall TabSmall Ctrl Alt ↑ ↓ ← →"
|
||||
- "~ ` | · √ π τ ÷ × ¶"
|
||||
- "© ® £ $ ¥ ^ ° * { }"
|
||||
- "show_numbers_from_symbols \\ / < > = [ ] BackSpace"
|
||||
- "show_letters preferences space show_eschars show_actions Return"
|
||||
eschars:
|
||||
- "EscSmall TabSmall Ctrl Alt ↑ ↓ ← →"
|
||||
- "à â ç é è ê î ô ù û"
|
||||
- "À Â Ç É È Ê Î Ô Ù Û"
|
||||
- "show_numbers_from_symbols æ œ ä ë ï ö ü BackSpace"
|
||||
- "show_letters preferences space show_eschars show_actions Return"
|
||||
actions:
|
||||
- "EscSmall TabSmall Ctrl Alt PgUp PgDn Home End"
|
||||
- "F1 F2 F3 F4 F5 F6"
|
||||
- "F7 F8 F9 F10 F11 F12"
|
||||
- "Esc Tab Pause Insert Up Del"
|
||||
- "show_letters Menu Break Left Down Right"
|
||||
|
||||
|
||||
buttons:
|
||||
F1:
|
||||
outline: "action"
|
||||
keysym: "F1"
|
||||
F2:
|
||||
outline: "action"
|
||||
keysym: "F2"
|
||||
F3:
|
||||
outline: "action"
|
||||
keysym: "F3"
|
||||
F4:
|
||||
outline: "action"
|
||||
keysym: "F4"
|
||||
F5:
|
||||
outline: "action"
|
||||
keysym: "F5"
|
||||
F6:
|
||||
outline: "action"
|
||||
keysym: "F6"
|
||||
F7:
|
||||
outline: "action"
|
||||
keysym: "F7"
|
||||
F8:
|
||||
outline: "action"
|
||||
keysym: "F8"
|
||||
F9:
|
||||
outline: "action"
|
||||
keysym: "F9"
|
||||
F10:
|
||||
outline: "action"
|
||||
keysym: "F10"
|
||||
F11:
|
||||
outline: "action"
|
||||
keysym: "F11"
|
||||
F12:
|
||||
outline: "action"
|
||||
keysym: "F12"
|
||||
Esc:
|
||||
outline: "action"
|
||||
keysym: "Escape"
|
||||
EscSmall:
|
||||
outline: "small"
|
||||
keysym: "Escape"
|
||||
label: "Esc"
|
||||
Tab:
|
||||
outline: "action"
|
||||
keysym: "Tab"
|
||||
TabSmall:
|
||||
outline: "small"
|
||||
keysym: "Tab"
|
||||
label: "Tab"
|
||||
Del:
|
||||
outline: "action"
|
||||
keysym: "Delete"
|
||||
Insert:
|
||||
outline: "action"
|
||||
keysym: "Insert"
|
||||
Menu:
|
||||
outline: "action"
|
||||
keysym: "Menu"
|
||||
Pause:
|
||||
outline: "action"
|
||||
keysym: "Pause"
|
||||
Break:
|
||||
outline: "action"
|
||||
keysym: "Break"
|
||||
Home:
|
||||
outline: "small"
|
||||
keysym: "Home"
|
||||
End:
|
||||
outline: "small"
|
||||
keysym: "End"
|
||||
PgUp:
|
||||
outline: "small"
|
||||
keysym: "Page_Up"
|
||||
PgDn:
|
||||
outline: "small"
|
||||
keysym: "Page_Down"
|
||||
"↑":
|
||||
outline: "small"
|
||||
keysym: "Up"
|
||||
"↓":
|
||||
outline: "small"
|
||||
keysym: "Down"
|
||||
"←":
|
||||
outline: "small"
|
||||
keysym: "Left"
|
||||
"→":
|
||||
outline: "small"
|
||||
keysym: "Right"
|
||||
Up:
|
||||
label: "↑"
|
||||
outline: "action"
|
||||
keysym: "Up"
|
||||
Left:
|
||||
label: "←"
|
||||
outline: "action"
|
||||
keysym: "Left"
|
||||
Down:
|
||||
label: "↓"
|
||||
outline: "action"
|
||||
keysym: "Down"
|
||||
Right:
|
||||
label: "→"
|
||||
outline: "action"
|
||||
keysym: "Right"
|
||||
Ctrl:
|
||||
modifier: "Control"
|
||||
outline: "small"
|
||||
label: "Ctrl"
|
||||
Alt:
|
||||
modifier: "Alt"
|
||||
outline: "small"
|
||||
label: "Alt"
|
||||
period:
|
||||
outline: "special"
|
||||
text: "."
|
||||
slash:
|
||||
outline: "special"
|
||||
text: "/"
|
||||
show_actions:
|
||||
action:
|
||||
set_view: "actions"
|
||||
outline: "special"
|
||||
label: ">_"
|
||||
Shift_L:
|
||||
action:
|
||||
locking:
|
||||
lock_view: "upper"
|
||||
unlock_view: "base"
|
||||
outline: "altline"
|
||||
icon: "key-shift"
|
||||
BackSpace:
|
||||
outline: "altline"
|
||||
icon: "edit-clear-symbolic"
|
||||
action: erase
|
||||
preferences:
|
||||
action: "show_prefs"
|
||||
outline: "special"
|
||||
icon: "keyboard-mode-symbolic"
|
||||
show_numbers:
|
||||
action:
|
||||
set_view: "numbers"
|
||||
outline: "wide"
|
||||
label: "123"
|
||||
show_numbers_from_symbols:
|
||||
action:
|
||||
set_view: "numbers"
|
||||
outline: "altline"
|
||||
label: "123"
|
||||
show_letters:
|
||||
action:
|
||||
set_view: "base"
|
||||
outline: "wide"
|
||||
label: "abc"
|
||||
show_symbols:
|
||||
action:
|
||||
set_view: "symbols"
|
||||
outline: "altline"
|
||||
label: "*/="
|
||||
show_eschars:
|
||||
action:
|
||||
locking:
|
||||
lock_view: "eschars"
|
||||
unlock_view: "base"
|
||||
outline: "altline"
|
||||
label: "âÂ"
|
||||
space:
|
||||
outline: "spaceline"
|
||||
text: " "
|
||||
Return:
|
||||
outline: "wide"
|
||||
icon: "key-enter"
|
||||
keysym: "Return"
|
||||
colon:
|
||||
text: ":"
|
||||
"\"":
|
||||
keysym: "quotedbl"
|
||||
@ -1,200 +0,0 @@
|
||||
---
|
||||
outlines:
|
||||
default: { width: 35.33, height: 46 }
|
||||
action: { width: 59, height: 46 }
|
||||
altline: { width: 52.67, height: 46 }
|
||||
wide: { width: 59, height: 46 }
|
||||
spaceline: { width: 140, height: 46 }
|
||||
special: { width: 44, height: 46 }
|
||||
small: { width: 59, height: 22 }
|
||||
|
||||
views:
|
||||
base:
|
||||
- "Ctrl Alt ↑ ↓ ← →"
|
||||
- "Shift_L p y f g c r l BackSpace"
|
||||
- "a o e u i d h t n s"
|
||||
- ", q j k x b m w v z"
|
||||
- "show_numbers preferences space show_actions Return"
|
||||
upper:
|
||||
- "Ctrl Alt PgUp PgDn Home End"
|
||||
- "Shift_L p y f g c r l BackSpace"
|
||||
- "a o e u i d h t n s"
|
||||
- ", q j k x b m w v z"
|
||||
- "show_numbers preferences space show_actions Return"
|
||||
numbers:
|
||||
- "Ctrl Alt ↑ ↓ ← →"
|
||||
- "show_symbols , \" ' colon ; ! ? BackSpace"
|
||||
- "* # $ / & - _ + ( )"
|
||||
- "1 2 3 4 5 6 7 8 9 0"
|
||||
- "show_letters preferences space period Return"
|
||||
symbols:
|
||||
- "Ctrl Alt ↑ ↓ ← →"
|
||||
- "show_numbers_from_symbols \\ % < > = [ ] BackSpace"
|
||||
- "© ® £ € ¥ ^ ° @ { }"
|
||||
- "~ ` | · √ π τ ÷ × ¶"
|
||||
- "show_letters preferences space period Return"
|
||||
actions:
|
||||
- "Ctrl Alt PgUp PgDn Home End"
|
||||
- "F1 F2 F3 F4 F5 F6"
|
||||
- "F7 F8 F9 F10 F11 F12"
|
||||
- "Esc Tab Pause Insert Up Del"
|
||||
- "show_letters Menu Break Left Down Right"
|
||||
|
||||
buttons:
|
||||
Shift_L:
|
||||
action:
|
||||
locking:
|
||||
lock_view: "upper"
|
||||
unlock_view: "base"
|
||||
outline: "altline"
|
||||
icon: "key-shift"
|
||||
BackSpace:
|
||||
outline: "altline"
|
||||
icon: "edit-clear-symbolic"
|
||||
action: erase
|
||||
preferences:
|
||||
action: "show_prefs"
|
||||
outline: "special"
|
||||
icon: "keyboard-mode-symbolic"
|
||||
show_numbers:
|
||||
action:
|
||||
set_view: "numbers"
|
||||
outline: "wide"
|
||||
label: "123"
|
||||
show_numbers_from_symbols:
|
||||
action:
|
||||
set_view: "numbers"
|
||||
outline: "altline"
|
||||
label: "123"
|
||||
show_letters:
|
||||
action:
|
||||
set_view: "base"
|
||||
outline: "wide"
|
||||
label: "ABC"
|
||||
show_symbols:
|
||||
action:
|
||||
set_view: "symbols"
|
||||
outline: "altline"
|
||||
label: "τ=\\"
|
||||
show_actions:
|
||||
action:
|
||||
set_view: "actions"
|
||||
outline: "altline"
|
||||
label: ">_"
|
||||
period:
|
||||
outline: "altline"
|
||||
text: "."
|
||||
space:
|
||||
outline: "spaceline"
|
||||
text: " "
|
||||
Return:
|
||||
outline: "wide"
|
||||
icon: "key-enter"
|
||||
keysym: "Return"
|
||||
colon:
|
||||
text: ":"
|
||||
F1:
|
||||
outline: "action"
|
||||
keysym: "F1"
|
||||
F2:
|
||||
outline: "action"
|
||||
keysym: "F2"
|
||||
F3:
|
||||
outline: "action"
|
||||
keysym: "F3"
|
||||
F4:
|
||||
outline: "action"
|
||||
keysym: "F4"
|
||||
F5:
|
||||
outline: "action"
|
||||
keysym: "F5"
|
||||
F6:
|
||||
outline: "action"
|
||||
keysym: "F6"
|
||||
F7:
|
||||
outline: "action"
|
||||
keysym: "F7"
|
||||
F8:
|
||||
outline: "action"
|
||||
keysym: "F8"
|
||||
F9:
|
||||
outline: "action"
|
||||
keysym: "F9"
|
||||
F10:
|
||||
outline: "action"
|
||||
keysym: "F10"
|
||||
F11:
|
||||
outline: "action"
|
||||
keysym: "F11"
|
||||
F12:
|
||||
outline: "action"
|
||||
keysym: "F12"
|
||||
Esc:
|
||||
outline: "action"
|
||||
keysym: "Escape"
|
||||
Tab:
|
||||
outline: "action"
|
||||
keysym: "Tab"
|
||||
Del:
|
||||
outline: "action"
|
||||
keysym: "Delete"
|
||||
Insert:
|
||||
outline: "action"
|
||||
keysym: "Insert"
|
||||
Menu:
|
||||
outline: "action"
|
||||
keysym: "Menu"
|
||||
Pause:
|
||||
outline: "action"
|
||||
keysym: "Pause"
|
||||
Break:
|
||||
outline: "action"
|
||||
keysym: "Break"
|
||||
Home:
|
||||
outline: "small"
|
||||
keysym: "Home"
|
||||
End:
|
||||
outline: "small"
|
||||
keysym: "End"
|
||||
PgUp:
|
||||
outline: "small"
|
||||
keysym: "Page_Up"
|
||||
PgDn:
|
||||
outline: "small"
|
||||
keysym: "Page_Down"
|
||||
"↑":
|
||||
outline: "small"
|
||||
keysym: "Up"
|
||||
"↓":
|
||||
outline: "small"
|
||||
keysym: "Down"
|
||||
"←":
|
||||
outline: "small"
|
||||
keysym: "Left"
|
||||
"→":
|
||||
outline: "small"
|
||||
keysym: "Right"
|
||||
Up:
|
||||
label: "↑"
|
||||
outline: "action"
|
||||
keysym: "Up"
|
||||
Left:
|
||||
label: "←"
|
||||
outline: "action"
|
||||
keysym: "Left"
|
||||
Down:
|
||||
label: "↓"
|
||||
outline: "action"
|
||||
keysym: "Down"
|
||||
Right:
|
||||
label: "→"
|
||||
outline: "action"
|
||||
keysym: "Right"
|
||||
Ctrl:
|
||||
modifier: "Control"
|
||||
outline: "small"
|
||||
label: "Ctrl"
|
||||
Alt:
|
||||
modifier: "Alt"
|
||||
outline: "small"
|
||||
label: "Alt"
|
||||
@ -1,208 +0,0 @@
|
||||
---
|
||||
outlines:
|
||||
default: { width: 54, height: 37 }
|
||||
action: { width: 90, height: 37 }
|
||||
altline: { width: 81, height: 37 }
|
||||
wide: { width: 90, height: 37 }
|
||||
spaceline: { width: 225, height: 37 }
|
||||
special: { width: 54, height: 37 }
|
||||
small: { width: 67.4, height: 22 }
|
||||
|
||||
views:
|
||||
base:
|
||||
- "EscSmall TabSmall Ctrl Alt ↑ ↓ ← →"
|
||||
- "Shift_L p y f g c r l BackSpace"
|
||||
- "a o e u i d h t n s"
|
||||
- ", q j k x b m w v z"
|
||||
- "show_numbers preferences space show_actions Return"
|
||||
upper:
|
||||
- "EscSmall TabSmall Ctrl Alt PgUp PgDn Home End"
|
||||
- "Shift_L p y f g c r l BackSpace"
|
||||
- "a o e u i d h t n s"
|
||||
- ", q j k x b m w v z"
|
||||
- "show_numbers preferences space show_actions Return"
|
||||
numbers:
|
||||
- "EscSmall TabSmall Ctrl Alt ↑ ↓ ← →"
|
||||
- "show_symbols , \" ' colon ; ! ? BackSpace"
|
||||
- "* # $ / & - _ + ( )"
|
||||
- "1 2 3 4 5 6 7 8 9 0"
|
||||
- "show_letters preferences space period Return"
|
||||
symbols:
|
||||
- "EscSmall TabSmall Ctrl Alt ↑ ↓ ← →"
|
||||
- "show_numbers_from_symbols \\ % < > = [ ] BackSpace"
|
||||
- "© ® £ € ¥ ^ ° @ { }"
|
||||
- "~ ` | · √ π τ ÷ × ¶"
|
||||
- "show_letters preferences space period Return"
|
||||
actions:
|
||||
- "EscSmall TabSmall Ctrl Alt PgUp PgDn Home End"
|
||||
- "F1 F2 F3 F4 F5 F6"
|
||||
- "F7 F8 F9 F10 F11 F12"
|
||||
- "Esc Tab Pause Insert Up Del"
|
||||
- "show_letters Menu Break Left Down Right"
|
||||
|
||||
buttons:
|
||||
Shift_L:
|
||||
action:
|
||||
locking:
|
||||
lock_view: "upper"
|
||||
unlock_view: "base"
|
||||
outline: "altline"
|
||||
icon: "key-shift"
|
||||
BackSpace:
|
||||
outline: "altline"
|
||||
icon: "edit-clear-symbolic"
|
||||
action: erase
|
||||
preferences:
|
||||
action: "show_prefs"
|
||||
outline: "special"
|
||||
icon: "keyboard-mode-symbolic"
|
||||
show_numbers:
|
||||
action:
|
||||
set_view: "numbers"
|
||||
outline: "wide"
|
||||
label: "123"
|
||||
show_numbers_from_symbols:
|
||||
action:
|
||||
set_view: "numbers"
|
||||
outline: "altline"
|
||||
label: "123"
|
||||
show_letters:
|
||||
action:
|
||||
set_view: "base"
|
||||
outline: "wide"
|
||||
label: "ABC"
|
||||
show_symbols:
|
||||
action:
|
||||
set_view: "symbols"
|
||||
outline: "altline"
|
||||
label: "τ=\\"
|
||||
show_actions:
|
||||
action:
|
||||
set_view: "actions"
|
||||
outline: "altline"
|
||||
label: ">_"
|
||||
period:
|
||||
outline: "altline"
|
||||
text: "."
|
||||
space:
|
||||
outline: "spaceline"
|
||||
text: " "
|
||||
Return:
|
||||
outline: "wide"
|
||||
icon: "key-enter"
|
||||
keysym: "Return"
|
||||
colon:
|
||||
text: ":"
|
||||
F1:
|
||||
outline: "action"
|
||||
keysym: "F1"
|
||||
F2:
|
||||
outline: "action"
|
||||
keysym: "F2"
|
||||
F3:
|
||||
outline: "action"
|
||||
keysym: "F3"
|
||||
F4:
|
||||
outline: "action"
|
||||
keysym: "F4"
|
||||
F5:
|
||||
outline: "action"
|
||||
keysym: "F5"
|
||||
F6:
|
||||
outline: "action"
|
||||
keysym: "F6"
|
||||
F7:
|
||||
outline: "action"
|
||||
keysym: "F7"
|
||||
F8:
|
||||
outline: "action"
|
||||
keysym: "F8"
|
||||
F9:
|
||||
outline: "action"
|
||||
keysym: "F9"
|
||||
F10:
|
||||
outline: "action"
|
||||
keysym: "F10"
|
||||
F11:
|
||||
outline: "action"
|
||||
keysym: "F11"
|
||||
F12:
|
||||
outline: "action"
|
||||
keysym: "F12"
|
||||
Esc:
|
||||
outline: "action"
|
||||
keysym: "Escape"
|
||||
EscSmall:
|
||||
outline: "small"
|
||||
keysym: "Escape"
|
||||
label: "Esc"
|
||||
Tab:
|
||||
outline: "action"
|
||||
keysym: "Tab"
|
||||
TabSmall:
|
||||
outline: "small"
|
||||
keysym: "Tab"
|
||||
label: "Tab"
|
||||
Del:
|
||||
outline: "action"
|
||||
keysym: "Delete"
|
||||
Insert:
|
||||
outline: "action"
|
||||
keysym: "Insert"
|
||||
Menu:
|
||||
outline: "action"
|
||||
keysym: "Menu"
|
||||
Pause:
|
||||
outline: "action"
|
||||
keysym: "Pause"
|
||||
Break:
|
||||
outline: "action"
|
||||
keysym: "Break"
|
||||
Home:
|
||||
outline: "small"
|
||||
keysym: "Home"
|
||||
End:
|
||||
outline: "small"
|
||||
keysym: "End"
|
||||
PgUp:
|
||||
outline: "small"
|
||||
keysym: "Page_Up"
|
||||
PgDn:
|
||||
outline: "small"
|
||||
keysym: "Page_Down"
|
||||
"↑":
|
||||
outline: "small"
|
||||
keysym: "Up"
|
||||
"↓":
|
||||
outline: "small"
|
||||
keysym: "Down"
|
||||
"←":
|
||||
outline: "small"
|
||||
keysym: "Left"
|
||||
"→":
|
||||
outline: "small"
|
||||
keysym: "Right"
|
||||
Up:
|
||||
label: "↑"
|
||||
outline: "action"
|
||||
keysym: "Up"
|
||||
Left:
|
||||
label: "←"
|
||||
outline: "action"
|
||||
keysym: "Left"
|
||||
Down:
|
||||
label: "↓"
|
||||
outline: "action"
|
||||
keysym: "Down"
|
||||
Right:
|
||||
label: "→"
|
||||
outline: "action"
|
||||
keysym: "Right"
|
||||
Ctrl:
|
||||
modifier: "Control"
|
||||
outline: "small"
|
||||
label: "Ctrl"
|
||||
Alt:
|
||||
modifier: "Alt"
|
||||
outline: "small"
|
||||
label: "Alt"
|
||||
@ -3,9 +3,7 @@ Name=Squeekboard
|
||||
GenericName=On Screen Keyboard
|
||||
Comment=An on screen virtual keyboard
|
||||
Exec=@bindir@/squeekboard
|
||||
Icon=input-keyboard-symbolic
|
||||
Terminal=false
|
||||
Type=Application
|
||||
NoDisplay=true
|
||||
Categories=GTK;Utility;
|
||||
X-Phosh-UsesFeedback=true
|
||||
|
||||
122
debian/changelog
vendored
122
debian/changelog
vendored
@ -1,131 +1,17 @@
|
||||
squeekboard (1.20.0-1) experimental; urgency=medium
|
||||
|
||||
[ Dorota Czaplejewicz ]
|
||||
* state: Don't animate when force-hidden
|
||||
* build: Use Cargo.lock included with the repo by default
|
||||
* build: Update Cargo.lock.newer
|
||||
|
||||
[ Darren R ]
|
||||
* added US Dvorak Terminal
|
||||
|
||||
[ Efstathios Iosifidis ]
|
||||
* Add Greek translation
|
||||
|
||||
[ Goran Vidović ]
|
||||
* Add Croatian translation
|
||||
|
||||
[ Sebastian Krzyszkowiak ]
|
||||
* data: Set an icon in the desktop file
|
||||
* data: Indicate that Squeekboard provides haptic feedback
|
||||
|
||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Sat, 03 Sep 2022 14:21:57 +0000
|
||||
|
||||
squeekboard (1.19.0-1) experimental; urgency=medium
|
||||
|
||||
[ Dorota Czaplejewicz ]
|
||||
* docs: Describe layouts
|
||||
* glib: Fix import
|
||||
* state: Record layout choice
|
||||
* doc: Describe how to control debugging mode
|
||||
* state: Include layout choice in visible outcome
|
||||
* state: Store layout override
|
||||
* state: Decide panel arrangement
|
||||
* state: Use dummy layout command
|
||||
* state: Use IM hint and purpose for layout selection
|
||||
* main: Dry-load layout in response to the layout command
|
||||
* state: Become the source of layout choice
|
||||
* cargo: Halt overzealous upgrader
|
||||
* ci: Use bookworm for online builds
|
||||
* build: Generate files before compiling sources
|
||||
* gtk: Persist panel state
|
||||
* build: Update Cargo.lock
|
||||
|
||||
[ Luke Luo ]
|
||||
* Add Chinese (China) translation
|
||||
|
||||
[ Éloi Rivard ]
|
||||
* Add French translation
|
||||
|
||||
[ Laurent Laffont ]
|
||||
* Add FR+Bépo layout
|
||||
|
||||
[ Bytez ]
|
||||
* Fixed missing characters in eschars view in italian layout.
|
||||
* Replaced foreign characters.
|
||||
|
||||
[ Aleksandr Melman ]
|
||||
* Add Russian translation
|
||||
|
||||
[ skysphr ]
|
||||
* Added Georgian layout
|
||||
|
||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Wed, 06 Jul 2022 06:10:40 +0000
|
||||
|
||||
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
|
||||
squeekboard (1.17.1-1) experimental; urgency=medium
|
||||
|
||||
[ 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...
|
||||
[ William Wold ]
|
||||
* Do not reset pending state on zwp_input_method_v2.done
|
||||
|
||||
[ 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
|
||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Tue, 05 Apr 2022 13:32:53 +0000
|
||||
|
||||
squeekboard (1.17.0-1) experimental; urgency=medium
|
||||
|
||||
|
||||
1
debian/control
vendored
1
debian/control
vendored
@ -23,7 +23,6 @@ Build-Depends:
|
||||
librust-serde-derive-1-dev (>= 1.0),
|
||||
librust-serde-yaml-0.8-dev (>= 0.8),
|
||||
librust-xkbcommon-0.4+wayland-dev (>= 0.4),
|
||||
librust-zbus-dev (>=1.0),
|
||||
libwayland-dev (>= 1.16),
|
||||
lsb-release,
|
||||
python3,
|
||||
|
||||
1
debian/control-newer
vendored
1
debian/control-newer
vendored
@ -23,7 +23,6 @@ Build-Depends:
|
||||
librust-serde-derive-1-dev (>= 1.0),
|
||||
librust-serde-yaml-0.8-dev (>= 0.8),
|
||||
librust-xkbcommon-0.4+wayland-dev (>= 0.4),
|
||||
librust-zbus-dev (>= 1.9),
|
||||
libwayland-dev (>= 1.16),
|
||||
lsb-release,
|
||||
python3,
|
||||
|
||||
@ -90,14 +90,6 @@ Layouts can be selected using the GNOME Settings application.
|
||||
$ gsettings set org.gnome.desktop.input-sources sources "[('xkb', 'us'), ('xkb', 'de')]"
|
||||
```
|
||||
|
||||
### Debugging mode
|
||||
|
||||
Squeekboard prints some information on standard output by default. To get deep debugging information, it can also print all changes in (some of) its internal state. Those logs are most useful when reporting hard to catch issues, and can be enabled using the following command:
|
||||
|
||||
```
|
||||
busctl set-property --user sm.puri.SqueekDebug /sm/puri/SqueekDebug sm.puri.SqueekDebug Enabled b true
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Besides the environment variables supported by GTK and [GLib](https://docs.gtk.org/glib/running.html) applications
|
||||
@ -110,17 +102,6 @@ contain a comma separated list of:
|
||||
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
|
||||
|
||||
Rust modules should be split into 2 categories: libraries, and user interface. They differ in the way they do error handling.
|
||||
|
||||
15
doc/index.md
15
doc/index.md
@ -1,6 +1,13 @@
|
||||
Welcome to squeekboard's documentation!
|
||||
=======================================
|
||||
|
||||
Contents
|
||||
--------
|
||||
|
||||
* [Tutorial](tutorial.md)
|
||||
* [Contributing](hacking.md)
|
||||
* [Switching views](views.md)
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
@ -11,9 +18,9 @@ Layouts
|
||||
|
||||
Squeekboard allows user-provided keyboard layouts. They can be created without recompiling the keyboard code. The [tutorial](tutorial.md) explains the process in detail.
|
||||
|
||||
Layouts are created using a [text-based format, based on YAML](layouts.md).
|
||||
Layouts are created using a text-based format, based on YAML.
|
||||
|
||||
### Views
|
||||
TODO: Provide a description of the format.
|
||||
|
||||
Squeekboard layouts are separated into *views* and use a *room metaphor* to [switch views](views.md).
|
||||
|
||||
@ -21,7 +28,3 @@ Contributions
|
||||
-------------
|
||||
|
||||
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).
|
||||
121
doc/layouts.md
121
doc/layouts.md
@ -1,121 +0,0 @@
|
||||
Layouts
|
||||
=====
|
||||
|
||||
Squeekboard is composed of multiple layouts, several for each language, multiplied by each hint.
|
||||
|
||||
Layouts live in the "keyboards" directory.
|
||||
|
||||
Hints
|
||||
-------
|
||||
|
||||
The currently supported hints are: default, "email", "emoji", "number', "pin", "terminal", and "url".
|
||||
|
||||
Each directory in "keyboards" is named after a hint, with the "keyboards" directory itself taking the role of default.
|
||||
|
||||
Languages/scripts
|
||||
-----------------------
|
||||
|
||||
Each hint directory contains multiple layout files. A single language will be composed of multiple files, with names starting with the same text. The language names are taken from iso639-3. An example is "gr".
|
||||
|
||||
After the language name optionally comes a "+" and an indication of the variant. For example, "it+fur".
|
||||
|
||||
Squeekboard will look for those based on the currently selected layout in Gnome Control Center.
|
||||
|
||||
Then, there's an optional part "_wide", which Squeekboard will try to use if the current display is rather wide. Example: "us+colemak_wide" or "us_wide".
|
||||
|
||||
Finally, the file name ends with ".yaml", e.g. "jp+kana_wide.yaml".
|
||||
|
||||
Together with hint information, this gives a complete path to the layout like this: "keyboards/terminal/fr_wide.yaml" or "keyboards/cz+qwerty.yaml".
|
||||
|
||||
Layout syntax
|
||||
------------------
|
||||
|
||||
The layout file follows the YAML syntax, with specific meanings given to sections.
|
||||
|
||||
### Outlines
|
||||
|
||||
The "outlines" dictionary controls the widths and heights of buttons.
|
||||
|
||||
```
|
||||
outlines:
|
||||
default: { width: 32, height: 52 }
|
||||
```
|
||||
The width and height numbers are not in pixels, but rather they are proportionally scaled to fit the panel size.
|
||||
|
||||
There may be any number of outlines, but there are some special names:
|
||||
- "default" applies to every button unless explicitly changed. It should be used for buttons that emit text
|
||||
- "altline", "wide" have own color scheme, should be used for buttons which cause view changes
|
||||
- "special" has own color scheme, to be used for confirmations like enter.
|
||||
|
||||
### Views
|
||||
|
||||
The "views" dictionary contains the actual views and positions of buttons.
|
||||
|
||||
```
|
||||
views:
|
||||
base:
|
||||
- "q w e r t y u i o p å"
|
||||
```
|
||||
|
||||
Squeekboard's layouts consist of multiple views, of which only one is visible at a time. Different views may contain different or the same buttons, more or fewer buttons, but each layout is independent. They are *not* shift levels – there is no concept of "shift" in Squeekboard. View selection is also not dependent on modifiers.
|
||||
|
||||
There is only one special view "base". Views and view switching are described in detail in the [views](views.md) document.
|
||||
|
||||
Views in Squeekboard are based on rows. The first row comes near the top of the panel, the next one below, and so on.
|
||||
|
||||
```
|
||||
- "Q W E R T Y U I O P Å"
|
||||
- "upper z x c v b n m BackSpace"
|
||||
```
|
||||
|
||||
Each row is a single string, and button names are separated by spaces. In left-to-right languages, the panel will be laid out just like the view code. CAUTION: buttons are placed on the panel left-to-right, starting from the earliest position in the string. That may not display great in your text editor when you use right-to-left characters as button names.
|
||||
|
||||
#### Button names in rows
|
||||
|
||||
Unicode characters are supported in the row string, so it's easy to use the correct name for most of them. However, the layout code is still YAML, which excludes certain characters: the space " ", the backslash "\", the double quote `"`. Those must use a replacement name.
|
||||
|
||||
Similarly, buttons that do not emit characters must have some names.
|
||||
|
||||
### Buttons
|
||||
|
||||
The buttons section describes what the button looks like and what it does.
|
||||
|
||||
```
|
||||
BackSpace:
|
||||
outline: altline
|
||||
icon: "edit-clear-symbolic"
|
||||
action: erase
|
||||
```
|
||||
|
||||
Each entry in the "buttons" dictionary describes some button already present in one of the "views" rows. In the above example, it's "BackSpace".
|
||||
|
||||
The button description can have a number of components, each optional. For details, see
|
||||
|
||||
- "outline" selects which entry from the "outlines" section to use to draw this button,
|
||||
- "label" is what should be displayed on the button, if its name is unsuitable,
|
||||
- "icon" is the name of the svg icon to use instead of a label (icons are builtin, see the "data/icons" directory),
|
||||
- "text" is the text to submit when the button is clicked – if the name of the button is not suitable,
|
||||
- "keysym" is the emulated keyboard keysym to send instead of sending text. Its use is discouraged: Squeekboard will automatically send keysyms if it detects that the receiving application does not accept text.
|
||||
- "modifier" makes the button set an emulated keyboard modifier. The use of this is discouraged, and never needed for entering text.
|
||||
- "action" sets aside the button for special actions like view switching
|
||||
|
||||
#### Action
|
||||
|
||||
```
|
||||
action:
|
||||
set_view: "numbers"
|
||||
```
|
||||
|
||||
The "action" property has multiple forms.
|
||||
|
||||
- "erase" will erase the position behind the cursor,
|
||||
- "show_preferences" will open the language selection popup,
|
||||
- "set_view" simply switches to a view,
|
||||
- "lock_view" switches to a view for a moment.
|
||||
|
||||
The two switching modes are better described in the [views](views.md) document.
|
||||
|
||||
Sources
|
||||
----------
|
||||
|
||||
The sources, where all this is documented and up to date are in "src/data/parsing.rs". The reference documentation for the `rs::data::parsing::Layout` structure is the main place to look at.
|
||||
@ -9,12 +9,14 @@ So at least I will try to start writing a short how-to here and edit this post a
|
||||
|
||||
## Creating a new layout
|
||||
|
||||
Creating a layout is easy. You don't need to recompile things, just edit and test. It's easiest to start with an existing layout, with the [layouts](layouts.md) documentation in hand.
|
||||
Creating a layout is easy. You don't need to recompile things, just edit and test. It's easiest to start with an existing layout.
|
||||
|
||||
### Get one of the existing keyboard layouts
|
||||
|
||||
* You can get one of the keyboards from the squeekboard git repository : [https://source.puri.sm/Librem5/squeekboard](https://source.puri.sm/Librem5/squeekboard)
|
||||
* The keyboard layouts are located in the subdirectory [`data/keyboards/`](https://source.puri.sm/Librem5/squeekboard/-/tree/master/data/keyboards) in the `.yaml` files
|
||||
* Take a look and try to understand them :slight_smile:
|
||||
|
||||
|
||||
### Creating the keyboard layout
|
||||
|
||||
|
||||
@ -35,7 +35,6 @@
|
||||
|
||||
#include "eekboard/eekboard-context-service.h"
|
||||
#include "src/layout.h"
|
||||
#include "src/popover.h"
|
||||
#include "src/submission.h"
|
||||
|
||||
#define LIBFEEDBACK_USE_UNSTABLE_API
|
||||
@ -49,8 +48,6 @@ typedef struct _EekGtkKeyboardPrivate
|
||||
struct render_geometry render_geometry; // mutable
|
||||
|
||||
EekboardContextService *eekboard_context; // unowned reference
|
||||
struct squeek_popover *popover; // shared reference
|
||||
struct squeek_state_manager *state_manager; // shared reference
|
||||
struct submission *submission; // unowned reference
|
||||
|
||||
struct squeek_layout_state *layout; // unowned
|
||||
@ -58,8 +55,6 @@ typedef struct _EekGtkKeyboardPrivate
|
||||
|
||||
GdkEventSequence *sequence; // unowned reference
|
||||
LfbEvent *event;
|
||||
|
||||
gulong kb_signal;
|
||||
} EekGtkKeyboardPrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (EekGtkKeyboard, eek_gtk_keyboard, GTK_TYPE_DRAWING_AREA)
|
||||
@ -121,6 +116,15 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Units of virtual pixels size
|
||||
static enum squeek_arrangement_kind get_type(uint32_t width, uint32_t height) {
|
||||
(void)height;
|
||||
if (width < 540) {
|
||||
return ARRANGEMENT_KIND_BASE;
|
||||
}
|
||||
return ARRANGEMENT_KIND_WIDE;
|
||||
}
|
||||
|
||||
static void
|
||||
eek_gtk_keyboard_real_size_allocate (GtkWidget *self,
|
||||
GtkAllocation *allocation)
|
||||
@ -128,6 +132,15 @@ eek_gtk_keyboard_real_size_allocate (GtkWidget *self,
|
||||
EekGtkKeyboard *keyboard = EEK_GTK_KEYBOARD (self);
|
||||
EekGtkKeyboardPrivate *priv =
|
||||
eek_gtk_keyboard_get_instance_private (keyboard);
|
||||
// check if the change would switch types
|
||||
enum squeek_arrangement_kind new_type = get_type(
|
||||
(uint32_t)(allocation->width - allocation->x),
|
||||
(uint32_t)(allocation->height - allocation->y));
|
||||
if (priv->layout->arrangement != new_type) {
|
||||
priv->layout->arrangement = new_type;
|
||||
uint32_t time = gdk_event_get_time(NULL);
|
||||
eekboard_context_service_use_layout(priv->eekboard_context, priv->layout, time);
|
||||
}
|
||||
|
||||
if (priv->renderer) {
|
||||
set_allocation_size (keyboard, priv->keyboard->layout,
|
||||
@ -143,7 +156,6 @@ on_event_triggered (LfbEvent *event,
|
||||
GAsyncResult *res,
|
||||
gpointer unused)
|
||||
{
|
||||
(void)unused;
|
||||
g_autoptr (GError) err = NULL;
|
||||
|
||||
if (!lfb_event_trigger_feedback_finish (event, res, &err)) {
|
||||
@ -174,7 +186,7 @@ static void drag(EekGtkKeyboard *self,
|
||||
squeek_layout_drag(eekboard_context_service_get_keyboard(priv->eekboard_context)->layout,
|
||||
priv->submission,
|
||||
x, y, priv->render_geometry.widget_to_layout, time,
|
||||
priv->popover, priv->state_manager, self);
|
||||
priv->eekboard_context, self);
|
||||
}
|
||||
|
||||
static void release(EekGtkKeyboard *self, guint32 time)
|
||||
@ -185,7 +197,7 @@ static void release(EekGtkKeyboard *self, guint32 time)
|
||||
}
|
||||
squeek_layout_release(eekboard_context_service_get_keyboard(priv->eekboard_context)->layout,
|
||||
priv->submission, priv->render_geometry.widget_to_layout, time,
|
||||
priv->popover, priv->state_manager, self);
|
||||
priv->eekboard_context, self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -295,19 +307,12 @@ 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
|
||||
eek_gtk_keyboard_dispose (GObject *object)
|
||||
{
|
||||
EekGtkKeyboard *self = EEK_GTK_KEYBOARD (object);
|
||||
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) {
|
||||
eek_renderer_free(priv->renderer);
|
||||
priv->renderer = NULL;
|
||||
@ -392,15 +397,13 @@ on_notify_keyboard (GObject *object,
|
||||
GtkWidget *
|
||||
eek_gtk_keyboard_new (EekboardContextService *eekservice,
|
||||
struct submission *submission,
|
||||
struct squeek_state_manager *state_manager,
|
||||
struct squeek_popover *popover)
|
||||
struct squeek_layout_state *layout)
|
||||
{
|
||||
EekGtkKeyboard *ret = EEK_GTK_KEYBOARD(g_object_new (EEK_TYPE_GTK_KEYBOARD, NULL));
|
||||
EekGtkKeyboardPrivate *priv = (EekGtkKeyboardPrivate*)eek_gtk_keyboard_get_instance_private (ret);
|
||||
priv->popover = popover;
|
||||
priv->eekboard_context = eekservice;
|
||||
priv->submission = submission;
|
||||
priv->state_manager = state_manager;
|
||||
priv->layout = layout;
|
||||
priv->renderer = NULL;
|
||||
// This should really be done on initialization.
|
||||
// Before the widget is allocated,
|
||||
@ -415,13 +418,12 @@ eek_gtk_keyboard_new (EekboardContextService *eekservice,
|
||||
.widget_to_layout = {
|
||||
.origin_x = 0,
|
||||
.origin_y = 0,
|
||||
.scale_x = 1,
|
||||
.scale_y = 1,
|
||||
.scale = 1,
|
||||
},
|
||||
};
|
||||
priv->render_geometry = initial_geometry;
|
||||
|
||||
priv->kb_signal = g_signal_connect (eekservice,
|
||||
g_signal_connect (eekservice,
|
||||
"notify::keyboard",
|
||||
G_CALLBACK(on_notify_keyboard),
|
||||
ret);
|
||||
|
||||
@ -30,8 +30,6 @@
|
||||
|
||||
#include "eek/eek-renderer.h"
|
||||
#include "eek/eek-types.h"
|
||||
#include "src/main.h"
|
||||
#include "src/popover.h"
|
||||
|
||||
struct submission;
|
||||
struct squeek_layout_state;
|
||||
@ -50,7 +48,7 @@ struct _EekGtkKeyboardClass
|
||||
gpointer pdummy[24];
|
||||
};
|
||||
|
||||
GtkWidget *eek_gtk_keyboard_new (EekboardContextService *eekservice, struct submission *submission, struct squeek_state_manager *state_manager, struct squeek_popover *popover);
|
||||
GtkWidget *eek_gtk_keyboard_new (EekboardContextService *eekservice, struct submission *submission, struct squeek_layout_state *layout);
|
||||
void eek_gtk_keyboard_emit_feedback (EekGtkKeyboard *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@ -219,7 +219,7 @@ eek_renderer_render_keyboard (EekRenderer *self,
|
||||
|
||||
cairo_save(cr);
|
||||
cairo_translate (cr, geometry.widget_to_layout.origin_x, geometry.widget_to_layout.origin_y);
|
||||
cairo_scale (cr, geometry.widget_to_layout.scale_x, geometry.widget_to_layout.scale_y);
|
||||
cairo_scale (cr, geometry.widget_to_layout.scale, geometry.widget_to_layout.scale);
|
||||
|
||||
squeek_draw_layout_base_view(keyboard->layout, self, cr);
|
||||
squeek_layout_draw_all_changed(keyboard->layout, self, cr, submission);
|
||||
|
||||
@ -87,8 +87,7 @@ void eek_bounds_free (EekBounds *bounds);
|
||||
struct transformation {
|
||||
gdouble origin_x;
|
||||
gdouble origin_y;
|
||||
gdouble scale_x;
|
||||
gdouble scale_y;
|
||||
gdouble scale;
|
||||
};
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@ -55,15 +55,15 @@ static guint signals[LAST_SIGNAL] = { 0, };
|
||||
*/
|
||||
struct _EekboardContextService {
|
||||
GObject parent;
|
||||
struct squeek_state_manager *state_manager; // shared reference
|
||||
struct squeek_layout_state *layout; // Unowned
|
||||
|
||||
LevelKeyboard *keyboard; // currently used keyboard
|
||||
GSettings *settings; // Owned reference
|
||||
|
||||
/// Needed for keymap changes after keyboard updates.
|
||||
// TODO: can the main loop access submission to change the key maps instead?
|
||||
// This should probably land together with passing buttons through state,
|
||||
// to avoid race conditions between setting buttons and key maps.
|
||||
// Maybe TODO: it's used only for fetching layout type.
|
||||
// Maybe let UI push the type to this structure?
|
||||
ServerContextService *ui; // unowned reference
|
||||
/// Needed for keymap changes after keyboard updates
|
||||
struct submission *submission; // unowned
|
||||
};
|
||||
|
||||
@ -126,7 +126,24 @@ settings_get_layout(GSettings *settings, char **type, char **layout)
|
||||
g_variant_unref(inputs);
|
||||
}
|
||||
|
||||
void eekboard_context_service_set_layout(EekboardContextService *context, struct squeek_layout *layout, uint32_t timestamp) {
|
||||
void
|
||||
eekboard_context_service_use_layout(EekboardContextService *context, struct squeek_layout_state *state, uint32_t timestamp) {
|
||||
gchar *layout_name = state->layout_name;
|
||||
gchar *overlay_name = state->overlay_name;
|
||||
|
||||
// try to get the best keyboard layout
|
||||
if (layout_name == NULL) {
|
||||
layout_name = "us";
|
||||
}
|
||||
|
||||
// overlay is "Normal" for most layouts, we will only look for "terminal" in rust code.
|
||||
// for now just avoid passing a null pointer
|
||||
if (overlay_name == NULL) {
|
||||
overlay_name = ""; // fallback to Normal
|
||||
}
|
||||
|
||||
// generic part follows
|
||||
struct squeek_layout *layout = squeek_load_layout(layout_name, state->arrangement, state->purpose, overlay_name);
|
||||
LevelKeyboard *keyboard = level_keyboard_new(layout);
|
||||
// set as current
|
||||
LevelKeyboard *previous_keyboard = context->keyboard;
|
||||
@ -152,7 +169,17 @@ static void eekboard_context_service_update_settings_layout(EekboardContextServi
|
||||
settings_get_layout(context->settings,
|
||||
&keyboard_type, &keyboard_layout);
|
||||
|
||||
squeek_state_send_layout_set(context->state_manager, keyboard_layout, keyboard_type, gdk_event_get_time(NULL));
|
||||
if (g_strcmp0(context->layout->layout_name, keyboard_layout) != 0 || context->layout->overlay_name) {
|
||||
g_free(context->layout->overlay_name);
|
||||
context->layout->overlay_name = NULL;
|
||||
if (keyboard_layout) {
|
||||
g_free(context->layout->layout_name);
|
||||
context->layout->layout_name = g_strdup(keyboard_layout);
|
||||
}
|
||||
// This must actually update the UI.
|
||||
uint32_t time = gdk_event_get_time(NULL);
|
||||
eekboard_context_service_use_layout(context, context->layout, time);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -270,18 +297,50 @@ eekboard_context_service_get_keyboard (EekboardContextService *context)
|
||||
return context->keyboard;
|
||||
}
|
||||
|
||||
EekboardContextService *eekboard_context_service_new(struct squeek_state_manager *state_manager)
|
||||
void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
|
||||
uint32_t hint, uint32_t purpose)
|
||||
{
|
||||
if (context->layout->hint != hint || context->layout->purpose != purpose) {
|
||||
context->layout->hint = hint;
|
||||
context->layout->purpose = purpose;
|
||||
uint32_t time = gdk_event_get_time(NULL);
|
||||
eekboard_context_service_use_layout(context, context->layout, time);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
eekboard_context_service_set_overlay(EekboardContextService *context, const char* name) {
|
||||
if (g_strcmp0(context->layout->overlay_name, name)) {
|
||||
g_free(context->layout->overlay_name);
|
||||
context->layout->overlay_name = g_strdup(name);
|
||||
uint32_t time = gdk_event_get_time(NULL);
|
||||
eekboard_context_service_use_layout(context, context->layout, time);
|
||||
}
|
||||
}
|
||||
|
||||
const char*
|
||||
eekboard_context_service_get_overlay(EekboardContextService *context) {
|
||||
return context->layout->overlay_name;
|
||||
}
|
||||
|
||||
EekboardContextService *eekboard_context_service_new(struct squeek_layout_state *state)
|
||||
{
|
||||
EekboardContextService *context = g_object_new (EEKBOARD_TYPE_CONTEXT_SERVICE, NULL);
|
||||
context->state_manager = state_manager;
|
||||
context->layout = state;
|
||||
eekboard_context_service_update_settings_layout(context);
|
||||
uint32_t time = gdk_event_get_time(NULL);
|
||||
eekboard_context_service_use_layout(context, context->layout, time);
|
||||
return context;
|
||||
}
|
||||
|
||||
void eekboard_context_service_set_submission(EekboardContextService *context, struct submission *submission) {
|
||||
context->submission = submission;
|
||||
if (context->submission && context->keyboard) {
|
||||
if (context->submission) {
|
||||
uint32_t time = gdk_event_get_time(NULL);
|
||||
submission_use_layout(context->submission, context->keyboard->layout, time);
|
||||
}
|
||||
}
|
||||
|
||||
void eekboard_context_service_set_ui(EekboardContextService *context, ServerContextService *ui) {
|
||||
context->ui = ui;
|
||||
}
|
||||
|
||||
@ -24,7 +24,6 @@
|
||||
|
||||
#include "src/submission.h"
|
||||
#include "src/layout.h"
|
||||
#include "src/main.h"
|
||||
|
||||
#include "virtual-keyboard-unstable-v1-client-protocol.h"
|
||||
#include "text-input-unstable-v3-client-protocol.h"
|
||||
@ -38,13 +37,19 @@ G_BEGIN_DECLS
|
||||
|
||||
G_DECLARE_FINAL_TYPE(EekboardContextService, eekboard_context_service, EEKBOARD, CONTEXT_SERVICE, GObject)
|
||||
|
||||
EekboardContextService *eekboard_context_service_new(struct squeek_state_manager *state_manager);
|
||||
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_ui(EekboardContextService *context, ServerContextService *ui);
|
||||
void eekboard_context_service_destroy (EekboardContextService *context);
|
||||
LevelKeyboard *eekboard_context_service_get_keyboard(EekboardContextService *context);
|
||||
|
||||
void eekboard_context_service_set_keymap(EekboardContextService *context,
|
||||
const LevelKeyboard *keyboard);
|
||||
|
||||
void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
|
||||
uint32_t hint,
|
||||
uint32_t purpose);
|
||||
void
|
||||
eekboard_context_service_use_layout(EekboardContextService *context, struct squeek_layout_state *layout, uint32_t timestamp);
|
||||
G_END_DECLS
|
||||
#endif /* EEKBOARD_CONTEXT_SERVICE_H */
|
||||
|
||||
18
meson.build
18
meson.build
@ -1,7 +1,7 @@
|
||||
project(
|
||||
'squeekboard',
|
||||
'c', 'rust',
|
||||
version: '1.20.0',
|
||||
version: '1.17.1',
|
||||
license: 'GPLv3',
|
||||
meson_version: '>=0.51.0',
|
||||
default_options: [
|
||||
@ -101,15 +101,10 @@ cargo_patch = []
|
||||
if get_option('newer') == true
|
||||
cargo_build_flags += ['--features', 'glib_v0_14']
|
||||
cargo_deps = files('Cargo.deps.newer')
|
||||
cargo_lock = files('Cargo.lock.newer')
|
||||
else
|
||||
cargo_deps = files('Cargo.deps')
|
||||
cargo_lock = []
|
||||
if get_option('online') == true
|
||||
cargo_patch = [files('Cargo.deps.online')]
|
||||
if get_option('reset_lock') == true
|
||||
cargo_lock = files('Cargo.lock')
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -121,17 +116,6 @@ cargo_toml = custom_target(
|
||||
capture: true,
|
||||
)
|
||||
|
||||
cargo_deps = [cargo_toml]
|
||||
if get_option('online') == true and get_option('reset_lock') == true
|
||||
cargo_lock = custom_target(
|
||||
'Cargo.lock',
|
||||
output: 'Cargo.lock',
|
||||
command: [cat, cargo_lock],
|
||||
capture: true,
|
||||
)
|
||||
cargo_deps += [cargo_lock]
|
||||
endif
|
||||
|
||||
dep_cargo = find_program('cargo')
|
||||
cargo_script = find_program('cargo.sh')
|
||||
cargo_build = find_program('cargo_build.py')
|
||||
|
||||
@ -15,10 +15,6 @@ option('online',
|
||||
type: 'boolean', value: true,
|
||||
description: 'Pull packages from the internet while building, as opposed to a local regstry.')
|
||||
|
||||
option('reset_lock',
|
||||
type: 'boolean', value: true,
|
||||
description: 'Resets Cargo.lock to the one found in the source repo. Does not affect builds with online == false.')
|
||||
|
||||
option('strict',
|
||||
type: 'boolean', value: true,
|
||||
description: 'Turn more warnings into errors')
|
||||
|
||||
15
po/LINGUAS
15
po/LINGUAS
@ -1,28 +1,13 @@
|
||||
ca
|
||||
de
|
||||
el
|
||||
es
|
||||
fa
|
||||
fi
|
||||
fr
|
||||
fur
|
||||
gl
|
||||
he
|
||||
hr
|
||||
hu
|
||||
it
|
||||
ka
|
||||
ko
|
||||
nl
|
||||
oc
|
||||
pl
|
||||
pt
|
||||
pt_BR
|
||||
ro
|
||||
ru
|
||||
sl
|
||||
sr
|
||||
tr
|
||||
uk
|
||||
sv
|
||||
zh_CN
|
||||
|
||||
46
po/el.po
46
po/el.po
@ -1,46 +0,0 @@
|
||||
# Greek translation for squeekboard.
|
||||
# Copyright (C) 2022 squeekboard's COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the squeekboard package.
|
||||
# Efstathios Iosifidis <eiosifidis@gnome.org>, 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-07-11 06:54+0000\n"
|
||||
"PO-Revision-Date: 2022-07-11 23:11+0300\n"
|
||||
"Last-Translator: Efstathios Iosifidis <eiosifidis@gnome.org>\n"
|
||||
"Language-Team: Greek <gnome-el-list@gnome.org>\n"
|
||||
"Language: el\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.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 "Τερματικό"
|
||||
|
||||
#: 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 "Εικονικό πληκτρολόγιο οθόνης"
|
||||
47
po/es.po
47
po/es.po
@ -1,47 +0,0 @@
|
||||
# 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"
|
||||
47
po/fr.po
47
po/fr.po
@ -1,47 +0,0 @@
|
||||
# French translation for squeekboard.
|
||||
# Copyright (C) 2022 squeekboard's COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the squeekboard package.
|
||||
# FULL NAME <EMAIL@ADDRESS>, 2022.
|
||||
# Éloi Rivard <eloi.rivard@nubla.fr>, 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-28 15:05+0000\n"
|
||||
"PO-Revision-Date: 2022-05-25 16:34+0200\n"
|
||||
"Last-Translator: Éloi Rivard <eloi.rivard@nubla.fr>\n"
|
||||
"Language-Team: French <gnomefr@traduc.org>\n"
|
||||
"Language: fr\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 40.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 "Paramètres du clavier"
|
||||
|
||||
#: 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 "Clavier virtuel"
|
||||
|
||||
#: data/sm.puri.Squeekboard.desktop.in.in:5
|
||||
msgid "An on screen virtual keyboard"
|
||||
msgstr "Un clavier virtuel affiché à l’écran"
|
||||
47
po/hr.po
47
po/hr.po
@ -1,47 +0,0 @@
|
||||
# Croatian 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.
|
||||
#
|
||||
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-07-11 20:12+0000\n"
|
||||
"PO-Revision-Date: 2022-08-31 09:49+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Croatian <hr@li.org>\n"
|
||||
"Language: hr\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%10==1 && n%100!=11 ? 0 : n%10>=2 "
|
||||
"&& n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
"X-Generator: Poedit 3.1.1\n"
|
||||
|
||||
#. translators: This is a emmoji keyboard layout
|
||||
#: data/popover.ui:6
|
||||
msgid "Emoji"
|
||||
msgstr "Smajli"
|
||||
|
||||
#. translators: This is a terminal keyboard layout
|
||||
#: data/popover.ui:12
|
||||
msgid "Terminal"
|
||||
msgstr "Terminal"
|
||||
|
||||
#: data/popover.ui:18
|
||||
msgid "Keyboard Settings"
|
||||
msgstr "Postavke tipkovnice"
|
||||
|
||||
#: 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 "Zaslonska tipkovnica"
|
||||
|
||||
#: data/sm.puri.Squeekboard.desktop.in.in:5
|
||||
msgid "An on screen virtual keyboard"
|
||||
msgstr "Zaslonska virtualna tipkovnica"
|
||||
46
po/hu.po
46
po/hu.po
@ -1,46 +0,0 @@
|
||||
# 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
47
po/it.po
@ -1,47 +0,0 @@
|
||||
# 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
46
po/ka.po
@ -1,46 +0,0 @@
|
||||
# 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
46
po/ko.po
@ -1,46 +0,0 @@
|
||||
# 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
45
po/oc.po
@ -1,45 +0,0 @@
|
||||
# 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
47
po/pl.po
@ -1,47 +0,0 @@
|
||||
# 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
46
po/pt.po
@ -1,46 +0,0 @@
|
||||
# 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ã"
|
||||
47
po/ru.po
47
po/ru.po
@ -1,47 +0,0 @@
|
||||
# Russian translation for squeekboard.
|
||||
# Copyright (C) 2022 squeekboard's COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the squeekboard package.
|
||||
# Aleksandr Melman <Alexmelman88@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-06-14 15:23+0000\n"
|
||||
"PO-Revision-Date: 2022-06-16 14:38+0300\n"
|
||||
"Last-Translator: Aleksandr Melman <Alexmelman88@gmail.com>\n"
|
||||
"Language-Team: Russian <gnome-cyr@gnome.org>\n"
|
||||
"Language: ru\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%10==1 && n%100!=11 ? 0 : n%10>=2 "
|
||||
"&& n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\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 "Виртуальная клавиатура на экране"
|
||||
45
po/sr.po
45
po/sr.po
@ -1,45 +0,0 @@
|
||||
# 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
46
po/tr.po
@ -1,46 +0,0 @@
|
||||
# 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"
|
||||
45
po/zh_CN.po
45
po/zh_CN.po
@ -1,45 +0,0 @@
|
||||
# Chinese (China) translation for squeekboard.
|
||||
# Copyright (C) 2022 squeekboard's COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the squeekboard package.
|
||||
# Luke Luo <2164381336@qq.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-21 07:28+0000\n"
|
||||
"PO-Revision-Date: 2022-04-23 20:30+0800\n"
|
||||
"Last-Translator: Luke Luo <njlyf2011@hotmail.com>\n"
|
||||
"Language-Team: Chinese (China) <i18n-zh@googlegroups.com>\n"
|
||||
"Language: zh_CN\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 "终端"
|
||||
|
||||
#: 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 "一个虚拟屏幕键盘"
|
||||
@ -1,23 +0,0 @@
|
||||
/* Copyright (C) 2022 Purism SPC
|
||||
* SPDX-License-Identifier: GPL-3.0+
|
||||
*/
|
||||
|
||||
/*! Actors are parts of Squeekboard containing state independent from the main application state.
|
||||
|
||||
Because main application state is meant to be immutable,
|
||||
it cannot be referenced directly by pieces of logic
|
||||
interacting with the environment.
|
||||
|
||||
Such impure logic is split away (actor's logic)
|
||||
and combined with relevant pieces of state (actor state),
|
||||
thus preserving the purity (and sometimes simplicity) of the main state.
|
||||
|
||||
Actors can communicate with the main state by sending it messages,
|
||||
and by receiving updates from it.
|
||||
*/
|
||||
|
||||
// TODO: move crate::panel into crate::actors::panel.
|
||||
// Panel contains state and logic to protect the main state from getting flooded
|
||||
// with low-level wayland and gtk sizing events.
|
||||
|
||||
pub mod popover;
|
||||
@ -1,40 +0,0 @@
|
||||
/* Copyright (C) 2022 Purism SPC
|
||||
* SPDX-License-Identifier: GPL-3.0+
|
||||
*/
|
||||
|
||||
/*! The popover is opened directly by the GTK surface,
|
||||
without bouncing click events off the main state.
|
||||
Then it must accurately show which layout has been selected.
|
||||
It can get the system layout directly from gsettings on open,
|
||||
but it cannot get the user-selected overlay, because it's stored in state.
|
||||
|
||||
To solve this, overlay will be cached in the popover actor,
|
||||
and updated by main state every time it changes.
|
||||
*/
|
||||
|
||||
pub mod c {
|
||||
use super::*;
|
||||
use crate::util::c::Wrapped;
|
||||
/// The mutable instance of state
|
||||
pub type Actor = Wrapped<State>;
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct State {
|
||||
pub overlay: Option<String>,
|
||||
}
|
||||
|
||||
impl State {
|
||||
pub fn new() -> Self {
|
||||
Self { overlay: None }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_overlay(
|
||||
actor: &c::Actor,
|
||||
overlay: Option<String>,
|
||||
) {
|
||||
let actor = actor.clone_ref();
|
||||
let mut actor = actor.borrow_mut();
|
||||
actor.overlay = overlay;
|
||||
}
|
||||
@ -6,30 +6,18 @@
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::imservice::ContentPurpose;
|
||||
use crate::layout::ArrangementKind;
|
||||
use crate::main::PixelSize;
|
||||
use crate::outputs::OutputId;
|
||||
use crate::panel::PixelSize;
|
||||
|
||||
/// The keyboard should hide after this has elapsed to prevent flickering.
|
||||
pub const HIDING_TIMEOUT: Duration = Duration::from_millis(200);
|
||||
|
||||
/// Description of parameters which influence panel contents
|
||||
#[derive(PartialEq, Clone, Debug)]
|
||||
pub struct Contents {
|
||||
pub name: String,
|
||||
pub kind: ArrangementKind,
|
||||
pub overlay_name: Option<String>,
|
||||
pub purpose: ContentPurpose,
|
||||
}
|
||||
|
||||
/// The outwardly visible state of visibility
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub enum Outcome {
|
||||
Visible {
|
||||
output: OutputId,
|
||||
height: PixelSize,
|
||||
contents: Contents,
|
||||
},
|
||||
Hidden,
|
||||
}
|
||||
|
||||
@ -7,16 +7,64 @@
|
||||
use std::env;
|
||||
use std::fmt;
|
||||
use std::path::PathBuf;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use super::{ Error, LoadError };
|
||||
use super::parsing;
|
||||
|
||||
use crate::layout;
|
||||
use crate::layout::ArrangementKind;
|
||||
use crate::logging;
|
||||
use crate::xdg;
|
||||
use crate::imservice::ContentPurpose;
|
||||
use ::layout::ArrangementKind;
|
||||
use ::logging;
|
||||
use ::util::c::as_str;
|
||||
use ::xdg;
|
||||
use ::imservice::ContentPurpose;
|
||||
|
||||
// traits, derives
|
||||
use ::logging::Warn;
|
||||
|
||||
|
||||
/// Gathers stuff defined in C or called by C
|
||||
pub mod c {
|
||||
use super::*;
|
||||
use std::os::raw::c_char;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C"
|
||||
fn squeek_load_layout(
|
||||
name: *const c_char, // name of the keyboard
|
||||
type_: u32, // type like Wide
|
||||
variant: u32, // purpose variant like numeric, terminal...
|
||||
overlay: *const c_char, // the overlay (looking for "terminal")
|
||||
) -> *mut ::layout::Layout {
|
||||
let type_ = match type_ {
|
||||
0 => ArrangementKind::Base,
|
||||
1 => ArrangementKind::Wide,
|
||||
_ => panic!("Bad enum value"),
|
||||
};
|
||||
|
||||
let name = as_str(&name)
|
||||
.expect("Bad layout name")
|
||||
.expect("Empty layout name");
|
||||
|
||||
let variant = ContentPurpose::try_from(variant)
|
||||
.or_print(
|
||||
logging::Problem::Warning,
|
||||
"Received invalid purpose value",
|
||||
)
|
||||
.unwrap_or(ContentPurpose::Normal);
|
||||
|
||||
let overlay_str = as_str(&overlay)
|
||||
.expect("Bad overlay name")
|
||||
.expect("Empty overlay name");
|
||||
let overlay_str = match overlay_str {
|
||||
"" => None,
|
||||
other => Some(other),
|
||||
};
|
||||
|
||||
let (kind, layout) = load_layout_data_with_fallback(&name, type_, variant, overlay_str);
|
||||
let layout = ::layout::Layout::new(layout, kind, variant);
|
||||
Box::into_raw(Box::new(layout))
|
||||
}
|
||||
}
|
||||
|
||||
const FALLBACK_LAYOUT_NAME: &str = "us";
|
||||
|
||||
@ -217,7 +265,7 @@ fn load_layout_data_with_fallback(
|
||||
kind: ArrangementKind,
|
||||
purpose: ContentPurpose,
|
||||
overlay: Option<&str>,
|
||||
) -> (ArrangementKind, layout::LayoutData) {
|
||||
) -> (ArrangementKind, ::layout::LayoutData) {
|
||||
|
||||
// Build the path to the right keyboard layout subdirectory
|
||||
let path = env::var_os("SQUEEKBOARD_KEYBOARDSDIR")
|
||||
@ -252,17 +300,6 @@ fn load_layout_data_with_fallback(
|
||||
panic!("No useful layout found!");
|
||||
}
|
||||
|
||||
pub fn load_layout(
|
||||
name: String,
|
||||
kind: ArrangementKind,
|
||||
variant: ContentPurpose,
|
||||
overlay: Option<String>,
|
||||
) -> layout::Layout {
|
||||
let overlay = overlay.as_ref().map(String::as_str);
|
||||
let (found_kind, layout)
|
||||
= load_layout_data_with_fallback(&name, kind, variant, overlay);
|
||||
layout::Layout::new(layout, found_kind, variant)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
/*! Combined module for dealing with layout files */
|
||||
|
||||
pub mod loading;
|
||||
mod loading;
|
||||
pub mod parsing;
|
||||
|
||||
use std::io;
|
||||
|
||||
71
src/debug.rs
71
src/debug.rs
@ -1,71 +0,0 @@
|
||||
/*
|
||||
* 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,
|
||||
}
|
||||
@ -39,9 +39,7 @@ type UISender = glib::Sender<Commands>;
|
||||
/// It sends outcomes to the glib main loop using a channel.
|
||||
/// The outcomes are applied by the UI end of the channel in the `main` module.
|
||||
// This could still be reasonably tested,
|
||||
/// by creating a glib::Sender and checking what messages it receives.
|
||||
// This can/should be abstracted over Event and Commands,
|
||||
// so that the C call-ins can be thrown away from here and defined near events.
|
||||
// by creating a glib::Sender and checking what messages it receives.
|
||||
#[derive(Clone)]
|
||||
pub struct Threaded {
|
||||
thread: Sender,
|
||||
@ -110,11 +108,8 @@ mod c {
|
||||
use super::*;
|
||||
|
||||
use crate::state::Presence;
|
||||
use crate::state::LayoutChoice;
|
||||
use crate::state::visibility;
|
||||
use crate::util;
|
||||
use crate::util::c::Wrapped;
|
||||
use std::os::raw::c_char;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C"
|
||||
@ -145,28 +140,4 @@ mod c {
|
||||
sender.send(Event::PhysicalKeyboard(state))
|
||||
.or_warn(&mut logging::Print, logging::Problem::Warning, "Can't send to state manager");
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C"
|
||||
fn squeek_state_send_layout_set(
|
||||
sender: Wrapped<Threaded>,
|
||||
name: *const c_char,
|
||||
source: *const c_char,
|
||||
// TODO: use when synthetic events are needed
|
||||
_timestamp: u32,
|
||||
) {
|
||||
let sender = sender.clone_ref();
|
||||
let sender = sender.borrow();
|
||||
let string_or_empty = |v| String::from(
|
||||
util::c::as_str(v)
|
||||
.unwrap_or(Some(""))
|
||||
.unwrap_or("")
|
||||
);
|
||||
sender
|
||||
.send(Event::LayoutChoice(LayoutChoice {
|
||||
name: string_or_empty(&name),
|
||||
source: string_or_empty(&source).into(),
|
||||
}))
|
||||
.or_warn(&mut logging::Print, logging::Problem::Warning, "Can't send to state manager");
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,7 +151,7 @@ mod test {
|
||||
use super::*;
|
||||
use crate::animation;
|
||||
use crate::imservice::{ ContentHint, ContentPurpose };
|
||||
use crate::panel;
|
||||
use crate::main::PanelCommand;
|
||||
use crate::state::{ Application, InputMethod, InputMethodDetails, Presence, visibility };
|
||||
use crate::state::test::application_with_fake_output;
|
||||
|
||||
@ -176,13 +176,13 @@ mod test {
|
||||
|
||||
let l = State::new(state, now);
|
||||
let (l, commands) = handle_event(l, InputMethod::InactiveSince(now).into(), now);
|
||||
assert_matches!(commands.panel_visibility, Some(panel::Command::Show{..}));
|
||||
assert_matches!(commands.panel_visibility, Some(PanelCommand::Show{..}));
|
||||
assert_eq!(l.scheduled_wakeup, Some(now + animation::HIDING_TIMEOUT));
|
||||
|
||||
now += animation::HIDING_TIMEOUT;
|
||||
|
||||
let (l, commands) = handle_event(l, Event::TimeoutReached(now), now);
|
||||
assert_eq!(commands.panel_visibility, Some(panel::Command::Hide));
|
||||
assert_eq!(commands.panel_visibility, Some(PanelCommand::Hide));
|
||||
assert_eq!(l.scheduled_wakeup, None);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
#include "input-method-unstable-v2-client-protocol.h"
|
||||
#include "virtual-keyboard-unstable-v1-client-protocol.h"
|
||||
|
||||
#include "submission.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
struct imservice;
|
||||
|
||||
void imservice_handle_input_method_activate(void *data, struct zwp_input_method_v2 *input_method);
|
||||
|
||||
@ -226,7 +226,7 @@ bitflags!{
|
||||
/// use rs::imservice::ContentPurpose;
|
||||
/// assert_eq!(ContentPurpose::Alpha as u32, 1);
|
||||
/// ```
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum ContentPurpose {
|
||||
Normal = 0,
|
||||
Alpha = 1,
|
||||
|
||||
@ -7,8 +7,6 @@
|
||||
#include "eek/eek-gtk-keyboard.h"
|
||||
#include "eek/eek-renderer.h"
|
||||
#include "eek/eek-types.h"
|
||||
#include "src/main.h"
|
||||
#include "src/popover.h"
|
||||
#include "src/submission.h"
|
||||
#include "virtual-keyboard-unstable-v1-client-protocol.h"
|
||||
#include "text-input-unstable-v3-client-protocol.h"
|
||||
@ -42,8 +40,7 @@ void squeek_layout_release(struct squeek_layout *layout,
|
||||
struct submission *submission,
|
||||
struct transformation widget_to_layout,
|
||||
uint32_t timestamp,
|
||||
struct squeek_popover *popover,
|
||||
struct squeek_state_manager *state,
|
||||
EekboardContextService *manager,
|
||||
EekGtkKeyboard *ui_keyboard);
|
||||
void squeek_layout_release_all_only(struct squeek_layout *layout,
|
||||
struct submission *submission,
|
||||
@ -57,8 +54,7 @@ void squeek_layout_drag(struct squeek_layout *layout,
|
||||
struct submission *submission,
|
||||
double x_widget, double y_widget,
|
||||
struct transformation widget_to_layout,
|
||||
uint32_t timestamp, struct squeek_popover *popover,
|
||||
struct squeek_state_manager *state,
|
||||
uint32_t timestamp, EekboardContextService *manager,
|
||||
EekGtkKeyboard *ui_keyboard);
|
||||
void squeek_layout_draw_all_changed(struct squeek_layout *layout, EekRenderer* renderer, cairo_t *cr, struct submission *submission);
|
||||
void squeek_draw_layout_base_view(struct squeek_layout *layout, EekRenderer* renderer, cairo_t *cr);
|
||||
|
||||
155
src/layout.rs
155
src/layout.rs
@ -18,43 +18,36 @@
|
||||
*/
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::cmp;
|
||||
use std::collections::{ HashMap, HashSet };
|
||||
use std::ffi::CString;
|
||||
use std::fmt;
|
||||
use std::rc::Rc;
|
||||
use std::vec::Vec;
|
||||
|
||||
use crate::action::Action;
|
||||
use crate::actors;
|
||||
use crate::drawing;
|
||||
use crate::float_ord::FloatOrd;
|
||||
use crate::keyboard::KeyState;
|
||||
use crate::logging;
|
||||
use crate::popover;
|
||||
use crate::receiver;
|
||||
use crate::submission::{ Submission, SubmitData, Timestamp };
|
||||
use crate::util::find_max_double;
|
||||
use ::action::Action;
|
||||
use ::drawing;
|
||||
use ::keyboard::KeyState;
|
||||
use ::logging;
|
||||
use ::manager;
|
||||
use ::submission::{ Submission, SubmitData, Timestamp };
|
||||
use ::util::find_max_double;
|
||||
|
||||
use crate::imservice::ContentPurpose;
|
||||
use ::imservice::ContentPurpose;
|
||||
|
||||
// Traits
|
||||
use std::borrow::Borrow;
|
||||
use crate::logging::Warn;
|
||||
use ::logging::Warn;
|
||||
|
||||
/// Gathers stuff defined in C or called by C
|
||||
pub mod c {
|
||||
use super::*;
|
||||
|
||||
use crate::receiver;
|
||||
use crate::submission::c::Submission as CSubmission;
|
||||
|
||||
use gtk_sys;
|
||||
use std::ops::{ Add, Sub };
|
||||
use std::os::raw::c_void;
|
||||
|
||||
use crate::util::CloneOwned;
|
||||
|
||||
use crate::submission::c::Submission as CSubmission;
|
||||
|
||||
use std::ops::{ Add, Sub };
|
||||
|
||||
// The following defined in C
|
||||
#[repr(transparent)]
|
||||
#[derive(Copy, Clone)]
|
||||
@ -124,30 +117,28 @@ pub mod c {
|
||||
pub struct Transformation {
|
||||
pub origin_x: f64,
|
||||
pub origin_y: f64,
|
||||
pub scale_x: f64,
|
||||
pub scale_y: f64,
|
||||
pub scale: f64,
|
||||
}
|
||||
|
||||
impl Transformation {
|
||||
/// Applies the new transformation after this one
|
||||
pub fn chain(self, next: Transformation) -> Transformation {
|
||||
Transformation {
|
||||
origin_x: self.origin_x + self.scale_x * next.origin_x,
|
||||
origin_y: self.origin_y + self.scale_y * next.origin_y,
|
||||
scale_x: self.scale_x * next.scale_x,
|
||||
scale_y: self.scale_y * next.scale_y,
|
||||
origin_x: self.origin_x + self.scale * next.origin_x,
|
||||
origin_y: self.origin_y + self.scale * next.origin_y,
|
||||
scale: self.scale * next.scale,
|
||||
}
|
||||
}
|
||||
fn forward(&self, p: Point) -> Point {
|
||||
Point {
|
||||
x: (p.x - self.origin_x) / self.scale_x,
|
||||
y: (p.y - self.origin_y) / self.scale_y,
|
||||
x: (p.x - self.origin_x) / self.scale,
|
||||
y: (p.y - self.origin_y) / self.scale,
|
||||
}
|
||||
}
|
||||
fn reverse(&self, p: Point) -> Point {
|
||||
Point {
|
||||
x: p.x * self.scale_x + self.origin_x,
|
||||
y: p.y * self.scale_y + self.origin_y,
|
||||
x: p.x * self.scale + self.origin_x,
|
||||
y: p.y * self.scale + self.origin_y,
|
||||
}
|
||||
}
|
||||
pub fn reverse_bounds(&self, b: Bounds) -> Bounds {
|
||||
@ -220,17 +211,13 @@ pub mod c {
|
||||
submission: CSubmission,
|
||||
widget_to_layout: Transformation,
|
||||
time: u32,
|
||||
popover: actors::popover::c::Actor,
|
||||
app_state: receiver::c::State,
|
||||
manager: manager::c::Manager,
|
||||
ui_keyboard: EekGtkKeyboard,
|
||||
) {
|
||||
let time = Timestamp(time);
|
||||
let layout = unsafe { &mut *layout };
|
||||
let submission = submission.clone_ref();
|
||||
let mut submission = submission.borrow_mut();
|
||||
let app_state = app_state.clone_owned();
|
||||
let popover_state = popover.clone_owned();
|
||||
|
||||
let ui_backend = UIBackend {
|
||||
widget_to_layout,
|
||||
keyboard: ui_keyboard,
|
||||
@ -245,7 +232,7 @@ pub mod c {
|
||||
&mut submission,
|
||||
Some(&ui_backend),
|
||||
time,
|
||||
Some((&popover_state, app_state.clone())),
|
||||
Some(manager),
|
||||
key,
|
||||
);
|
||||
}
|
||||
@ -324,18 +311,13 @@ pub mod c {
|
||||
x_widget: f64, y_widget: f64,
|
||||
widget_to_layout: Transformation,
|
||||
time: u32,
|
||||
popover: actors::popover::c::Actor,
|
||||
app_state: receiver::c::State,
|
||||
manager: manager::c::Manager,
|
||||
ui_keyboard: EekGtkKeyboard,
|
||||
) {
|
||||
let time = Timestamp(time);
|
||||
let layout = unsafe { &mut *layout };
|
||||
let submission = submission.clone_ref();
|
||||
let mut submission = submission.borrow_mut();
|
||||
// We only need to query state here, not update.
|
||||
// A copy is enough.
|
||||
let popover_state = popover.clone_owned();
|
||||
let app_state = app_state.clone_owned();
|
||||
let ui_backend = UIBackend {
|
||||
widget_to_layout,
|
||||
keyboard: ui_keyboard,
|
||||
@ -366,7 +348,7 @@ pub mod c {
|
||||
&mut submission,
|
||||
Some(&ui_backend),
|
||||
time,
|
||||
Some((&popover_state, app_state.clone())),
|
||||
Some(manager),
|
||||
key,
|
||||
);
|
||||
}
|
||||
@ -391,7 +373,7 @@ pub mod c {
|
||||
&mut submission,
|
||||
Some(&ui_backend),
|
||||
time,
|
||||
Some((&popover_state, app_state.clone())),
|
||||
Some(manager),
|
||||
key,
|
||||
);
|
||||
}
|
||||
@ -412,8 +394,7 @@ pub mod c {
|
||||
let transform = Transformation {
|
||||
origin_x: 10f64,
|
||||
origin_y: 11f64,
|
||||
scale_x: 12f64,
|
||||
scale_y: 13f64,
|
||||
scale: 12f64,
|
||||
};
|
||||
let point = Point { x: 1f64, y: 1f64 };
|
||||
let transformed = transform.reverse(transform.forward(point.clone()));
|
||||
@ -774,20 +755,16 @@ impl Layout {
|
||||
let size = self.calculate_size();
|
||||
let h_scale = available.width / size.width;
|
||||
let v_scale = available.height / size.height;
|
||||
// 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 scale = if h_scale < v_scale { h_scale } else { v_scale };
|
||||
let outside_margins = c::Transformation {
|
||||
origin_x: (available.width - (scale_x * size.width)) / 2.0,
|
||||
origin_y: (available.height - (scale_y * size.height)) / 2.0,
|
||||
scale_x: scale_x,
|
||||
scale_y: scale_y,
|
||||
origin_x: (available.width - (scale * size.width)) / 2.0,
|
||||
origin_y: (available.height - (scale * size.height)) / 2.0,
|
||||
scale: scale,
|
||||
};
|
||||
outside_margins.chain(c::Transformation {
|
||||
origin_x: self.margins.left,
|
||||
origin_y: self.margins.top,
|
||||
scale_x: 1.0,
|
||||
scale_y: 1.0,
|
||||
scale: 1.0,
|
||||
})
|
||||
}
|
||||
|
||||
@ -1049,11 +1026,7 @@ mod seat {
|
||||
submission: &mut Submission,
|
||||
ui: Option<&UIBackend>,
|
||||
time: Timestamp,
|
||||
// TODO: intermediate measure:
|
||||
// passing state conditionally because it's only used for popover.
|
||||
// Eventually, it should be used for sumitting button events,
|
||||
// and passed always.
|
||||
manager: Option<(&actors::popover::State, receiver::State)>,
|
||||
manager: Option<manager::c::Manager>,
|
||||
rckey: &Rc<RefCell<KeyState>>,
|
||||
) {
|
||||
let key: KeyState = {
|
||||
@ -1088,7 +1061,7 @@ mod seat {
|
||||
// only show when UI is present
|
||||
Action::ShowPreferences => if let Some(ui) = &ui {
|
||||
// only show when layout manager is available
|
||||
if let Some((manager, app_state)) = manager {
|
||||
if let Some(manager) = manager {
|
||||
let view = layout.get_current_view();
|
||||
let places = ::layout::procedures::find_key_places(
|
||||
view, &rckey,
|
||||
@ -1103,11 +1076,10 @@ mod seat {
|
||||
width: button.size.width,
|
||||
height: button.size.height,
|
||||
};
|
||||
popover::show(
|
||||
::popover::show(
|
||||
ui.keyboard,
|
||||
ui.widget_to_layout.reverse_bounds(bounds),
|
||||
manager,
|
||||
app_state,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1499,63 +1471,8 @@ mod test {
|
||||
let transformation = layout.calculate_transformation(
|
||||
Size { width: 2.0, height: 2.0 }
|
||||
);
|
||||
assert_eq!(transformation.scale_x, 1.0);
|
||||
assert_eq!(transformation.scale_y, 1.0);
|
||||
assert_eq!(transformation.scale, 1.0);
|
||||
assert_eq!(transformation.origin_x, 0.5);
|
||||
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,8 +13,6 @@ extern crate gtk_sys;
|
||||
extern crate maplit;
|
||||
extern crate serde;
|
||||
extern crate xkbcommon;
|
||||
extern crate zbus;
|
||||
extern crate zvariant;
|
||||
|
||||
#[cfg(test)]
|
||||
#[macro_use]
|
||||
@ -23,10 +21,8 @@ mod assert_matches;
|
||||
mod logging;
|
||||
|
||||
mod action;
|
||||
mod actors;
|
||||
mod animation;
|
||||
pub mod data;
|
||||
mod debug;
|
||||
mod drawing;
|
||||
mod event_loop;
|
||||
pub mod float_ord;
|
||||
@ -35,10 +31,9 @@ mod keyboard;
|
||||
mod layout;
|
||||
mod locale;
|
||||
mod main;
|
||||
mod manager;
|
||||
mod outputs;
|
||||
mod panel;
|
||||
mod popover;
|
||||
mod receiver;
|
||||
mod resources;
|
||||
mod state;
|
||||
mod style;
|
||||
|
||||
@ -8,8 +8,6 @@
|
||||
|
||||
#include "eek/eek-types.h"
|
||||
#include "dbus.h"
|
||||
#include "panel.h"
|
||||
#include "src/popover.h"
|
||||
|
||||
|
||||
struct receiver;
|
||||
@ -24,10 +22,9 @@ struct rsobjects {
|
||||
struct squeek_state_manager *state_manager;
|
||||
struct submission *submission;
|
||||
struct squeek_wayland *wayland;
|
||||
struct squeek_popover *popover;
|
||||
};
|
||||
|
||||
void register_ui_loop_handler(struct receiver *receiver, struct panel_manager *panel, struct squeek_popover *popover, EekboardContextService *hint_manager, DBusHandler *dbus_handler);
|
||||
void register_ui_loop_handler(struct receiver *receiver, ServerContextService *ui, DBusHandler *dbus_handler);
|
||||
|
||||
struct rsobjects squeek_init(void);
|
||||
|
||||
@ -35,4 +32,3 @@ void squeek_state_send_force_visible(struct squeek_state_manager *state);
|
||||
void squeek_state_send_force_hidden(struct squeek_state_manager *state);
|
||||
|
||||
void squeek_state_send_keyboard_present(struct squeek_state_manager *state, uint32_t keyboard_present);
|
||||
void squeek_state_send_layout_set(struct squeek_state_manager *state, char *name, char *layout, uint32_t timestamp);
|
||||
|
||||
116
src/main.rs
116
src/main.rs
@ -3,11 +3,8 @@
|
||||
*/
|
||||
|
||||
/*! Glue for the main loop. */
|
||||
use crate::actors;
|
||||
use crate::animation;
|
||||
use crate::debug;
|
||||
use crate::data::loading;
|
||||
use crate::panel;
|
||||
use crate::outputs::OutputId;
|
||||
use crate::state;
|
||||
use glib::{Continue, MainContext, PRIORITY_DEFAULT, Receiver};
|
||||
|
||||
|
||||
@ -21,23 +18,20 @@ mod c {
|
||||
use crate::event_loop::driver;
|
||||
use crate::imservice::IMService;
|
||||
use crate::imservice::c::InputMethod;
|
||||
use crate::layout;
|
||||
use crate::outputs::Outputs;
|
||||
use crate::outputs::c::WlOutput;
|
||||
use crate::state;
|
||||
use crate::submission::Submission;
|
||||
use crate::util::c::Wrapped;
|
||||
use crate::vkeyboard::c::ZwpVirtualKeyboardV1;
|
||||
|
||||
/// ServerContextService*
|
||||
#[repr(transparent)]
|
||||
pub struct UIManager(*const c_void);
|
||||
|
||||
/// DbusHandler*
|
||||
#[repr(transparent)]
|
||||
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.
|
||||
#[repr(C)]
|
||||
@ -49,7 +43,6 @@ mod c {
|
||||
submission: Wrapped<Submission>,
|
||||
/// Not wrapped, because C needs to access this.
|
||||
wayland: *mut Wayland,
|
||||
popover: actors::popover::c::Actor,
|
||||
}
|
||||
|
||||
/// Corresponds to wayland.h::squeek_wayland.
|
||||
@ -82,8 +75,9 @@ mod c {
|
||||
extern "C" {
|
||||
#[allow(improper_ctypes)]
|
||||
fn init_wayland(wayland: *mut Wayland);
|
||||
#[allow(improper_ctypes)]
|
||||
fn eekboard_context_service_set_layout(service: HintManager, layout: *const layout::Layout, timestamp: u32);
|
||||
fn server_context_service_update_keyboard(service: *const UIManager, output: WlOutput, scaled_height: 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,
|
||||
// given that dbus handler is using glib.
|
||||
fn dbus_handler_set_visible(dbus: *const DBusHandler, visible: u8);
|
||||
@ -100,8 +94,6 @@ mod c {
|
||||
let now = Instant::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 mut wayland = Box::new(Wayland::new(outputs));
|
||||
let wayland_raw = &mut *wayland as *mut _;
|
||||
@ -121,7 +113,6 @@ mod c {
|
||||
state_manager: Wrapped::new(state_manager),
|
||||
receiver: Wrapped::new(receiver),
|
||||
wayland: Box::into_raw(wayland),
|
||||
popover: Wrapped::new(actors::popover::State::new()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,27 +121,18 @@ mod c {
|
||||
pub extern "C"
|
||||
fn register_ui_loop_handler(
|
||||
receiver: Wrapped<Receiver<Commands>>,
|
||||
panel_manager: panel::c::PanelManager,
|
||||
popover: actors::popover::c::Actor,
|
||||
hint_manager: HintManager,
|
||||
ui_manager: *const UIManager,
|
||||
dbus_handler: *const DBusHandler,
|
||||
) {
|
||||
let receiver = unsafe { receiver.unwrap() };
|
||||
let receiver = Rc::try_unwrap(receiver).expect("References still present");
|
||||
let receiver = receiver.into_inner();
|
||||
let panel_manager = Wrapped::new(panel::Manager::new(panel_manager));
|
||||
let ctx = MainContext::default();
|
||||
let _acqu = ctx.acquire();
|
||||
receiver.attach(
|
||||
Some(&ctx),
|
||||
move |msg| {
|
||||
main_loop_handle_message(
|
||||
msg,
|
||||
panel_manager.clone(),
|
||||
&popover,
|
||||
hint_manager,
|
||||
dbus_handler,
|
||||
);
|
||||
main_loop_handle_message(msg, ui_manager, dbus_handler);
|
||||
Continue(true)
|
||||
},
|
||||
);
|
||||
@ -164,51 +146,73 @@ mod c {
|
||||
/// and doesn't lend itself to testing other than integration.
|
||||
fn main_loop_handle_message(
|
||||
msg: Commands,
|
||||
panel_manager: Wrapped<panel::Manager>,
|
||||
popover: &actors::popover::c::Actor,
|
||||
hint_manager: HintManager,
|
||||
ui_manager: *const UIManager,
|
||||
dbus_handler: *const DBusHandler,
|
||||
) {
|
||||
if let Some(visibility) = msg.panel_visibility {
|
||||
panel::Manager::update(panel_manager, visibility);
|
||||
}
|
||||
match msg.panel_visibility {
|
||||
Some(PanelCommand::Show { output, height }) => unsafe {
|
||||
server_context_service_update_keyboard(ui_manager, output.0, height.as_scaled_ceiling());
|
||||
},
|
||||
Some(PanelCommand::Hide) => unsafe {
|
||||
server_context_service_real_hide_keyboard(ui_manager);
|
||||
},
|
||||
None => {},
|
||||
};
|
||||
|
||||
if let Some(visible) = msg.dbus_visible_set {
|
||||
if dbus_handler != std::ptr::null() {
|
||||
unsafe { dbus_handler_set_visible(dbus_handler, visible as u8) };
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(commands::SetLayout { description }) = msg.layout_selection {
|
||||
let animation::Contents {
|
||||
name,
|
||||
kind,
|
||||
overlay_name,
|
||||
purpose,
|
||||
} = description;
|
||||
actors::popover::set_overlay(popover, overlay_name.clone());
|
||||
let layout = loading::load_layout(name, kind, purpose, overlay_name);
|
||||
let layout = Box::into_raw(Box::new(layout));
|
||||
|
||||
if let Some(hints) = msg.layout_hint_set {
|
||||
unsafe {
|
||||
eekboard_context_service_set_layout(hint_manager, layout, 0);
|
||||
}
|
||||
server_context_service_set_hint_purpose(
|
||||
ui_manager,
|
||||
hints.hint.bits(),
|
||||
hints.purpose.clone() as u32,
|
||||
)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod commands {
|
||||
use crate::animation;
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct SetLayout {
|
||||
pub description: animation::Contents,
|
||||
/// 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, PartialEq, Debug)]
|
||||
pub enum PanelCommand {
|
||||
Show {
|
||||
output: OutputId,
|
||||
height: PixelSize,
|
||||
},
|
||||
Hide,
|
||||
}
|
||||
|
||||
/// The commands consumed by the main loop,
|
||||
/// to be sent out to external components.
|
||||
#[derive(Clone)]
|
||||
pub struct Commands {
|
||||
pub panel_visibility: Option<panel::Command>,
|
||||
pub panel_visibility: Option<PanelCommand>,
|
||||
pub layout_hint_set: Option<state::InputMethodDetails>,
|
||||
pub dbus_visible_set: Option<bool>,
|
||||
pub layout_selection: Option<commands::SetLayout>,
|
||||
}
|
||||
|
||||
33
src/manager.rs
Normal file
33
src/manager.rs
Normal file
@ -0,0 +1,33 @@
|
||||
/*! Procedures relating to the management of the switching of layouts */
|
||||
use ::util;
|
||||
|
||||
pub mod c {
|
||||
use std::os::raw::{c_char, c_void};
|
||||
|
||||
/// EekboardContextService*
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Manager(*const c_void);
|
||||
|
||||
extern "C" {
|
||||
pub fn eekboard_context_service_set_overlay(
|
||||
manager: Manager,
|
||||
name: *const c_char,
|
||||
);
|
||||
|
||||
pub fn eekboard_context_service_get_overlay(
|
||||
manager: Manager,
|
||||
) -> *const c_char;
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the overlay name.
|
||||
/// The result lifetime is "as long as the C copy lives"
|
||||
pub fn get_overlay(manager: c::Manager) -> Option<String> {
|
||||
let raw_str = unsafe {
|
||||
c::eekboard_context_service_get_overlay(manager)
|
||||
};
|
||||
// this string is generated from Rust, should never be invalid
|
||||
util::c::as_str(&raw_str).unwrap()
|
||||
.map(String::from)
|
||||
}
|
||||
@ -14,7 +14,6 @@ sources = [
|
||||
config_h,
|
||||
'dbus.c',
|
||||
'imservice.c',
|
||||
'panel.c',
|
||||
'popover.c',
|
||||
'server-context-service.c',
|
||||
'wayland.c',
|
||||
@ -25,22 +24,18 @@ sources = [
|
||||
'../eek/eek-renderer.c',
|
||||
'../eek/eek-types.c',
|
||||
'../eek/layersurface.c',
|
||||
dbus_src,
|
||||
'../eekboard/eekboard-context-service.c',
|
||||
# '../eekboard/eekboard-xklutil.c',
|
||||
squeekboard_resources,
|
||||
wl_proto_sources,
|
||||
]
|
||||
|
||||
generated_sources = declare_dependency(
|
||||
sources: [
|
||||
dbus_src,
|
||||
squeekboard_resources,
|
||||
wl_proto_sources,
|
||||
],
|
||||
)
|
||||
|
||||
cc = meson.get_compiler('c')
|
||||
|
||||
|
||||
deps = [
|
||||
generated_sources,
|
||||
# dependency('glib-2.0', version: '>=2.26.0'),
|
||||
dependency('gio-2.0', version: '>=2.26.0'),
|
||||
dependency('gio-unix-2.0'),
|
||||
dependency('gnome-desktop-3.0', version: '>=3.0'),
|
||||
@ -63,7 +58,7 @@ rslibs = custom_target(
|
||||
install: false,
|
||||
console: true,
|
||||
command: [cargo_build] + ['@OUTPUT@', '--lib'] + cargo_build_flags,
|
||||
depends: cargo_deps,
|
||||
depends: cargo_toml,
|
||||
)
|
||||
|
||||
build_rstests = custom_target(
|
||||
@ -78,7 +73,7 @@ build_rstests = custom_target(
|
||||
install: false,
|
||||
console: true,
|
||||
command: [cargo_script, 'test', '--no-run'] + cargo_build_flags,
|
||||
depends: [rslibs, cargo_deps], # no point building tests if the code itself fails
|
||||
depends: [rslibs, cargo_toml], # no point building tests if the code itself fails
|
||||
)
|
||||
|
||||
test(
|
||||
@ -88,7 +83,7 @@ test(
|
||||
env: ['SOURCE_DIR=' + meson.source_root()],
|
||||
# this is a whole Carg-based test suite, let it run for a while
|
||||
timeout: 900,
|
||||
depends: [build_rstests, cargo_deps],
|
||||
depends: [build_rstests, cargo_toml],
|
||||
)
|
||||
|
||||
libsqueekboard = static_library('libsqueekboard',
|
||||
@ -105,6 +100,8 @@ libsqueekboard = static_library('libsqueekboard',
|
||||
|
||||
squeekboard = executable('squeekboard',
|
||||
'server-main.c',
|
||||
wl_proto_sources,
|
||||
squeekboard_resources,
|
||||
link_with: libsqueekboard,
|
||||
include_directories: [include_directories('..'), include_directories('../eek')],
|
||||
dependencies: deps,
|
||||
|
||||
118
src/outputs.rs
118
src/outputs.rs
@ -4,11 +4,9 @@
|
||||
|
||||
/*! Managing Wayland outputs */
|
||||
|
||||
use std::ops;
|
||||
use std::vec::Vec;
|
||||
use crate::event_loop;
|
||||
use ::logging;
|
||||
use crate::util::DivCeil;
|
||||
|
||||
// traits
|
||||
use ::logging::Warn;
|
||||
@ -128,7 +126,7 @@ pub mod c {
|
||||
outputs: COutputs,
|
||||
wl_output: WlOutput,
|
||||
_x: i32, _y: i32,
|
||||
phys_width: i32, phys_height: i32,
|
||||
_phys_width: i32, _phys_height: i32,
|
||||
_subpixel: i32,
|
||||
_make: *const c_char, _model: *const c_char,
|
||||
transform: i32,
|
||||
@ -146,19 +144,7 @@ pub mod c {
|
||||
.find_output_mut(wl_output)
|
||||
.map(|o| &mut o.pending);
|
||||
match output_state {
|
||||
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,
|
||||
});
|
||||
},
|
||||
Some(state) => { state.transform = Some(transform) },
|
||||
None => log_print!(
|
||||
logging::Level::Warning,
|
||||
"Got geometry on unknown output",
|
||||
@ -300,51 +286,24 @@ pub mod c {
|
||||
// TODO: handle unregistration
|
||||
}
|
||||
|
||||
|
||||
/// Generic size
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct Size<Unit> {
|
||||
pub width: Unit,
|
||||
pub height: Unit,
|
||||
#[derive(Clone)]
|
||||
pub struct Size {
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
}
|
||||
|
||||
pub type PixelSize = Size<u32>;
|
||||
|
||||
/// wl_output mode
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct Mode {
|
||||
pub width: 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>>,
|
||||
width: i32,
|
||||
height: i32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct OutputState {
|
||||
pub current_mode: Option<Mode>,
|
||||
pub geometry: Option<Geometry>,
|
||||
pub transform: Option<c::Transform>,
|
||||
pub scale: i32,
|
||||
}
|
||||
|
||||
@ -358,56 +317,33 @@ impl OutputState {
|
||||
fn uninitialized() -> OutputState {
|
||||
OutputState {
|
||||
current_mode: None,
|
||||
geometry: None,
|
||||
transform: None,
|
||||
scale: 1,
|
||||
}
|
||||
}
|
||||
|
||||
fn transform_size<T>(
|
||||
width: T,
|
||||
height: T,
|
||||
transform: self::c::Transform,
|
||||
) -> Size<T> {
|
||||
pub fn get_pixel_size(&self) -> Option<Size> {
|
||||
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 {
|
||||
OutputState {
|
||||
current_mode: Some(Mode { width, height } ),
|
||||
geometry: Some(Geometry { transform, .. } ),
|
||||
transform: Some(transform),
|
||||
scale: _,
|
||||
} => Some(Self::transform_size(*width as u32, *height as u32, *transform)),
|
||||
OutputState {
|
||||
current_mode: Some(Mode { width, height } ),
|
||||
..
|
||||
} => Some(PixelSize { width: *width as u32, height: *height as u32 } ),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Return physical dimensions adjusted for current transform
|
||||
pub fn get_physical_size(&self) -> Option<Size<Option<Millimeter>>> {
|
||||
match self {
|
||||
OutputState {
|
||||
geometry: Some(Geometry { transform, phys_size } ),
|
||||
..
|
||||
} => Some(Self::transform_size(phys_size.width, phys_size.height, *transform)),
|
||||
} => Some(
|
||||
match transform {
|
||||
Transform::Normal
|
||||
| Transform::Rotated180
|
||||
| Transform::Flipped
|
||||
| Transform::FlippedRotated180 => Size {
|
||||
width: *width as u32,
|
||||
height: *height as u32,
|
||||
},
|
||||
_ => Size {
|
||||
width: *height as u32,
|
||||
height: *width as u32,
|
||||
},
|
||||
}
|
||||
),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
124
src/panel.c
124
src/panel.c
@ -1,124 +0,0 @@
|
||||
#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_hide (GTK_WIDGET (self->window));
|
||||
}
|
||||
}
|
||||
|
||||
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->state_manager, self->popover);
|
||||
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
if (!self->widget) {
|
||||
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_state_manager *state_manager, struct squeek_popover *popover)
|
||||
{
|
||||
struct panel_manager mgr = {
|
||||
.state = state,
|
||||
.submission = submission,
|
||||
.window = NULL,
|
||||
.widget = NULL,
|
||||
.current_output = NULL,
|
||||
.state_manager = state_manager,
|
||||
.popover = popover,
|
||||
};
|
||||
return mgr;
|
||||
}
|
||||
25
src/panel.h
25
src/panel.h
@ -1,25 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "eek/layersurface.h"
|
||||
#include "src/layout.h"
|
||||
#include "src/main.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 squeek_state_manager *state_manager; // shared reference
|
||||
struct squeek_popover *popover; // shared reference
|
||||
struct submission *submission; // unowned
|
||||
|
||||
// both memoized - doesn't have to be, but bugs happen:
|
||||
// https://gitlab.gnome.org/World/Phosh/squeekboard/-/issues/343
|
||||
PhoshLayerSurface *window;
|
||||
GtkWidget *widget;
|
||||
|
||||
// Those should be held in Rust
|
||||
struct wl_output *current_output;
|
||||
};
|
||||
|
||||
struct panel_manager panel_manager_new(EekboardContextService *state, struct submission *submission, struct squeek_state_manager *state_manager, struct squeek_popover *popover);
|
||||
247
src/panel.rs
247
src/panel.rs
@ -1,247 +0,0 @@
|
||||
/* 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 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});
|
||||
glib::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}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
#pragma once
|
||||
/// Popover state.
|
||||
/// Wrapped<actors::popover::State>
|
||||
struct squeek_popover;
|
||||
|
||||
@ -4,13 +4,11 @@ use gio;
|
||||
use gtk;
|
||||
use std::ffi::CString;
|
||||
use std::cmp::Ordering;
|
||||
use crate::actors;
|
||||
use crate::layout::c::{ Bounds, EekGtkKeyboard };
|
||||
use crate::locale::{ OwnedTranslation, compare_current_locale };
|
||||
use crate::logging;
|
||||
use crate::receiver;
|
||||
use crate::resources;
|
||||
use crate::state;
|
||||
use ::layout::c::{ Bounds, EekGtkKeyboard };
|
||||
use ::locale::{ OwnedTranslation, compare_current_locale };
|
||||
use ::logging;
|
||||
use ::manager;
|
||||
use ::resources;
|
||||
|
||||
// Traits
|
||||
use gio::prelude::ActionMapExt;
|
||||
@ -18,7 +16,7 @@ use gio::prelude::SettingsExt;
|
||||
use glib::translate::FromGlibPtrNone;
|
||||
use glib::variant::ToVariant;
|
||||
use gtk::prelude::*;
|
||||
use crate::logging::Warn;
|
||||
use ::logging::Warn;
|
||||
|
||||
mod c {
|
||||
use std::os::raw::c_char;
|
||||
@ -129,11 +127,9 @@ fn get_settings(schema_name: &str) -> Option<gio::Settings> {
|
||||
.map(|_sschema| gio::Settings::new(schema_name))
|
||||
}
|
||||
|
||||
fn set_layout(kind: &str, name: &str) {
|
||||
fn set_layout(kind: String, name: String) {
|
||||
let settings = get_settings("org.gnome.desktop.input-sources");
|
||||
if let Some(settings) = settings {
|
||||
let kind = String::from(kind);
|
||||
let name = String::from(name);
|
||||
#[cfg(feature = "glib_v0_14")]
|
||||
let inputs = settings.value("sources");
|
||||
#[cfg(not(feature = "glib_v0_14"))]
|
||||
@ -154,7 +150,7 @@ fn set_layout(kind: &str, name: &str) {
|
||||
|
||||
/// A reference to what the user wants to see
|
||||
#[derive(PartialEq, Clone, Debug)]
|
||||
pub enum LayoutId {
|
||||
enum LayoutId {
|
||||
/// Affects the layout in system settings
|
||||
System {
|
||||
kind: String,
|
||||
@ -174,23 +170,40 @@ impl LayoutId {
|
||||
}
|
||||
|
||||
fn set_visible_layout(
|
||||
layout_id: &LayoutId,
|
||||
manager: manager::c::Manager,
|
||||
layout_id: LayoutId,
|
||||
) {
|
||||
match layout_id {
|
||||
LayoutId::System { kind, name } => {
|
||||
unsafe {
|
||||
use std::ptr;
|
||||
manager::c::eekboard_context_service_set_overlay(
|
||||
manager,
|
||||
ptr::null(),
|
||||
);
|
||||
}
|
||||
set_layout(kind, name);
|
||||
}
|
||||
LayoutId::Local(name) => {
|
||||
let name = CString::new(name.as_str()).unwrap();
|
||||
let name_ptr = name.as_ptr();
|
||||
unsafe {
|
||||
manager::c::eekboard_context_service_set_overlay(
|
||||
manager,
|
||||
name_ptr,
|
||||
)
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
/// Takes into account first any overlays, then system layouts from the list
|
||||
fn get_current_layout(
|
||||
popover: &actors::popover::State,
|
||||
manager: manager::c::Manager,
|
||||
system_layouts: &Vec<LayoutId>,
|
||||
) -> Option<LayoutId> {
|
||||
match &popover.overlay {
|
||||
Some(name) => Some(LayoutId::Local(name.into())),
|
||||
match manager::get_overlay(manager) {
|
||||
Some(name) => Some(LayoutId::Local(name)),
|
||||
None => system_layouts.get(0).map(LayoutId::clone),
|
||||
}
|
||||
}
|
||||
@ -234,8 +247,7 @@ fn translate_layout_names(layouts: &Vec<LayoutId>) -> Vec<OwnedTranslation> {
|
||||
pub fn show(
|
||||
window: EekGtkKeyboard,
|
||||
position: Bounds,
|
||||
popover: &actors::popover::State,
|
||||
app_state: receiver::State,
|
||||
manager: manager::c::Manager,
|
||||
) {
|
||||
unsafe { gtk::set_initialized() };
|
||||
let window = unsafe { gtk::Widget::from_glib_none(window.0) };
|
||||
@ -315,7 +327,7 @@ pub fn show(
|
||||
|
||||
let action_group = gio::SimpleActionGroup::new();
|
||||
|
||||
if let Some(current_layout) = get_current_layout(popover, &system_layouts) {
|
||||
if let Some(current_layout) = get_current_layout(manager, &system_layouts) {
|
||||
let current_layout_name = all_layouts.iter()
|
||||
.find(
|
||||
|l| l.get_name() == current_layout.get_name()
|
||||
@ -344,13 +356,10 @@ pub fn show(
|
||||
.find(
|
||||
|choices| state == choices.get_name()
|
||||
).unwrap();
|
||||
app_state
|
||||
.send(state::Event::OverlayChanged(layout.clone()))
|
||||
.or_print(
|
||||
logging::Problem::Bug,
|
||||
&format!("Can't send to state"),
|
||||
);
|
||||
set_visible_layout(layout)
|
||||
set_visible_layout(
|
||||
manager,
|
||||
layout.clone(),
|
||||
)
|
||||
});
|
||||
},
|
||||
None => log_print!(
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
/*! Defines the application-wide message bus for updating state.*/
|
||||
|
||||
use crate::event_loop::driver::Threaded;
|
||||
|
||||
pub mod c {
|
||||
use super::*;
|
||||
use crate::util::c::Wrapped;
|
||||
pub type State = Wrapped<Threaded>;
|
||||
}
|
||||
|
||||
// The state receiver is an endpoint of a channel, so it's safely cloneable.
|
||||
// There's no need to keep it in a Rc.
|
||||
// The C version uses Wrapped with an underlying Rc,
|
||||
// because Wrapped is well-tested already.
|
||||
pub type State = Threaded;
|
||||
@ -52,13 +52,8 @@ static KEYBOARDS: &[(&'static str, &'static str)] = &[
|
||||
|
||||
("fr", include_str!("../data/keyboards/fr.yaml")),
|
||||
("fr_wide", include_str!("../data/keyboards/fr_wide.yaml")),
|
||||
("fr+bepo", include_str!("../data/keyboards/fr+bepo.yaml")),
|
||||
("fr+bepo_wide", include_str!("../data/keyboards/fr+bepo_wide.yaml")),
|
||||
|
||||
("ge", include_str!("../data/keyboards/ge.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")),
|
||||
|
||||
@ -110,8 +105,6 @@ static KEYBOARDS: &[(&'static str, &'static str)] = &[
|
||||
|
||||
("terminal/us", include_str!("../data/keyboards/terminal/us.yaml")),
|
||||
("terminal/us_wide", include_str!("../data/keyboards/terminal/us_wide.yaml")),
|
||||
("terminal/us+dvorak", include_str!("../data/keyboards/terminal/us+dvorak.yaml")),
|
||||
("terminal/us+dvorak_wide", include_str!("../data/keyboards/terminal/us+dvorak_wide.yaml")),
|
||||
|
||||
// Overlays
|
||||
("emoji/us", include_str!("../data/keyboards/emoji/us.yaml")),
|
||||
|
||||
@ -20,7 +20,14 @@
|
||||
#include <gtk/gtk.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 "wayland-client-protocol.h"
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
@ -30,13 +37,149 @@ enum {
|
||||
|
||||
struct _ServerContextService {
|
||||
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
|
||||
|
||||
PhoshLayerSurface *window;
|
||||
GtkWidget *widget; // nullable
|
||||
|
||||
struct wl_output *current_output;
|
||||
guint last_requested_height;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(ServerContextService, server_context_service, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
on_destroy (ServerContextService *self, GtkWidget *widget)
|
||||
{
|
||||
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.
|
||||
/// Height is in scaled units.
|
||||
void
|
||||
server_context_service_update_keyboard (ServerContextService *self, struct wl_output *output, uint32_t scaled_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 != scaled_height) {
|
||||
|
||||
//TODO: make sure that redrawing happens in the correct place (it doesn't now).
|
||||
phosh_layer_surface_set_size(self->window, 0, scaled_height);
|
||||
phosh_layer_surface_set_exclusive_zone(self->window, scaled_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, scaled_height);
|
||||
}
|
||||
if (!self->widget) {
|
||||
make_widget (self);
|
||||
}
|
||||
gtk_widget_show (GTK_WIDGET(self->window));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
server_context_service_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
@ -67,6 +210,17 @@ 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
|
||||
server_context_service_class_init (ServerContextServiceClass *klass)
|
||||
{
|
||||
@ -75,6 +229,7 @@ server_context_service_class_init (ServerContextServiceClass *klass)
|
||||
|
||||
gobject_class->set_property = server_context_service_set_property;
|
||||
gobject_class->get_property = server_context_service_get_property;
|
||||
gobject_class->dispose = server_context_service_dispose;
|
||||
|
||||
/**
|
||||
* ServerContextServie:keyboard:
|
||||
@ -95,29 +250,41 @@ server_context_service_class_init (ServerContextServiceClass *klass)
|
||||
static void
|
||||
server_context_service_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;
|
||||
|
||||
static void
|
||||
init (ServerContextService *self) {
|
||||
const char *schema_name = "org.gnome.desktop.a11y.applications";
|
||||
GSettingsSchemaSource *ssrc = g_settings_schema_source_get_default();
|
||||
g_autoptr(GSettingsSchema) schema = NULL;
|
||||
|
||||
if (!ssrc) {
|
||||
g_warning("No gsettings schemas installed.");
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
schema = g_settings_schema_source_lookup(ssrc, schema_name, TRUE);
|
||||
if (schema) {
|
||||
g_autoptr(GSettings) settings = g_settings_new (schema_name);
|
||||
g_settings_bind (settings, "screen-keyboard-enabled",
|
||||
holder, "enabled", G_SETTINGS_BIND_GET);
|
||||
self, "enabled", G_SETTINGS_BIND_GET);
|
||||
} else {
|
||||
g_warning("Gsettings schema %s is not installed on the system. "
|
||||
"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
|
||||
#define SERVER_CONTEXT_SERVICE_H 1
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "src/layout.h"
|
||||
#include "src/submission.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -28,8 +28,8 @@ G_BEGIN_DECLS
|
||||
/** Manages the lifecycle of the window displaying layouts. */
|
||||
G_DECLARE_FINAL_TYPE (ServerContextService, server_context_service, SERVER, CONTEXT_SERVICE, GObject)
|
||||
|
||||
ServerContextService *server_context_service_new(struct squeek_state_manager *state_manager);
|
||||
ServerContextService *server_context_service_new(EekboardContextService *self, struct submission *submission, struct squeek_layout_state *layout, struct squeek_state_manager *state_manager);
|
||||
enum squeek_arrangement_kind server_context_service_get_layout_type(ServerContextService *);
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* SERVER_CONTEXT_SERVICE_H */
|
||||
|
||||
|
||||
@ -31,7 +31,6 @@
|
||||
#include "layout.h"
|
||||
#include "main.h"
|
||||
#include "outputs.h"
|
||||
#include "panel.h"
|
||||
#include "submission.h"
|
||||
#include "server-context-service.h"
|
||||
#include "wayland.h"
|
||||
@ -52,10 +51,10 @@ typedef enum _SqueekboardDebugFlags {
|
||||
struct squeekboard {
|
||||
struct squeek_wayland wayland; // Just hooks.
|
||||
DBusHandler *dbus_handler; // Controls visibility of the OSK.
|
||||
EekboardContextService *settings_context; // Gsettings hooks for layouts.
|
||||
/// 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.
|
||||
EekboardContextService *settings_context; // Gsettings hooks.
|
||||
ServerContextService *ui_context; // mess, includes the entire UI
|
||||
/// Currently wanted layout. TODO: merge into state::Application
|
||||
struct squeek_layout_state layout_choice;
|
||||
};
|
||||
|
||||
|
||||
@ -398,7 +397,7 @@ main (int argc, char **argv)
|
||||
// Also initializes wayland
|
||||
struct rsobjects rsobjects = squeek_init();
|
||||
|
||||
instance.settings_context = eekboard_context_service_new(rsobjects.state_manager);
|
||||
instance.settings_context = eekboard_context_service_new(&instance.layout_choice);
|
||||
|
||||
// set up dbus
|
||||
|
||||
@ -436,22 +435,20 @@ main (int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
ServerContextService *setting_listener = server_context_service_new(
|
||||
rsobjects.state_manager);
|
||||
if (!setting_listener) {
|
||||
g_warning ("could not connect to gsettings");
|
||||
}
|
||||
|
||||
instance.settings_handler = setting_listener;
|
||||
|
||||
eekboard_context_service_set_submission(instance.settings_context, rsobjects.submission);
|
||||
|
||||
instance.panel_manager = panel_manager_new(instance.settings_context,
|
||||
rsobjects.submission,
|
||||
rsobjects.state_manager,
|
||||
rsobjects.popover);
|
||||
ServerContextService *ui_context = server_context_service_new(
|
||||
instance.settings_context,
|
||||
rsobjects.submission,
|
||||
&instance.layout_choice,
|
||||
rsobjects.state_manager);
|
||||
if (!ui_context) {
|
||||
g_error("Could not initialize GUI");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
register_ui_loop_handler(rsobjects.receiver, &instance.panel_manager, rsobjects.popover, instance.settings_context, instance.dbus_handler);
|
||||
instance.ui_context = ui_context;
|
||||
register_ui_loop_handler(rsobjects.receiver, instance.ui_context, instance.dbus_handler);
|
||||
|
||||
session_register();
|
||||
|
||||
|
||||
371
src/state.rs
371
src/state.rs
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2021,2022 Purism SPC
|
||||
/* Copyright (C) 2021 Purism SPC
|
||||
* SPDX-License-Identifier: GPL-3.0+
|
||||
*/
|
||||
|
||||
@ -6,74 +6,40 @@
|
||||
* It's driven by the loop defined in the loop module. */
|
||||
|
||||
use crate::animation;
|
||||
use crate::debug;
|
||||
use crate::imservice::{ ContentHint, ContentPurpose };
|
||||
use crate::layout::ArrangementKind;
|
||||
use crate::main;
|
||||
use crate::main::Commands;
|
||||
use crate::main::{ Commands, PanelCommand, PixelSize };
|
||||
use crate::outputs;
|
||||
use crate::outputs::{Millimeter, OutputId, OutputState};
|
||||
use crate::panel;
|
||||
use crate::panel::PixelSize;
|
||||
use crate::popover;
|
||||
use crate::util::Rational;
|
||||
use crate::outputs::{OutputId, OutputState};
|
||||
use std::cmp;
|
||||
use std::collections::HashMap;
|
||||
use std::time::Instant;
|
||||
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum Presence {
|
||||
Present,
|
||||
Missing,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone)]
|
||||
pub struct InputMethodDetails {
|
||||
pub hint: ContentHint,
|
||||
pub purpose: ContentPurpose,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone)]
|
||||
pub enum InputMethod {
|
||||
Active(InputMethodDetails),
|
||||
InactiveSince(Instant),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum LayoutSource {
|
||||
Xkb,
|
||||
Other(String),
|
||||
}
|
||||
|
||||
impl From<String> for LayoutSource {
|
||||
fn from(v: String) -> Self {
|
||||
if v.as_str() == "xkb" {
|
||||
LayoutSource::Xkb
|
||||
} else {
|
||||
LayoutSource::Other(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The user's preferred system layout
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct LayoutChoice {
|
||||
pub name: String,
|
||||
pub source: LayoutSource,
|
||||
}
|
||||
|
||||
/// Incoming events.
|
||||
/// This contains events that cause a change to the internal state.
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone)]
|
||||
pub enum Event {
|
||||
InputMethod(InputMethod),
|
||||
Visibility(visibility::Event),
|
||||
PhysicalKeyboard(Presence),
|
||||
Output(outputs::Event),
|
||||
LayoutChoice(LayoutChoice),
|
||||
OverlayChanged(popover::LayoutId),
|
||||
Debug(debug::Event),
|
||||
/// Event triggered because a moment in time passed.
|
||||
/// Use to animate state transitions.
|
||||
/// The value is the ideal arrival time.
|
||||
@ -93,7 +59,7 @@ impl From<outputs::Event> for Event {
|
||||
}
|
||||
|
||||
pub mod visibility {
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone)]
|
||||
pub enum Event {
|
||||
/// User requested the panel to show
|
||||
ForceVisible,
|
||||
@ -113,9 +79,9 @@ pub mod visibility {
|
||||
}
|
||||
|
||||
/// The outwardly visible state.
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone)]
|
||||
pub struct Outcome {
|
||||
pub panel: animation::Outcome,
|
||||
pub visibility: animation::Outcome,
|
||||
pub im: InputMethod,
|
||||
}
|
||||
|
||||
@ -126,40 +92,36 @@ impl Outcome {
|
||||
/// The receivers of the commands bear the burden
|
||||
/// of checking if the commands end up being no-ops.
|
||||
pub fn get_commands_to_reach(&self, new_state: &Self) -> Commands {
|
||||
// FIXME: handle switching outputs
|
||||
let (dbus_visible_set, panel_visibility) = match new_state.panel {
|
||||
animation::Outcome::Visible{output, height, ..}
|
||||
=> (Some(true), Some(panel::Command::Show{output, height})),
|
||||
animation::Outcome::Hidden => (Some(false), Some(panel::Command::Hide)),
|
||||
let layout_hint_set = match new_state {
|
||||
Outcome {
|
||||
visibility: animation::Outcome::Visible{..},
|
||||
im: InputMethod::Active(hints),
|
||||
} => Some(hints.clone()),
|
||||
|
||||
Outcome {
|
||||
visibility: animation::Outcome::Visible{..},
|
||||
im: InputMethod::InactiveSince(_),
|
||||
} => Some(InputMethodDetails {
|
||||
hint: ContentHint::NONE,
|
||||
purpose: ContentPurpose::Normal,
|
||||
}),
|
||||
|
||||
Outcome {
|
||||
visibility: animation::Outcome::Hidden,
|
||||
..
|
||||
} => None,
|
||||
};
|
||||
// FIXME: handle switching outputs
|
||||
let (dbus_visible_set, panel_visibility) = match new_state.visibility {
|
||||
animation::Outcome::Visible{output, height}
|
||||
=> (Some(true), Some(PanelCommand::Show{output, height})),
|
||||
animation::Outcome::Hidden => (Some(false), Some(PanelCommand::Hide)),
|
||||
};
|
||||
|
||||
// Compare the old and new states as not to flood with updates,
|
||||
// which may look up in the file system.
|
||||
use animation::Outcome::*;
|
||||
let layout_selection = match &new_state.panel {
|
||||
Visible{ contents: new_contents, ..} => {
|
||||
let same
|
||||
= if let Visible { contents, .. } = &self.panel {
|
||||
contents == new_contents
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
if !same {
|
||||
Some(main::commands::SetLayout {
|
||||
description: new_contents.clone()
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
},
|
||||
animation::Outcome::Hidden => None,
|
||||
};
|
||||
|
||||
Commands {
|
||||
panel_visibility,
|
||||
layout_hint_set,
|
||||
dbus_visible_set,
|
||||
layout_selection,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -175,12 +137,11 @@ impl Outcome {
|
||||
/// 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.
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone)]
|
||||
pub struct Application {
|
||||
pub im: InputMethod,
|
||||
pub visibility_override: visibility::State,
|
||||
pub physical_keyboard: Presence,
|
||||
pub debug_mode_enabled: bool,
|
||||
/// The output on which the panel should appear.
|
||||
/// This is stored as part of the state
|
||||
/// because it's not clear how to derive the output from the rest of the state.
|
||||
@ -188,13 +149,6 @@ pub struct Application {
|
||||
/// but not sure about being allowed on non-touch displays.
|
||||
pub preferred_output: Option<OutputId>,
|
||||
pub outputs: HashMap<OutputId, OutputState>,
|
||||
/// We presume that the system always has some preference,
|
||||
/// even though we receive the preference after init,
|
||||
/// and we might not receive one at all (gsettings missing).
|
||||
/// Then a default is used.
|
||||
pub layout_choice: LayoutChoice,
|
||||
/// Manual override of the system layout
|
||||
pub overlay_layout: Option<popover::LayoutId>,
|
||||
}
|
||||
|
||||
impl Application {
|
||||
@ -209,34 +163,13 @@ impl Application {
|
||||
im: InputMethod::InactiveSince(now),
|
||||
visibility_override: visibility::State::NotForced,
|
||||
physical_keyboard: Presence::Missing,
|
||||
debug_mode_enabled: false,
|
||||
preferred_output: None,
|
||||
outputs: Default::default(),
|
||||
layout_choice: LayoutChoice {
|
||||
name: String::from("us"),
|
||||
source: LayoutSource::Xkb,
|
||||
},
|
||||
overlay_layout: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apply_event(self, event: Event, now: Instant) -> Self {
|
||||
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
|
||||
},
|
||||
|
||||
pub fn apply_event(self, event: Event, _now: Instant) -> Self {
|
||||
match event {
|
||||
Event::TimeoutReached(_) => self,
|
||||
|
||||
Event::Visibility(visibility) => Self {
|
||||
@ -271,9 +204,8 @@ impl Application {
|
||||
app
|
||||
},
|
||||
|
||||
Event::InputMethod(new_im)
|
||||
=> match (self.im.clone(), new_im, self.visibility_override) {
|
||||
(InputMethod::Active(_old), InputMethod::Active(new_im), _)
|
||||
Event::InputMethod(new_im) => match (self.im.clone(), new_im) {
|
||||
(InputMethod::Active(_old), InputMethod::Active(new_im))
|
||||
=> Self {
|
||||
im: InputMethod::Active(new_im),
|
||||
..self
|
||||
@ -281,20 +213,13 @@ impl Application {
|
||||
// For changes in active state, remove user's visibility override.
|
||||
// Both cases spelled out explicitly, rather than by the wildcard,
|
||||
// to not lose the notion that it's the opposition that matters
|
||||
(InputMethod::InactiveSince(_old), InputMethod::Active(new_im), _)
|
||||
(InputMethod::InactiveSince(_old), InputMethod::Active(new_im))
|
||||
=> Self {
|
||||
im: InputMethod::Active(new_im),
|
||||
visibility_override: visibility::State::NotForced,
|
||||
..self
|
||||
},
|
||||
// Avoid triggering animation when old state was forced hidden
|
||||
(InputMethod::Active(_old), InputMethod::InactiveSince(_since), visibility::State::ForcedHidden)
|
||||
=> Self {
|
||||
im: InputMethod::InactiveSince(now - animation::HIDING_TIMEOUT * 2),
|
||||
visibility_override: visibility::State::NotForced,
|
||||
..self
|
||||
},
|
||||
(InputMethod::Active(_old), InputMethod::InactiveSince(since), _)
|
||||
(InputMethod::Active(_old), InputMethod::InactiveSince(since))
|
||||
=> Self {
|
||||
im: InputMethod::InactiveSince(since),
|
||||
visibility_override: visibility::State::NotForced,
|
||||
@ -302,159 +227,58 @@ impl Application {
|
||||
},
|
||||
// This is a weird case, there's no need to update an inactive state.
|
||||
// But it's not wrong, just superfluous.
|
||||
(InputMethod::InactiveSince(old), InputMethod::InactiveSince(_new), _)
|
||||
(InputMethod::InactiveSince(old), InputMethod::InactiveSince(_new))
|
||||
=> Self {
|
||||
// New is going to be newer than old, so it can be ignored.
|
||||
// It was already inactive at that moment.
|
||||
im: InputMethod::InactiveSince(old),
|
||||
..self
|
||||
},
|
||||
},
|
||||
|
||||
Event::LayoutChoice(layout_choice) => Self {
|
||||
layout_choice,
|
||||
overlay_layout: None,
|
||||
..self
|
||||
},
|
||||
|
||||
Event::OverlayChanged(overlay_layout) => Self {
|
||||
overlay_layout: Some(overlay_layout),
|
||||
..self
|
||||
},
|
||||
};
|
||||
|
||||
if state.debug_mode_enabled {
|
||||
println!(
|
||||
"State is now:
|
||||
{:#?}
|
||||
Outcome:
|
||||
{:#?}",
|
||||
state,
|
||||
state.get_outcome(now),
|
||||
);
|
||||
}
|
||||
}
|
||||
state
|
||||
}
|
||||
|
||||
fn get_preferred_height_and_arrangement(output: &OutputState)
|
||||
-> Option<(PixelSize, ArrangementKind)>
|
||||
{
|
||||
fn get_preferred_height(output: &OutputState) -> Option<PixelSize> {
|
||||
output.get_pixel_size()
|
||||
.map(|px_size| {
|
||||
// Assume isotropy.
|
||||
// Pixels/mm.
|
||||
let density = output.get_physical_size()
|
||||
.and_then(|size| size.width)
|
||||
.map(|width| Rational {
|
||||
numerator: px_size.width as i32,
|
||||
denominator: width.0 as u32,
|
||||
})
|
||||
// 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,
|
||||
};
|
||||
|
||||
// TODO: calculate based on selected layout
|
||||
const ROW_COUNT: u32 = 4;
|
||||
|
||||
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 (arrangement, height_as_widths) = {
|
||||
if abstract_width < 540 {(
|
||||
ArrangementKind::Base,
|
||||
Rational {
|
||||
numerator: 210,
|
||||
denominator: 360,
|
||||
},
|
||||
)} else {(
|
||||
ArrangementKind::Wide,
|
||||
Rational {
|
||||
numerator: 172,
|
||||
denominator: 540,
|
||||
let height = {
|
||||
if px_size.width > px_size.height {
|
||||
px_size.width / 5
|
||||
} else {
|
||||
let abstract_width
|
||||
= PixelSize {
|
||||
scale_factor: output.scale as u32,
|
||||
pixels: px_size.width,
|
||||
}
|
||||
.as_scaled_ceiling();
|
||||
if (abstract_width < 540) && (px_size.width > 0) {
|
||||
px_size.width * 7 / 12 // to match 360×210
|
||||
} else {
|
||||
// Here we switch to wide layout, less height needed
|
||||
px_size.width * 7 / 22
|
||||
}
|
||||
)}
|
||||
}
|
||||
};
|
||||
|
||||
let height
|
||||
= 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),
|
||||
},
|
||||
arrangement,
|
||||
)
|
||||
PixelSize {
|
||||
scale_factor: output.scale as u32,
|
||||
pixels: cmp::min(height, px_size.height / 2),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns layout name, overlay name
|
||||
fn get_layout_names(&self) -> (String, Option<String>) {
|
||||
(
|
||||
String::from(match &self.overlay_layout {
|
||||
Some(popover::LayoutId::System { name, .. }) => name,
|
||||
_ => &self.layout_choice.name,
|
||||
}),
|
||||
match &self.overlay_layout {
|
||||
Some(popover::LayoutId::Local(name)) => Some(name.clone()),
|
||||
_ => None,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_outcome(&self, now: Instant) -> Outcome {
|
||||
// FIXME: include physical keyboard presence
|
||||
Outcome {
|
||||
panel: match self.preferred_output {
|
||||
visibility: match self.preferred_output {
|
||||
None => animation::Outcome::Hidden,
|
||||
Some(output) => {
|
||||
let (height, arrangement) = Self::get_preferred_height_and_arrangement(self.outputs.get(&output).unwrap())
|
||||
.unwrap_or((
|
||||
PixelSize{pixels: 0, scale_factor: 1},
|
||||
ArrangementKind::Base,
|
||||
));
|
||||
let (layout_name, overlay) = self.get_layout_names();
|
||||
|
||||
// Hoping that this will get optimized out on branches not using `visible`.
|
||||
let height = Self::get_preferred_height(self.outputs.get(&output).unwrap())
|
||||
.unwrap_or(PixelSize{pixels: 0, scale_factor: 1});
|
||||
// TODO: Instead of setting size to 0 when the output is invalid,
|
||||
// simply go invisible.
|
||||
let visible = animation::Outcome::Visible{
|
||||
output,
|
||||
height,
|
||||
contents: animation::Contents {
|
||||
kind: arrangement,
|
||||
name: layout_name,
|
||||
overlay_name: overlay,
|
||||
purpose: match self.im {
|
||||
InputMethod::Active(InputMethodDetails { purpose, .. }) => purpose,
|
||||
InputMethod::InactiveSince(_) => ContentPurpose::Normal,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
let visible = animation::Outcome::Visible{ output, height };
|
||||
|
||||
match (self.physical_keyboard, self.visibility_override) {
|
||||
(_, visibility::State::ForcedHidden) => animation::Outcome::Hidden,
|
||||
(_, visibility::State::ForcedVisible) => visible,
|
||||
@ -517,7 +341,7 @@ pub mod test {
|
||||
id,
|
||||
OutputState {
|
||||
current_mode: None,
|
||||
geometry: None,
|
||||
transform: None,
|
||||
scale: 1,
|
||||
},
|
||||
);
|
||||
@ -545,7 +369,7 @@ pub mod test {
|
||||
for _i in 0..100 {
|
||||
now += Duration::from_millis(1);
|
||||
assert_matches!(
|
||||
state.get_outcome(now).panel,
|
||||
state.get_outcome(now).visibility,
|
||||
animation::Outcome::Visible{..},
|
||||
"Hidden when it should remain visible: {:?}",
|
||||
now.saturating_duration_since(start),
|
||||
@ -554,10 +378,7 @@ pub mod test {
|
||||
|
||||
let state = state.apply_event(Event::InputMethod(InputMethod::Active(imdetails_new())), now);
|
||||
|
||||
assert_matches!(
|
||||
state.get_outcome(now).panel,
|
||||
animation::Outcome::Visible{..}
|
||||
);
|
||||
assert_matches!(state.get_outcome(now).visibility, animation::Outcome::Visible{..});
|
||||
}
|
||||
|
||||
/// Make sure that hiding works when input method goes away
|
||||
@ -574,7 +395,7 @@ pub mod test {
|
||||
|
||||
let state = state.apply_event(Event::InputMethod(InputMethod::InactiveSince(now)), now);
|
||||
|
||||
while let animation::Outcome::Visible{..} = state.get_outcome(now).panel {
|
||||
while let animation::Outcome::Visible{..} = state.get_outcome(now).visibility {
|
||||
now += Duration::from_millis(1);
|
||||
assert!(
|
||||
now < start + Duration::from_millis(250),
|
||||
@ -604,7 +425,7 @@ pub mod test {
|
||||
let state = state.apply_event(Event::InputMethod(InputMethod::Active(imdetails_new())), now);
|
||||
let state = state.apply_event(Event::InputMethod(InputMethod::InactiveSince(now)), now);
|
||||
|
||||
while let animation::Outcome::Visible{..} = state.get_outcome(now).panel {
|
||||
while let animation::Outcome::Visible{..} = state.get_outcome(now).visibility {
|
||||
now += Duration::from_millis(1);
|
||||
assert!(
|
||||
now < start + Duration::from_millis(250),
|
||||
@ -617,7 +438,7 @@ pub mod test {
|
||||
for _i in 0..1000 {
|
||||
now += Duration::from_millis(1);
|
||||
assert_eq!(
|
||||
state.get_outcome(now).panel,
|
||||
state.get_outcome(now).visibility,
|
||||
animation::Outcome::Hidden,
|
||||
"Appeared unnecessarily: {:?}",
|
||||
now.saturating_duration_since(start),
|
||||
@ -639,7 +460,7 @@ pub mod test {
|
||||
|
||||
let state = state.apply_event(Event::Visibility(visibility::Event::ForceVisible), now);
|
||||
assert_matches!(
|
||||
state.get_outcome(now).panel,
|
||||
state.get_outcome(now).visibility,
|
||||
animation::Outcome::Visible{..},
|
||||
"Failed to show: {:?}",
|
||||
now.saturating_duration_since(start),
|
||||
@ -652,7 +473,7 @@ pub mod test {
|
||||
now += Duration::from_secs(1);
|
||||
|
||||
assert_eq!(
|
||||
state.get_outcome(now).panel,
|
||||
state.get_outcome(now).visibility,
|
||||
animation::Outcome::Hidden,
|
||||
"Failed to release forced visibility: {:?}",
|
||||
now.saturating_duration_since(start),
|
||||
@ -673,7 +494,7 @@ pub mod test {
|
||||
|
||||
let state = state.apply_event(Event::PhysicalKeyboard(Presence::Present), now);
|
||||
assert_eq!(
|
||||
state.get_outcome(now).panel,
|
||||
state.get_outcome(now).visibility,
|
||||
animation::Outcome::Hidden,
|
||||
"Failed to hide: {:?}",
|
||||
now.saturating_duration_since(start),
|
||||
@ -685,7 +506,7 @@ pub mod test {
|
||||
let state = state.apply_event(Event::InputMethod(InputMethod::Active(imdetails_new())), now);
|
||||
|
||||
assert_eq!(
|
||||
state.get_outcome(now).panel,
|
||||
state.get_outcome(now).visibility,
|
||||
animation::Outcome::Hidden,
|
||||
"Failed to remain hidden: {:?}",
|
||||
now.saturating_duration_since(start),
|
||||
@ -695,39 +516,11 @@ pub mod test {
|
||||
let state = state.apply_event(Event::PhysicalKeyboard(Presence::Missing), now);
|
||||
|
||||
assert_matches!(
|
||||
state.get_outcome(now).panel,
|
||||
state.get_outcome(now).visibility,
|
||||
animation::Outcome::Visible{..},
|
||||
"Failed to appear: {:?}",
|
||||
now.saturating_duration_since(start),
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn size_l5() {
|
||||
use crate::outputs::{Mode, Geometry, c, Size};
|
||||
assert_eq!(
|
||||
Application::get_preferred_height_and_arrangement(&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,
|
||||
},
|
||||
ArrangementKind::Base,
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
#ifndef __SUBMISSION_H
|
||||
#define __SUBMISSION_H
|
||||
|
||||
#include "inttypes.h"
|
||||
|
||||
#include "input-method-unstable-v2-client-protocol.h"
|
||||
#include "virtual-keyboard-unstable-v1-client-protocol.h"
|
||||
#include "eek/eek-types.h"
|
||||
#include "main.h"
|
||||
|
||||
struct squeek_layout;
|
||||
struct submission;
|
||||
|
||||
// Defined in Rust
|
||||
uint8_t submission_hint_available(struct submission *self);
|
||||
|
||||
49
src/util.rs
49
src/util.rs
@ -7,7 +7,6 @@ use ::float_ord::FloatOrd;
|
||||
use std::borrow::Borrow;
|
||||
use std::hash::{ Hash, Hasher };
|
||||
use std::iter::FromIterator;
|
||||
use std::ops::Mul;
|
||||
|
||||
pub mod c {
|
||||
use super::*;
|
||||
@ -158,54 +157,6 @@ pub fn find_max_double<T, I, F>(iterator: I, get: F)
|
||||
.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
|
||||
pub struct Pointer<T>(pub Rc<T>);
|
||||
|
||||
|
||||
@ -76,10 +76,7 @@ foreach layout : [
|
||||
'es+cat',
|
||||
'fi',
|
||||
'fr', 'fr_wide',
|
||||
'ge',
|
||||
'gr', 'gr_wide',
|
||||
'gr+polytonic',
|
||||
'fr+bepo', 'fr+bepo_wide',
|
||||
'gr',
|
||||
'il',
|
||||
'ir',
|
||||
'it',
|
||||
@ -100,8 +97,6 @@ foreach layout : [
|
||||
'terminal/fr_wide',
|
||||
'terminal/us',
|
||||
'terminal/us_wide',
|
||||
'terminal/us+dvorak',
|
||||
'terminal/us+dvorak_wide',
|
||||
|
||||
# Block: Not languages.
|
||||
'emoji/us',
|
||||
|
||||
@ -16,5 +16,5 @@ test_layout = custom_target('squeekboard-test-layout',
|
||||
+ cargo_build_flags,
|
||||
install: true,
|
||||
install_dir: bindir,
|
||||
depends: cargo_deps,
|
||||
depends: cargo_toml,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user