Compare commits
31 Commits
pureos/1.1
...
byz_1.14
| Author | SHA1 | Date | |
|---|---|---|---|
| 2e44b448af | |||
| 8293c5f10d | |||
| 601c835416 | |||
| 07d7486e06 | |||
| 5cb70a096c | |||
| cb211bb764 | |||
| 8c8728aa0f | |||
| f71e769315 | |||
| 273179e1ec | |||
| eb4b630b39 | |||
| b60ebdbd99 | |||
| 8afcd87fc8 | |||
| 99f062fe31 | |||
| be458fb10e | |||
| b8e74b3721 | |||
| 0bc654b832 | |||
| 00e9641a5f | |||
| ea3da22f9b | |||
| d753f2dc2c | |||
| 99c04fd8f5 | |||
| 2b7e8f829e | |||
| f91c58ae4d | |||
| 0c258711cf | |||
| 622cd03918 | |||
| 7589a2d1d1 | |||
| 7cb431b58d | |||
| 1dd4b38c88 | |||
| 1d3e8c9a4b | |||
| 1c6448a9f7 | |||
| 3d2f9f3d9e | |||
| a20ab70984 |
24
Cargo.lock
generated
24
Cargo.lock
generated
@ -265,9 +265,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.93"
|
version = "0.2.94"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41"
|
checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linked-hash-map"
|
name = "linked-hash-map"
|
||||||
@ -353,9 +353,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.6.23"
|
version = "0.6.25"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548"
|
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rs"
|
name = "rs"
|
||||||
@ -380,18 +380,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.125"
|
version = "1.0.126"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
|
checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.125"
|
version = "1.0.126"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
|
checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -412,9 +412,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.69"
|
version = "1.0.72"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "48fe99c6bd8b1cc636890bcc071842de909d902c81ac7dab53ba33c421ab8ffb"
|
checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -438,9 +438,9 @@ checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
version = "0.2.1"
|
version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
|
|||||||
@ -34,7 +34,7 @@ if out_path:
|
|||||||
i = args.index(out_path)
|
i = args.index(out_path)
|
||||||
args.pop(i)
|
args.pop(i)
|
||||||
|
|
||||||
subprocess.run(['sh', "{}/cargo.sh".format(shlex.quote(source_dir.as_posix())), 'build']
|
subprocess.run(['sh', "{}/cargo.sh".format(source_dir.as_posix()), 'build']
|
||||||
+ args,
|
+ args,
|
||||||
check=True)
|
check=True)
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ if out_path:
|
|||||||
out_basename = out_path.name
|
out_basename = out_path.name
|
||||||
filename = filename or out_basename
|
filename = filename or out_basename
|
||||||
subprocess.run(['cp', '-a',
|
subprocess.run(['cp', '-a',
|
||||||
'./{}/{}'.format(shlex.quote(binary_dir), shlex.quote(filename)),
|
'./{}/{}'.format(binary_dir, filename),
|
||||||
out_path],
|
out_path],
|
||||||
check=True)
|
check=True)
|
||||||
|
|
||||||
|
|||||||
@ -438,7 +438,7 @@ buttons:
|
|||||||
unlock_view: "カタカナ"
|
unlock_view: "カタカナ"
|
||||||
outline: "altline"
|
outline: "altline"
|
||||||
label: "。"
|
label: "。"
|
||||||
# Buttons for Latin charachters
|
# Buttons for Latin characters
|
||||||
RSYM1:
|
RSYM1:
|
||||||
action:
|
action:
|
||||||
locking:
|
locking:
|
||||||
|
|||||||
@ -438,7 +438,7 @@ buttons:
|
|||||||
unlock_view: "カタカナ"
|
unlock_view: "カタカナ"
|
||||||
outline: "altline"
|
outline: "altline"
|
||||||
label: "。"
|
label: "。"
|
||||||
# Buttons for Latin charachters
|
# Buttons for Latin characters
|
||||||
RSYM1:
|
RSYM1:
|
||||||
action:
|
action:
|
||||||
locking:
|
locking:
|
||||||
|
|||||||
594
debian/changelog
vendored
594
debian/changelog
vendored
@ -1,570 +1,94 @@
|
|||||||
squeekboard (1.13.0pureos0~amber0) amber-phone; urgency=medium
|
squeekboard (1.14.0-1pureos1) byzantium; urgency=medium
|
||||||
|
|
||||||
[ Dorota Czaplejewicz ]
|
[ Dorota Czaplejewicz ]
|
||||||
* layout: Latch keys when clicked twice
|
* debian: New upstream release
|
||||||
* layout: Add stateless view switching
|
|
||||||
* layout: Plug in stateless view switching
|
|
||||||
* layout: Remove the little abomination of view change promise
|
|
||||||
* view: Ąto-unlatching when multiple latching buttons pressed
|
|
||||||
* renderer: Bring button drawing closer to Rust
|
|
||||||
* ffi: Eliminate squeek_button and squeek_row
|
|
||||||
* imservice: Increment serials on receiving done, not sending commit
|
|
||||||
* input-method: Fix commit/done mixup in protocol text
|
|
||||||
* CI: fix xheck_tag to be compatible with Amber
|
|
||||||
* italian: Fix colon
|
|
||||||
* popover: Fix prematurely deallocated CString
|
|
||||||
* Rust: Remove unnecessary no_mangle statements to silence warnings
|
|
||||||
* renderer: Reduce reliance on knowing the transform
|
|
||||||
* renderer: Split mutable geometry and place it directly in GtkKeyboard
|
|
||||||
* Revert "moved data/langs/he_IL.txt -> data/langs/he-IL.txt to better conform with existing translations."
|
|
||||||
* layout: Make it possible to opt out of latching per-key
|
|
||||||
* renderer: Mark latched buttons differently than locked
|
|
||||||
* appearance: Colour latched/locked according to design
|
|
||||||
* docs: Describe view switching
|
|
||||||
* language-terminal: Place keyboards in a sub-path
|
|
||||||
* layout selection: Fix emoji and number
|
|
||||||
* rust: Fix compiler warnings
|
|
||||||
* layout: Take into account text purpose again
|
|
||||||
* layouts: Make selection testable
|
|
||||||
* layouts: Stop assuming that layout name always changes on switch
|
|
||||||
* Cargo: Version bump
|
|
||||||
|
|
||||||
[ J.D. Laub ]
|
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Sat, 22 May 2021 14:19:27 +0000
|
||||||
* Add US Dvorak layout (and Colemak wide)
|
|
||||||
* Add US Dvorak layout (and Colemak wide)
|
|
||||||
|
|
||||||
[ Jordi Masip ]
|
squeekboard (1.13.0-1pureos1) byzantium; urgency=medium
|
||||||
* Catalan keyboard layout
|
|
||||||
|
|
||||||
[ Myth ]
|
|
||||||
* Added hebrew keyboard layout
|
|
||||||
|
|
||||||
[ David96 ]
|
|
||||||
* Add Mod4 (Windows) key
|
|
||||||
|
|
||||||
[ Panawat Wong-klaew ]
|
|
||||||
* Add wide Thai keyboard layout
|
|
||||||
|
|
||||||
[ Guido Günther ]
|
|
||||||
* server-main: Add quit()
|
|
||||||
* server-main: Properly register to gnome-session (Closes: #274)
|
|
||||||
|
|
||||||
[ Kozova1 ]
|
|
||||||
* Added Hebrew translations for most layouts.
|
|
||||||
* moved data/langs/he_IL.txt -> data/langs/he-IL.txt to better conform with existing translations.
|
|
||||||
* Fixed Hebrew layout.
|
|
||||||
* moved data/langs/he_IL.txt -> data/langs/he-IL.txt to better conform with existing translations.
|
|
||||||
|
|
||||||
[ M33 ]
|
|
||||||
* Revert "Update tests/meson.build"
|
|
||||||
|
|
||||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Mon, 12 Apr 2021 10:40:32 +0000
|
|
||||||
|
|
||||||
squeekboard (1.12.0pureos0~amber0) amber-phone; urgency=medium
|
|
||||||
|
|
||||||
[ Dorota Czaplejewicz ]
|
[ Dorota Czaplejewicz ]
|
||||||
* docs: Correct Cargo update instructions
|
* debian: New upstream release
|
||||||
* visibility: Centralize keyboard panel visibility policy and handling
|
|
||||||
* build: Fix release
|
|
||||||
* tests: Prefer the env var for finding test layouts
|
|
||||||
* tests: Explicitly pass source directory to tests
|
|
||||||
* debian: Build reproducibly
|
|
||||||
* tests: Allow legacy mode to have much longer tests.
|
|
||||||
* build: Enable unused warnings in C
|
|
||||||
* build: Enable wformat to remove warnings about missing wformat
|
|
||||||
* build: Fail on any C warnings when strict
|
|
||||||
* data: Made data flow in fallback clearer
|
|
||||||
* data: Flattened layout fallback function
|
|
||||||
* layouts: Use base as fallback for alternative layouts
|
|
||||||
* layouts: Simplify the main flow of source list
|
|
||||||
* tests: Add some description to the list of tested layouts
|
|
||||||
* layout_names: Unmess the list of builtin layouts
|
|
||||||
* dbus: Reset hints if text input missing
|
|
||||||
* visibility: Stop calling GTK functions from the visibility manager
|
|
||||||
|
|
||||||
[ Wannaphong Phatthiyaphaibun ]
|
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Mon, 12 Apr 2021 10:50:32 +0000a
|
||||||
* Add thai keyboard
|
|
||||||
* Update resources.rs
|
|
||||||
* Update meson.build
|
|
||||||
* escape " on thai keyboard
|
|
||||||
|
|
||||||
[ clonex10100 ]
|
squeekboard (1.12.0-1pureos1) byzantium; urgency=medium
|
||||||
* Added US Colemak Keyboard Layout
|
|
||||||
|
[ Dorota Czaplejewicz ]
|
||||||
|
* debian: New Byzantium release
|
||||||
|
|
||||||
|
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Thu, 28 Jan 2021 14:36:20 +0000
|
||||||
|
|
||||||
|
squeekboard (1.12.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
[ Henry-Nicolas Tourneur ]
|
[ Henry-Nicolas Tourneur ]
|
||||||
* d/rules: fix an FTBFS on mips64el with GOT > 64kb
|
* d/rules: fix an FTBFS on mips64el with GOT > 64kb
|
||||||
* d/rules: export RUSTFLAGS only on architecture that needs it
|
* d/rules: export RUSTFLAGS only on architecture that needs it
|
||||||
* d/rules: export RUSTFLAGS only on architecture that needs it
|
|
||||||
|
|
||||||
[ Jiří Stránský ]
|
|
||||||
* Add Czech keyboard layouts
|
|
||||||
|
|
||||||
[ Stefan Grotz ]
|
|
||||||
* Esperanto keyboard
|
|
||||||
|
|
||||||
[ Vladimir ]
|
|
||||||
* Bulgarian language keyboard layout
|
|
||||||
|
|
||||||
[ Vladimir Stoilov ]
|
|
||||||
* bulgarian add translation and to needed lists
|
|
||||||
* Fix bulgarian layout size
|
|
||||||
|
|
||||||
[ Andreas Rönnquist ]
|
|
||||||
* no: Use wide button switching between numbers, symbols and base
|
|
||||||
|
|
||||||
[ jranaraki ]
|
|
||||||
* Farsi/Persian keyboard layout
|
|
||||||
* Farsi/Persian keyboard layout
|
|
||||||
* Added requirements to resources.rs and meson.build
|
|
||||||
* Updated the layout to provide more convenient and faster typing experience
|
|
||||||
|
|
||||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Sun, 10 Jan 2021 09:43:42 +0000
|
|
||||||
|
|
||||||
squeekboard (1.11.1) amber-phone; urgency=medium
|
|
||||||
|
|
||||||
[ Mark Müller ]
|
|
||||||
* keyboard: Fix semicolon in German layout
|
|
||||||
* keyboard: Move semicolon in German layout to numbers view replacing redundant comma key
|
|
||||||
|
|
||||||
[ Dorota Czaplejewicz ]
|
[ Dorota Czaplejewicz ]
|
||||||
* imservice: Set up UI according to current needs when it shows up
|
* debian: Build reproducibly
|
||||||
* UI: Keep visibility factors in a central place
|
|
||||||
* cargo: Update deps
|
|
||||||
|
|
||||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Sat, 21 Nov 2020 11:08:06 +0000
|
|
||||||
|
|
||||||
squeekboard (1.11.0) amber-phone; urgency=medium
|
|
||||||
|
|
||||||
[ Dorota Czaplejewicz ]
|
|
||||||
* UI: Delay hiding only when leaving a text field
|
|
||||||
* ui: Cancel hiding delay when activity requested again
|
|
||||||
* Update dependencies
|
|
||||||
|
|
||||||
[ Fabio Tomat ]
|
|
||||||
* Update fur-IT.txt fix typo for Spanish
|
|
||||||
|
|
||||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Sat, 14 Nov 2020 06:46:28 +0000
|
|
||||||
|
|
||||||
squeekboard (1.10.0) amber-phone; urgency=medium
|
|
||||||
|
|
||||||
[ Dorota Czaplejewicz ]
|
|
||||||
* virtual_keyboard: Fix desynced modifiers state
|
|
||||||
* rust: Fix deprecation warnings
|
|
||||||
* docs: Tutorial syntax cleanups
|
|
||||||
* docs: Reorganize tutorial
|
|
||||||
* build: Error on repeating declarations
|
|
||||||
* keymap: Generate from symbol map, not layout
|
|
||||||
* data: Restore testability of action->keysym conversion
|
|
||||||
* syntax: Let older rustc understand symbolmap's lifetime
|
|
||||||
* debian: Insert a "breaks" for librem5-base < 24
|
|
||||||
* keymap: Keep keymap fd management in one place
|
|
||||||
* vkeyboard: Use a generic slice instead of a vector
|
|
||||||
* tests: Check for missing return in builtin layouts except emoji
|
|
||||||
* keymap: Concentrate special handling of BackSpace, which is implicit in Erase action
|
|
||||||
* keymaps: Use multiple key maps, each within the limit of what Xorg can accept.
|
|
||||||
* build: Avoid MaybeUninit on older Debian
|
|
||||||
* tests: Fix bad field access
|
|
||||||
* cargo: Update dependencies
|
|
||||||
|
|
||||||
[ Guido Günther ]
|
|
||||||
* eekboard-context-service: Return early if schema is unavailable
|
|
||||||
* treewide: Use new style function definitions
|
|
||||||
* build: Enable '-Wold-style-definition' '-Wstrict-prototypes'
|
|
||||||
* build: Enable '-Wunused-function'
|
|
||||||
* eekboard-context-service: Drop EEKBOARD_CONTEXT_SERVICE_GET_PRIVATE
|
|
||||||
* keyboard: Fix warning
|
|
||||||
* layout: Fix warning
|
|
||||||
* gitlab-ci: Enable --Werror
|
|
||||||
* eek-keyboard: Don't ignore return value
|
|
||||||
* build: Enable -Winit-self
|
|
||||||
* build: Enable -Wformat-security
|
|
||||||
* build: Enable -Wmaybe-uninitialized
|
|
||||||
* treewide: Drop redundant declarations
|
|
||||||
* build: Enable -Wredundant-declarations
|
|
||||||
* ServerContextService: Drop GObject boilerplate
|
|
||||||
* build: Enable '-Wformat-nonliteral'
|
|
||||||
* eekboad-context-service: Drop signal class handler
|
|
||||||
* eekboard-context-service: Drop docstrings for inexistent functions
|
|
||||||
* eekboard-context-service: Drop the GObject boilerplate
|
|
||||||
* eekboard-context-service: Drop private struct
|
|
||||||
* server-context-service: Consistenty name self argument 'self'
|
|
||||||
* server-context-service: swap signal arguments
|
|
||||||
* server-context-service: Don't show keyboard when disabled (Closes: #222)
|
|
||||||
|
|
||||||
[ Nazarii Kretovych ]
|
|
||||||
* Add Ukrainian keyboard layout.
|
|
||||||
|
|
||||||
[ Benjamin Schaaf ]
|
|
||||||
* Fix spelling mistakes in doc/hacking.md
|
|
||||||
* Expand the development documentation in the readme
|
|
||||||
* Expand key press detection to the edges of the view's bounding box
|
|
||||||
* Sort layouts by type before sorting by name
|
|
||||||
* Fix leak in level_keyboard_new
|
|
||||||
* Fix leak endlessly adding a resource path to the default theme
|
|
||||||
* Add settings option to popover
|
|
||||||
|
|
||||||
[ Al ]
|
|
||||||
* proposal for belgian layout (copy of fr)
|
|
||||||
* alphabetical order for src/resources.rs tests/meson.build
|
|
||||||
|
|
||||||
[ Arnaud Ferraris ]
|
[ Arnaud Ferraris ]
|
||||||
* eek-gtk-keyboard: use virtual resolution to check arrangement kind
|
* New upstream version 1.12.0
|
||||||
* server-context-service: optimize height calculation
|
|
||||||
* keyboards: add wide French layout
|
|
||||||
* keyboards: add wide Belgian layout
|
|
||||||
* keyboards: add wide terminal layout
|
|
||||||
|
|
||||||
[ Fabio Tomat ]
|
-- Arnaud Ferraris <arnaud.ferraris@gmail.com> Tue, 26 Jan 2021 18:19:42 +0100
|
||||||
* Revert "Add friulian keyboard"
|
|
||||||
|
|
||||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Mon, 19 Oct 2020 14:07:01 +0000
|
squeekboard (1.11.1-1) unstable; urgency=medium
|
||||||
|
|
||||||
squeekboard (1.9.3) amber-phone; urgency=medium
|
* New upstream version 1.11.1
|
||||||
|
|
||||||
[ Björn Tantau ]
|
-- Arnaud Ferraris <arnaud.ferraris@gmail.com> Tue, 24 Nov 2020 11:52:41 +0100
|
||||||
* Show more useful keys at the same time.
|
|
||||||
* Add Ctrl and Alt modifier keys.
|
|
||||||
* Add missing Ê key.
|
|
||||||
* Make f-keys slightly wider.
|
|
||||||
* Add Menu key.
|
|
||||||
|
|
||||||
[ Guido Günther ]
|
squeekboard (1.11.0-1) unstable; urgency=medium
|
||||||
* d/rules: Only remove Cargo.lock if it exists
|
|
||||||
* eek: Drop libcanberra usage
|
|
||||||
* debian: Build-depend on libfeedback
|
|
||||||
* eek-gtk-keyboard: Trigger event feedback on button press (Closes: #166)
|
|
||||||
|
|
||||||
[ Dorota Czaplejewicz ]
|
* New upstream release 1.11.0
|
||||||
* build: Add missing gio-unix dependency
|
|
||||||
* build: Make compatible with Debian Bullseye
|
|
||||||
* debian: Add amber to legacy distro list
|
|
||||||
* ci: Add amber job
|
|
||||||
* debian: Require lsb-release
|
|
||||||
* size: Hardcode size to work around screen rotation
|
|
||||||
* ci: Re-add x64 Buster build
|
|
||||||
* italian: Fix space and period
|
|
||||||
|
|
||||||
[ Sebastian Krzyszkowiak ]
|
-- Arnaud Ferraris <arnaud.ferraris@gmail.com> Mon, 16 Nov 2020 11:17:23 +0100
|
||||||
* Revert "Merge branch 'btantau-master-patch-76686' into 'master'"
|
|
||||||
* Terminal layout: another approach
|
|
||||||
|
|
||||||
[ Luís Fernando Stürmer da Rosa ]
|
squeekboard (1.10.0-2) unstable; urgency=medium
|
||||||
* Brazilian Portuguese Keyboard Layout.
|
|
||||||
|
|
||||||
-- Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm> Wed, 05 Aug 2020 16:16:08 +0200
|
* Team upload.
|
||||||
|
* d/rules: set RUSTFLAGS to avoid an FTBFS on mips64el (Closes: #974036)
|
||||||
|
|
||||||
squeekboard (1.9.2) amber-phone; urgency=medium
|
-- Henry-Nicolas Tourneur <debian@nilux.be> Tue, 10 Nov 2020 18:40:50 +0000
|
||||||
|
|
||||||
[ Dorota Czaplejewicz ]
|
squeekboard (1.10.0-1) unstable; urgency=medium
|
||||||
* keyboard: Remove unused code
|
|
||||||
* gsettings: Don't crash when unavailable
|
|
||||||
* dbus: Don't crash if can't make a connection
|
|
||||||
* gsettings: Don't crash on switching when unavailable
|
|
||||||
* layout: Split out choice to a struct on its own
|
|
||||||
* renderer: Simplify by dropping gobjectness
|
|
||||||
* levelkeyboard: Rearrange to make future conversion easier
|
|
||||||
* layout: Minor generalizations
|
|
||||||
* Remove unused code
|
|
||||||
* sizing: Create a standalone UI shape manager
|
|
||||||
* sizing: Ignore scaling factor for layout selection
|
|
||||||
* CI: Fix typo
|
|
||||||
* Update rust deps for release
|
|
||||||
|
|
||||||
[ Andreas Rönnquist ]
|
* New upstream release 1.10.0
|
||||||
* Swedish keyboard, wide button switching between numbers, symbols and base
|
* d/control: build-depend on libfeedbackd-dev and set team maintainership
|
||||||
* More fixes of button sizes
|
* d/control: fix dependency name
|
||||||
* Folder is doc, not docs
|
* d/copyright: add missing entries
|
||||||
|
* d/copyright: add entries for new keyboard files and remove duplicate
|
||||||
|
`src/meson.build` appeared in 2 different paragraphs, remove the
|
||||||
|
duplicate entry.
|
||||||
|
* d/gbp.conf: fix debian version number
|
||||||
|
|
||||||
[ uzanto ]
|
-- Arnaud Ferraris <arnaud.ferraris@gmail.com> Fri, 23 Oct 2020 13:18:43 +0200
|
||||||
* Add new file
|
|
||||||
* Replace duplicated show_symbols by show_eschars and removed "Delete" button that it's doing nothing
|
|
||||||
|
|
||||||
[ Arnaud Ferraris ]
|
squeekboard (1.9.3-1) experimental; urgency=medium
|
||||||
* keyboards: fr: fix keyboard layout
|
|
||||||
* keyboards: fr: make sure the layout fits the screen
|
|
||||||
* resources: include French keyboard layout
|
|
||||||
* keyboards: fr: improve consistency with other layouts
|
|
||||||
* keyboards: fr: improve diacritics layout
|
|
||||||
* tests: add french layout
|
|
||||||
|
|
||||||
[ Vlad ]
|
* Upload to experimental
|
||||||
* Fresh Russian layout
|
* Update upstream source from tag 'v1.9.3'
|
||||||
|
Update to upstream version '1.9.3'
|
||||||
|
with Debian dir 7a3f8b82779759ba288b75755ba54500250b0ff4
|
||||||
|
* d/control: Use librust-xkbcommon-dev
|
||||||
|
This one avoids the empty feature package.
|
||||||
|
* Ship sm.puri.OSK0.desktop.
|
||||||
|
This is needed to fulfill phosh's session dependencies
|
||||||
|
* Conflict with phosh-osk-stub.
|
||||||
|
They're not useful at the same time and we'll drop phosh-osk-stub from
|
||||||
|
Debian once squeekboard is in.
|
||||||
|
* Drop pathes no longer required due to upstream changes
|
||||||
|
- 0001-Cargo.toml-update-to-Debian-dependencies-versions.patch
|
||||||
|
- 0002-popover.rs-fix-build-with-gtk-rs-0.7.0.patch
|
||||||
|
* d/gbp.conf: Don't use patch numbers.
|
||||||
|
Ordering is defined via the series file and patch numbers just
|
||||||
|
cause manual work.
|
||||||
|
|
||||||
[ Jordi Masip ]
|
-- Guido Günther <agx@sigxcpu.org> Sat, 26 Sep 2020 13:01:18 +0200
|
||||||
* Removed unused dependency 'libcroco'
|
|
||||||
|
|
||||||
[ Florian Klink ]
|
squeekboard (1.9.2-1) UNRELEASED; urgency=medium
|
||||||
* sm.puri.Squeekboard.desktop: make path to Exec= absolute
|
|
||||||
|
|
||||||
[ Ole Guldberg ]
|
* Initial Debian release (Closes: #956960)
|
||||||
* Danish keyboard layout
|
|
||||||
* Danish keyboard layout
|
|
||||||
* add test for danish layout
|
|
||||||
|
|
||||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Mon, 01 Jun 2020 09:39:12 +0000
|
-- Arnaud Ferraris <arnaud.ferraris@gmail.com> Tue, 09 Jun 2020 23:29:19 +0200
|
||||||
|
|
||||||
squeekboard (1.9.1) amber-phone; urgency=medium
|
|
||||||
|
|
||||||
[ Dorota Czaplejewicz ]
|
|
||||||
* layout: Improve press handling
|
|
||||||
* settings: Handle empty settings
|
|
||||||
* Variant: Use proper pointer conversion between C and Rust
|
|
||||||
* meta: Add doap file
|
|
||||||
* modifiers: Support Control and Alt
|
|
||||||
* CI: Test that any bump to changelog has a corresponding tag
|
|
||||||
* docs: Add the guiding principle
|
|
||||||
* hacking: Move into docs/
|
|
||||||
|
|
||||||
[ &t ]
|
|
||||||
* Fix minor comment typos
|
|
||||||
|
|
||||||
[ Dorota Czaplejewicz ]
|
|
||||||
* cargo: Bump package versions before release
|
|
||||||
|
|
||||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Sun, 08 Mar 2020 10:04:29 +0000
|
|
||||||
|
|
||||||
squeekboard (1.9.0) amber-phone; urgency=medium
|
|
||||||
|
|
||||||
[ Dorota Czaplejewicz ]
|
|
||||||
* imservice: Add commit_string method
|
|
||||||
* submission: Handle submitting strings
|
|
||||||
* input_method: Use for erasing
|
|
||||||
* logging: Use in merged functions
|
|
||||||
* translations: Remove redundant ones
|
|
||||||
* translations: Translate builtin layouts
|
|
||||||
* greek: Rename to gr which is used by gnome settings
|
|
||||||
|
|
||||||
[ Sebastian Krzyszkowiak ]
|
|
||||||
* layouts: Add Polish layouts
|
|
||||||
|
|
||||||
[ Dorota Czaplejewicz ]
|
|
||||||
* locks: Draw based on current view
|
|
||||||
* locking: Lock keys statelessly
|
|
||||||
* layouts: Better accented uppercase in PL
|
|
||||||
* emoji: Add more choices
|
|
||||||
* row: Eliminate angle
|
|
||||||
* layout: Center views relative to each other and the layout bounds
|
|
||||||
* drawing: Generalized foreach_visible_button
|
|
||||||
* variant: Fix double-free
|
|
||||||
* variant: Fix leak
|
|
||||||
* keyboard_layout: Fix leak
|
|
||||||
* layout: Improve scoping of locked variable
|
|
||||||
* terminal: Make */ easier to reach
|
|
||||||
|
|
||||||
[ Sebastian Krzyszkowiak ]
|
|
||||||
* layouts: terminal: Use altline outline for dot key
|
|
||||||
|
|
||||||
[ Dorota Czaplejewicz ]
|
|
||||||
* text input: Disable erasing
|
|
||||||
* cargo: Update deps
|
|
||||||
|
|
||||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Wed, 19 Feb 2020 14:32:39 +0000
|
|
||||||
|
|
||||||
squeekboard (1.8.1) amber-phone; urgency=medium
|
|
||||||
|
|
||||||
[ Dorota Czaplejewicz ]
|
|
||||||
* action: Rename Level to View
|
|
||||||
* keyboard: Introduce a KeyCode type wrapping u32
|
|
||||||
* layout: Centralize handling key releases
|
|
||||||
* layout: Make handling presses uniform
|
|
||||||
* UI: Drop indirection for show/hide functions
|
|
||||||
* managers: Move visible flag to UI manager
|
|
||||||
* dbus_service: Remove unused function
|
|
||||||
* dbus: Remove unneeded gobjectness
|
|
||||||
* dbus: Rename handler from eekboard_service
|
|
||||||
* context: Moved keymap setting together with its generation
|
|
||||||
* key-emitter: Remove unused
|
|
||||||
* eekboard_context_service: Drop unused enable property
|
|
||||||
* services: Split out layout management from EekboardContextService
|
|
||||||
* submission: Move away from virtual-keyboard
|
|
||||||
* submission: Create a new wrapper over imservice
|
|
||||||
* imservice: Limited scope of unsafe
|
|
||||||
* EekGtkKeyboard: Use a direct reference to EekboardContext
|
|
||||||
* submission: Take over virtual_keyboard handling
|
|
||||||
* keyboard: Cleanups of unused code
|
|
||||||
* levelkeyboard: Drop unused manager references
|
|
||||||
* keyboard: Gather up keymap handling, drop layout
|
|
||||||
* submission: Remove wildcard reexport
|
|
||||||
* imservice: Rename commit_state to done to match protocol
|
|
||||||
* ci: Clean up `..` before it's searched for artifacts
|
|
||||||
* dbus: Log error on dbus exit
|
|
||||||
* logging: Try to improve common operations
|
|
||||||
* imservice: Return something more resembling an Error on failure
|
|
||||||
* logging: Unified to remove random eprint calls
|
|
||||||
* press_key: Use proper logging
|
|
||||||
* number: Fix keysym for Return
|
|
||||||
* build: Strip clap of optional features
|
|
||||||
* layouts: Fix segfault on switching to wide
|
|
||||||
* font: Use font from style context
|
|
||||||
* font: Only pass relevant data to label renderer
|
|
||||||
|
|
||||||
[ Sebastian Krzyszkowiak ]
|
|
||||||
* layout: terminal: Swap positions of preferences and actions button
|
|
||||||
* layout: terminal: Show actions button on all views
|
|
||||||
* layout: terminal: Replace actions button with period on symbols view
|
|
||||||
|
|
||||||
[ Dorota Czaplejewicz ]
|
|
||||||
* setup: Connect ui to the state manager
|
|
||||||
* debian: Add missing commas
|
|
||||||
|
|
||||||
[ David Boddie ]
|
|
||||||
* Tidy build file and docs
|
|
||||||
* Use pip to install recommonmark
|
|
||||||
|
|
||||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Fri, 31 Jan 2020 09:59:12 +0000
|
|
||||||
|
|
||||||
squeekboard (1.8.0) amber-phone; urgency=medium
|
|
||||||
|
|
||||||
[ Dorota Czaplejewicz ]
|
|
||||||
* translations: Use gnome-desktop's xkb info database for layout names
|
|
||||||
* translations: Make the code cleaner
|
|
||||||
* overlay: Add terminal
|
|
||||||
* eek-layout: Remove unused
|
|
||||||
* pre-release: Update deps
|
|
||||||
|
|
||||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Tue, 14 Jan 2020 13:55:00 +0000
|
|
||||||
|
|
||||||
squeekboard (1.7.0) amber-phone; urgency=medium
|
|
||||||
|
|
||||||
* New terminal layout appearing on terminal input hint
|
|
||||||
|
|
||||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Wed, 08 Jan 2020 11:53:07 +0000
|
|
||||||
|
|
||||||
squeekboard (1.7.0) amber-phone; urgency=medium
|
|
||||||
|
|
||||||
* New terminal layout appearing on terminal input hint
|
|
||||||
|
|
||||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Wed, 08 Jan 2020 11:53:07 +0000
|
|
||||||
|
|
||||||
squeekboard (1.6.0) amber-phone; urgency=medium
|
|
||||||
|
|
||||||
[ Dorota Czaplejewicz ]
|
|
||||||
* tools: Move entry.py
|
|
||||||
* build: Move building of squeekboard-test-layout to tools
|
|
||||||
* packaging: Install entty.py as squeekboard-entry
|
|
||||||
* Remove unused build dependencies
|
|
||||||
* Remove unused header generator
|
|
||||||
* logging: Move all facilities to one file
|
|
||||||
* logging: Described the design
|
|
||||||
* logging: Add described log levels
|
|
||||||
* popover: Install emoji layout
|
|
||||||
* popover: Show overlays as selected
|
|
||||||
* Fix old Rust woes
|
|
||||||
* emoji: Add a passable layout
|
|
||||||
* Fix g_ and stdlib allocation/free mismatches
|
|
||||||
|
|
||||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Thu, 02 Jan 2020 12:02:50 +0000
|
|
||||||
|
|
||||||
squeekboard (1.5.0) amber-phone; urgency=medium
|
|
||||||
|
|
||||||
[ Dorota Czaplejewicz ]
|
|
||||||
* keycodes: Sort to eliminate runtime indeterminism
|
|
||||||
* switcher: Switch layout on menu item click
|
|
||||||
* Drop squeek_key
|
|
||||||
* renderer: Remove some unneeded vars
|
|
||||||
* renderer: Simplified outline rendering
|
|
||||||
* renderer: Drop row from button rendering
|
|
||||||
* renderer: Drop unused params
|
|
||||||
* renderer: Simplify surface rendering
|
|
||||||
* rendering: Simplify Cairo context usage, remove unneeded calls.
|
|
||||||
* rendering: Remove unneeded redraw after button release
|
|
||||||
* renderer: Remove unused locked key render function
|
|
||||||
* renderer: Simply cut off when painting outside bounds
|
|
||||||
* renderer: Render whole keyboard the same way as pressed buttons
|
|
||||||
|
|
||||||
[ Mark Müller ]
|
|
||||||
* layout: add German wide layout
|
|
||||||
|
|
||||||
[ Dorota Czaplejewicz ]
|
|
||||||
* renderer: Remove unused functions
|
|
||||||
* cleanup: Remove references to squeek_view
|
|
||||||
* cleanup: Unbox View and Row
|
|
||||||
* cleanup: Remove unused single frame draw
|
|
||||||
* positioning: Calculate sizes instead of storing, move position out of widgets
|
|
||||||
* positioning: Clean up unused code
|
|
||||||
* Fix old Rust woes
|
|
||||||
|
|
||||||
[ Mark Müller ]
|
|
||||||
* layout: add Japanese Kana wide layout
|
|
||||||
|
|
||||||
[ Dorota Czaplejewicz ]
|
|
||||||
* Entry test: Add Terminal input purpose
|
|
||||||
* readme: Add note about Cargo dependencies
|
|
||||||
* Create a library/UI module separation
|
|
||||||
* hacking: Add DCO and licensing requirement
|
|
||||||
* Fix internal .md link
|
|
||||||
|
|
||||||
[ Mark Müller ]
|
|
||||||
* squeekboard-test-layout: add argument parsing and some more output
|
|
||||||
|
|
||||||
[ Dorota Czaplejewicz ]
|
|
||||||
* Use clap in the lockfile
|
|
||||||
* parsing: Remove bounds which weren't used anyway
|
|
||||||
* layout: Respect margins
|
|
||||||
* CI: Build arm64 .deb
|
|
||||||
|
|
||||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Mon, 23 Dec 2019 11:58:57 +0000
|
|
||||||
|
|
||||||
squeekboard (1.4.0) amber-phone; urgency=medium
|
|
||||||
|
|
||||||
* "text" property in layouts
|
|
||||||
* Adjusts to user's color scheme
|
|
||||||
|
|
||||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Mon, 02 Dec 2019 19:37:01 +0000
|
|
||||||
|
|
||||||
squeekboard (1.3.2) amber-phone; urgency=medium
|
|
||||||
|
|
||||||
* Make sure all key presses get accepted by the compositor
|
|
||||||
|
|
||||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Tue, 26 Nov 2019 15:36:27 +0000
|
|
||||||
|
|
||||||
squeekboard (1.3.1) amber-phone; urgency=medium
|
|
||||||
|
|
||||||
* Update and fix layouts and languages
|
|
||||||
* Make tests less likely to fail
|
|
||||||
|
|
||||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Wed, 20 Nov 2019 22:10:48 +0000
|
|
||||||
|
|
||||||
squeekboard (1.3.0) amber-phone; urgency=medium
|
|
||||||
|
|
||||||
* Language selection popup
|
|
||||||
* Swedish and Finnish layouts
|
|
||||||
|
|
||||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Sat, 16 Nov 2019 15:38:14 +0000
|
|
||||||
|
|
||||||
squeekboard (1.2.2) amber-phone; urgency=medium
|
|
||||||
|
|
||||||
* Landscape mode
|
|
||||||
|
|
||||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Wed, 30 Oct 2019 12:38:39 +0000
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Tue, 24 Sep 2019 10:42:15 +0000
|
|
||||||
|
|
||||||
squeekboard (1.1.0) unstable; urgency=medium
|
|
||||||
|
|
||||||
* Use new keyboard layout format
|
|
||||||
|
|
||||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Mon, 02 Sep 2019 10:12:02 +0000
|
|
||||||
|
|
||||||
|
|
||||||
squeekboard (1.0.10) unstable; urgency=medium
|
|
||||||
|
|
||||||
* Use a shared DBus definition
|
|
||||||
|
|
||||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Tue, 02 Jul 2019 20:12:02 +0000
|
|
||||||
|
|
||||||
squeekboard (1.0.9) unstable; urgency=medium
|
|
||||||
|
|
||||||
* Initial release.
|
|
||||||
|
|
||||||
-- David Boddie <david.boddie@puri.sm> Tue, 25 Jun 2019 19:33:00 +0200
|
|
||||||
|
|||||||
2
debian/control
vendored
2
debian/control
vendored
@ -31,6 +31,8 @@ Build-Depends:
|
|||||||
wayland-protocols (>= 1.14),
|
wayland-protocols (>= 1.14),
|
||||||
Standards-Version: 4.1.3
|
Standards-Version: 4.1.3
|
||||||
Homepage: https://source.puri.sm/Librem5/squeekboard
|
Homepage: https://source.puri.sm/Librem5/squeekboard
|
||||||
|
Vcs-Browser: https://source.puri.sm/pureos/squeekboard
|
||||||
|
Vcs-Git: https://source.puri.sm/pureos/squeekboard.git
|
||||||
|
|
||||||
Package: squeekboard
|
Package: squeekboard
|
||||||
Architecture: linux-any
|
Architecture: linux-any
|
||||||
|
|||||||
7
debian/gbp.conf
vendored
Normal file
7
debian/gbp.conf
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
debian-branch = pureos/byzantium
|
||||||
|
debian-tag = pureos/%(version)s
|
||||||
|
debian-tag-msg = %(pkg)s %(version)s
|
||||||
|
|
||||||
|
[tag]
|
||||||
|
sign-tags = true
|
||||||
29
debian/librem5-ci.yml
vendored
Normal file
29
debian/librem5-ci.yml
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
include:
|
||||||
|
- 'https://source.puri.sm/Librem5/librem5-ci/raw/master/librem5-pipeline-definitions.yml'
|
||||||
|
- 'https://source.puri.sm/Librem5/librem5-ci/raw/master/librem5-pipeline-byzantium-jobs.yml'
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- package
|
||||||
|
- test-package
|
||||||
|
|
||||||
|
.tags: &tags
|
||||||
|
tags:
|
||||||
|
- librem5
|
||||||
|
|
||||||
|
check_release:
|
||||||
|
<<: *tags
|
||||||
|
stage: test-package
|
||||||
|
only:
|
||||||
|
refs:
|
||||||
|
- pureos/byzantium
|
||||||
|
script:
|
||||||
|
- apt-get -y install git python3
|
||||||
|
- (head -n 1 ./debian/changelog && git tag) | ./debian/check_release.py
|
||||||
|
|
||||||
|
# check-tarball relies on the contents of other branches,
|
||||||
|
# which are irrelevant for MRs. It's similar to checking tags in this way.
|
||||||
|
check-tarball:
|
||||||
|
extends: .l5-check-tarball
|
||||||
|
only:
|
||||||
|
refs:
|
||||||
|
- pureos/byzantium
|
||||||
2
debian/source/format
vendored
2
debian/source/format
vendored
@ -1 +1 @@
|
|||||||
3.0 (native)
|
3.0 (quilt)
|
||||||
|
|||||||
@ -287,7 +287,7 @@ eek_renderer_new (LevelKeyboard *keyboard,
|
|||||||
}
|
}
|
||||||
gtk_style_context_add_provider (renderer->view_context,
|
gtk_style_context_add_provider (renderer->view_context,
|
||||||
GTK_STYLE_PROVIDER(renderer->css_provider),
|
GTK_STYLE_PROVIDER(renderer->css_provider),
|
||||||
GTK_STYLE_PROVIDER_PRIORITY_USER);
|
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||||
|
|
||||||
/* Create a style context for the buttons */
|
/* Create a style context for the buttons */
|
||||||
path = gtk_widget_path_new();
|
path = gtk_widget_path_new();
|
||||||
@ -303,7 +303,7 @@ eek_renderer_new (LevelKeyboard *keyboard,
|
|||||||
gtk_style_context_set_state (renderer->button_context, GTK_STATE_FLAG_NORMAL);
|
gtk_style_context_set_state (renderer->button_context, GTK_STATE_FLAG_NORMAL);
|
||||||
gtk_style_context_add_provider (renderer->button_context,
|
gtk_style_context_add_provider (renderer->button_context,
|
||||||
GTK_STYLE_PROVIDER(renderer->css_provider),
|
GTK_STYLE_PROVIDER(renderer->css_provider),
|
||||||
GTK_STYLE_PROVIDER_PRIORITY_USER);
|
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||||
return renderer;
|
return renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
project(
|
project(
|
||||||
'squeekboard',
|
'squeekboard',
|
||||||
'c', 'rust',
|
'c', 'rust',
|
||||||
version: '1.13.0',
|
version: '1.14.0',
|
||||||
license: 'GPLv3',
|
license: 'GPLv3',
|
||||||
meson_version: '>=0.51.0',
|
meson_version: '>=0.51.0',
|
||||||
default_options: [
|
default_options: [
|
||||||
|
|||||||
424
src/data/loading.rs
Normal file
424
src/data/loading.rs
Normal file
@ -0,0 +1,424 @@
|
|||||||
|
/* Copyright (C) 2020-2021 Purism SPC
|
||||||
|
* SPDX-License-Identifier: GPL-3.0+
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! Loading layout files */
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
use std::fmt;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
|
use super::{ Error, LoadError };
|
||||||
|
use super::parsing;
|
||||||
|
|
||||||
|
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);
|
||||||
|
Box::into_raw(Box::new(layout))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const FALLBACK_LAYOUT_NAME: &str = "us";
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
enum DataSource {
|
||||||
|
File(PathBuf),
|
||||||
|
Resource(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for DataSource {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
DataSource::File(path) => write!(f, "Path: {:?}", path.display()),
|
||||||
|
DataSource::Resource(name) => write!(f, "Resource: {}", name),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All functions in this family carry around ArrangementKind,
|
||||||
|
* because it's not guaranteed to be preserved,
|
||||||
|
* and the resulting layout needs to know which version was loaded.
|
||||||
|
* See `squeek_layout_get_kind`.
|
||||||
|
* Possible TODO: since this is used only in styling,
|
||||||
|
* and makes the below code nastier than needed, maybe it should go.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/// Returns ordered names treating `name` as the base name,
|
||||||
|
/// ignoring any `+` inside.
|
||||||
|
fn _get_arrangement_names(name: &str, arrangement: ArrangementKind)
|
||||||
|
-> Vec<(ArrangementKind, String)>
|
||||||
|
{
|
||||||
|
let name_with_arrangement = match arrangement {
|
||||||
|
ArrangementKind::Base => name.into(),
|
||||||
|
ArrangementKind::Wide => format!("{}_wide", name),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut ret = Vec::new();
|
||||||
|
if name_with_arrangement != name {
|
||||||
|
ret.push((arrangement, name_with_arrangement));
|
||||||
|
}
|
||||||
|
ret.push((ArrangementKind::Base, name.into()));
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns names accounting for any `+` in the `name`,
|
||||||
|
/// including the fallback to the default layout.
|
||||||
|
fn get_preferred_names(name: &str, kind: ArrangementKind)
|
||||||
|
-> Vec<(ArrangementKind, String)>
|
||||||
|
{
|
||||||
|
let mut ret = _get_arrangement_names(name, kind);
|
||||||
|
|
||||||
|
let base_name_preferences = {
|
||||||
|
let mut parts = name.splitn(2, '+');
|
||||||
|
match parts.next() {
|
||||||
|
Some(base) => {
|
||||||
|
// The name is already equal to base, so nothing to add
|
||||||
|
if base == name {
|
||||||
|
vec![]
|
||||||
|
} else {
|
||||||
|
_get_arrangement_names(base, kind)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// The layout's base name starts with a "+". Weird but OK.
|
||||||
|
None => {
|
||||||
|
log_print!(logging::Level::Surprise, "Base layout name is empty: {}", name);
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ret.extend(base_name_preferences.into_iter());
|
||||||
|
let fallback_names = _get_arrangement_names(FALLBACK_LAYOUT_NAME, kind);
|
||||||
|
ret.extend(fallback_names.into_iter());
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Includes the subdirectory before the forward slash.
|
||||||
|
type LayoutPath = String;
|
||||||
|
|
||||||
|
// This is only used inside iter_fallbacks_with_meta.
|
||||||
|
// Placed at the top scope
|
||||||
|
// because `use LayoutPurpose::*;`
|
||||||
|
// complains about "not in scope" otherwise.
|
||||||
|
// This seems to be a Rust 2015 edition problem.
|
||||||
|
/// Helper for determining where to look up the layout.
|
||||||
|
enum LayoutPurpose<'a> {
|
||||||
|
Default,
|
||||||
|
Special(&'a str),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the directory string
|
||||||
|
/// where the layout should be looked up, including the slash.
|
||||||
|
fn get_directory_string(
|
||||||
|
content_purpose: ContentPurpose,
|
||||||
|
overlay: Option<&str>) -> String
|
||||||
|
{
|
||||||
|
use self::LayoutPurpose::*;
|
||||||
|
|
||||||
|
let layout_purpose = match overlay {
|
||||||
|
None => match content_purpose {
|
||||||
|
ContentPurpose::Number => Special("number"),
|
||||||
|
ContentPurpose::Digits => Special("number"),
|
||||||
|
ContentPurpose::Phone => Special("number"),
|
||||||
|
ContentPurpose::Terminal => Special("terminal"),
|
||||||
|
_ => Default,
|
||||||
|
},
|
||||||
|
Some(overlay) => Special(overlay),
|
||||||
|
};
|
||||||
|
|
||||||
|
// For intuitiveness,
|
||||||
|
// default purpose layouts are stored in the root directory,
|
||||||
|
// as they correspond to typical text
|
||||||
|
// and are seen the most often.
|
||||||
|
match layout_purpose {
|
||||||
|
Default => "".into(),
|
||||||
|
Special(purpose) => format!("{}/", purpose),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator over all fallback paths.
|
||||||
|
fn to_layout_paths(
|
||||||
|
name_fallbacks: Vec<(ArrangementKind, String)>,
|
||||||
|
content_purpose: ContentPurpose,
|
||||||
|
overlay: Option<&str>,
|
||||||
|
) -> impl Iterator<Item=(ArrangementKind, LayoutPath)> {
|
||||||
|
let prepend_directory = get_directory_string(content_purpose, overlay);
|
||||||
|
|
||||||
|
name_fallbacks.into_iter()
|
||||||
|
.map(move |(arrangement, name)|
|
||||||
|
(arrangement, format!("{}{}", prepend_directory, name))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
type LayoutSource = (ArrangementKind, DataSource);
|
||||||
|
|
||||||
|
fn to_layout_sources(
|
||||||
|
layout_paths: impl Iterator<Item=(ArrangementKind, LayoutPath)>,
|
||||||
|
filesystem_path: Option<PathBuf>,
|
||||||
|
) -> impl Iterator<Item=LayoutSource> {
|
||||||
|
layout_paths.flat_map(move |(arrangement, layout_path)| {
|
||||||
|
let mut sources = Vec::new();
|
||||||
|
if let Some(path) = &filesystem_path {
|
||||||
|
sources.push((
|
||||||
|
arrangement,
|
||||||
|
DataSource::File(
|
||||||
|
path.join(&layout_path)
|
||||||
|
.with_extension("yaml")
|
||||||
|
)
|
||||||
|
));
|
||||||
|
};
|
||||||
|
sources.push((arrangement, DataSource::Resource(layout_path.clone())));
|
||||||
|
sources.into_iter()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns possible sources, with first as the most preferred one.
|
||||||
|
/// Trying order: native lang of the right kind, native base,
|
||||||
|
/// fallback lang of the right kind, fallback base
|
||||||
|
fn iter_layout_sources(
|
||||||
|
name: &str,
|
||||||
|
arrangement: ArrangementKind,
|
||||||
|
purpose: ContentPurpose,
|
||||||
|
ui_overlay: Option<&str>,
|
||||||
|
layout_storage: Option<PathBuf>,
|
||||||
|
) -> impl Iterator<Item=LayoutSource> {
|
||||||
|
let names = get_preferred_names(name, arrangement);
|
||||||
|
let paths = to_layout_paths(names, purpose, ui_overlay);
|
||||||
|
to_layout_sources(paths, layout_storage)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_layout_data(source: DataSource)
|
||||||
|
-> Result<::layout::LayoutData, LoadError>
|
||||||
|
{
|
||||||
|
let handler = logging::Print {};
|
||||||
|
match source {
|
||||||
|
DataSource::File(path) => {
|
||||||
|
parsing::Layout::from_file(path.clone())
|
||||||
|
.map_err(LoadError::BadData)
|
||||||
|
.and_then(|layout|
|
||||||
|
layout.build(handler).0.map_err(LoadError::BadKeyMap)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
DataSource::Resource(name) => {
|
||||||
|
parsing::Layout::from_resource(&name)
|
||||||
|
.and_then(|layout|
|
||||||
|
layout.build(handler).0.map_err(LoadError::BadKeyMap)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_layout_data_with_fallback(
|
||||||
|
name: &str,
|
||||||
|
kind: ArrangementKind,
|
||||||
|
purpose: ContentPurpose,
|
||||||
|
overlay: Option<&str>,
|
||||||
|
) -> (ArrangementKind, ::layout::LayoutData) {
|
||||||
|
|
||||||
|
// Build the path to the right keyboard layout subdirectory
|
||||||
|
let path = env::var_os("SQUEEKBOARD_KEYBOARDSDIR")
|
||||||
|
.map(PathBuf::from)
|
||||||
|
.or_else(|| xdg::data_path("squeekboard/keyboards"));
|
||||||
|
|
||||||
|
for (kind, source) in iter_layout_sources(&name, kind, purpose, overlay, path) {
|
||||||
|
let layout = load_layout_data(source.clone());
|
||||||
|
match layout {
|
||||||
|
Err(e) => match (e, source) {
|
||||||
|
(
|
||||||
|
LoadError::BadData(Error::Missing(e)),
|
||||||
|
DataSource::File(file)
|
||||||
|
) => log_print!(
|
||||||
|
logging::Level::Debug,
|
||||||
|
"Tried file {:?}, but it's missing: {}",
|
||||||
|
file, e
|
||||||
|
),
|
||||||
|
(e, source) => log_print!(
|
||||||
|
logging::Level::Warning,
|
||||||
|
"Failed to load layout from {}: {}, skipping",
|
||||||
|
source, e
|
||||||
|
),
|
||||||
|
},
|
||||||
|
Ok(layout) => {
|
||||||
|
log_print!(logging::Level::Info, "Loaded layout {}", source);
|
||||||
|
return (kind, layout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!("No useful layout found!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
use ::logging::ProblemPanic;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parsing_fallback() {
|
||||||
|
assert!(parsing::Layout::from_resource(FALLBACK_LAYOUT_NAME)
|
||||||
|
.map(|layout| layout.build(ProblemPanic).0.unwrap())
|
||||||
|
.is_ok()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// First fallback should be to builtin, not to FALLBACK_LAYOUT_NAME
|
||||||
|
#[test]
|
||||||
|
fn test_fallback_basic_builtin() {
|
||||||
|
let sources = iter_layout_sources("nb", ArrangementKind::Base, ContentPurpose::Normal, None, None);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
sources.collect::<Vec<_>>(),
|
||||||
|
vec!(
|
||||||
|
(ArrangementKind::Base, DataSource::Resource("nb".into())),
|
||||||
|
(
|
||||||
|
ArrangementKind::Base,
|
||||||
|
DataSource::Resource(FALLBACK_LAYOUT_NAME.into())
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Prefer loading from file system before builtin.
|
||||||
|
#[test]
|
||||||
|
fn test_preferences_order_path() {
|
||||||
|
let sources = iter_layout_sources("nb", ArrangementKind::Base, ContentPurpose::Normal, None, Some(".".into()));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
sources.collect::<Vec<_>>(),
|
||||||
|
vec!(
|
||||||
|
(ArrangementKind::Base, DataSource::File("./nb.yaml".into())),
|
||||||
|
(ArrangementKind::Base, DataSource::Resource("nb".into())),
|
||||||
|
(
|
||||||
|
ArrangementKind::Base,
|
||||||
|
DataSource::File("./us.yaml".into())
|
||||||
|
),
|
||||||
|
(
|
||||||
|
ArrangementKind::Base,
|
||||||
|
DataSource::Resource("us".into())
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If layout contains a "+", it should reach for what's in front of it too.
|
||||||
|
#[test]
|
||||||
|
fn test_preferences_order_base() {
|
||||||
|
let sources = iter_layout_sources("nb+aliens", ArrangementKind::Base, ContentPurpose::Normal, None, None);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
sources.collect::<Vec<_>>(),
|
||||||
|
vec!(
|
||||||
|
(ArrangementKind::Base, DataSource::Resource("nb+aliens".into())),
|
||||||
|
(ArrangementKind::Base, DataSource::Resource("nb".into())),
|
||||||
|
(
|
||||||
|
ArrangementKind::Base,
|
||||||
|
DataSource::Resource(FALLBACK_LAYOUT_NAME.into())
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_preferences_order_arrangement() {
|
||||||
|
let sources = iter_layout_sources("nb", ArrangementKind::Wide, ContentPurpose::Normal, None, None);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
sources.collect::<Vec<_>>(),
|
||||||
|
vec!(
|
||||||
|
(ArrangementKind::Wide, DataSource::Resource("nb_wide".into())),
|
||||||
|
(ArrangementKind::Base, DataSource::Resource("nb".into())),
|
||||||
|
(
|
||||||
|
ArrangementKind::Wide,
|
||||||
|
DataSource::Resource("us_wide".into())
|
||||||
|
),
|
||||||
|
(
|
||||||
|
ArrangementKind::Base,
|
||||||
|
DataSource::Resource("us".into())
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_preferences_order_overlay() {
|
||||||
|
let sources = iter_layout_sources("nb", ArrangementKind::Base, ContentPurpose::Normal, Some("terminal"), None);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
sources.collect::<Vec<_>>(),
|
||||||
|
vec!(
|
||||||
|
(ArrangementKind::Base, DataSource::Resource("terminal/nb".into())),
|
||||||
|
(
|
||||||
|
ArrangementKind::Base,
|
||||||
|
DataSource::Resource("terminal/us".into())
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_preferences_order_hint() {
|
||||||
|
let sources = iter_layout_sources("nb", ArrangementKind::Base, ContentPurpose::Terminal, None, None);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
sources.collect::<Vec<_>>(),
|
||||||
|
vec!(
|
||||||
|
(ArrangementKind::Base, DataSource::Resource("terminal/nb".into())),
|
||||||
|
(
|
||||||
|
ArrangementKind::Base,
|
||||||
|
DataSource::Resource("terminal/us".into())
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
65
src/data/mod.rs
Normal file
65
src/data/mod.rs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/* Copyright (C) 2020-2021 Purism SPC
|
||||||
|
* SPDX-License-Identifier: GPL-3.0+
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! Combined module for dealing with layout files */
|
||||||
|
|
||||||
|
mod loading;
|
||||||
|
pub mod parsing;
|
||||||
|
|
||||||
|
use std::io;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
use ::keyboard::FormattingError;
|
||||||
|
|
||||||
|
/// 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 {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
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),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum LoadError {
|
||||||
|
BadData(Error),
|
||||||
|
MissingResource,
|
||||||
|
BadResource(serde_yaml::Error),
|
||||||
|
BadKeyMap(FormattingError),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for LoadError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
use self::LoadError::*;
|
||||||
|
match self {
|
||||||
|
BadData(e) => write!(f, "Bad data: {}", e),
|
||||||
|
MissingResource => write!(f, "Missing resource"),
|
||||||
|
BadResource(e) => write!(f, "Bad resource: {}", e),
|
||||||
|
BadKeyMap(e) => write!(f, "Bad key map: {}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,34 +1,30 @@
|
|||||||
/**! The parsing of the data files for layouts */
|
/* Copyright (C) 2020-2021 Purism SPC
|
||||||
|
* SPDX-License-Identifier: GPL-3.0+
|
||||||
|
*/
|
||||||
|
|
||||||
// TODO: find a nice way to make sure non-positive sizes don't break layouts
|
/*! Parsing of the data files containing layouts */
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::{ HashMap, HashSet };
|
use std::collections::{ HashMap, HashSet };
|
||||||
use std::env;
|
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::fmt;
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
use std::convert::TryFrom;
|
|
||||||
|
|
||||||
use xkbcommon::xkb;
|
use xkbcommon::xkb;
|
||||||
|
|
||||||
|
use super::{ Error, LoadError };
|
||||||
|
|
||||||
use ::action;
|
use ::action;
|
||||||
use ::keyboard::{
|
use ::keyboard::{
|
||||||
KeyState, PressType,
|
KeyState, PressType,
|
||||||
generate_keymaps, generate_keycodes, KeyCode, FormattingError
|
generate_keymaps, generate_keycodes, KeyCode, FormattingError
|
||||||
};
|
};
|
||||||
use ::layout;
|
use ::layout;
|
||||||
use ::layout::ArrangementKind;
|
|
||||||
use ::logging;
|
use ::logging;
|
||||||
use ::resources;
|
|
||||||
use ::util::c::as_str;
|
|
||||||
use ::util::hash_map_map;
|
use ::util::hash_map_map;
|
||||||
use ::xdg;
|
use ::resources;
|
||||||
use ::imservice::ContentPurpose;
|
|
||||||
|
|
||||||
// traits, derives
|
// traits, derives
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
@ -36,299 +32,7 @@ use std::io::BufReader;
|
|||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
use ::logging::Warn;
|
use ::logging::Warn;
|
||||||
|
|
||||||
/// Gathers stuff defined in C or called by C
|
// TODO: find a nice way to make sure non-positive sizes don't break layouts
|
||||||
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);
|
|
||||||
Box::into_raw(Box::new(layout))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const FALLBACK_LAYOUT_NAME: &str = "us";
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum LoadError {
|
|
||||||
BadData(Error),
|
|
||||||
MissingResource,
|
|
||||||
BadResource(serde_yaml::Error),
|
|
||||||
BadKeyMap(FormattingError),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for LoadError {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
use self::LoadError::*;
|
|
||||||
match self {
|
|
||||||
BadData(e) => write!(f, "Bad data: {}", e),
|
|
||||||
MissingResource => write!(f, "Missing resource"),
|
|
||||||
BadResource(e) => write!(f, "Bad resource: {}", e),
|
|
||||||
BadKeyMap(e) => write!(f, "Bad key map: {}", e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
|
||||||
enum DataSource {
|
|
||||||
File(PathBuf),
|
|
||||||
Resource(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for DataSource {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
DataSource::File(path) => write!(f, "Path: {:?}", path.display()),
|
|
||||||
DataSource::Resource(name) => write!(f, "Resource: {}", name),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* All functions in this family carry around ArrangementKind,
|
|
||||||
* because it's not guaranteed to be preserved,
|
|
||||||
* and the resulting layout needs to know which version was loaded.
|
|
||||||
* See `squeek_layout_get_kind`.
|
|
||||||
* Possible TODO: since this is used only in styling,
|
|
||||||
* and makes the below code nastier than needed, maybe it should go.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/// Returns ordered names treating `name` as the base name,
|
|
||||||
/// ignoring any `+` inside.
|
|
||||||
fn _get_arrangement_names(name: &str, arrangement: ArrangementKind)
|
|
||||||
-> Vec<(ArrangementKind, String)>
|
|
||||||
{
|
|
||||||
let name_with_arrangement = match arrangement {
|
|
||||||
ArrangementKind::Base => name.into(),
|
|
||||||
ArrangementKind::Wide => format!("{}_wide", name),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut ret = Vec::new();
|
|
||||||
if name_with_arrangement != name {
|
|
||||||
ret.push((arrangement, name_with_arrangement));
|
|
||||||
}
|
|
||||||
ret.push((ArrangementKind::Base, name.into()));
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns names accounting for any `+` in the `name`,
|
|
||||||
/// including the fallback to the default layout.
|
|
||||||
fn get_preferred_names(name: &str, kind: ArrangementKind)
|
|
||||||
-> Vec<(ArrangementKind, String)>
|
|
||||||
{
|
|
||||||
let mut ret = _get_arrangement_names(name, kind);
|
|
||||||
|
|
||||||
let base_name_preferences = {
|
|
||||||
let mut parts = name.splitn(2, '+');
|
|
||||||
match parts.next() {
|
|
||||||
Some(base) => {
|
|
||||||
// The name is already equal to base, so nothing to add
|
|
||||||
if base == name {
|
|
||||||
vec![]
|
|
||||||
} else {
|
|
||||||
_get_arrangement_names(base, kind)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// The layout's base name starts with a "+". Weird but OK.
|
|
||||||
None => {
|
|
||||||
log_print!(logging::Level::Surprise, "Base layout name is empty: {}", name);
|
|
||||||
vec![]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ret.extend(base_name_preferences.into_iter());
|
|
||||||
let fallback_names = _get_arrangement_names(FALLBACK_LAYOUT_NAME, kind);
|
|
||||||
ret.extend(fallback_names.into_iter());
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Includes the subdirectory before the forward slash.
|
|
||||||
type LayoutPath = String;
|
|
||||||
|
|
||||||
// This is only used inside iter_fallbacks_with_meta.
|
|
||||||
// Placed at the top scope
|
|
||||||
// because `use LayoutPurpose::*;`
|
|
||||||
// complains about "not in scope" otherwise.
|
|
||||||
// This seems to be a Rust 2015 edition problem.
|
|
||||||
/// Helper for determining where to look up the layout.
|
|
||||||
enum LayoutPurpose<'a> {
|
|
||||||
Default,
|
|
||||||
Special(&'a str),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the directory string
|
|
||||||
/// where the layout should be looked up, including the slash.
|
|
||||||
fn get_directory_string(
|
|
||||||
content_purpose: ContentPurpose,
|
|
||||||
overlay: Option<&str>) -> String
|
|
||||||
{
|
|
||||||
use self::LayoutPurpose::*;
|
|
||||||
|
|
||||||
let layout_purpose = match overlay {
|
|
||||||
None => match content_purpose {
|
|
||||||
ContentPurpose::Number => Special("number"),
|
|
||||||
ContentPurpose::Digits => Special("number"),
|
|
||||||
ContentPurpose::Phone => Special("number"),
|
|
||||||
ContentPurpose::Terminal => Special("terminal"),
|
|
||||||
_ => Default,
|
|
||||||
},
|
|
||||||
Some(overlay) => Special(overlay),
|
|
||||||
};
|
|
||||||
|
|
||||||
// For intuitiveness,
|
|
||||||
// default purpose layouts are stored in the root directory,
|
|
||||||
// as they correspond to typical text
|
|
||||||
// and are seen the most often.
|
|
||||||
match layout_purpose {
|
|
||||||
Default => "".into(),
|
|
||||||
Special(purpose) => format!("{}/", purpose),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns an iterator over all fallback paths.
|
|
||||||
fn to_layout_paths(
|
|
||||||
name_fallbacks: Vec<(ArrangementKind, String)>,
|
|
||||||
content_purpose: ContentPurpose,
|
|
||||||
overlay: Option<&str>,
|
|
||||||
) -> impl Iterator<Item=(ArrangementKind, LayoutPath)> {
|
|
||||||
let prepend_directory = get_directory_string(content_purpose, overlay);
|
|
||||||
|
|
||||||
name_fallbacks.into_iter()
|
|
||||||
.map(move |(arrangement, name)|
|
|
||||||
(arrangement, format!("{}{}", prepend_directory, name))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
type LayoutSource = (ArrangementKind, DataSource);
|
|
||||||
|
|
||||||
fn to_layout_sources(
|
|
||||||
layout_paths: impl Iterator<Item=(ArrangementKind, LayoutPath)>,
|
|
||||||
filesystem_path: Option<PathBuf>,
|
|
||||||
) -> impl Iterator<Item=LayoutSource> {
|
|
||||||
layout_paths.flat_map(move |(arrangement, layout_path)| {
|
|
||||||
let mut sources = Vec::new();
|
|
||||||
if let Some(path) = &filesystem_path {
|
|
||||||
sources.push((
|
|
||||||
arrangement,
|
|
||||||
DataSource::File(
|
|
||||||
path.join(&layout_path)
|
|
||||||
.with_extension("yaml")
|
|
||||||
)
|
|
||||||
));
|
|
||||||
};
|
|
||||||
sources.push((arrangement, DataSource::Resource(layout_path.clone())));
|
|
||||||
sources.into_iter()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns possible sources, with first as the most preferred one.
|
|
||||||
/// Trying order: native lang of the right kind, native base,
|
|
||||||
/// fallback lang of the right kind, fallback base
|
|
||||||
fn iter_layout_sources(
|
|
||||||
name: &str,
|
|
||||||
arrangement: ArrangementKind,
|
|
||||||
purpose: ContentPurpose,
|
|
||||||
ui_overlay: Option<&str>,
|
|
||||||
layout_storage: Option<PathBuf>,
|
|
||||||
) -> impl Iterator<Item=LayoutSource> {
|
|
||||||
let names = get_preferred_names(name, arrangement);
|
|
||||||
let paths = to_layout_paths(names, purpose, ui_overlay);
|
|
||||||
to_layout_sources(paths, layout_storage)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn load_layout_data(source: DataSource)
|
|
||||||
-> Result<::layout::LayoutData, LoadError>
|
|
||||||
{
|
|
||||||
let handler = logging::Print {};
|
|
||||||
match source {
|
|
||||||
DataSource::File(path) => {
|
|
||||||
Layout::from_file(path.clone())
|
|
||||||
.map_err(LoadError::BadData)
|
|
||||||
.and_then(|layout|
|
|
||||||
layout.build(handler).0.map_err(LoadError::BadKeyMap)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
DataSource::Resource(name) => {
|
|
||||||
Layout::from_resource(&name)
|
|
||||||
.and_then(|layout|
|
|
||||||
layout.build(handler).0.map_err(LoadError::BadKeyMap)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn load_layout_data_with_fallback(
|
|
||||||
name: &str,
|
|
||||||
kind: ArrangementKind,
|
|
||||||
purpose: ContentPurpose,
|
|
||||||
overlay: Option<&str>,
|
|
||||||
) -> (ArrangementKind, ::layout::LayoutData) {
|
|
||||||
|
|
||||||
// Build the path to the right keyboard layout subdirectory
|
|
||||||
let path = env::var_os("SQUEEKBOARD_KEYBOARDSDIR")
|
|
||||||
.map(PathBuf::from)
|
|
||||||
.or_else(|| xdg::data_path("squeekboard/keyboards"));
|
|
||||||
|
|
||||||
for (kind, source) in iter_layout_sources(&name, kind, purpose, overlay, path) {
|
|
||||||
let layout = load_layout_data(source.clone());
|
|
||||||
match layout {
|
|
||||||
Err(e) => match (e, source) {
|
|
||||||
(
|
|
||||||
LoadError::BadData(Error::Missing(e)),
|
|
||||||
DataSource::File(file)
|
|
||||||
) => log_print!(
|
|
||||||
logging::Level::Debug,
|
|
||||||
"Tried file {:?}, but it's missing: {}",
|
|
||||||
file, e
|
|
||||||
),
|
|
||||||
(e, source) => log_print!(
|
|
||||||
logging::Level::Warning,
|
|
||||||
"Failed to load layout from {}: {}, skipping",
|
|
||||||
source, e
|
|
||||||
),
|
|
||||||
},
|
|
||||||
Ok(layout) => {
|
|
||||||
log_print!(logging::Level::Info, "Loaded layout {}", source);
|
|
||||||
return (kind, layout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
panic!("No useful layout found!");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The root element describing an entire keyboard
|
/// The root element describing an entire keyboard
|
||||||
#[derive(Debug, Deserialize, PartialEq)]
|
#[derive(Debug, Deserialize, PartialEq)]
|
||||||
@ -421,37 +125,6 @@ struct Outline {
|
|||||||
height: f64,
|
height: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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 {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
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),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_offsets<'a, I: 'a, T, F: 'a>(iterator: I, get_size: F)
|
pub fn add_offsets<'a, I: 'a, T, F: 'a>(iterator: I, get_size: F)
|
||||||
-> impl Iterator<Item=(f64, T)> + 'a
|
-> impl Iterator<Item=(f64, T)> + 'a
|
||||||
where I: Iterator<Item=T>,
|
where I: Iterator<Item=T>,
|
||||||
@ -871,10 +544,13 @@ fn extract_symbol_names<'a>(actions: &'a [(&str, action::Action)])
|
|||||||
.map(|named_keysym| named_keysym.0)
|
.map(|named_keysym| named_keysym.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
|
||||||
use ::logging::ProblemPanic;
|
use ::logging::ProblemPanic;
|
||||||
|
|
||||||
fn path_from_root(file: &'static str) -> PathBuf {
|
fn path_from_root(file: &'static str) -> PathBuf {
|
||||||
@ -1024,124 +700,6 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn parsing_fallback() {
|
|
||||||
assert!(Layout::from_resource(FALLBACK_LAYOUT_NAME)
|
|
||||||
.map(|layout| layout.build(ProblemPanic).0.unwrap())
|
|
||||||
.is_ok()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// First fallback should be to builtin, not to FALLBACK_LAYOUT_NAME
|
|
||||||
#[test]
|
|
||||||
fn test_fallback_basic_builtin() {
|
|
||||||
let sources = iter_layout_sources("nb", ArrangementKind::Base, ContentPurpose::Normal, None, None);
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
sources.collect::<Vec<_>>(),
|
|
||||||
vec!(
|
|
||||||
(ArrangementKind::Base, DataSource::Resource("nb".into())),
|
|
||||||
(
|
|
||||||
ArrangementKind::Base,
|
|
||||||
DataSource::Resource(FALLBACK_LAYOUT_NAME.into())
|
|
||||||
),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Prefer loading from file system before builtin.
|
|
||||||
#[test]
|
|
||||||
fn test_preferences_order_path() {
|
|
||||||
let sources = iter_layout_sources("nb", ArrangementKind::Base, ContentPurpose::Normal, None, Some(".".into()));
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
sources.collect::<Vec<_>>(),
|
|
||||||
vec!(
|
|
||||||
(ArrangementKind::Base, DataSource::File("./nb.yaml".into())),
|
|
||||||
(ArrangementKind::Base, DataSource::Resource("nb".into())),
|
|
||||||
(
|
|
||||||
ArrangementKind::Base,
|
|
||||||
DataSource::File("./us.yaml".into())
|
|
||||||
),
|
|
||||||
(
|
|
||||||
ArrangementKind::Base,
|
|
||||||
DataSource::Resource("us".into())
|
|
||||||
),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// If layout contains a "+", it should reach for what's in front of it too.
|
|
||||||
#[test]
|
|
||||||
fn test_preferences_order_base() {
|
|
||||||
let sources = iter_layout_sources("nb+aliens", ArrangementKind::Base, ContentPurpose::Normal, None, None);
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
sources.collect::<Vec<_>>(),
|
|
||||||
vec!(
|
|
||||||
(ArrangementKind::Base, DataSource::Resource("nb+aliens".into())),
|
|
||||||
(ArrangementKind::Base, DataSource::Resource("nb".into())),
|
|
||||||
(
|
|
||||||
ArrangementKind::Base,
|
|
||||||
DataSource::Resource(FALLBACK_LAYOUT_NAME.into())
|
|
||||||
),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_preferences_order_arrangement() {
|
|
||||||
let sources = iter_layout_sources("nb", ArrangementKind::Wide, ContentPurpose::Normal, None, None);
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
sources.collect::<Vec<_>>(),
|
|
||||||
vec!(
|
|
||||||
(ArrangementKind::Wide, DataSource::Resource("nb_wide".into())),
|
|
||||||
(ArrangementKind::Base, DataSource::Resource("nb".into())),
|
|
||||||
(
|
|
||||||
ArrangementKind::Wide,
|
|
||||||
DataSource::Resource("us_wide".into())
|
|
||||||
),
|
|
||||||
(
|
|
||||||
ArrangementKind::Base,
|
|
||||||
DataSource::Resource("us".into())
|
|
||||||
),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_preferences_order_overlay() {
|
|
||||||
let sources = iter_layout_sources("nb", ArrangementKind::Base, ContentPurpose::Normal, Some("terminal"), None);
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
sources.collect::<Vec<_>>(),
|
|
||||||
vec!(
|
|
||||||
(ArrangementKind::Base, DataSource::Resource("terminal/nb".into())),
|
|
||||||
(
|
|
||||||
ArrangementKind::Base,
|
|
||||||
DataSource::Resource("terminal/us".into())
|
|
||||||
),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_preferences_order_hint() {
|
|
||||||
let sources = iter_layout_sources("nb", ArrangementKind::Base, ContentPurpose::Terminal, None, None);
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
sources.collect::<Vec<_>>(),
|
|
||||||
vec!(
|
|
||||||
(ArrangementKind::Base, DataSource::Resource("terminal/nb".into())),
|
|
||||||
(
|
|
||||||
ArrangementKind::Base,
|
|
||||||
DataSource::Resource("terminal/us".into())
|
|
||||||
),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn unicode_keysym() {
|
fn unicode_keysym() {
|
||||||
let keysym = xkb::keysym_from_name(
|
let keysym = xkb::keysym_from_name(
|
||||||
@ -621,12 +621,6 @@ pub enum LatchedState {
|
|||||||
Not,
|
Not,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LatchedState {
|
|
||||||
pub fn is_latched(&self) -> bool {
|
|
||||||
self != &LatchedState::Not
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: split into sth like
|
// TODO: split into sth like
|
||||||
// Arrangement (views) + details (keymap) + State (keys)
|
// Arrangement (views) + details (keymap) + State (keys)
|
||||||
/// State of the UI, contains the backend as well
|
/// State of the UI, contains the backend as well
|
||||||
@ -776,23 +770,6 @@ impl Layout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_locked_keys(&self) -> Vec<Rc<RefCell<KeyState>>> {
|
|
||||||
let mut out = Vec::new();
|
|
||||||
let view = self.get_current_view();
|
|
||||||
for (_, row) in view.get_rows() {
|
|
||||||
for (_, button) in &row.buttons {
|
|
||||||
let locked = {
|
|
||||||
let state = RefCell::borrow(&button.state).clone();
|
|
||||||
state.action.is_locked(&self.current_view)
|
|
||||||
};
|
|
||||||
if locked {
|
|
||||||
out.push(button.state.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out
|
|
||||||
}
|
|
||||||
|
|
||||||
fn apply_view_transition(
|
fn apply_view_transition(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|||||||
@ -401,6 +401,7 @@ pub fn show(
|
|||||||
width: position.width.floor() as i32,
|
width: position.width.floor() as i32,
|
||||||
height: position.width.floor() as i32,
|
height: position.width.floor() as i32,
|
||||||
});
|
});
|
||||||
|
menu.set_constrain_to(gtk::PopoverConstraint::None);
|
||||||
|
|
||||||
if let Some(current_layout) = get_current_layout(manager, &system_layouts) {
|
if let Some(current_layout) = get_current_layout(manager, &system_layouts) {
|
||||||
let current_name_variant = choices.iter()
|
let current_name_variant = choices.iter()
|
||||||
|
|||||||
@ -11,7 +11,7 @@ use std::iter::FromIterator;
|
|||||||
// and what a convenience layout. "_wide" is not a layout,
|
// and what a convenience layout. "_wide" is not a layout,
|
||||||
// neither is "number"
|
// neither is "number"
|
||||||
/// List of builtin layouts
|
/// List of builtin layouts
|
||||||
const KEYBOARDS: &[(*const str, *const str)] = &[
|
static KEYBOARDS: &[(&'static str, &'static str)] = &[
|
||||||
// layouts: us must be left as first, as it is the,
|
// layouts: us must be left as first, as it is the,
|
||||||
// fallback layout.
|
// fallback layout.
|
||||||
("us", include_str!("../data/keyboards/us.yaml")),
|
("us", include_str!("../data/keyboards/us.yaml")),
|
||||||
@ -93,34 +93,20 @@ const KEYBOARDS: &[(*const str, *const str)] = &[
|
|||||||
];
|
];
|
||||||
|
|
||||||
pub fn get_keyboard(needle: &str) -> Option<&'static str> {
|
pub fn get_keyboard(needle: &str) -> Option<&'static str> {
|
||||||
// Need to dereference in unsafe code
|
KEYBOARDS.iter().find(|(name, _)| *name == needle).map(|(_, layout)| *layout)
|
||||||
// comparing *const str to &str will compare pointers
|
|
||||||
KEYBOARDS.iter()
|
|
||||||
.find(|(name, _)| {
|
|
||||||
let name: *const str = *name;
|
|
||||||
(unsafe { &*name }) == needle
|
|
||||||
})
|
|
||||||
.map(|(_, value)| {
|
|
||||||
let value: *const str = *value;
|
|
||||||
unsafe { &*value }
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const OVERLAY_NAMES: &[*const str] = &[
|
static OVERLAY_NAMES: &[&'static str] = &[
|
||||||
"emoji",
|
"emoji",
|
||||||
"terminal",
|
"terminal",
|
||||||
];
|
];
|
||||||
|
|
||||||
pub fn get_overlays() -> Vec<&'static str> {
|
pub fn get_overlays() -> Vec<&'static str> {
|
||||||
OVERLAY_NAMES.iter()
|
OVERLAY_NAMES.to_vec()
|
||||||
.map(|name| {
|
|
||||||
let name: *const str = *name;
|
|
||||||
unsafe { &*name }
|
|
||||||
}).collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Translations of the layout identifier strings
|
/// Translations of the layout identifier strings
|
||||||
const LAYOUT_NAMES: &[(*const str, *const str)] = &[
|
static LAYOUT_NAMES: &[(&'static str, &'static str)] = &[
|
||||||
("de-DE", include_str!("../data/langs/de-DE.txt")),
|
("de-DE", include_str!("../data/langs/de-DE.txt")),
|
||||||
("en-US", include_str!("../data/langs/en-US.txt")),
|
("en-US", include_str!("../data/langs/en-US.txt")),
|
||||||
("es-ES", include_str!("../data/langs/es-ES.txt")),
|
("es-ES", include_str!("../data/langs/es-ES.txt")),
|
||||||
@ -135,14 +121,8 @@ pub fn get_layout_names(lang: &str)
|
|||||||
-> Option<HashMap<&'static str, Translation<'static>>>
|
-> Option<HashMap<&'static str, Translation<'static>>>
|
||||||
{
|
{
|
||||||
let translations = LAYOUT_NAMES.iter()
|
let translations = LAYOUT_NAMES.iter()
|
||||||
.find(|(name, _data)| {
|
.find(|(name, _data)| *name == lang)
|
||||||
let name: *const str = *name;
|
.map(|(_name, data)| *data);
|
||||||
(unsafe { &*name }) == lang
|
|
||||||
})
|
|
||||||
.map(|(_name, data)| {
|
|
||||||
let data: *const str = *data;
|
|
||||||
unsafe { &*data }
|
|
||||||
});
|
|
||||||
translations.map(make_mapping)
|
translations.map(make_mapping)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/*! Testing functionality */
|
/*! Testing functionality */
|
||||||
|
|
||||||
use ::data::Layout;
|
use ::data::parsing::Layout;
|
||||||
use ::logging;
|
use ::logging;
|
||||||
use xkbcommon::xkb;
|
use xkbcommon::xkb;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user