Merge branch 'master' into x11kb
This commit is contained in:
29
README.md
29
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
|
||||
----------
|
||||
|
||||
|
||||
89
data/keyboards/be.yaml
Normal file
89
data/keyboards/be.yaml
Normal file
@ -0,0 +1,89 @@
|
||||
---
|
||||
outlines:
|
||||
default: { width: 35.33, height: 52 }
|
||||
altline: { width: 52.67, height: 52 }
|
||||
wide: { width: 59, height: 52 }
|
||||
spaceline: { width: 140, height: 52 }
|
||||
special: { width: 44, height: 52 }
|
||||
|
||||
views:
|
||||
base:
|
||||
- "a z e r t y u i o p"
|
||||
- "q s d f g h j k l m"
|
||||
- "Shift_L w x c v b n . BackSpace"
|
||||
- "show_numbers preferences space show_eschars Return"
|
||||
upper:
|
||||
- "A Z E R T Y U I O P"
|
||||
- "Q S D F G H J K L M"
|
||||
- "Shift_L W X C V B N , BackSpace"
|
||||
- "show_numbers preferences space show_eschars Return"
|
||||
numbers:
|
||||
- "1 2 3 4 5 6 7 8 9 0"
|
||||
- "@ # € % & - _ + ( )"
|
||||
- "show_symbols , \" ' colon ; ! ? BackSpace"
|
||||
- "show_letters preferences space show_eschars Return"
|
||||
symbols:
|
||||
- "~ ` | · √ π τ ÷ × ¶"
|
||||
- "© ® £ $ ¥ ^ ° * { }"
|
||||
- "show_numbers_from_symbols \\ / < > = [ ] BackSpace"
|
||||
- "show_letters preferences space show_eschars Return"
|
||||
eschars:
|
||||
- "à â ç é è ê î ô ù û"
|
||||
- "À Â Ç É È Ê Î Ô Ù Û"
|
||||
- "show_numbers_from_symbols æ œ ä ë ï ö ü BackSpace"
|
||||
- "show_letters preferences space show_eschars Return"
|
||||
|
||||
buttons:
|
||||
Shift_L:
|
||||
action:
|
||||
locking:
|
||||
lock_view: "upper"
|
||||
unlock_view: "base"
|
||||
outline: "altline"
|
||||
icon: "key-shift"
|
||||
BackSpace:
|
||||
outline: "altline"
|
||||
icon: "edit-clear-symbolic"
|
||||
action: erase
|
||||
preferences:
|
||||
action: "show_prefs"
|
||||
outline: "special"
|
||||
icon: "keyboard-mode-symbolic"
|
||||
show_numbers:
|
||||
action:
|
||||
set_view: "numbers"
|
||||
outline: "wide"
|
||||
label: "123"
|
||||
show_numbers_from_symbols:
|
||||
action:
|
||||
set_view: "numbers"
|
||||
outline: "altline"
|
||||
label: "123"
|
||||
show_letters:
|
||||
action:
|
||||
set_view: "base"
|
||||
outline: "wide"
|
||||
label: "abc"
|
||||
show_symbols:
|
||||
action:
|
||||
set_view: "symbols"
|
||||
outline: "altline"
|
||||
label: "*/="
|
||||
show_eschars:
|
||||
action:
|
||||
locking:
|
||||
lock_view: "eschars"
|
||||
unlock_view: "base"
|
||||
outline: "altline"
|
||||
label: "âÂ"
|
||||
space:
|
||||
outline: "spaceline"
|
||||
text: " "
|
||||
Return:
|
||||
outline: "wide"
|
||||
icon: "key-enter"
|
||||
keysym: "Return"
|
||||
colon:
|
||||
text: ":"
|
||||
"\"":
|
||||
keysym: "quotedbl"
|
||||
@ -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
|
||||
|
||||
@ -360,6 +360,10 @@ eek_gtk_keyboard_init (EekGtkKeyboard *self)
|
||||
priv->event = lfb_event_new ("button-pressed");
|
||||
else
|
||||
g_warning ("Failed to init libfeedback: %s", err->message);
|
||||
|
||||
GtkIconTheme *theme = gtk_icon_theme_get_default ();
|
||||
|
||||
gtk_icon_theme_add_resource_path (theme, "/sm/puri/squeekboard/icons");
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@ -51,8 +51,9 @@ struct KeyMap eek_key_map_from_str(char *keymap_str) {
|
||||
g_error("Bad keymap:\n%s", keymap_str);
|
||||
|
||||
xkb_context_unref(context);
|
||||
keymap_str = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1);
|
||||
size_t keymap_len = strlen(keymap_str) + 1;
|
||||
|
||||
char *xkb_keymap_str = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1);
|
||||
size_t keymap_len = strlen(xkb_keymap_str) + 1;
|
||||
|
||||
g_autofree char *path = strdup("/eek_keymap-XXXXXX");
|
||||
char *r = &path[strlen(path) - 6];
|
||||
@ -76,9 +77,9 @@ struct KeyMap eek_key_map_from_str(char *keymap_str) {
|
||||
if ((void*)ptr == (void*)-1) {
|
||||
g_error("Failed to set up mmap");
|
||||
}
|
||||
strncpy(ptr, keymap_str, keymap_len);
|
||||
strncpy(ptr, xkb_keymap_str, keymap_len);
|
||||
munmap(ptr, keymap_len);
|
||||
free(keymap_str);
|
||||
free(xkb_keymap_str);
|
||||
xkb_keymap_unref(keymap);
|
||||
struct KeyMap km = {
|
||||
.fd = keymap_fd,
|
||||
|
||||
@ -265,10 +265,6 @@ renderer_init (EekRenderer *self)
|
||||
self->allocation_height = 0.0;
|
||||
self->scale_factor = 1;
|
||||
|
||||
GtkIconTheme *theme = gtk_icon_theme_get_default ();
|
||||
|
||||
gtk_icon_theme_add_resource_path (theme, "/sm/puri/squeekboard/icons");
|
||||
|
||||
self->css_provider = squeek_load_style();
|
||||
}
|
||||
|
||||
|
||||
@ -744,7 +744,6 @@ fn extract_symbol_names<'a>(actions: &'a [(&str, action::Action)])
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use std::error::Error as ErrorTrait;
|
||||
use ::logging::ProblemPanic;
|
||||
|
||||
const THIS_FILE: &str = file!();
|
||||
@ -792,7 +791,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);
|
||||
@ -810,7 +810,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 {
|
||||
|
||||
@ -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<T> = ::std::result::Result<T, Error>;
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ const KEYBOARDS: &[(*const str, *const str)] = &[
|
||||
("us_wide", include_str!("../data/keyboards/us_wide.yaml")),
|
||||
("br", include_str!("../data/keyboards/br.yaml")),
|
||||
("de", include_str!("../data/keyboards/de.yaml")),
|
||||
("be", include_str!("../data/keyboards/be.yaml")),
|
||||
("de_wide", include_str!("../data/keyboards/de_wide.yaml")),
|
||||
("dk", include_str!("../data/keyboards/dk.yaml")),
|
||||
("es", include_str!("../data/keyboards/es.yaml")),
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -50,6 +50,7 @@ endforeach
|
||||
foreach layout : [
|
||||
'us', 'us_wide',
|
||||
'br',
|
||||
'be',
|
||||
'de', 'de_wide',
|
||||
'dk',
|
||||
'es',
|
||||
|
||||
Reference in New Issue
Block a user