From 4ccf11f4fd26083048f0ba80f5bc150dfa6aa688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Fri, 11 Sep 2020 16:17:45 +0200 Subject: [PATCH 01/86] server-context-service: Don't show keyboard when disabled If the corresponding a11y settings is disbaled don't unfold the keyboad at all. This helps e.g. running the same session on laptops or when an external keyboard is attached. Closes: #222 --- src/server-context-service.c | 58 ++++++++++++++++++++++++++++++++++-- src/server-context-service.h | 1 + 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/server-context-service.c b/src/server-context-service.c index ded432ef..515caf6e 100644 --- a/src/server-context-service.c +++ b/src/server-context-service.c @@ -31,6 +31,7 @@ enum { PROP_0, PROP_VISIBLE, + PROP_ENABLED, PROP_LAST }; @@ -44,6 +45,7 @@ struct _ServerContextService { struct ui_manager *manager; // unowned gboolean visible; + gboolean enabled; PhoshLayerSurface *window; GtkWidget *widget; // nullable guint hiding; @@ -208,6 +210,9 @@ on_hide (ServerContextService *self) static void server_context_service_real_show_keyboard (ServerContextService *self) { + if (!self->enabled) + return; + if (self->hiding) { g_source_remove (self->hiding); self->hiding = 0; @@ -263,7 +268,9 @@ server_context_service_set_property (GObject *object, case PROP_VISIBLE: self->visible = g_value_get_boolean (value); break; - + case PROP_ENABLED: + server_context_service_set_enabled (self, g_value_get_boolean (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -319,11 +326,43 @@ server_context_service_class_init (ServerContextServiceClass *klass) g_object_class_install_property (gobject_class, PROP_VISIBLE, pspec); + + /** + * ServerContextServie:keyboard: + * + * Does the user want the keyboard to show up automatically? + */ + pspec = + g_param_spec_boolean ("enabled", + "Enabled", + "Whether the keyboard is enabled", + TRUE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (gobject_class, + PROP_ENABLED, + pspec); } static void server_context_service_init (ServerContextService *self) { - (void)self; + const char *schema_name = "org.gnome.desktop.a11y.applications"; + GSettingsSchemaSource *ssrc = g_settings_schema_source_get_default(); + g_autoptr(GSettingsSchema) schema = NULL; + + self->enabled = TRUE; + if (!ssrc) { + g_warning("No gsettings schemas installed."); + return; + } + schema = g_settings_schema_source_lookup(ssrc, schema_name, TRUE); + if (schema) { + g_autoptr(GSettings) settings = g_settings_new (schema_name); + g_settings_bind (settings, "screen-keyboard-enabled", + self, "enabled", G_SETTINGS_BIND_GET); + } else { + g_warning("Gsettings schema %s is not installed on the system. " + "Enabling by default.", schema_name); + } } ServerContextService * @@ -336,3 +375,18 @@ server_context_service_new (EekboardContextService *self, struct submission *sub ui->manager = uiman; return ui; } + +void +server_context_service_set_enabled (ServerContextService *self, gboolean enabled) +{ + g_return_if_fail (SERVER_IS_CONTEXT_SERVICE (self)); + + if (enabled == self->enabled) + return; + + self->enabled = enabled; + if (self->enabled) + server_context_service_show_keyboard (self); + else + server_context_service_hide_keyboard (self); +} diff --git a/src/server-context-service.h b/src/server-context-service.h index bafe71c3..a091d0f9 100644 --- a/src/server-context-service.h +++ b/src/server-context-service.h @@ -33,6 +33,7 @@ ServerContextService *server_context_service_new(EekboardContextService *self, s enum squeek_arrangement_kind server_context_service_get_layout_type(ServerContextService *); void server_context_service_show_keyboard (ServerContextService *self); void server_context_service_hide_keyboard (ServerContextService *self); +void server_context_service_set_enabled (ServerContextService *self, gboolean enabled); G_END_DECLS #endif /* SERVER_CONTEXT_SERVICE_H */ From d93e9c2b110650ae64c2b1fdb8dde44200fdc2b4 Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Mon, 21 Sep 2020 09:43:32 +0000 Subject: [PATCH 02/86] rust: Fix deprecation warnings --- src/data.rs | 8 ++++---- src/locale_config.rs | 12 +++--------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/data.rs b/src/data.rs index 4ff7cc2d..c3cf5345 100644 --- a/src/data.rs +++ b/src/data.rs @@ -737,8 +737,7 @@ fn create_button( #[cfg(test)] mod tests { use super::*; - - use std::error::Error as ErrorTrait; + use ::logging::ProblemPanic; const THIS_FILE: &str = file!(); @@ -786,7 +785,8 @@ mod tests { Err(e) => { let mut handled = false; if let Error::Yaml(ye) = &e { - handled = ye.description() == "missing field `views`"; + handled = ye.to_string() + .starts_with("missing field `views`"); }; if !handled { println!("Unexpected error {:?}", e); @@ -804,7 +804,7 @@ mod tests { Err(e) => { let mut handled = false; if let Error::Yaml(ye) = &e { - handled = ye.description() + handled = ye.to_string() .starts_with("unknown field `bad_field`"); }; if !handled { diff --git a/src/locale_config.rs b/src/locale_config.rs index 0595f2b7..959dfde1 100644 --- a/src/locale_config.rs +++ b/src/locale_config.rs @@ -31,22 +31,16 @@ pub enum Error { impl ::std::fmt::Display for Error { fn fmt(&self, out: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - use ::std::error::Error; - out.write_str(self.description()) - } -} - -impl ::std::error::Error for Error { - fn description(&self) -> &str { - match self { + out.write_str(match self { &Error::NotWellFormed => "Language tag is not well-formed.", // this is exception: here we do want exhaustive match so we don't publish version with // missing descriptions by mistake. &Error::__NonExhaustive => panic!("Placeholder error must not be instantiated!"), - } + }) } } + /// Convenience Result alias. type Result = ::std::result::Result; From 7aa004ceff69a929bb9db24de92f79101d48b23f Mon Sep 17 00:00:00 2001 From: Benjamin Schaaf Date: Fri, 25 Sep 2020 21:44:27 +1000 Subject: [PATCH 03/86] Fix spelling mistakes in doc/hacking.md Fixes #217 --- doc/hacking.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/hacking.md b/doc/hacking.md index 551b701b..d8c37811 100644 --- a/doc/hacking.md +++ b/doc/hacking.md @@ -13,16 +13,16 @@ The overarching principle of *squeekboard* is to empower users. Software is primarily meant to solve problems of its users. Often in the quest to make software better, a hard distinction is made between the developer, who becomes the creator, and the user, who takes the role of the consumer, without direct influence on the software they use. This project aims to give users the power to make the software work for them by blurring the lines between users and developers. -Nonwithstanding its current state, *squeekboard* must be structured in a way that provides users a gradual way to gain more experience and power to adjust it. It must be easy, in order of importance: +Notwithstanding its current state, *squeekboard* must be structured in a way that provides users a gradual way to gain more experience and power to adjust it. It must be easy, in order of importance: - to use the software, - to modify its resources, -- to change its behaviour, +- to change its behavior, - to contribute upstream. To give an idea of what it means in practice, those are some examples of what has been important for *squeekboard* so far: -- being quick and useable, +- being quick and usable, - allowing local overrides of resources and config, - storing resources and config as editable, standard files, - having complete, up to date documentation of interfaces, @@ -33,7 +33,7 @@ To give an idea of what it means in practice, those are some examples of what ha - having code that is [simple and obvious](https://www.python.org/dev/peps/pep-0020/), - having an easy process of testing and accepting contributions. -You may notice that they are ordered roughly from "user-focused" to "maintainer-focused". While good properties are desired, sometimes they conflict, and maintainers should give additional weight to those benefitting the user compared to those benefitting regular contributors. +You may notice that they are ordered roughly from "user-focused" to "maintainer-focused". While good properties are desired, sometimes they conflict, and maintainers should give additional weight to those benefiting the user compared to those benefiting regular contributors. Sending patches --------------- @@ -43,7 +43,7 @@ By submitting a change to this project, you agree to license it under the [GPL l Development environment ----------------------- -*Squeekboard* is regularly built and tested on [the develpment environment](https://developer.puri.sm/Librem5/Development_Environment.html). +*Squeekboard* is regularly built and tested on [the development environment](https://developer.puri.sm/Librem5/Development_Environment.html). Recent Fedora releases are likely to be tested as well. @@ -162,7 +162,7 @@ Maintenance Squeekboard uses Rust & Cargo for some of its dependencies. -Use the `cargo.sh` script for maintaining the Cargo part of the build. The script takes the usual Cargo commands, after the first 2 positionsl arguments: source directory, and output artifact. So, `cargo test` becomes: +Use the `cargo.sh` script for maintaining the Cargo part of the build. The script takes the usual Cargo commands, after the first 2 positional arguments: source directory, and output artifact. So, `cargo test` becomes: ``` cd build_dir From 94bfa92c12aee4a198f4e1ef38ba3cbbcd7fa411 Mon Sep 17 00:00:00 2001 From: Benjamin Schaaf Date: Fri, 25 Sep 2020 21:38:42 +1000 Subject: [PATCH 04/86] Expand the development documentation in the readme Fixes #227 --- README.md | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 2beb667c..8ccb13ba 100644 --- a/README.md +++ b/README.md @@ -30,29 +30,42 @@ Building ### Dependencies -See `.gitlab-ci.yml`. +See `.gitlab-ci.yml` or run `apt-get build-dep .` ### Build from git repo -``` +```bash $ git clone https://source.puri.sm/Librem5/squeekboard.git $ cd squeekboard -$ mkdir ../build -$ meson ../build/ -$ cd ../build -$ ninja test -$ ninja install +$ mkdir _build +$ meson _build/ +$ cd _build +$ ninja ``` +To run tests use `ninja test`. To install squeekboard run `ninja install`. + Running ------- -``` +```bash $ phoc # if no compatible Wayland compositor is running yet $ cd ../build/ $ src/squeekboard ``` +Squeekboard honors the gnome "screen-keyboard-enabled" setting. Either enable this through gnome-settings under accessibility or run: + +```bash +$ gsettings set org.gnome.desktop.a11y.applications screen-keyboard-enabled true +``` + +To make the keyboard show you can use either an application that does so automatically, like a text editor or `python3 ./tests/entry.py`, or you can manually trigger it with: + +```bash +busctl call --user sm.puri.OSK0 /sm/puri/OSK0 sm.puri.OSK0 SetVisible b true +``` + Developing ---------- From 74479ff2266f12b3c8e2f9149af0dd1ee0f44718 Mon Sep 17 00:00:00 2001 From: Benjamin Schaaf Date: Sat, 26 Sep 2020 01:37:23 +1000 Subject: [PATCH 05/86] Expand key press detection to the edges of the view's bounding box If you have a keyboard layout like the following: A B C D E F G H I J K The E and G keys here should be pressed when clicking in the empty space next to them. This is achieved by not checking the bounding boxes of each key and instead just using the button and row offset to extend buttons/rows to the edges of the view. Caching for the size and position of rows is introduced to simplify implementation and possibly improve performance. Fixes #191 --- src/data.rs | 18 ++-- src/layout.rs | 243 ++++++++++++++++++++++++++++++++------------------ src/tests.rs | 4 +- 3 files changed, 165 insertions(+), 100 deletions(-) diff --git a/src/data.rs b/src/data.rs index c3cf5345..2c3fd353 100644 --- a/src/data.rs +++ b/src/data.rs @@ -459,14 +459,14 @@ impl Layout { &mut warning_handler, )) }); - layout::Row { - buttons: add_offsets( + layout::Row::new( + add_offsets( buttons, |button| button.size.width, ).collect() - } + ) }); - let rows = add_offsets(rows, |row| row.get_height()) + let rows = add_offsets(rows, |row| row.get_size().height) .collect(); ( name.clone(), @@ -484,8 +484,8 @@ impl Layout { name, ( layout::c::Point { - x: (total_size.width - view.get_width()) / 2.0, - y: (total_size.height - view.get_height()) / 2.0, + x: (total_size.width - view.get_size().width) / 2.0, + y: (total_size.height - view.get_size().height) / 2.0, }, view, ), @@ -824,7 +824,7 @@ mod tests { assert_eq!( out.views["base"].1 .get_rows()[0].1 - .buttons[0].1 + .get_buttons()[0].1 .label, ::layout::Label::Text(CString::new("test").unwrap()) ); @@ -839,7 +839,7 @@ mod tests { assert_eq!( out.views["base"].1 .get_rows()[0].1 - .buttons[0].1 + .get_buttons()[0].1 .label, ::layout::Label::Text(CString::new("test").unwrap()) ); @@ -855,7 +855,7 @@ mod tests { assert_eq!( out.views["base"].1 .get_rows()[0].1 - .buttons[0].1 + .get_buttons()[0].1 .state.borrow() .keycodes.len(), 2 diff --git a/src/layout.rs b/src/layout.rs index b1cae8ee..2fa09112 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -493,38 +493,63 @@ pub struct Button { } /// The graphical representation of a row of buttons +#[derive(Clone, Debug)] pub struct Row { - /// Buttons together with their offset from the left - pub buttons: Vec<(f64, Box