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]]
|
||||
name = "libc"
|
||||
version = "0.2.93"
|
||||
version = "0.2.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41"
|
||||
checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e"
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
@ -353,9 +353,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.23"
|
||||
version = "0.6.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "rs"
|
||||
@ -380,18 +380,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.125"
|
||||
version = "1.0.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171"
|
||||
checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.125"
|
||||
version = "1.0.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d"
|
||||
checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -412,9 +412,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.69"
|
||||
version = "1.0.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48fe99c6bd8b1cc636890bcc071842de909d902c81ac7dab53ba33c421ab8ffb"
|
||||
checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -438,9 +438,9 @@ checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
|
||||
@ -34,7 +34,7 @@ if out_path:
|
||||
i = args.index(out_path)
|
||||
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,
|
||||
check=True)
|
||||
|
||||
@ -43,7 +43,7 @@ if out_path:
|
||||
out_basename = out_path.name
|
||||
filename = filename or out_basename
|
||||
subprocess.run(['cp', '-a',
|
||||
'./{}/{}'.format(shlex.quote(binary_dir), shlex.quote(filename)),
|
||||
'./{}/{}'.format(binary_dir, filename),
|
||||
out_path],
|
||||
check=True)
|
||||
|
||||
|
||||
@ -438,7 +438,7 @@ buttons:
|
||||
unlock_view: "カタカナ"
|
||||
outline: "altline"
|
||||
label: "。"
|
||||
# Buttons for Latin charachters
|
||||
# Buttons for Latin characters
|
||||
RSYM1:
|
||||
action:
|
||||
locking:
|
||||
|
||||
@ -438,7 +438,7 @@ buttons:
|
||||
unlock_view: "カタカナ"
|
||||
outline: "altline"
|
||||
label: "。"
|
||||
# Buttons for Latin charachters
|
||||
# Buttons for Latin characters
|
||||
RSYM1:
|
||||
action:
|
||||
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 ]
|
||||
* layout: Latch keys when clicked twice
|
||||
* 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
|
||||
* debian: New upstream release
|
||||
|
||||
[ J.D. Laub ]
|
||||
* Add US Dvorak layout (and Colemak wide)
|
||||
* Add US Dvorak layout (and Colemak wide)
|
||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Sat, 22 May 2021 14:19:27 +0000
|
||||
|
||||
[ Jordi Masip ]
|
||||
* 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
|
||||
squeekboard (1.13.0-1pureos1) byzantium; urgency=medium
|
||||
|
||||
[ Dorota Czaplejewicz ]
|
||||
* docs: Correct Cargo update instructions
|
||||
* 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
|
||||
* debian: New upstream release
|
||||
|
||||
[ Wannaphong Phatthiyaphaibun ]
|
||||
* Add thai keyboard
|
||||
* Update resources.rs
|
||||
* Update meson.build
|
||||
* escape " on thai keyboard
|
||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Mon, 12 Apr 2021 10:50:32 +0000a
|
||||
|
||||
[ clonex10100 ]
|
||||
* Added US Colemak Keyboard Layout
|
||||
squeekboard (1.12.0-1pureos1) byzantium; urgency=medium
|
||||
|
||||
[ 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 ]
|
||||
* 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
|
||||
|
||||
[ 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 ]
|
||||
* imservice: Set up UI according to current needs when it shows up
|
||||
* 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
|
||||
* debian: Build reproducibly
|
||||
|
||||
[ Arnaud Ferraris ]
|
||||
* eek-gtk-keyboard: use virtual resolution to check arrangement kind
|
||||
* server-context-service: optimize height calculation
|
||||
* keyboards: add wide French layout
|
||||
* keyboards: add wide Belgian layout
|
||||
* keyboards: add wide terminal layout
|
||||
* New upstream version 1.12.0
|
||||
|
||||
[ Fabio Tomat ]
|
||||
* Revert "Add friulian keyboard"
|
||||
-- Arnaud Ferraris <arnaud.ferraris@gmail.com> Tue, 26 Jan 2021 18:19:42 +0100
|
||||
|
||||
-- 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 ]
|
||||
* 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.
|
||||
-- Arnaud Ferraris <arnaud.ferraris@gmail.com> Tue, 24 Nov 2020 11:52:41 +0100
|
||||
|
||||
[ Guido Günther ]
|
||||
* 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)
|
||||
squeekboard (1.11.0-1) unstable; urgency=medium
|
||||
|
||||
[ Dorota Czaplejewicz ]
|
||||
* 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
|
||||
* New upstream release 1.11.0
|
||||
|
||||
[ Sebastian Krzyszkowiak ]
|
||||
* Revert "Merge branch 'btantau-master-patch-76686' into 'master'"
|
||||
* Terminal layout: another approach
|
||||
-- Arnaud Ferraris <arnaud.ferraris@gmail.com> Mon, 16 Nov 2020 11:17:23 +0100
|
||||
|
||||
[ Luís Fernando Stürmer da Rosa ]
|
||||
* Brazilian Portuguese Keyboard Layout.
|
||||
squeekboard (1.10.0-2) unstable; urgency=medium
|
||||
|
||||
-- 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 ]
|
||||
* 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
|
||||
squeekboard (1.10.0-1) unstable; urgency=medium
|
||||
|
||||
[ Andreas Rönnquist ]
|
||||
* Swedish keyboard, wide button switching between numbers, symbols and base
|
||||
* More fixes of button sizes
|
||||
* Folder is doc, not docs
|
||||
* New upstream release 1.10.0
|
||||
* d/control: build-depend on libfeedbackd-dev and set team maintainership
|
||||
* d/control: fix dependency name
|
||||
* 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 ]
|
||||
* Add new file
|
||||
* Replace duplicated show_symbols by show_eschars and removed "Delete" button that it's doing nothing
|
||||
-- Arnaud Ferraris <arnaud.ferraris@gmail.com> Fri, 23 Oct 2020 13:18:43 +0200
|
||||
|
||||
[ Arnaud Ferraris ]
|
||||
* 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
|
||||
squeekboard (1.9.3-1) experimental; urgency=medium
|
||||
|
||||
[ Vlad ]
|
||||
* Fresh Russian layout
|
||||
* Upload to experimental
|
||||
* 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 ]
|
||||
* Removed unused dependency 'libcroco'
|
||||
-- Guido Günther <agx@sigxcpu.org> Sat, 26 Sep 2020 13:01:18 +0200
|
||||
|
||||
[ Florian Klink ]
|
||||
* sm.puri.Squeekboard.desktop: make path to Exec= absolute
|
||||
squeekboard (1.9.2-1) UNRELEASED; urgency=medium
|
||||
|
||||
[ Ole Guldberg ]
|
||||
* Danish keyboard layout
|
||||
* Danish keyboard layout
|
||||
* add test for danish layout
|
||||
* Initial Debian release (Closes: #956960)
|
||||
|
||||
-- Dorota Czaplejewicz <dorota.czaplejewicz@puri.sm> Mon, 01 Jun 2020 09:39:12 +0000
|
||||
|
||||
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
|
||||
-- Arnaud Ferraris <arnaud.ferraris@gmail.com> Tue, 09 Jun 2020 23:29:19 +0200
|
||||
|
||||
2
debian/control
vendored
2
debian/control
vendored
@ -31,6 +31,8 @@ Build-Depends:
|
||||
wayland-protocols (>= 1.14),
|
||||
Standards-Version: 4.1.3
|
||||
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
|
||||
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_PROVIDER(renderer->css_provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_USER);
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
|
||||
/* Create a style context for the buttons */
|
||||
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_add_provider (renderer->button_context,
|
||||
GTK_STYLE_PROVIDER(renderer->css_provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_USER);
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
return renderer;
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
project(
|
||||
'squeekboard',
|
||||
'c', 'rust',
|
||||
version: '1.13.0',
|
||||
version: '1.14.0',
|
||||
license: 'GPLv3',
|
||||
meson_version: '>=0.51.0',
|
||||
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::collections::{ HashMap, HashSet };
|
||||
use std::env;
|
||||
use std::ffi::CString;
|
||||
use std::fmt;
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
use std::vec::Vec;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use xkbcommon::xkb;
|
||||
|
||||
use super::{ Error, LoadError };
|
||||
|
||||
use ::action;
|
||||
use ::keyboard::{
|
||||
KeyState, PressType,
|
||||
generate_keymaps, generate_keycodes, KeyCode, FormattingError
|
||||
};
|
||||
use ::layout;
|
||||
use ::layout::ArrangementKind;
|
||||
use ::logging;
|
||||
use ::resources;
|
||||
use ::util::c::as_str;
|
||||
use ::util::hash_map_map;
|
||||
use ::xdg;
|
||||
use ::imservice::ContentPurpose;
|
||||
use ::resources;
|
||||
|
||||
// traits, derives
|
||||
use serde::Deserialize;
|
||||
@ -36,299 +32,7 @@ use std::io::BufReader;
|
||||
use std::iter::FromIterator;
|
||||
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)]
|
||||
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!");
|
||||
}
|
||||
// TODO: find a nice way to make sure non-positive sizes don't break layouts
|
||||
|
||||
/// The root element describing an entire keyboard
|
||||
#[derive(Debug, Deserialize, PartialEq)]
|
||||
@ -421,37 +125,6 @@ struct Outline {
|
||||
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)
|
||||
-> impl Iterator<Item=(f64, T)> + 'a
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use std::env;
|
||||
|
||||
use ::logging::ProblemPanic;
|
||||
|
||||
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]
|
||||
fn unicode_keysym() {
|
||||
let keysym = xkb::keysym_from_name(
|
||||
@ -621,12 +621,6 @@ pub enum LatchedState {
|
||||
Not,
|
||||
}
|
||||
|
||||
impl LatchedState {
|
||||
pub fn is_latched(&self) -> bool {
|
||||
self != &LatchedState::Not
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: split into sth like
|
||||
// Arrangement (views) + details (keymap) + State (keys)
|
||||
/// State of the UI, contains the backend as well
|
||||
@ -777,23 +771,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(
|
||||
&mut self,
|
||||
action: &Action,
|
||||
|
||||
@ -401,6 +401,7 @@ pub fn show(
|
||||
width: 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) {
|
||||
let current_name_variant = choices.iter()
|
||||
|
||||
@ -11,7 +11,7 @@ use std::iter::FromIterator;
|
||||
// and what a convenience layout. "_wide" is not a layout,
|
||||
// neither is "number"
|
||||
/// 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,
|
||||
// fallback layout.
|
||||
("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> {
|
||||
// Need to dereference in unsafe code
|
||||
// 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 }
|
||||
})
|
||||
KEYBOARDS.iter().find(|(name, _)| *name == needle).map(|(_, layout)| *layout)
|
||||
}
|
||||
|
||||
const OVERLAY_NAMES: &[*const str] = &[
|
||||
static OVERLAY_NAMES: &[&'static str] = &[
|
||||
"emoji",
|
||||
"terminal",
|
||||
];
|
||||
|
||||
pub fn get_overlays() -> Vec<&'static str> {
|
||||
OVERLAY_NAMES.iter()
|
||||
.map(|name| {
|
||||
let name: *const str = *name;
|
||||
unsafe { &*name }
|
||||
}).collect()
|
||||
OVERLAY_NAMES.to_vec()
|
||||
}
|
||||
|
||||
/// 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")),
|
||||
("en-US", include_str!("../data/langs/en-US.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>>>
|
||||
{
|
||||
let translations = LAYOUT_NAMES.iter()
|
||||
.find(|(name, _data)| {
|
||||
let name: *const str = *name;
|
||||
(unsafe { &*name }) == lang
|
||||
})
|
||||
.map(|(_name, data)| {
|
||||
let data: *const str = *data;
|
||||
unsafe { &*data }
|
||||
});
|
||||
.find(|(name, _data)| *name == lang)
|
||||
.map(|(_name, data)| *data);
|
||||
translations.map(make_mapping)
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*! Testing functionality */
|
||||
|
||||
use ::data::Layout;
|
||||
use ::data::parsing::Layout;
|
||||
use ::logging;
|
||||
use xkbcommon::xkb;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user