Compare commits

..

66 Commits

Author SHA1 Message Date
aee981d9c0 debian: Bump distribution 2019-10-08 10:59:00 +00:00
3bede84a2d Merge branch 'silence' into 'master'
logs: Silence missing file warnings

See merge request Librem5/squeekboard!199
2019-10-04 12:15:11 +00:00
e14d411150 logs: Silence missing file warnings 2019-10-03 12:59:26 +00:00
f91f000df1 Merge branch 'locklight' into 'master'
style: Add styling for locked buttons

See merge request Librem5/squeekboard!197
2019-10-03 12:52:28 +00:00
18f8443a9f Merge branch 'it' into 'master'
Italian keyboard

See merge request Librem5/squeekboard!196
2019-10-03 12:51:26 +00:00
746d842dd4 Merge branch 'patch-3' into 'master'
Update es.yaml

See merge request Librem5/squeekboard!195
2019-10-03 11:37:57 +00:00
185efb1c2a show_symbols replaced by show_eschars in eschars view and improved Catalan support 2019-10-02 20:36:54 +00:00
a31f9b5e04 layout: Register it 2019-10-02 18:39:44 +00:00
94aec87b5d Merge branch 'el_layout' into 'master'
layouts: Add Greek

See merge request Librem5/squeekboard!198
2019-10-02 18:02:12 +00:00
854a9bb22e layouts: Add Greek
Greek layout created by Antonis Tsolomitis
University of the Aegean, Department of Mathematics, atsol@aegean.gr
2019-10-02 17:56:16 +00:00
477a883885 style: Add styling for locked buttons 2019-10-02 16:32:13 +00:00
b3a63042cb Merge branch 'undefined' into 'master'
italian keyboard

See merge request Librem5/squeekboard!193
2019-10-02 13:49:08 +00:00
d53a683285 Update es.yaml 2019-10-01 20:50:57 +00:00
27a99e2973 italian keyboard 2019-10-01 17:51:58 +00:00
53c64010e8 Merge branch 'style' into 'master'
style: Rename button selectors

See merge request Librem5/squeekboard!192
2019-10-01 17:23:59 +00:00
7f704bcd61 style: Rename button selectors 2019-10-01 08:11:44 +00:00
1e08adb26b Merge branch 'fallbacks' into 'master'
layout: Fallback to builtin before switching layouts

See merge request Librem5/squeekboard!186
2019-09-29 16:29:47 +00:00
75bbb17881 Merge branch 'test_build' into 'master'
tests: Compile in advance

See merge request Librem5/squeekboard!189
2019-09-29 16:17:23 +00:00
58c8556058 Merge branch 'es' into 'master'
es layout: Add to resources and testing

See merge request Librem5/squeekboard!188
2019-09-29 15:56:30 +00:00
1c56de8698 Merge branch 'style' into 'master'
style: Avoid conflict with GTK widget names

Closes #119

See merge request Librem5/squeekboard!184
2019-09-29 15:01:32 +00:00
0eb0a6e8fd Merge branch 'drops' into 'master'
Drop more dead code

See merge request Librem5/squeekboard!185
2019-09-29 15:00:30 +00:00
9b5e0109a7 Merge branch 'style_better' into 'master'
Style better

See merge request Librem5/squeekboard!180
2019-09-29 14:28:42 +00:00
a1b811aada tests: Compile in advance
Cargo is always trying to compile things if they are not ready yet. It caused the first test to take a lot of time, and potentially time out.
2019-09-29 09:01:09 +00:00
1b424bd663 layout: Attempt to build xdg keymap at every load 2019-09-29 07:54:32 +00:00
938ba53a38 es layout: Add to resources and testing 2019-09-28 21:53:24 +00:00
1e609f4550 Merge branch 'patch-1' into 'master'
Spanish keyboard layout

See merge request Librem5/squeekboard!187
2019-09-28 21:51:50 +00:00
e33f591a1f layouts: Test fallback order 2019-09-28 21:37:51 +00:00
456af0f1ef Spanish keyboard layout 2019-09-28 21:27:04 +00:00
b6d25da7c2 layout: Fallback to builtin before switching layouts
When the user-provided layout was broken or missing, the loading would proceed with the fallback layout. It tries to load the builtin one first now.
2019-09-28 21:17:32 +00:00
288d2247da cleanup: Remove dead fullscreen mode 2019-09-28 18:29:58 +00:00
e5eb9f0fd3 cleanup: Drop unused header 2019-09-28 18:18:44 +00:00
908aa20036 cleanup: Drop unused EekboardContext 2019-09-28 18:17:26 +00:00
60f1ca1408 style: Avoid conflict with GTK widget names
GTK style provider loads the theme on top of the selected CSS file. To ignore the theme, element names must be different than the predefined ones.
2019-09-28 12:11:32 +00:00
5ef687a722 Merge branch 'deb' into 'master'
debian: Fix build-arch

Closes #120

See merge request Librem5/squeekboard!183
2019-09-27 19:13:17 +00:00
86ed9a7a01 Merge branch 'spacing' into 'master'
Unhardcode spacing

See merge request Librem5/squeekboard!176
2019-09-27 17:03:48 +00:00
4fee2fad01 debian: Fix build-arch
Some builds call the `build-arch` target instead of `build`. That causes the old `Cargo.lock` to be used.
2019-09-27 16:58:27 +00:00
35ba8ad81c Merge branch 'shel' into 'master'
cargo.sh fixes

Closes #118

See merge request Librem5/squeekboard!182
2019-09-27 15:18:10 +00:00
0985724b19 shellcheck: Pass cargo.sh 2019-09-27 13:47:49 +00:00
7aff7977fc build: Remove empty variable from cargo.sh 2019-09-27 13:47:04 +00:00
55bb263a12 build: Fix script path detection 2019-09-27 13:27:30 +00:00
32b85e75db Merge branch 'cargo.sh' into 'master'
Stop requiring Bash for cargo.sh

See merge request Librem5/squeekboard!181
2019-09-27 13:24:23 +00:00
3935375d1b Stop requiring Bash for cargo.sh
There aren't actually any Bashism's used and it works fine with Busybox
compatible shells
2019-09-27 10:21:07 +02:00
97dd2b1096 Merge branch 'corners' into 'master'
display: Remove unused corner_radius

See merge request Librem5/squeekboard!174
2019-09-26 21:16:43 +00:00
de7211d1a5 Merge branch 'drop_color' into 'master'
cleanup: Unused default backgrounds

See merge request Librem5/squeekboard!179
2019-09-26 20:58:49 +00:00
26380ab987 Merge branch 'style' into 'master'
Style: Change classes to paths

See merge request Librem5/squeekboard!178
2019-09-26 19:57:42 +00:00
f898b75b9d Merge branch 'drops' into 'master'
Drop dead drawing procedures

See merge request Librem5/squeekboard!177
2019-09-26 17:28:29 +00:00
e513cb9b54 style: Use outline name as CSS class 2019-09-26 13:28:31 +00:00
6fd7ab7405 rendering: Generalize outline rendering 2019-09-26 12:51:45 +00:00
15833323ae styling: Use same context for the entire rendering of a button 2019-09-26 12:51:39 +00:00
653462721b cleanup: Unused default backgrounds 2019-09-26 12:48:22 +00:00
2889e50507 style: Simplified layout styling
Layout background is styled in the same place as button background, and obtains the path "layout".
2019-09-26 11:10:25 +00:00
6b15f69e00 style: Use path instead of class for key 2019-09-26 11:08:38 +00:00
231982d7f7 Drop dead drawing procedures 2019-09-26 07:27:16 +00:00
3bea256ca5 Appease Debian's Rust version's borrow checker 2019-09-26 07:02:06 +00:00
4c0f23c5c1 layout: Unhardcode button and row spacing values
They are specified by each layout now
2019-09-25 19:01:38 +00:00
27d54fb38a Merge branch 'reduce-flickr' into 'master'
Don't hide keyboard right away

See merge request Librem5/squeekboard!175
2019-09-25 18:45:22 +00:00
3b6999f6ef Don't hide keyboard right away
instead keep it around for 200ms. This reduces flicker a lot since
the keyboard will not hide when switching through input fields in
e.g. contacts or chatty.
2019-09-25 20:38:27 +02:00
de43d67638 display: Remove unused corner_radius 2019-09-25 18:10:58 +00:00
2fca71aa53 Merge branch 'cargo' into 'master'
build: Simplified the calling of cargo.sh

See merge request Librem5/squeekboard!173
2019-09-25 15:44:55 +00:00
7870791fef Merge branch 'deps' into 'master'
deps: Accept only bugfix version changes

See merge request Librem5/squeekboard!172
2019-09-25 15:15:34 +00:00
83f9b580ef Merge branch 'sizes' into 'master'
layout: Improved UI layout looks

See merge request Librem5/squeekboard!167
2019-09-24 14:41:10 +00:00
54f9e61b6a style: Make pressed button 20% lighter 2019-09-24 11:28:29 +00:00
94b7ba1ccc layout: Improved UI layout looks 2019-09-24 11:28:29 +00:00
e7d30d933f build: Simplified the calling of cargo.sh 2019-09-24 11:27:01 +00:00
150fb3cf6a deps: Accept only bugfix version changes 2019-09-24 11:18:35 +00:00
169f33c67a Merge branch 'pre-release' into 'master'
Pre release

See merge request Librem5/squeekboard!171
2019-09-24 10:52:52 +00:00
37 changed files with 814 additions and 1431 deletions

6
Cargo.lock generated
View File

@ -2,7 +2,7 @@
# It is not intended for manual editing.
[[package]]
name = "bitflags"
version = "1.2.0"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -54,7 +54,7 @@ dependencies = [
name = "rs"
version = "0.1.0"
dependencies = [
"bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)",
@ -142,7 +142,7 @@ dependencies = [
]
[metadata]
"checksum bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a606a02debe2813760609f57a64a2ffd27d9fdf5b2f133eaca0b248dd92cdd2"
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
"checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e"
"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
"checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83"

View File

@ -3,11 +3,11 @@ name = "rs"
version = "0.1.0"
[dependencies]
bitflags = "1.0"
maplit = "1.0"
serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.8"
xkbcommon = { version = "0.4", features = ["wayland"] }
bitflags = "1.0.*"
maplit = "1.0.*"
serde = { version = "1.0.*", features = ["derive"] }
serde_yaml = "0.8.*"
xkbcommon = { version = "0.4.*", features = ["wayland"] }
[lib]
name = "rs"

View File

@ -42,7 +42,7 @@ Use the `cargo.sh` script for maintaining the Cargo part of the build. The scrip
```
cd build_dir
sh /source_path/cargo.sh /source_path '' test
sh /source_path/cargo.sh '' test
```
### Cargo dependencies
@ -53,6 +53,6 @@ Dependencies must be specified in `Cargo.toml` with 2 numbers: "major.minor". Si
```
cd build_dir
sh /source_path/cargo.sh /source_path '' update
sh /source_path/cargo.sh '' update
ninja test
```

19
cargo.sh Normal file → Executable file
View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/bin/sh
# This script manages Cargo operations
# while keeping the artifact directory within the build tree
@ -6,18 +6,19 @@
set -e
SOURCE_DIR="$1"
SCRIPT_PATH="$(realpath "$0")"
SOURCE_DIR="$(dirname "$SCRIPT_PATH")"
export CARGO_TARGET_DIR=`pwd`
if [ ! -z ${2} ]; then
OUT_PATH=`realpath "${2}"`
CARGO_TARGET_DIR="$(pwd)"
export CARGO_TARGET_DIR
if [ -n "${1}" ]; then
OUT_PATH="$(realpath "$1")"
fi
cd $SOURCE_DIR
cd "$SOURCE_DIR"
shift
shift
cargo $BUILD_ARG $@
cargo "$@"
if [ ! -z ${OUT_PATH} ]; then
if [ -n "${OUT_PATH}" ]; then
cp "${CARGO_TARGET_DIR}"/debug/librs.a "${OUT_PATH}"
fi

197
data/keyboards/el.yaml Normal file
View File

@ -0,0 +1,197 @@
# Greek layout created by Antonis Tsolomitis
# University of the Aegean, Department of Mathematics, atsol@aegean.gr
# Sep 2019
---
row_spacing: 11.33
button_spacing: 4.67
bounds: { x: 0, y: 6.33, width: 426, height: 250 }
outlines:
default:
bounds: { x: 0, y: 0, width: 32, height: 52 }
altline:
bounds: { x: 0, y: 0, width: 48.39024, height: 52 }
outline7:
bounds: { x: 0, y: 0, width: 88.97561, height: 52 }
spaceline:
bounds: { x: 0, y: 0, width: 150.5853, height: 52 }
views:
base:
- "; ς ε ρ τ υ θ ι ο π !"
- "α σ δ φ γ η ξ κ λ show_accented"
- "Shift_L ζ χ ψ ω β ν μ , BackSpace"
- "show_numbers preferences space . Return"
upper:
- ": EuroSign Ε Ρ Τ Υ Θ Ι Ο Π"
- "Α Σ Δ Φ Γ Η Ξ Κ Λ show_accented"
- "Shift_L Ζ Χ Ψ Ω Β Ν Μ · BackSpace"
- "show_numbers preferences space « » Return"
accented:
- "ά έ ή ί ό ύ ώ ϊ ϋ ΐ"
- "ΰ Ά Έ Ή Ί Ό Ύ Ώ Ϊ 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 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 Return"
buttons:
Shift_L:
action:
locking:
lock_view: "upper"
unlock_view: "base"
outline: "altline"
icon: "key-shift"
BackSpace:
outline: "altline"
icon: "edit-clear-symbolic"
preferences:
action: "show_prefs"
outline: "altline"
icon: "keyboard-mode-symbolic"
show_numbers:
action:
set_view: "numbers"
outline: "altline"
label: "123"
show_letters:
action:
set_view: "base"
outline: "altline"
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: "αι"
period:
outline: altline
label: "."
space:
outline: spaceline
label: " "
Return:
outline: outline7
icon: "key-enter"
aring:
label: "å"
Aring:
label: "Å"
oslash:
label: "ø"
Oslash:
label: "Ø"
ae:
label: "æ"
AE:
label: "Æ"
asterisk:
label: "*"
asciitilde:
label: "~"
quoteleft:
label: "`"
bar:
label: "|"
U00B7:
label: "·"
squareroot:
label: "√"
Greek_pi:
label: "π"
division:
label: "÷"
multiply:
label: "×"
paragraph:
label: "¶"
Greek_tau:
label: "τ"
copyright:
label: "©"
numbersign:
label: "#"
U00AE:
label: "®"
at:
label: "@"
dollar:
label: "$"
U00A3:
label: "£"
percent:
label: "%"
EuroSign:
label: "€"
ampersand:
label: "&"
U00A5:
label: "¥"
minus:
label: "-"
asciicircum:
label: "^"
underscore:
label: "_"
degree:
label: "°"
plus:
label: "+"
equal:
label: "="
parenleft:
label: "("
parenright:
label: ")"
braceleft:
label: "{"
braceright:
label: "}"
comma:
label: ","
backslash:
label: "\\"
slash:
label: "/"
quotedbl:
label: "\""
quoteright:
label: "'"
less:
label: "<"
greater:
label: ">"
colon:
label: ":"
semicolon:
label: ";"
exclam:
label: "!"
question:
label: "?"
bracketleft:
label: "["
bracketright:
label: "]"

96
data/keyboards/es.yaml Normal file
View File

@ -0,0 +1,96 @@
---
row_spacing: 11.33
button_spacing: 4.67
bounds: { x: 0, y: 1, width: 360, height: 198 }
outlines:
default:
bounds: { x: 0, y: 0, width: 30.67, height: 40.67 }
altline:
bounds: { x: 0, y: 0, width: 48, height: 40.67 }
wide:
bounds: { x: 0, y: 0, width: 57.33, height: 40.67 }
spaceline:
bounds: { x: 0, y: 0, width: 95.00, height: 40.67 }
special:
bounds: { x: 0, y: 0, width: 39.33, height: 40.67 }
views:
base:
- "q w e r t y u i o p"
- "a s d f g h j k l ñ"
- "Shift_L z x c v b n m BackSpace"
- "show_numbers show_eschars preferences space ? period Return"
upper:
- "Q W E R T Y U I O P"
- "A S D F G H J K L Ñ"
- "Shift_L Z X C V B N M BackSpace"
- "show_numbers show_eschars preferences space ¿ period Return"
numbers:
- "1 2 3 4 5 6 7 8 9 0"
- "@ # € % & - _ + ( )"
- "show_symbols , \" ' colon ; ! = BackSpace"
- "show_letters show_eschars preferences space ? period Return"
symbols:
- "~ ` | · √ π τ ÷ × ¶"
- "© ® £ $ ¥ ^ ° * { }"
- "show_numbers \\ / < > = [ ] BackSpace"
- "show_letters show_eschars preferences space ? period Return"
eschars:
- "á é í ó ú Á É Í Ó Ú"
- "à è ì ò ù À È Ì Ò Ù"
- "show_numbers ü ç ï Ü Ç Ï ¡ BackSpace"
- "show_letters show_eschars preferences space « » Return"
buttons:
Shift_L:
action:
locking:
lock_view: "upper"
unlock_view: "base"
outline: "altline"
icon: "key-shift"
BackSpace:
outline: "altline"
icon: "edit-clear-symbolic"
preferences:
action: "show_prefs"
outline: "default"
icon: "keyboard-mode-symbolic"
show_numbers:
action:
set_view: "numbers"
outline: "altline"
label: "123"
show_letters:
action:
set_view: "base"
outline: "altline"
label: "abc"
show_symbols:
action:
set_view: "symbols"
outline: "altline"
label: "*/="
show_eschars:
action:
locking:
lock_view: "eschars"
unlock_view: "base"
outline: "altline"
label: "áÁ"
period:
outline: "default"
label: "."
space:
outline: "spaceline"
label: " "
Return:
outline: "altline"
icon: "key-enter"
colon:
label: ":"
"\"":
keysym: "quotedbl"

98
data/keyboards/it.yaml Normal file
View File

@ -0,0 +1,98 @@
---
row_spacing: 11.33
button_spacing: 4.67
bounds: { x: 0, y: 1, width: 360, height: 198 }
outlines:
default:
bounds: { x: 0, y: 0, width: 30.67, height: 40.67 }
altline:
bounds: { x: 0, y: 0, width: 48, height: 40.67 }
wide:
bounds: { x: 0, y: 0, width: 57.33, height: 40.67 }
spaceline:
bounds: { x: 0, y: 0, width: 95.00, height: 40.67 }
special:
bounds: { x: 0, y: 0, width: 39.33, height: 40.67 }
views:
base:
- "q w e r t y u i o p"
- "a s d f g h j k l n"
- "Shift_L z x c v b n m BackSpace"
- "show_numbers show_eschar preferences space ? period Return"
upper:
- "Q W E R T Y U I O P"
- "A S D F G H J K L Ñ"
- "Shift_L Z X C V B N M BackSpace"
- "show_numbers show_eschar preferences space ? period Return"
numbers:
- "1 2 3 4 5 6 7 8 9 0"
- "@ # € % & - _ + ( )"
- "show_symbols , \" ' colon ; ! ? BackSpace"
- "show_letters show_eschar preferences space ? period Return"
symbols:
- "~ ` | · √ π τ ÷ × ¶"
- "© ® £ $ ¥ ^ ° * { }"
- "show_numbers_from_symbols \\ / < > = [ ] BackSpace"
- "show_letters show_eschar preferences space ? period Return"
eschar:
- "á é í ó ú Á É Í Ó Ú"
- "à è ì ò « » ù ! { }"
- "show_numbers_from_symbols \\ / < > = [ ] BackSpace"
- "show_letters show_symbols 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"
preferences:
action: "show_prefs"
outline: "default"
icon: "keyboard-mode-symbolic"
show_numbers:
action:
set_view: "numbers"
outline: "altline"
label: "123"
show_numbers_from_symbols:
action:
set_view: "numbers"
outline: "altline"
label: "123"
show_letters:
action:
set_view: "base"
outline: "altline"
label: "ABC"
show_symbols:
action:
set_view: "symbols"
outline: "altline"
label: "*/="
show_eschar:
action:
set_view: "eschar"
outline: "altline"
label: "àè"
period:
outline: "default"
label: "."
space:
outline: "spaceline"
label: " "
Return:
outline: "altline"
icon: "key-enter"
colon:
label: ":"
"\"":
keysym: "quotedbl"

View File

@ -1,18 +1,17 @@
---
bounds: { x: 0, y: 10, width: 426, height: 229 }
row_spacing: 11.33
button_spacing: 4.67
bounds: { x: 0, y: 6.33, width: 426, height: 250 }
outlines:
default:
corner_radius: 1
bounds: { x: 0, y: 0, width: 32, height: 52 }
altline:
corner_radius: 1
bounds: { x: 0, y: 0, width: 48.39024, height: 52 }
outline7:
corner_radius: 1
bounds: { x: 0, y: 0, width: 88.97561, height: 52 }
spaceline:
corner_radius: 1
bounds: { x: 0, y: 0, width: 150.5853, height: 52 }
views:

View File

@ -1,18 +1,17 @@
---
bounds: { x: 0, y: 10, width: 410, height: 229 }
row_spacing: 11.33
button_spacing: 4.67
bounds: { x: 0, y: 6.33, width: 410, height: 250 }
outlines:
default:
corner_radius: 1
bounds: { x: 0, y: 0, width: 37.46341, height: 52 }
altline:
corner_radius: 1
bounds: { x: 0, y: 0, width: 48.39024, height: 52 }
outline7:
corner_radius: 1
bounds: { x: 0, y: 0, width: 88.97561, height: 52 }
spaceline:
corner_radius: 1
bounds: { x: 0, y: 0, width: 120.5853, height: 52 }
views:

View File

@ -1,41 +1,42 @@
---
bounds: { x: 10, y: 10, width: 410, height: 229 }
row_spacing: 11.33
button_spacing: 4.67
bounds: { x: 0, y: 1, width: 360, height: 198 }
outlines:
default:
corner_radius: 1
bounds: { x: 0, y: 0, width: 37.46341, height: 52 }
bounds: { x: 0, y: 0, width: 30.67, height: 40.67 }
altline:
corner_radius: 1
bounds: { x: 0, y: 0, width: 48.39024, height: 52 }
outline7:
corner_radius: 1
bounds: { x: 0, y: 0, width: 88.97561, height: 52 }
bounds: { x: 0, y: 0, width: 48, height: 40.67 }
wide:
bounds: { x: 0, y: 0, width: 57.33, height: 40.67 }
spaceline:
corner_radius: 1
bounds: { x: 0, y: 0, width: 150.5853, height: 52 }
bounds: { x: 0, y: 0, width: 137.33, height: 40.67 }
special:
bounds: { x: 0, y: 0, width: 39.33, height: 40.67 }
views:
base:
- "q w e r t y u i o p"
- "a s d f g h j k l"
- "Shift_L z x c v b n m BackSpace"
- "show_numbers preferences space . Return"
- "show_numbers preferences space period Return"
upper:
- "Q W E R T Y U I O P"
- "A S D F G H J K L"
- "Shift_L Z X C V B N M BackSpace"
- "show_numbers preferences space . Return"
- "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 . Return"
- "show_letters preferences space period Return"
symbols:
- "~ ` | · √ π τ ÷ × ¶"
- "© ® £ € ¥ ^ ° * { }"
- "show_numbers \\ / < > = [ ] BackSpace"
- "show_letters preferences space . Return"
- "show_numbers_from_symbols \\ / < > = [ ] BackSpace"
- "show_letters preferences space period Return"
buttons:
Shift_L:
@ -50,9 +51,14 @@ buttons:
icon: "edit-clear-symbolic"
preferences:
action: "show_prefs"
outline: "altline"
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"
@ -60,20 +66,21 @@ buttons:
show_letters:
action:
set_view: "base"
outline: "altline"
outline: "wide"
label: "ABC"
show_symbols:
action:
set_view: "symbols"
outline: "altline"
label: "*/="
".":
outline: altline
period:
outline: "special"
label: "."
space:
outline: spaceline
outline: "spaceline"
label: " "
Return:
outline: outline7
outline: "wide"
icon: "key-enter"
colon:
label: ":"

View File

@ -1,21 +1,33 @@
.keyboard {
sq_view {
background-color: rgba(0, 0, 0, 255);
color: #ffffff;
font-family: cantarell, sans-serif;
}
.key {
sq_button {
color: #deddda;
background: #464448;
border-style: solid;
border-width: 1px;
border-color: #5e5c64;
border-radius: 2px;
border-radius: 3px;
}
.key:active {
background: #1c71d8;
border-color: #3584e4;
sq_button:active {
background: #545256;
border-color: #716e78;
}
sq_button.altline,
sq_button.special,
sq_button.wide {
background: #2b292f;
border-color: #3e3a44
}
sq_button.locked {
background: #ffffff;
color: #2b292f;
}
#Return {
@ -27,13 +39,3 @@
background: #1c71d8;
border-color: #3584e4;
}
#Shift_L {
background: #2b292f;
border-color: #3e3a44
}
#Shift_L:active {
background: #1c71d8;
border-color: #3584e4;
}

6
debian/changelog vendored
View File

@ -1,3 +1,9 @@
squeekboard (1.2.1) amber-phone; urgency=medium
* Use different distribution
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Tue, 08 Oct 2019 10:56:10 +0000
squeekboard (1.2.0) unstable; urgency=medium
* Use Cargo-based dependencies

2
debian/rules vendored
View File

@ -8,7 +8,7 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=+all
# The Debian version of linked-hash-map doesn't provide any hash,
# causing Cargo to refuse to build with a crates.io copy
build:
build-arch:
rm Cargo.lock
dh $@ --builddirectory=_build --buildsystem=meson

View File

@ -52,8 +52,6 @@ typedef struct _EekGtkKeyboardPrivate
{
EekRenderer *renderer;
LevelKeyboard *keyboard;
GtkCssProvider *css_provider;
GtkStyleContext *scontext;
GdkEventSequence *sequence; // unowned reference
} EekGtkKeyboardPrivate;
@ -98,7 +96,7 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
if (!priv->renderer) {
PangoContext *pcontext = gtk_widget_get_pango_context (self);
priv->renderer = eek_renderer_new (priv->keyboard, pcontext, priv->scontext);
priv->renderer = eek_renderer_new (priv->keyboard, pcontext);
eek_renderer_set_allocation_size (priv->renderer,
allocation.width,
@ -383,22 +381,7 @@ eek_gtk_keyboard_class_init (EekGtkKeyboardClass *klass)
static void
eek_gtk_keyboard_init (EekGtkKeyboard *self)
{
EekGtkKeyboardPrivate *priv = eek_gtk_keyboard_get_instance_private (self);
/* Create a default CSS provider and load a style sheet */
priv->css_provider = gtk_css_provider_new ();
gtk_css_provider_load_from_resource (priv->css_provider,
"/sm/puri/squeekboard/style.css");
/* Apply the style to the widget */
priv->scontext = gtk_widget_get_style_context (GTK_WIDGET(self));
gtk_style_context_add_class (priv->scontext, "keyboard");
gtk_style_context_add_provider (priv->scontext,
GTK_STYLE_PROVIDER(priv->css_provider),
GTK_STYLE_PROVIDER_PRIORITY_USER);
gtk_style_context_set_state (priv->scontext, GTK_STATE_FLAG_NORMAL);
}
{}
/**
* eek_gtk_keyboard_new:

View File

@ -1,217 +0,0 @@
/*
* Copyright (C) 2006 Sergey V. Udaltsov <svu@gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <math.h>
#include <pango/pangocairo.h>
#include "eek-types.h"
static gdouble
length (gdouble x, gdouble y)
{
return sqrt (x * x + y * y);
}
static gdouble
point_line_distance (gdouble ax, gdouble ay, gdouble nx, gdouble ny)
{
return ax * nx + ay * ny;
}
static void
normal_form (gdouble ax, gdouble ay,
gdouble bx, gdouble by,
gdouble * nx, gdouble * ny, gdouble * d)
{
gdouble l;
*nx = by - ay;
*ny = ax - bx;
l = length (*nx, *ny);
*nx /= l;
*ny /= l;
*d = point_line_distance (ax, ay, *nx, *ny);
}
static void
inverse (gdouble a, gdouble b, gdouble c, gdouble d,
gdouble * e, gdouble * f, gdouble * g, gdouble * h)
{
gdouble det;
det = a * d - b * c;
*e = d / det;
*f = -b / det;
*g = -c / det;
*h = a / det;
}
static void
multiply (gdouble a, gdouble b, gdouble c, gdouble d,
gdouble e, gdouble f, gdouble * x, gdouble * y)
{
*x = a * e + b * f;
*y = c * e + d * f;
}
static void
intersect (gdouble n1x, gdouble n1y, gdouble d1,
gdouble n2x, gdouble n2y, gdouble d2, gdouble * x, gdouble * y)
{
gdouble e, f, g, h;
inverse (n1x, n1y, n2x, n2y, &e, &f, &g, &h);
multiply (e, f, g, h, d1, d2, x, y);
}
/* draw an angle from the current point to b and then to c,
* with a rounded corner of the given radius.
*/
static void
rounded_corner (cairo_t * cr,
gdouble bx, gdouble by,
gdouble cx, gdouble cy, gdouble radius)
{
gdouble ax, ay;
gdouble n1x, n1y, d1;
gdouble n2x, n2y, d2;
gdouble pd1, pd2;
gdouble ix, iy;
gdouble dist1, dist2;
gdouble nx, ny, d;
gdouble a1x, a1y, c1x, c1y;
gdouble phi1, phi2;
cairo_get_current_point (cr, &ax, &ay);
#ifdef KBDRAW_DEBUG
printf (" current point: (%f, %f), radius %f:\n", ax, ay,
radius);
#endif
/* make sure radius is not too large */
dist1 = length (bx - ax, by - ay);
dist2 = length (cx - bx, cy - by);
radius = MIN (radius, MIN (dist1, dist2));
/* construct normal forms of the lines */
normal_form (ax, ay, bx, by, &n1x, &n1y, &d1);
normal_form (bx, by, cx, cy, &n2x, &n2y, &d2);
/* find which side of the line a,b the point c is on */
if (point_line_distance (cx, cy, n1x, n1y) < d1)
pd1 = d1 - radius;
else
pd1 = d1 + radius;
/* find which side of the line b,c the point a is on */
if (point_line_distance (ax, ay, n2x, n2y) < d2)
pd2 = d2 - radius;
else
pd2 = d2 + radius;
/* intersect the parallels to find the center of the arc */
intersect (n1x, n1y, pd1, n2x, n2y, pd2, &ix, &iy);
nx = (bx - ax) / dist1;
ny = (by - ay) / dist1;
d = point_line_distance (ix, iy, nx, ny);
/* a1 is the point on the line a-b where the arc starts */
intersect (n1x, n1y, d1, nx, ny, d, &a1x, &a1y);
nx = (cx - bx) / dist2;
ny = (cy - by) / dist2;
d = point_line_distance (ix, iy, nx, ny);
/* c1 is the point on the line b-c where the arc ends */
intersect (n2x, n2y, d2, nx, ny, d, &c1x, &c1y);
/* determine the first angle */
if (a1x - ix == 0)
phi1 = (a1y - iy > 0) ? M_PI_2 : 3 * M_PI_2;
else if (a1x - ix > 0)
phi1 = atan ((a1y - iy) / (a1x - ix));
else
phi1 = M_PI + atan ((a1y - iy) / (a1x - ix));
/* determine the second angle */
if (c1x - ix == 0)
phi2 = (c1y - iy > 0) ? M_PI_2 : 3 * M_PI_2;
else if (c1x - ix > 0)
phi2 = atan ((c1y - iy) / (c1x - ix));
else
phi2 = M_PI + atan ((c1y - iy) / (c1x - ix));
/* compute the difference between phi2 and phi1 mod 2pi */
d = phi2 - phi1;
while (d < 0)
d += 2 * M_PI;
while (d > 2 * M_PI)
d -= 2 * M_PI;
#ifdef KBDRAW_DEBUG
printf (" line 1 to: (%f, %f):\n", a1x, a1y);
#endif
if (!(isnan (a1x) || isnan (a1y)))
cairo_line_to (cr, a1x, a1y);
/* pick the short arc from phi1 to phi2 */
if (d < M_PI)
cairo_arc (cr, ix, iy, radius, phi1, phi2);
else
cairo_arc_negative (cr, ix, iy, radius, phi1, phi2);
#ifdef KBDRAW_DEBUG
printf (" line 2 to: (%f, %f):\n", cx, cy);
#endif
cairo_line_to (cr, cx, cy);
}
/* renamed from rounded_polygon, use EekPoint instead of GdkPoint not
to depend on GTK+, and exported */
void
_eek_rounded_polygon (cairo_t *cr,
gdouble radius,
EekPoint *points,
guint num_points)
{
cairo_move_to (cr,
(gdouble) (points[num_points - 1].x +
points[0].x) / 2,
(gdouble) (points[num_points - 1].y +
points[0].y) / 2);
for (guint i = 0; i < num_points; i++) {
guint j = (i + 1) % num_points;
rounded_corner (cr, (gdouble) points[i].x,
(gdouble) points[i].y,
(gdouble) (points[i].x + points[j].x) / 2,
(gdouble) (points[i].y + points[j].y) / 2,
radius);
}
cairo_close_path (cr);
}

View File

@ -29,7 +29,6 @@
enum {
PROP_0,
PROP_PCONTEXT,
PROP_STYLE_CONTEXT,
PROP_LAST
};
@ -38,11 +37,9 @@ typedef struct _EekRendererPrivate
LevelKeyboard *keyboard;
PangoContext *pcontext;
GtkCssProvider *css_provider;
GtkStyleContext *scontext;
GtkStyleContext *key_context;
GtkStyleContext *layout_context;
GtkStyleContext *button_context; // TODO: maybe move a copy to each button
EekColor default_foreground_color;
EekColor default_background_color;
gdouble border_width;
gdouble allocation_width;
@ -54,6 +51,7 @@ typedef struct _EekRendererPrivate
PangoFontDescription *ascii_font;
PangoFontDescription *font;
// TODO: Drop those or transform into general button surface caches
GHashTable *outline_surface_cache;
GHashTable *active_outline_surface_cache;
GHashTable *icons;
@ -63,15 +61,7 @@ typedef struct _EekRendererPrivate
G_DEFINE_TYPE_WITH_PRIVATE (EekRenderer, eek_renderer, G_TYPE_OBJECT)
static const EekColor DEFAULT_FOREGROUND_COLOR = {0.3, 0.3, 0.3, 1.0};
static const EekColor DEFAULT_BACKGROUND_COLOR = {1.0, 1.0, 1.0, 1.0};
/* eek-keyboard-drawing.c */
extern void _eek_rounded_polygon (cairo_t *cr,
gdouble radius,
EekPoint *points,
guint num_points);
static void eek_renderer_real_render_button_label (EekRenderer *self,
PangoLayout *layout,
const struct squeek_button *button);
@ -79,7 +69,7 @@ static void eek_renderer_real_render_button_label (EekRenderer *self,
static void invalidate (EekRenderer *renderer);
static void render_button (EekRenderer *self,
cairo_t *cr, struct button_place *place,
gboolean active);
gboolean pressed, gboolean locked);
struct _CreateKeyboardSurfaceCallbackData {
cairo_t *cr;
@ -109,7 +99,7 @@ create_keyboard_surface_button_callback (struct squeek_button *button,
.row = data->row,
.button = button,
};
render_button (data->renderer, data->cr, &place, FALSE);
render_button (data->renderer, data->cr, &place, FALSE, FALSE);
cairo_restore (data->cr);
}
@ -140,7 +130,7 @@ render_keyboard_surface (EekRenderer *renderer, struct squeek_view *view)
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
EekColor foreground;
eek_renderer_get_foreground_color (renderer, priv->scontext, &foreground);
eek_renderer_get_foreground_color (renderer, priv->layout_context, &foreground);
EekBounds bounds = squeek_view_get_bounds (level_keyboard_current(priv->keyboard));
@ -151,11 +141,11 @@ render_keyboard_surface (EekRenderer *renderer, struct squeek_view *view)
};
/* Paint the background covering the entire widget area */
gtk_render_background (priv->scontext,
gtk_render_background (priv->layout_context,
data.cr,
0, 0,
priv->allocation_width, priv->allocation_height);
gtk_render_frame (priv->scontext,
gtk_render_frame (priv->layout_context,
data.cr,
0, 0,
priv->allocation_width, priv->allocation_height);
@ -180,49 +170,25 @@ render_keyboard_surface (EekRenderer *renderer, struct squeek_view *view)
}
static void
render_button_outline (EekRenderer *renderer,
cairo_t *cr,
const struct squeek_button *button,
gboolean active)
render_outline (cairo_t *cr,
GtkStyleContext *ctx,
EekBounds bounds)
{
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
EekBounds bounds = squeek_button_get_bounds(button);
/* Set the name of the button on the widget path, using the name obtained
from the button's symbol. */
g_autoptr (GtkWidgetPath) path = NULL;
path = gtk_widget_path_copy (gtk_style_context_get_path (priv->key_context));
const char *name = squeek_button_get_name(button);
gtk_widget_path_iter_set_name (path, -1, name);
/* Update the style context with the updated widget path. */
gtk_style_context_set_path (priv->key_context, path);
/* Set the state to take into account whether the button is active
(pressed) or normal. */
gtk_style_context_set_state(priv->key_context,
active ? GTK_STATE_FLAG_ACTIVE : GTK_STATE_FLAG_NORMAL);
gtk_render_background (priv->key_context,
cr, 0, 0, bounds.width, bounds.height);
gtk_render_frame (priv->key_context,
cr, 0, 0, bounds.width, bounds.height);
gtk_style_context_set_state(priv->key_context, GTK_STATE_FLAG_NORMAL);
gtk_render_background (ctx, cr, 0, 0, bounds.width, bounds.height);
gtk_render_frame (ctx, cr, 0, 0, bounds.width, bounds.height);
}
static void
render_button (EekRenderer *self,
static void render_button_in_context(EekRenderer *self,
cairo_t *cr,
GtkStyleContext *ctx,
struct button_place *place,
gboolean active)
{
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
gboolean active) {
cairo_surface_t *outline_surface;
GHashTable *outline_surface_cache;
PangoLayout *layout;
PangoRectangle extents = { 0, };
EekColor foreground;
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
/* render outline */
EekBounds bounds = squeek_button_get_bounds(place->button);
@ -233,6 +199,7 @@ render_button (EekRenderer *self,
outline_surface_cache = priv->outline_surface_cache;
outline_surface = g_hash_table_lookup (outline_surface_cache, place->button);
if (!outline_surface) {
cairo_t *cr;
@ -250,7 +217,7 @@ render_button (EekRenderer *self,
cairo_save (cr);
eek_renderer_apply_transformation_for_button (self, cr, place, 1.0, FALSE);
render_button_outline (self, cr, place->button, active);
render_outline (cr, ctx, bounds);
cairo_restore (cr);
cairo_destroy (cr);
@ -259,11 +226,10 @@ render_button (EekRenderer *self,
(gpointer)place->button,
outline_surface);
}
cairo_set_source_surface (cr, outline_surface, 0.0, 0.0);
cairo_paint (cr);
eek_renderer_get_foreground_color (self, priv->key_context, &foreground);
eek_renderer_get_foreground_color (self, ctx, &foreground);
/* render icon (if any) */
const char *icon_name = squeek_button_get_icon_name(place->button);
@ -294,7 +260,6 @@ render_button (EekRenderer *self,
return;
}
}
/* render label */
layout = pango_cairo_create_layout (cr);
eek_renderer_real_render_button_label (self, layout, place->button);
@ -311,10 +276,49 @@ render_button (EekRenderer *self,
foreground.green,
foreground.blue,
foreground.alpha);
pango_cairo_show_layout (cr, layout);
cairo_restore (cr);
g_object_unref (layout);
}
static void
render_button (EekRenderer *self,
cairo_t *cr,
struct button_place *place,
gboolean pressed,
gboolean locked)
{
EekRendererPrivate *priv = eek_renderer_get_instance_private (self);
GtkStyleContext *ctx = priv->button_context;
/* Set the name of the button on the widget path, using the name obtained
from the button's symbol. */
g_autoptr (GtkWidgetPath) path = NULL;
path = gtk_widget_path_copy (gtk_style_context_get_path (ctx));
const char *name = squeek_button_get_name(place->button);
gtk_widget_path_iter_set_name (path, -1, name);
/* Update the style context with the updated widget path. */
gtk_style_context_set_path (ctx, path);
/* Set the state to take into account whether the button is active
(pressed) or normal. */
gtk_style_context_set_state(ctx,
pressed ? GTK_STATE_FLAG_ACTIVE : GTK_STATE_FLAG_NORMAL);
const char *outline_name = squeek_button_get_outline_name(place->button);
if (locked) {
gtk_style_context_add_class(ctx, "locked");
}
gtk_style_context_add_class(ctx, outline_name);
render_button_in_context(self, cr, ctx, place, pressed);
// Save and restore functions don't work if gtk_render_* was used in between
gtk_style_context_set_state(ctx, GTK_STATE_FLAG_NORMAL);
gtk_style_context_remove_class(ctx, outline_name);
if (locked) {
gtk_style_context_remove_class(ctx, "locked");
}
}
/**
@ -445,7 +449,8 @@ eek_renderer_real_render_button (EekRenderer *self,
struct squeek_key *key = squeek_button_get_key(place->button);
render_button (
self, cr, place,
squeek_key_is_pressed(key) || squeek_key_is_locked (key)
squeek_key_is_pressed(key),
squeek_key_is_locked (key)
);
cairo_restore (cr);
}
@ -496,10 +501,6 @@ eek_renderer_set_property (GObject *object,
priv->pcontext = g_value_get_object (value);
g_object_ref (priv->pcontext);
break;
case PROP_STYLE_CONTEXT:
priv->scontext = g_value_get_object (value);
g_object_ref (priv->scontext);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -576,15 +577,33 @@ eek_renderer_class_init (EekRendererClass *klass)
g_object_class_install_property (gobject_class,
PROP_PCONTEXT,
pspec);
}
pspec = g_param_spec_object ("style-context",
"GTK Style Context",
"GTK Style Context",
GTK_TYPE_STYLE_CONTEXT,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE);
g_object_class_install_property (gobject_class,
PROP_STYLE_CONTEXT,
pspec);
static GType new_type(char *name) {
GTypeInfo info = {0};
info.class_size = sizeof(GtkWidgetClass);
info.instance_size = sizeof(GtkWidget);
return g_type_register_static(GTK_TYPE_WIDGET, name, &info,
G_TYPE_FLAG_ABSTRACT
);
}
static GType layout_type() {
static GType type = 0;
if (!type) {
type = new_type("sq_view");
}
return type;
}
static GType button_type() {
static GType type = 0;
if (!type) {
type = new_type("sq_button");
}
return type;
}
static void
@ -594,8 +613,6 @@ eek_renderer_init (EekRenderer *self)
priv->keyboard = NULL;
priv->pcontext = NULL;
priv->default_foreground_color = DEFAULT_FOREGROUND_COLOR;
priv->default_background_color = DEFAULT_BACKGROUND_COLOR;
priv->border_width = 1.0;
priv->allocation_width = 0.0;
priv->allocation_height = 0.0;
@ -627,18 +644,30 @@ eek_renderer_init (EekRenderer *self)
gtk_css_provider_load_from_resource (priv->css_provider,
"/sm/puri/squeekboard/style.css");
/* Create a style context for keys */
priv->key_context = gtk_style_context_new ();
gtk_style_context_add_class (priv->key_context, "key");
gtk_style_context_add_provider (priv->key_context,
/* Create a style context for the layout */
GtkWidgetPath *path = gtk_widget_path_new();
gtk_widget_path_append_type(path, layout_type());
priv->layout_context = gtk_style_context_new();
gtk_style_context_set_path(priv->layout_context, path);
gtk_widget_path_unref(path);
gtk_style_context_add_provider (priv->layout_context,
GTK_STYLE_PROVIDER(priv->css_provider),
GTK_STYLE_PROVIDER_PRIORITY_USER);
g_autoptr (GtkWidgetPath) path = NULL;
/* Create a style context for the buttons */
path = gtk_widget_path_new();
gtk_widget_path_append_type (path, GTK_TYPE_BUTTON);
gtk_style_context_set_path (priv->key_context, path);
gtk_style_context_set_state (priv->key_context, GTK_STATE_FLAG_NORMAL);
gtk_widget_path_append_type(path, layout_type());
gtk_widget_path_append_type(path, button_type());
priv->button_context = gtk_style_context_new ();
gtk_style_context_set_path(priv->button_context, path);
gtk_widget_path_unref(path);
gtk_style_context_set_parent(priv->button_context, priv->layout_context);
gtk_style_context_set_state (priv->button_context, GTK_STATE_FLAG_NORMAL);
gtk_style_context_add_provider (priv->button_context,
GTK_STYLE_PROVIDER(priv->css_provider),
GTK_STYLE_PROVIDER_PRIORITY_USER);
}
static void
@ -660,12 +689,10 @@ invalidate (EekRenderer *renderer)
EekRenderer *
eek_renderer_new (LevelKeyboard *keyboard,
PangoContext *pcontext,
GtkStyleContext *scontext)
PangoContext *pcontext)
{
EekRenderer *renderer = g_object_new (EEK_TYPE_RENDERER,
"pango-context", pcontext,
"style-context", scontext,
NULL);
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
priv->keyboard = keyboard;
@ -759,7 +786,7 @@ eek_renderer_get_button_bounds (EekRenderer *renderer,
min = points[2];
max = points[0];
for (uint i = 0; i < G_N_ELEMENTS(points); i++) {
for (unsigned i = 0; i < G_N_ELEMENTS(points); i++) {
eek_point_rotate (&points[i], angle);
if (points[i].x < min.x)
min.x = points[i].x;
@ -862,30 +889,6 @@ eek_renderer_render_keyboard (EekRenderer *renderer,
EEK_RENDERER_GET_CLASS(renderer)->render_keyboard (renderer, cr);
}
void
eek_renderer_set_default_foreground_color (EekRenderer *renderer,
const EekColor *color)
{
g_return_if_fail (EEK_IS_RENDERER(renderer));
g_return_if_fail (color);
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
memcpy (&priv->default_foreground_color, color, sizeof(EekColor));
}
void
eek_renderer_set_default_background_color (EekRenderer *renderer,
const EekColor *color)
{
g_return_if_fail (EEK_IS_RENDERER(renderer));
g_return_if_fail (color);
EekRendererPrivate *priv = eek_renderer_get_instance_private (renderer);
memcpy (&priv->default_background_color, color, sizeof(EekColor));
}
void
eek_renderer_get_foreground_color (EekRenderer *renderer,
GtkStyleContext *context,
@ -927,7 +930,7 @@ eek_are_bounds_inside (EekBounds bounds, EekPoint point, EekPoint origin, int32_
points[3].x = points[0].x;
points[3].y = points[2].y;
for (uint i = 0; i < G_N_ELEMENTS(points); i++) {
for (unsigned i = 0; i < G_N_ELEMENTS(points); i++) {
eek_point_rotate (&points[i], angle);
points[i].x += origin.x;
points[i].y += origin.y;

View File

@ -57,8 +57,7 @@ struct _EekRendererClass
GType eek_renderer_get_type (void) G_GNUC_CONST;
EekRenderer *eek_renderer_new (LevelKeyboard *keyboard,
PangoContext *pcontext,
GtkStyleContext *scontext);
PangoContext *pcontext);
void eek_renderer_set_allocation_size
(EekRenderer *renderer,
gdouble width,

View File

@ -51,7 +51,6 @@ enum {
PROP_0, // Magic: without this, keyboard is not useable in g_object_notify
PROP_KEYBOARD,
PROP_VISIBLE,
PROP_FULLSCREEN,
PROP_LAST
};
@ -70,7 +69,6 @@ static guint signals[LAST_SIGNAL] = { 0, };
struct _EekboardContextServicePrivate {
gboolean enabled;
gboolean visible;
gboolean fullscreen;
LevelKeyboard *keyboard; // currently used keyboard
GHashTable *keyboard_hash; // a table of available keyboards, per layout
@ -170,9 +168,6 @@ eekboard_context_service_set_property (GObject *object,
case PROP_VISIBLE:
context->priv->visible = g_value_get_boolean (value);
break;
case PROP_FULLSCREEN:
context->priv->fullscreen = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -194,9 +189,6 @@ eekboard_context_service_get_property (GObject *object,
case PROP_VISIBLE:
g_value_set_boolean (value, context->priv->visible);
break;
case PROP_FULLSCREEN:
g_value_set_boolean (value, context->priv->fullscreen);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -401,20 +393,6 @@ eekboard_context_service_class_init (EekboardContextServiceClass *klass)
g_object_class_install_property (gobject_class,
PROP_VISIBLE,
pspec);
/**
* EekboardContextService:fullscreen:
*
* Flag to indicate if keyboard is rendered in fullscreen mode.
*/
pspec = g_param_spec_boolean ("fullscreen",
"Fullscreen",
"Fullscreen",
FALSE,
G_PARAM_READWRITE);
g_object_class_install_property (gobject_class,
PROP_FULLSCREEN,
pspec);
}
static void
@ -524,19 +502,6 @@ eekboard_context_service_get_keyboard (EekboardContextService *context)
return context->priv->keyboard;
}
/**
* eekboard_context_service_get_fullscreen:
* @context: an #EekboardContextService
*
* Check if keyboard is rendered in fullscreen mode in @context.
* Returns: %TRUE or %FALSE
*/
gboolean
eekboard_context_service_get_fullscreen (EekboardContextService *context)
{
return context->priv->fullscreen;
}
void eekboard_context_service_set_keymap(EekboardContextService *context,
const LevelKeyboard *keyboard)
{

View File

@ -98,8 +98,6 @@ void eekboard_context_service_hide_keyboard
(EekboardContextService *context);
void eekboard_context_service_destroy (EekboardContextService *context);
LevelKeyboard *eekboard_context_service_get_keyboard(EekboardContextService *context);
gboolean eekboard_context_service_get_fullscreen
(EekboardContextService *context);
void eekboard_context_service_set_keymap(EekboardContextService *context,
const LevelKeyboard *keyboard);

View File

@ -1,654 +0,0 @@
/*
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010-2011 Red Hat, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* SECTION:eekboard-context
* @short_description: client interface of eekboard input context service
*
* The #EekboardContext class provides a client access to remote input
* context.
*/
#include "config.h"
#include "eekboard/eekboard-context.h"
//#include "eekboard/eekboard-marshalers.h"
#define I_(string) g_intern_static_string (string)
enum {
ENABLED,
DISABLED,
DESTROYED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0, };
enum {
PROP_0,
PROP_VISIBLE,
PROP_LAST
};
typedef struct _EekboardContextPrivate
{
gboolean visible;
gboolean enabled;
gboolean fullscreen;
gint group;
} EekboardContextPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (EekboardContext, eekboard_context, G_TYPE_DBUS_PROXY)
static void
eekboard_context_real_g_signal (GDBusProxy *self,
const gchar *sender_name,
const gchar *signal_name,
GVariant *parameters)
{
EekboardContext *context = EEKBOARD_CONTEXT (self);
EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
if (g_strcmp0 (signal_name, "Enabled") == 0) {
g_signal_emit (context, signals[ENABLED], 0);
return;
}
if (g_strcmp0 (signal_name, "Disabled") == 0) {
g_signal_emit (context, signals[DISABLED], 0);
return;
}
if (g_strcmp0 (signal_name, "Destroyed") == 0) {
g_signal_emit (context, signals[DESTROYED], 0);
return;
}
if (g_strcmp0 (signal_name, "VisibilityChanged") == 0) {
gboolean visible = FALSE;
g_variant_get (parameters, "(b)", &visible);
if (visible != priv->visible) {
priv->visible = visible;
g_object_notify (G_OBJECT(context), "visible");
}
return;
}
if (g_strcmp0 (signal_name, "GroupChanged") == 0) {
gint group = 0;
g_variant_get (parameters, "(i)", &group);
if (group != priv->group) {
priv->group = group;
/* g_object_notify (G_OBJECT(context), "group"); */
}
return;
}
g_return_if_reached ();
}
static void
eekboard_context_real_enabled (EekboardContext *self)
{
EekboardContextPrivate *priv = eekboard_context_get_instance_private (self);
priv->enabled = TRUE;
}
static void
eekboard_context_real_disabled (EekboardContext *self)
{
EekboardContextPrivate *priv = eekboard_context_get_instance_private (self);
priv->enabled = FALSE;
}
static void
eekboard_context_real_destroyed (EekboardContext *self)
{
}
static void
eekboard_context_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
EekboardContext *context = EEKBOARD_CONTEXT(object);
EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
switch (prop_id) {
case PROP_VISIBLE:
g_value_set_boolean (value, priv->visible);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
eekboard_context_class_init (EekboardContextClass *klass)
{
GDBusProxyClass *proxy_class = G_DBUS_PROXY_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GParamSpec *pspec;
klass->enabled = eekboard_context_real_enabled;
klass->disabled = eekboard_context_real_disabled;
klass->destroyed = eekboard_context_real_destroyed;
proxy_class->g_signal = eekboard_context_real_g_signal;
gobject_class->get_property = eekboard_context_get_property;
/**
* EekboardContext:visible:
*
* Flag to indicate if keyboard is visible or not.
*/
pspec = g_param_spec_boolean ("visible",
"visible",
"Flag that indicates if keyboard is visible",
FALSE,
G_PARAM_READABLE);
g_object_class_install_property (gobject_class,
PROP_VISIBLE,
pspec);
/**
* EekboardContext::enabled:
* @context: an #EekboardContext
*
* Emitted when @context is enabled.
*/
signals[ENABLED] =
g_signal_new (I_("enabled"),
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(EekboardContextClass, enabled),
NULL,
NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
/**
* EekboardContext::disabled:
* @context: an #EekboardContext
*
* The ::disabled signal is emitted each time @context is disabled.
*/
signals[DISABLED] =
g_signal_new (I_("disabled"),
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(EekboardContextClass, disabled),
NULL,
NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
/**
* EekboardContext::destroyed:
* @context: an #EekboardContext
*
* The ::destroyed signal is emitted each time the name of remote
* end is vanished.
*/
signals[DESTROYED] =
g_signal_new (I_("destroyed"),
G_TYPE_FROM_CLASS(gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(EekboardContextClass, destroyed),
NULL,
NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
}
static void
eekboard_context_init (EekboardContext *self)
{
/* void */
}
static void
context_name_vanished_callback (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
EekboardContext *context = user_data;
g_signal_emit (context, signals[DESTROYED], 0);
}
/**
* eekboard_context_new:
* @connection: a #GDBusConnection
* @object_path: object path
* @cancellable: a #GCancellable
*
* Create a D-Bus proxy of an input context maintained by
* eekboard-server. This function is seldom called from applications
* since eekboard_server_create_context() calls it implicitly.
*/
EekboardContext *
eekboard_context_new (GDBusConnection *connection,
const gchar *object_path,
GCancellable *cancellable)
{
GInitable *initable;
GError *error;
g_return_val_if_fail (object_path != NULL, NULL);
g_return_val_if_fail (G_IS_DBUS_CONNECTION(connection), NULL);
error = NULL;
initable =
g_initable_new (EEKBOARD_TYPE_CONTEXT,
cancellable,
&error,
"g-name", "org.fedorahosted.Eekboard",
"g-connection", connection,
"g-interface-name", "org.fedorahosted.Eekboard.Context",
"g-object-path", object_path,
NULL);
if (initable != NULL) {
EekboardContext *context = EEKBOARD_CONTEXT (initable);
gchar *name_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY(context));
if (name_owner == NULL) {
g_object_unref (context);
return NULL;
}
/* the vanished callback is called when the server is disconnected */
g_bus_watch_name_on_connection (connection,
name_owner,
G_BUS_NAME_WATCHER_FLAGS_NONE,
NULL,
context_name_vanished_callback,
context,
NULL);
g_free (name_owner);
return context;
}
g_warning ("can't create context client: %s", error->message);
g_error_free (error);
return NULL;
}
static void
context_async_ready_callback (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
GError *error = NULL;
GVariant *result;
result = g_dbus_proxy_call_finish (G_DBUS_PROXY(source_object),
res,
&error);
if (result)
g_variant_unref (result);
else {
g_warning ("error in D-Bus proxy call: %s", error->message);
g_error_free (error);
}
}
/**
* eekboard_context_add_keyboard:
* @context: an #EekboardContext
* @keyboard: a string representing keyboard
* @cancellable: a #GCancellable
*
* Register @keyboard in @context.
*/
guint
eekboard_context_add_keyboard (EekboardContext *context,
const gchar *keyboard,
GCancellable *cancellable)
{
GVariant *result;
GError *error;
g_return_val_if_fail (EEKBOARD_IS_CONTEXT(context), 0);
error = NULL;
result = g_dbus_proxy_call_sync (G_DBUS_PROXY(context),
"AddKeyboard",
g_variant_new ("(s)", keyboard),
G_DBUS_CALL_FLAGS_NONE,
-1,
cancellable,
&error);
if (result) {
guint keyboard_id;
g_variant_get (result, "(u)", &keyboard_id);
g_variant_unref (result);
return keyboard_id;
}
g_warning ("error in AddKeyboard call: %s", error->message);
g_error_free (error);
return 0;
}
/**
* eekboard_context_remove_keyboard:
* @context: an #EekboardContext
* @keyboard_id: keyboard ID
* @cancellable: a #GCancellable
*
* Unregister the keyboard with @keyboard_id in @context.
*/
void
eekboard_context_remove_keyboard (EekboardContext *context,
guint keyboard_id,
GCancellable *cancellable)
{
g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
g_dbus_proxy_call (G_DBUS_PROXY(context),
"RemoveKeyboard",
g_variant_new ("(u)", keyboard_id),
G_DBUS_CALL_FLAGS_NONE,
-1,
cancellable,
context_async_ready_callback,
NULL);
}
/**
* eekboard_context_set_keyboard:
* @context: an #EekboardContext
* @keyboard_id: keyboard ID
* @cancellable: a #GCancellable
*
* Select a keyboard with ID @keyboard_id in @context.
*/
void
eekboard_context_set_keyboard (EekboardContext *context,
guint keyboard_id,
GCancellable *cancellable)
{
g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
g_dbus_proxy_call (G_DBUS_PROXY(context),
"SetKeyboard",
g_variant_new ("(u)", keyboard_id),
G_DBUS_CALL_FLAGS_NONE,
-1,
cancellable,
context_async_ready_callback,
NULL);
}
/**
* eekboard_context_set_group:
* @context: an #EekboardContext
* @group: group number
* @cancellable: a #GCancellable
*
* Set the keyboard group of @context.
*/
void
eekboard_context_set_group (EekboardContext *context,
gint group,
GCancellable *cancellable)
{
g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
if (priv->group != group) {
g_dbus_proxy_call (G_DBUS_PROXY(context),
"SetGroup",
g_variant_new ("(i)", group),
G_DBUS_CALL_FLAGS_NONE,
-1,
cancellable,
context_async_ready_callback,
NULL);
}
}
/**
* eekboard_context_get_group:
* @context: an #EekboardContext
* @cancellable: a #GCancellable
*
* Get the keyboard group of @context.
*/
gint
eekboard_context_get_group (EekboardContext *context,
GCancellable *cancellable)
{
g_return_val_if_fail (EEKBOARD_IS_CONTEXT(context), 0);
EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
return priv->group;
}
/**
* eekboard_context_show_keyboard:
* @context: an #EekboardContext
* @cancellable: a #GCancellable
*
* Request eekboard-server to show a keyboard set by
* eekboard_context_set_keyboard().
*/
void
eekboard_context_show_keyboard (EekboardContext *context,
GCancellable *cancellable)
{
g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
if (priv->enabled) {
g_dbus_proxy_call (G_DBUS_PROXY(context),
"ShowKeyboard",
NULL,
G_DBUS_CALL_FLAGS_NONE,
-1,
cancellable,
context_async_ready_callback,
NULL);
}
}
/**
* eekboard_context_hide_keyboard:
* @context: an #EekboardContext
* @cancellable: a #GCancellable
*
* Request eekboard-server to hide a keyboard.
*/
void
eekboard_context_hide_keyboard (EekboardContext *context,
GCancellable *cancellable)
{
g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
if (priv->enabled) {
g_dbus_proxy_call (G_DBUS_PROXY(context),
"HideKeyboard",
NULL,
G_DBUS_CALL_FLAGS_NONE,
-1,
cancellable,
context_async_ready_callback,
NULL);
}
}
/**
* eekboard_context_press_keycode:
* @context: an #EekboardContext
* @keycode: keycode number
* @cancellable: a #GCancellable
*
* Tell eekboard-server that a key identified by @keycode is pressed.
*/
void
eekboard_context_press_keycode (EekboardContext *context,
guint keycode,
GCancellable *cancellable)
{
g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
if (priv->enabled) {
g_dbus_proxy_call (G_DBUS_PROXY(context),
"PressKeycode",
g_variant_new ("(u)", keycode),
G_DBUS_CALL_FLAGS_NONE,
-1,
cancellable,
context_async_ready_callback,
NULL);
}
}
/**
* eekboard_context_release_keycode:
* @context: an #EekboardContext
* @keycode: keycode number
* @cancellable: a #GCancellable
*
* Tell eekboard-server that a key identified by @keycode is released.
*/
void
eekboard_context_release_keycode (EekboardContext *context,
guint keycode,
GCancellable *cancellable)
{
g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
if (priv->enabled) {
g_dbus_proxy_call (G_DBUS_PROXY(context),
"ReleaseKeycode",
g_variant_new ("(u)", keycode),
G_DBUS_CALL_FLAGS_NONE,
-1,
cancellable,
context_async_ready_callback,
NULL);
}
}
/**
* eekboard_context_is_visible:
* @context: an #EekboardContext
*
* Check if keyboard is visible.
*/
gboolean
eekboard_context_is_visible (EekboardContext *context)
{
g_return_val_if_fail (EEKBOARD_IS_CONTEXT(context), FALSE);
EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
return priv->enabled && priv->visible;
}
/**
* eekboard_context_set_enabled:
* @context: an #EekboardContext
* @enabled: flag to indicate if @context is enabled
*
* Set @context enabled or disabled. This function is seldom called
* since the flag is set via D-Bus signal #EekboardContext::enabled
* and #EekboardContext::disabled.
*/
void
eekboard_context_set_enabled (EekboardContext *context,
gboolean enabled)
{
g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
priv->enabled = enabled;
}
/**
* eekboard_context_is_enabled:
* @context: an #EekboardContext
*
* Check if @context is enabled.
*/
gboolean
eekboard_context_is_enabled (EekboardContext *context)
{
g_return_val_if_fail (EEKBOARD_IS_CONTEXT(context), FALSE);
EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
return priv->enabled;
}
/**
* eekboard_context_set_fullscreen:
* @context: an #EekboardContext
* @fullscreen: a flag to indicate fullscreen mode
* @cancellable: a #GCancellable
*
* Set the fullscreen mode of @context.
*/
void
eekboard_context_set_fullscreen (EekboardContext *context,
gboolean fullscreen,
GCancellable *cancellable)
{
g_return_if_fail (EEKBOARD_IS_CONTEXT(context));
EekboardContextPrivate *priv = eekboard_context_get_instance_private (context);
if (priv->fullscreen != fullscreen) {
g_dbus_proxy_call (G_DBUS_PROXY(context),
"SetFullscreen",
g_variant_new ("(b)", fullscreen),
G_DBUS_CALL_FLAGS_NONE,
-1,
cancellable,
context_async_ready_callback,
NULL);
}
}

View File

@ -1,94 +0,0 @@
/*
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010-2011 Red Hat, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(__EEKBOARD_CLIENT_H_INSIDE__) && !defined(EEKBOARD_COMPILATION)
#error "Only <eekboard/eekboard-client.h> can be included directly."
#endif
#ifndef EEKBOARD_CONTEXT_H
#define EEKBOARD_CONTEXT_H 1
#include <gio/gio.h>
#include "eek/eek.h"
G_BEGIN_DECLS
#define EEKBOARD_TYPE_CONTEXT (eekboard_context_get_type())
G_DECLARE_DERIVABLE_TYPE (EekboardContext, eekboard_context, EEKBOARD, CONTEXT, GDBusProxy)
/**
* EekboardContextClass:
* @enabled: class handler for #EekboardContext::enabled signal
* @disabled: class handler for #EekboardContext::disabled signal
* @key_pressed: class handler for #EekboardContext::key-pressed signal
* @destroyed: class handler for #EekboardContext::destroyed signal
*/
struct _EekboardContextClass {
/*< private >*/
GDBusProxyClass parent_class;
/*< public >*/
/* signals */
void (*enabled) (EekboardContext *self);
void (*disabled) (EekboardContext *self);
void (*destroyed) (EekboardContext *self);
/*< private >*/
/* padding */
gpointer pdummy[24];
};
GType eekboard_context_get_type (void) G_GNUC_CONST;
EekboardContext *eekboard_context_new (GDBusConnection *connection,
const gchar *object_path,
GCancellable *cancellable);
guint eekboard_context_add_keyboard (EekboardContext *context,
const gchar *keyboard,
GCancellable *cancellable);
void eekboard_context_remove_keyboard (EekboardContext *context,
guint keyboard_id,
GCancellable *cancellable);
void eekboard_context_set_keyboard (EekboardContext *context,
guint keyboard_id,
GCancellable *cancellable);
void eekboard_context_show_keyboard (EekboardContext *context,
GCancellable *cancellable);
void eekboard_context_hide_keyboard (EekboardContext *context,
GCancellable *cancellable);
void eekboard_context_set_group (EekboardContext *context,
gint group,
GCancellable *cancellable);
gint eekboard_context_get_group (EekboardContext *context,
GCancellable *cancellable);
void eekboard_context_press_keycode (EekboardContext *context,
guint keycode,
GCancellable *cancellable);
void eekboard_context_release_keycode (EekboardContext *context,
guint keycode,
GCancellable *cancellable);
gboolean eekboard_context_is_visible
(EekboardContext *context);
void eekboard_context_set_enabled (EekboardContext *context,
gboolean enabled);
gboolean eekboard_context_is_enabled (EekboardContext *context);
void eekboard_context_set_fullscreen (EekboardContext *context,
gboolean fullscreen,
GCancellable *cancellable);
G_END_DECLS
#endif /* EEKBOARD_CONTEXT_H */

View File

@ -3,13 +3,13 @@ extern crate xkbcommon;
use std::env;
use rs::data::{ load_layout_from_resource, LoadError };
use rs::data::{ Layout, LoadError };
use xkbcommon::xkb;
fn check_layout(name: &str) {
let layout = load_layout_from_resource(name)
let layout = Layout::from_resource(name)
.and_then(|layout| layout.build().map_err(LoadError::BadKeyMap))
.expect("layout broken");

View File

@ -1,7 +1,7 @@
project(
'squeekboard',
'c', 'rust',
version: '1.2.0',
version: '1.2.1',
license: 'GPLv3',
meson_version: '>=0.51.0',
default_options: [

View File

@ -67,15 +67,7 @@ impl fmt::Display for LoadError {
}
}
pub fn load_layout_from_resource(
name: &str
) -> Result<Layout, LoadError> {
let data = resources::get_keyboard(name)
.ok_or(LoadError::MissingResource)?;
serde_yaml::from_str(data)
.map_err(|e| LoadError::BadResource(e))
}
#[derive(Debug, PartialEq)]
enum DataSource {
File(PathBuf),
Resource(String),
@ -93,63 +85,90 @@ impl fmt::Display for DataSource {
/// Tries to load the layout from the first place where it's present.
/// If the layout exists, but is broken, fallback is activated.
fn load_layout(
name: &str
) -> (Result<::layout::Layout, LoadError>, DataSource) {
let path = env::var_os("SQUEEKBOARD_KEYBOARDSDIR")
.map(PathBuf::from)
.or_else(|| xdg::data_path("squeekboard/keyboards"))
.map(|path| path.join(name).with_extension("yaml"));
let (layout, source) = match path {
Some(path) => {(
Layout::from_yaml_stream(path.clone())
.map_err(|e| LoadError::BadData(e)),
DataSource::File(path)
)},
None => {(
load_layout_from_resource(name),
DataSource::Resource(name.into())
)},
};
let layout = layout.and_then(
|layout| layout.build().map_err(LoadError::BadKeyMap)
name: &str,
keyboards_path: Option<PathBuf>,
) -> (
Result<::layout::Layout, LoadError>, // last attempted
DataSource, // last attempt source
Option<(LoadError, DataSource)>, // first attempt source
) {
let path = keyboards_path.map(|path|
path.join(name).with_extension("yaml")
);
(layout, source)
let layout = match path {
Some(path) => Some((
Layout::from_file(path.clone())
.map_err(LoadError::BadData)
.and_then(|layout|
layout.build().map_err(LoadError::BadKeyMap)
),
DataSource::File(path),
)),
None => None, // No env var, not an error
};
let (failed_attempt, layout) = match layout {
Some((Ok(layout), path)) => (None, Some((layout, path))),
Some((Err(e), path)) => (Some((e, path)), None),
None => (None, None),
};
let (layout, source) = match layout {
Some((layout, path)) => (Ok(layout), path),
None => (
Layout::from_resource(name)
.and_then(|layout|
layout.build().map_err(LoadError::BadKeyMap)
),
DataSource::Resource(name.into()),
),
};
(layout, source, failed_attempt)
}
fn log_attempt_info(attempt: Option<(LoadError, DataSource)>) {
match attempt {
Some((
LoadError::BadData(Error::Missing(_e)),
DataSource::File(_file)
)) => {
// Missing file, not to worry. TODO: print in debug logging level
}
Some((e, source)) => {
eprintln!(
"Failed to load layout from {}: {}, trying builtin",
source, e
);
},
_ => {}
};
}
fn load_layout_with_fallback(
name: &str
) -> ::layout::Layout {
let (layout, source) = load_layout(name);
let (layout, source) = match (layout, source) {
let path = env::var_os("SQUEEKBOARD_KEYBOARDSDIR")
.map(PathBuf::from)
.or_else(|| xdg::data_path("squeekboard/keyboards"));
let (layout, source, attempt) = load_layout(name, path.clone());
log_attempt_info(attempt);
let (layout, source, attempt) = match (layout, source) {
(Err(e), source) => {
eprintln!(
"Failed to load layout from {}: {}, using fallback",
source, e
);
load_layout(FALLBACK_LAYOUT_NAME)
load_layout(FALLBACK_LAYOUT_NAME, path)
},
res => res,
(res, source) => (res, source, None),
};
let (layout, source) = match (layout, source) {
(Err(e), source) => {
eprintln!(
"Failed to load fallback layout from {}: {}, using hardcoded",
source, e
);
(
load_layout_from_resource(FALLBACK_LAYOUT_NAME)
.and_then(
|layout| layout.build().map_err(LoadError::BadKeyMap)
),
DataSource::Resource(FALLBACK_LAYOUT_NAME.into()),
)
},
res => res,
};
log_attempt_info(attempt);
match (layout, source) {
(Err(e), source) => {
@ -170,6 +189,8 @@ fn load_layout_with_fallback(
#[derive(Debug, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct Layout {
row_spacing: f64,
button_spacing: f64,
bounds: Bounds,
views: HashMap<String, Vec<ButtonIds>>,
#[serde(default)]
@ -218,14 +239,18 @@ enum Action {
#[derive(Debug, Clone, Deserialize, PartialEq)]
#[serde(deny_unknown_fields)]
struct Outline {
corner_radius: f64,
bounds: Bounds,
}
/// Errors encountered loading the layout into yaml
#[derive(Debug)]
pub enum Error {
Yaml(serde_yaml::Error),
Io(io::Error),
/// The file was missing.
/// It's distinct from Io in order to make it matchable
/// without calling io::Error::kind()
Missing(io::Error),
}
impl fmt::Display for Error {
@ -233,21 +258,38 @@ impl fmt::Display for Error {
match self {
Error::Yaml(e) => write!(f, "YAML: {}", e),
Error::Io(e) => write!(f, "IO: {}", e),
Error::Missing(e) => write!(f, "Missing: {}", e),
}
}
}
impl From<io::Error> for Error {
fn from(e: io::Error) -> Self {
let kind = e.kind();
match kind {
io::ErrorKind::NotFound => Error::Missing(e),
_ => Error::Io(e),
}
}
}
impl Layout {
fn from_yaml_stream(path: PathBuf) -> Result<Layout, Error> {
pub fn from_resource(name: &str) -> Result<Layout, LoadError> {
let data = resources::get_keyboard(name)
.ok_or(LoadError::MissingResource)?;
serde_yaml::from_str(data)
.map_err(LoadError::BadResource)
}
fn from_file(path: PathBuf) -> Result<Layout, Error> {
let infile = BufReader::new(
fs::OpenOptions::new()
.read(true)
.open(&path)
.map_err(Error::Io)?
.open(&path)?
);
serde_yaml::from_reader(infile)
.map_err(Error::Yaml)
serde_yaml::from_reader(infile).map_err(Error::Yaml)
}
pub fn build(self) -> Result<::layout::Layout, FormattingError> {
let button_names = self.views.values()
.flat_map(|rows| {
@ -303,6 +345,10 @@ impl Layout {
width: self.bounds.width,
height: self.bounds.height,
},
spacing: ::layout::Spacing {
row: self.row_spacing,
button: self.button_spacing,
},
rows: view.iter().map(|row| {
Box::new(::layout::Row {
angle: 0,
@ -469,13 +515,13 @@ fn create_button(
.unwrap_or_else(|| {
eprintln!("No default outline defied Using 1x1!");
Outline {
corner_radius: 0f64,
bounds: Bounds { x: 0f64, y: 0f64, width: 1f64, height: 1f64 },
}
});
::layout::Button {
name: cname,
outline_name: CString::new(outline_name).expect("Bad outline"),
// TODO: do layout before creating buttons
bounds: ::layout::c::Bounds {
x: outline.bounds.x,
@ -483,7 +529,6 @@ fn create_button(
width: outline.bounds.width,
height: outline.bounds.height,
},
corner_radius: outline.corner_radius,
label: label,
state: state,
}
@ -498,10 +543,10 @@ mod tests {
#[test]
fn test_parse_path() {
assert_eq!(
Layout::from_yaml_stream(
PathBuf::from("tests/layout.yaml")
).unwrap(),
Layout::from_file(PathBuf::from("tests/layout.yaml")).unwrap(),
Layout {
row_spacing: 0f64,
button_spacing: 0f64,
bounds: Bounds { x: 0f64, y: 0f64, width: 0f64, height: 0f64 },
views: hashmap!(
"base".into() => vec!("test".into()),
@ -517,7 +562,6 @@ mod tests {
},
outlines: hashmap!{
"default".into() => Outline {
corner_radius: 1f64,
bounds: Bounds {
x: 0f64, y: 0f64, width: 0f64, height: 0f64
},
@ -530,7 +574,7 @@ mod tests {
/// Check if the default protection works
#[test]
fn test_empty_views() {
let out = Layout::from_yaml_stream(PathBuf::from("tests/layout2.yaml"));
let out = Layout::from_file(PathBuf::from("tests/layout2.yaml"));
match out {
Ok(_) => assert!(false, "Data mistakenly accepted"),
Err(e) => {
@ -548,7 +592,7 @@ mod tests {
#[test]
fn test_extra_field() {
let out = Layout::from_yaml_stream(PathBuf::from("tests/layout3.yaml"));
let out = Layout::from_file(PathBuf::from("tests/layout3.yaml"));
match out {
Ok(_) => assert!(false, "Data mistakenly accepted"),
Err(e) => {
@ -567,7 +611,7 @@ mod tests {
#[test]
fn test_layout_punctuation() {
let out = Layout::from_yaml_stream(PathBuf::from("tests/layout_key1.yaml"))
let out = Layout::from_file(PathBuf::from("tests/layout_key1.yaml"))
.unwrap()
.build()
.unwrap();
@ -582,7 +626,7 @@ mod tests {
#[test]
fn test_layout_unicode() {
let out = Layout::from_yaml_stream(PathBuf::from("tests/layout_key2.yaml"))
let out = Layout::from_file(PathBuf::from("tests/layout_key2.yaml"))
.unwrap()
.build()
.unwrap();
@ -597,12 +641,26 @@ mod tests {
#[test]
fn parsing_fallback() {
assert!(load_layout_from_resource(FALLBACK_LAYOUT_NAME)
assert!(Layout::from_resource(FALLBACK_LAYOUT_NAME)
.and_then(|layout| layout.build().map_err(LoadError::BadKeyMap))
.is_ok()
);
}
/// First fallback should be to builtin, not to FALLBACK_LAYOUT_NAME
#[test]
fn fallbacks_order() {
let (layout, source, _failure) = load_layout(
"nb",
Some(PathBuf::from("tests"))
);
assert_eq!(
source,
load_layout("nb", None).1
);
}
#[test]
fn unicode_keysym() {
let keysym = xkb::keysym_from_name(

View File

@ -3,7 +3,6 @@ use std::ffi::CString;
use std::num::Wrapping;
use std::string::String;
use super::bitflags;
use ::util::c::into_cstring;
// Traits

View File

@ -32,6 +32,7 @@ EekBounds squeek_button_get_bounds(const struct squeek_button*);
const char *squeek_button_get_label(const struct squeek_button*);
const char *squeek_button_get_icon_name(const struct squeek_button*);
const char *squeek_button_get_name(const struct squeek_button*);
const char *squeek_button_get_outline_name(const struct squeek_button*);
struct squeek_key *squeek_button_get_key(const struct squeek_button*);
uint32_t *squeek_button_has_key(const struct squeek_button* button,

View File

@ -40,11 +40,6 @@ pub mod c {
#[repr(transparent)]
pub struct UserData(*const c_void);
/// The index in the relevant outline table
#[repr(C)]
#[derive(Clone, Debug)]
pub struct OutlineRef(u32);
/// Defined in eek-types.h
#[repr(C)]
#[derive(Clone, Debug)]
@ -195,6 +190,13 @@ pub mod c {
button.name.as_ptr()
}
#[no_mangle]
pub extern "C"
fn squeek_button_get_outline_name(button: *const Button) -> *const c_char {
let button = unsafe { &*button };
button.outline_name.as_ptr()
}
#[no_mangle]
pub extern "C"
fn squeek_button_has_key(
@ -328,8 +330,8 @@ pub mod c {
.map(|button| button.bounds.clone())
.collect()
}).collect();
view.place_buttons_with_sizes(sizes);
let spacing = view.spacing.clone();
view.place_buttons_with_sizes(sizes, spacing);
}
}
@ -440,6 +442,10 @@ pub mod c {
x: 0f64, y: 0f64,
width: 0f64, height: 0f64
},
spacing: Spacing {
button: 0f64,
row: 0f64,
},
rows: vec!(row),
};
@ -459,6 +465,10 @@ pub mod c {
x: 0f64, y: 0f64,
width: 0f64, height: 0f64
},
spacing: Spacing {
button: 0f64,
row: 0f64,
},
rows: Vec::new(),
};
assert_eq!(
@ -498,10 +508,10 @@ pub mod c {
) -> Box<Button> {
Box::new(Button {
name: CString::new(name.clone()).unwrap(),
corner_radius: 0f64,
bounds: c::Bounds {
x: 0f64, y: 0f64, width: 0f64, height: 0f64
},
outline_name: CString::new("test").unwrap(),
label: Label::Text(CString::new(name).unwrap()),
state: state,
})
@ -561,18 +571,15 @@ pub struct Button {
pub name: CString,
/// Label to display to the user
pub label: Label,
pub corner_radius: f64,
/// TODO: position the buttons before they get initial bounds
/// Position relative to some origin (i.e. parent/row)
pub bounds: c::Bounds,
/// The name of the visual class applied
pub outline_name: CString,
/// current state, shared with other buttons
pub state: Rc<RefCell<KeyState>>,
}
// FIXME: derive from the style/margin/padding
const BUTTON_SPACING: f64 = 4.0;
const ROW_SPACING: f64 = 7.0;
/// The graphical representation of a row of buttons
pub struct Row {
pub buttons: Vec<Box<Button>>,
@ -599,7 +606,7 @@ impl Row {
}
}
fn calculate_button_positions(outlines: Vec<c::Bounds>)
fn calculate_button_positions(outlines: Vec<c::Bounds>, button_spacing: f64)
-> Vec<c::Bounds>
{
let mut x_offset = 0f64;
@ -609,7 +616,7 @@ impl Row {
x: x_offset,
..outline.clone()
};
x_offset += outline.width + BUTTON_SPACING;
x_offset += outline.width + button_spacing;
position
}).collect()
}
@ -648,9 +655,16 @@ impl Row {
}
}
#[derive(Clone, Debug)]
pub struct Spacing {
pub row: f64,
pub button: f64,
}
pub struct View {
/// Position relative to keyboard origin
pub bounds: c::Bounds,
pub spacing: Spacing,
pub rows: Vec<Box<Row>>,
}
@ -662,7 +676,9 @@ impl View {
/// and derive a scaling factor that lets contents fit into view)
/// (or TODO: blow up view bounds to match contents
/// and then scale the entire thing)
fn calculate_row_positions(&self, sizes: Vec<Size>) -> Vec<c::Bounds> {
fn calculate_row_positions(&self, sizes: Vec<Size>, row_spacing: f64)
-> Vec<c::Bounds>
{
let mut y_offset = self.bounds.y;
sizes.into_iter().map(|size| {
let position = c::Bounds {
@ -671,7 +687,7 @@ impl View {
width: size.width,
height: size.height,
};
y_offset += size.height + ROW_SPACING;
y_offset += size.height + row_spacing;
position
}).collect()
}
@ -680,19 +696,23 @@ impl View {
/// The view itself will not be affected by the sizes
fn place_buttons_with_sizes(
&mut self,
button_outlines: Vec<Vec<c::Bounds>>
button_outlines: Vec<Vec<c::Bounds>>,
spacing: Spacing,
) {
// Determine all positions
let button_positions: Vec<_>
= button_outlines.into_iter()
.map(Row::calculate_button_positions)
.map(|outlines| {
Row::calculate_button_positions(outlines, spacing.button)
})
.collect();
let row_sizes = button_positions.iter()
.map(Row::calculate_row_size)
.collect();
let row_positions = self.calculate_row_positions(row_sizes);
let row_positions
= self.calculate_row_positions(row_sizes, spacing.row);
// Apply all positions
for ((mut row, row_position), button_positions)

View File

@ -19,7 +19,6 @@ sources = [
'../eek/eek-element.c',
'../eek/eek-gtk-keyboard.c',
'../eek/eek-keyboard.c',
'../eek/eek-keyboard-drawing.c',
'../eek/eek-layout.c',
'../eek/eek-renderer.c',
'../eek/eek-types.c',
@ -29,7 +28,6 @@ sources = [
enums,
'../eekboard/key-emitter.c',
'../eekboard/eekboard-context-service.c',
'../eekboard/eekboard-context.c',
'../eekboard/eekboard-service.c',
# '../eekboard/eekboard-xklutil.c',
squeekboard_resources,
@ -60,13 +58,29 @@ rslibs = custom_target(
output: ['librs.a'],
install: false,
console: true,
command: [cargo_script, '@CURRENT_SOURCE_DIR@', '@OUTPUT@', 'build']
command: [cargo_script, '@OUTPUT@', 'build']
)
build_rstests = custom_target(
'build_rstests',
build_by_default: false,
# HACK: this target needs to build before all the tests,
# but it doesn't produce anything stable.
# Declaring build_by_default with some random but irrelevant output
# ensures that it's always built as it should
build_always_stale: true,
output: ['src'],
install: false,
console: true,
command: [cargo_script, '', 'build', '--tests'],
depends: rslibs, # no point building tests if the code itself fails
)
test(
'rstest',
cargo_script,
args: [meson.source_root(), '', 'test']
args: ['', 'test'],
depends: build_rstests,
)
libsqueekboard = static_library('libsqueekboard',

View File

@ -5,6 +5,9 @@
const KEYBOARDS: &[(*const str, *const str)] = &[
("us", include_str!("../data/keyboards/us.yaml")),
("el", include_str!("../data/keyboards/el.yaml")),
("es", include_str!("../data/keyboards/es.yaml")),
("it", include_str!("../data/keyboards/it.yaml")),
("nb", include_str!("../data/keyboards/nb.yaml")),
("number", include_str!("../data/keyboards/number.yaml")),
];

View File

@ -40,6 +40,7 @@ struct _ServerContextService {
GtkWidget *window;
GtkWidget *widget;
guint hiding;
gdouble size_constraint_landscape[2];
gdouble size_constraint_portrait[2];
@ -51,17 +52,6 @@ struct _ServerContextServiceClass {
G_DEFINE_TYPE (ServerContextService, server_context_service, EEKBOARD_TYPE_CONTEXT_SERVICE);
static void set_geometry (ServerContextService *context);
static void
on_monitors_changed (GdkScreen *screen,
ServerContextService *context)
{
if (context->window)
set_geometry (context);
}
static void
on_destroy (GtkWidget *widget, gpointer user_data)
{
@ -107,15 +97,6 @@ on_notify_keyboard (GObject *object,
}
}
static void
on_notify_fullscreen (GObject *object,
GParamSpec *spec,
ServerContextService *context)
{
if (context->window)
set_geometry (context);
}
static void
on_notify_map (GObject *object,
ServerContextService *context)
@ -131,49 +112,6 @@ on_notify_unmap (GObject *object,
g_object_set (context, "visible", FALSE, NULL);
}
static void
set_geometry (ServerContextService *context)
{
GdkScreen *screen = gdk_screen_get_default ();
GdkWindow *root = gdk_screen_get_root_window (screen);
GdkDisplay *display = gdk_display_get_default ();
GdkMonitor *monitor = gdk_display_get_monitor_at_window (display, root);
LevelKeyboard *keyboard = eekboard_context_service_get_keyboard (EEKBOARD_CONTEXT_SERVICE(context));
GdkRectangle rect;
gdk_monitor_get_geometry (monitor, &rect);
EekBounds bounds = squeek_view_get_bounds (level_keyboard_current(keyboard));
if (eekboard_context_service_get_fullscreen (EEKBOARD_CONTEXT_SERVICE(context))) {
gint width = rect.width;
gint height = rect.height;
if (width > height) {
width *= context->size_constraint_landscape[0];
height *= context->size_constraint_landscape[1];
} else {
width *= context->size_constraint_portrait[0];
height *= context->size_constraint_portrait[1];
}
if (width * bounds.height > height * bounds.width)
width = (height / bounds.height) * bounds.width;
else
height = (width / bounds.width) * bounds.height;
gtk_window_resize (GTK_WINDOW(context->widget), width, height);
gtk_window_move (GTK_WINDOW(context->window),
(rect.width - width) / 2,
rect.height - height);
gtk_window_set_decorated (GTK_WINDOW(context->window), FALSE);
gtk_window_set_resizable (GTK_WINDOW(context->window), FALSE);
}
}
#define KEYBOARD_HEIGHT 210
static void
make_window (ServerContextService *context)
@ -237,7 +175,6 @@ make_widget (ServerContextService *context)
gtk_widget_set_has_tooltip (context->widget, TRUE);
gtk_container_add (GTK_CONTAINER(context->window), context->widget);
gtk_widget_show (context->widget);
set_geometry (context);
}
static void
@ -245,6 +182,11 @@ server_context_service_real_show_keyboard (EekboardContextService *_context)
{
ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
if (context->hiding) {
g_source_remove (context->hiding);
context->hiding = 0;
}
if (!context->window)
make_window (context);
if (!context->widget)
@ -255,12 +197,22 @@ server_context_service_real_show_keyboard (EekboardContextService *_context)
gtk_widget_show (context->window);
}
static gboolean
on_hide (ServerContextService *context)
{
gtk_widget_hide (context->window);
context->hiding = 0;
return G_SOURCE_REMOVE;
}
static void
server_context_service_real_hide_keyboard (EekboardContextService *_context)
{
ServerContextService *context = SERVER_CONTEXT_SERVICE(_context);
gtk_widget_hide (context->window);
if (!context->hiding)
context->hiding = g_timeout_add (200, (GSourceFunc) on_hide, context);
EEKBOARD_CONTEXT_SERVICE_CLASS (server_context_service_parent_class)->
hide_keyboard (_context);
@ -349,21 +301,10 @@ server_context_service_class_init (ServerContextServiceClass *klass)
static void
server_context_service_init (ServerContextService *context)
{
GdkScreen *screen = gdk_screen_get_default ();
g_signal_connect (screen,
"monitors-changed",
G_CALLBACK(on_monitors_changed),
context);
g_signal_connect (context,
"notify::keyboard",
G_CALLBACK(on_notify_keyboard),
context);
g_signal_connect (context,
"notify::fullscreen",
G_CALLBACK(on_notify_fullscreen),
context);
}
EekboardContextService *

View File

@ -1,51 +0,0 @@
/*
* Copyright (C) 2010-2011 Daiki Ueno <ueno@unixuser.org>
* Copyright (C) 2010-2011 Red Hat, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SERVER_CONTEXT_H
#define SERVER_CONTEXT_H 1
#include <gio/gio.h>
G_BEGIN_DECLS
#define SERVER_CONTEXT_PATH "/org/fedorahosted/Eekboard/Context_%d"
#define SERVER_CONTEXT_INTERFACE "org.fedorahosted.Eekboard.Context"
#define SERVER_TYPE_CONTEXT (server_context_get_type())
#define SERVER_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SERVER_TYPE_CONTEXT, ServerContext))
#define SERVER_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SERVER_TYPE_CONTEXT, ServerContextClass))
#define SERVER_IS_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SERVER_TYPE_CONTEXT))
#define SERVER_IS_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SERVER_TYPE_CONTEXT))
#define SERVER_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SERVER_TYPE_CONTEXT, ServerContextClass))
typedef struct _ServerContext ServerContext;
ServerContext *server_context_new (const gchar *object_path,
GDBusConnection *connection);
void server_context_set_enabled (ServerContext *context,
gboolean enabled);
void server_context_set_client_connection
(ServerContext *context,
const gchar *client_connection);
const gchar *server_context_get_client_connection
(ServerContext *context);
void server_context_set_client_name
(ServerContext *context,
const gchar *client_name);
G_END_DECLS
#endif /* SERVER_CONTEXT_H */

View File

@ -1,4 +1,7 @@
---
row_spacing: 0
button_spacing: 0
bounds:
x: 0
y: 0
@ -9,7 +12,6 @@ views:
- "test"
outlines:
default:
corner_radius: 1
bounds: { x: 0, y: 0, width: 0, height: 0 }
buttons:

View File

@ -1,5 +1,8 @@
---
# missing views
row_spacing: 0
button_spacing: 0
bounds:
x: 0
y: 0
@ -7,6 +10,5 @@ bounds:
height: 0
outlines:
default:
corner_radius: 1
bounds: { x: 0, y: 0, width: 0, height: 0 }

View File

@ -1,5 +1,8 @@
---
# extra field
row_spacing: 0
button_spacing: 0
bounds:
x: 0
y: 0
@ -10,7 +13,6 @@ views:
- "test"
outlines:
default:
corner_radius: 1
bounds: { x: 0, y: 0, width: 0, height: 0 }
bad_field: false

View File

@ -1,5 +1,8 @@
---
# punctuation
row_spacing: 0
button_spacing: 0
bounds:
x: 0
y: 0
@ -10,7 +13,6 @@ views:
- "."
outlines:
default:
corner_radius: 1
bounds: { x: 0, y: 0, width: 0, height: 0 }
buttons:

View File

@ -1,5 +1,8 @@
---
# punctuation
row_spacing: 0
button_spacing: 0
bounds:
x: 0
y: 0
@ -10,7 +13,6 @@ views:
- "å"
outlines:
default:
corner_radius: 1
bounds: { x: 0, y: 0, width: 0, height: 0 }
buttons:

View File

@ -47,11 +47,11 @@ endforeach
# The layout test is in the examples directory
# due to the way Cargo builds executables
# and the need to call it manually
foreach layout : ['us', 'nb', 'number']
foreach layout : ['us', 'el', 'es', 'it', 'nb', 'number']
test(
'test_layout_' + layout,
cargo_script,
args: [meson.source_root(), '', 'run', '--example', 'test_layout', layout]
args: ['', 'run', '--example', 'test_layout', layout]
)
endforeach