Compare commits
30 Commits
v1.9.3
...
pureos/1.9
| Author | SHA1 | Date | |
|---|---|---|---|
| 3d2f9f3d9e | |||
| a20ab70984 | |||
| 6c5df02921 | |||
| b137e2e3a0 | |||
| 820a8b6ca1 | |||
| 8bdfb69dc1 | |||
| 1e6bcef055 | |||
| 07faf906d8 | |||
| 53f30324f0 | |||
| 3e212ddab4 | |||
| 966990ad65 | |||
| a8b81172fc | |||
| 97f51591b3 | |||
| 6756fb423a | |||
| eb7673d2c2 | |||
| 24b6a04903 | |||
| b197cd839e | |||
| 857a916402 | |||
| ca68fc2040 | |||
| bd661bd4f4 | |||
| 4228192bda | |||
| 0f7ab99da3 | |||
| e15d317488 | |||
| 93e9ce0dd7 | |||
| 9d63b505ec | |||
| 306c11f1fd | |||
| c26feed8b2 | |||
| 2f4a652f53 | |||
| e5796d0d7b | |||
| 9512fd8436 |
@ -36,7 +36,7 @@ build_meson:
|
|||||||
expire_in: 3h
|
expire_in: 3h
|
||||||
script:
|
script:
|
||||||
- apt-get -y build-dep .
|
- apt-get -y build-dep .
|
||||||
- meson . _build/ -Ddepdatadir=/usr/share
|
- meson . _build/ -Ddepdatadir=/usr/share --werror
|
||||||
- ninja -C _build install
|
- ninja -C _build install
|
||||||
|
|
||||||
build_deb:
|
build_deb:
|
||||||
|
|||||||
94
data/keyboards/ua.yaml
Normal file
94
data/keyboards/ua.yaml
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
---
|
||||||
|
outlines:
|
||||||
|
default: { width: 32, height: 52 }
|
||||||
|
altline: { width: 32, height: 52 }
|
||||||
|
wide: { width: 57, height: 52 }
|
||||||
|
narrow: { width: 26, height: 52 }
|
||||||
|
spaceline: { width: 107, height: 52 }
|
||||||
|
fill: { width: 159, height: 52 }
|
||||||
|
special: { width: 42, height: 52 }
|
||||||
|
|
||||||
|
views:
|
||||||
|
base:
|
||||||
|
- "й ц у к е н г ш щ з х"
|
||||||
|
- "ф і в а п р о л д ж є"
|
||||||
|
- "Shift_L я ч с м и т ь б ю BackSpace"
|
||||||
|
- "show_numbers preferences ґ space ї period Return"
|
||||||
|
upper:
|
||||||
|
- "Й Ц У К Е Н Г Ш Щ З Х"
|
||||||
|
- "Ф І В А П Р О Л Д Ж Є"
|
||||||
|
- "Shift_L Я Ч С М И Т Ь Б Ю BackSpace"
|
||||||
|
- "show_numbers preferences Ґ space Ї comma Return"
|
||||||
|
numbers:
|
||||||
|
- "1 2 3 4 5 6 7 8 9 0"
|
||||||
|
- "@ # $ % & - _ + ( )"
|
||||||
|
- "show_symbols , \" ' colon ; ! ? BackSpace"
|
||||||
|
- "show_letters preferences space_fill period Return"
|
||||||
|
symbols:
|
||||||
|
- "~ ` | · √ π τ ÷ × ¶"
|
||||||
|
- "© ® £ € ¥ ^ ° * { }"
|
||||||
|
- "show_numbers_from_symbols \\ / < > = [ ] BackSpace"
|
||||||
|
- "show_letters preferences space_fill period Return"
|
||||||
|
|
||||||
|
buttons:
|
||||||
|
Shift_L:
|
||||||
|
action:
|
||||||
|
locking:
|
||||||
|
lock_view: "upper"
|
||||||
|
unlock_view: "base"
|
||||||
|
outline: "altline"
|
||||||
|
icon: "key-shift"
|
||||||
|
BackSpace:
|
||||||
|
outline: "altline"
|
||||||
|
icon: "edit-clear-symbolic"
|
||||||
|
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: "wide"
|
||||||
|
label: "123"
|
||||||
|
show_letters:
|
||||||
|
action:
|
||||||
|
set_view: "base"
|
||||||
|
outline: "wide"
|
||||||
|
label: "АБВ"
|
||||||
|
show_symbols:
|
||||||
|
action:
|
||||||
|
set_view: "symbols"
|
||||||
|
outline: "wide"
|
||||||
|
label: "*/="
|
||||||
|
period:
|
||||||
|
outline: "special"
|
||||||
|
text: "."
|
||||||
|
comma:
|
||||||
|
outline: "special"
|
||||||
|
text: ","
|
||||||
|
space:
|
||||||
|
outline: "spaceline"
|
||||||
|
text: " "
|
||||||
|
space_fill:
|
||||||
|
outline: "fill"
|
||||||
|
text: " "
|
||||||
|
Return:
|
||||||
|
outline: "wide"
|
||||||
|
icon: "key-enter"
|
||||||
|
keysym: "Return"
|
||||||
|
colon:
|
||||||
|
text: ":"
|
||||||
|
ґ:
|
||||||
|
outline: "narrow"
|
||||||
|
Ґ:
|
||||||
|
outline: "narrow"
|
||||||
|
ї:
|
||||||
|
outline: "narrow"
|
||||||
|
Ї:
|
||||||
|
outline: "narrow"
|
||||||
6
debian/changelog
vendored
6
debian/changelog
vendored
@ -1,3 +1,9 @@
|
|||||||
|
squeekboard (1.9.3.0pureos0.1) byzantium; urgency=medium
|
||||||
|
|
||||||
|
* Upload to byzantium
|
||||||
|
|
||||||
|
-- Guido Günther <agx@sigxcpu.org> Tue, 22 Sep 2020 12:42:41 +0200
|
||||||
|
|
||||||
squeekboard (1.9.3) amber-phone; urgency=medium
|
squeekboard (1.9.3) amber-phone; urgency=medium
|
||||||
|
|
||||||
[ Björn Tantau ]
|
[ Björn Tantau ]
|
||||||
|
|||||||
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
|
||||||
@ -38,8 +38,6 @@ struct _EekElementClass
|
|||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType eek_element_get_type (void) G_GNUC_CONST;
|
|
||||||
|
|
||||||
void eek_element_set_name (EekElement *element,
|
void eek_element_set_name (EekElement *element,
|
||||||
const gchar *name);
|
const gchar *name);
|
||||||
|
|
||||||
|
|||||||
@ -126,8 +126,8 @@ eek_gtk_keyboard_real_size_allocate (GtkWidget *self,
|
|||||||
(uint32_t)(allocation->height - allocation->y) * scale);
|
(uint32_t)(allocation->height - allocation->y) * scale);
|
||||||
if (priv->layout->arrangement != new_type) {
|
if (priv->layout->arrangement != new_type) {
|
||||||
priv->layout->arrangement = new_type;
|
priv->layout->arrangement = new_type;
|
||||||
|
uint32_t time = gdk_event_get_time(NULL);
|
||||||
eekboard_context_service_use_layout(priv->eekboard_context, priv->layout);
|
eekboard_context_service_use_layout(priv->eekboard_context, priv->layout, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->renderer)
|
if (priv->renderer)
|
||||||
|
|||||||
@ -47,7 +47,6 @@ struct _EekGtkKeyboardClass
|
|||||||
gpointer pdummy[24];
|
gpointer pdummy[24];
|
||||||
};
|
};
|
||||||
|
|
||||||
GType eek_gtk_keyboard_get_type (void) G_GNUC_CONST;
|
|
||||||
GtkWidget *eek_gtk_keyboard_new (EekboardContextService *eekservice, struct submission *submission, struct squeek_layout_state *layout);
|
GtkWidget *eek_gtk_keyboard_new (EekboardContextService *eekservice, struct submission *submission, struct squeek_layout_state *layout);
|
||||||
void eek_gtk_keyboard_emit_feedback (EekGtkKeyboard *self);
|
void eek_gtk_keyboard_emit_feedback (EekGtkKeyboard *self);
|
||||||
|
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#define _XOPEN_SOURCE 500
|
#define _XOPEN_SOURCE 500
|
||||||
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
@ -68,7 +69,8 @@ level_keyboard_new (struct squeek_layout *layout)
|
|||||||
|
|
||||||
g_autofree char *path = strdup("/eek_keymap-XXXXXX");
|
g_autofree char *path = strdup("/eek_keymap-XXXXXX");
|
||||||
char *r = &path[strlen(path) - 6];
|
char *r = &path[strlen(path) - 6];
|
||||||
getrandom(r, 6, GRND_NONBLOCK);
|
if (getrandom(r, 6, GRND_NONBLOCK) < 0)
|
||||||
|
g_error("Failed to get random numbers: %s", strerror(errno));
|
||||||
for (unsigned i = 0; i < 6; i++) {
|
for (unsigned i = 0; i < 6; i++) {
|
||||||
r[i] = (r[i] & 0b1111111) | 0b1000000; // A-z
|
r[i] = (r[i] & 0b1111111) | 0b1000000; // A-z
|
||||||
r[i] = r[i] > 'z' ? '?' : r[i]; // The randomizer doesn't need to be good...
|
r[i] = r[i] > 'z' ? '?' : r[i]; // The randomizer doesn't need to be good...
|
||||||
|
|||||||
@ -241,7 +241,7 @@ static GType new_type(char *name) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GType view_type() {
|
static GType view_type(void) {
|
||||||
static GType type = 0;
|
static GType type = 0;
|
||||||
if (!type) {
|
if (!type) {
|
||||||
type = new_type("sq_view");
|
type = new_type("sq_view");
|
||||||
@ -249,7 +249,7 @@ static GType view_type() {
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GType button_type() {
|
static GType button_type(void) {
|
||||||
static GType type = 0;
|
static GType type = 0;
|
||||||
if (!type) {
|
if (!type) {
|
||||||
type = new_type("sq_button");
|
type = new_type("sq_button");
|
||||||
|
|||||||
@ -42,10 +42,21 @@ enum {
|
|||||||
|
|
||||||
static guint signals[LAST_SIGNAL] = { 0, };
|
static guint signals[LAST_SIGNAL] = { 0, };
|
||||||
|
|
||||||
#define EEKBOARD_CONTEXT_SERVICE_GET_PRIVATE(obj) \
|
/**
|
||||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), EEKBOARD_TYPE_CONTEXT_SERVICE, EekboardContextServicePrivate))
|
* EekboardContextService:
|
||||||
|
*
|
||||||
|
* Handles layout state, gsettings, and virtual-keyboard.
|
||||||
|
*
|
||||||
|
* TODO: Restrict to managing keyboard layouts, and maybe button repeats,
|
||||||
|
* and the virtual keyboard protocol.
|
||||||
|
*
|
||||||
|
* The #EekboardContextService structure contains only private data
|
||||||
|
* and should only be accessed using the provided API.
|
||||||
|
*/
|
||||||
|
struct _EekboardContextService {
|
||||||
|
GObject parent;
|
||||||
|
struct squeek_layout_state *layout; // Unowned
|
||||||
|
|
||||||
struct _EekboardContextServicePrivate {
|
|
||||||
LevelKeyboard *keyboard; // currently used keyboard
|
LevelKeyboard *keyboard; // currently used keyboard
|
||||||
GSettings *settings; // Owned reference
|
GSettings *settings; // Owned reference
|
||||||
|
|
||||||
@ -56,7 +67,7 @@ struct _EekboardContextServicePrivate {
|
|||||||
struct submission *submission; // unowned
|
struct submission *submission; // unowned
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (EekboardContextService, eekboard_context_service, G_TYPE_OBJECT);
|
G_DEFINE_TYPE (EekboardContextService, eekboard_context_service, G_TYPE_OBJECT);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eekboard_context_service_set_property (GObject *object,
|
eekboard_context_service_set_property (GObject *object,
|
||||||
@ -82,7 +93,7 @@ eekboard_context_service_get_property (GObject *object,
|
|||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_KEYBOARD:
|
case PROP_KEYBOARD:
|
||||||
g_value_set_object (value, context->priv->keyboard);
|
g_value_set_object (value, context->keyboard);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
@ -116,7 +127,7 @@ settings_get_layout(GSettings *settings, char **type, char **layout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
eekboard_context_service_use_layout(EekboardContextService *context, struct squeek_layout_state *state) {
|
eekboard_context_service_use_layout(EekboardContextService *context, struct squeek_layout_state *state, uint32_t timestamp) {
|
||||||
gchar *layout_name = state->overlay_name;
|
gchar *layout_name = state->overlay_name;
|
||||||
|
|
||||||
if (layout_name == NULL) {
|
if (layout_name == NULL) {
|
||||||
@ -143,12 +154,12 @@ eekboard_context_service_use_layout(EekboardContextService *context, struct sque
|
|||||||
struct squeek_layout *layout = squeek_load_layout(layout_name, state->arrangement);
|
struct squeek_layout *layout = squeek_load_layout(layout_name, state->arrangement);
|
||||||
LevelKeyboard *keyboard = level_keyboard_new(layout);
|
LevelKeyboard *keyboard = level_keyboard_new(layout);
|
||||||
// set as current
|
// set as current
|
||||||
LevelKeyboard *previous_keyboard = context->priv->keyboard;
|
LevelKeyboard *previous_keyboard = context->keyboard;
|
||||||
context->priv->keyboard = keyboard;
|
context->keyboard = keyboard;
|
||||||
// Update the keymap if necessary.
|
// Update the keymap if necessary.
|
||||||
// TODO: Update submission on change event
|
// TODO: Update submission on change event
|
||||||
if (context->priv->submission) {
|
if (context->submission) {
|
||||||
submission_set_keyboard(context->priv->submission, keyboard);
|
submission_set_keyboard(context->submission, keyboard, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update UI
|
// Update UI
|
||||||
@ -163,7 +174,7 @@ eekboard_context_service_use_layout(EekboardContextService *context, struct sque
|
|||||||
static void eekboard_context_service_update_settings_layout(EekboardContextService *context) {
|
static void eekboard_context_service_update_settings_layout(EekboardContextService *context) {
|
||||||
g_autofree gchar *keyboard_layout = NULL;
|
g_autofree gchar *keyboard_layout = NULL;
|
||||||
g_autofree gchar *keyboard_type = NULL;
|
g_autofree gchar *keyboard_type = NULL;
|
||||||
settings_get_layout(context->priv->settings,
|
settings_get_layout(context->settings,
|
||||||
&keyboard_type, &keyboard_layout);
|
&keyboard_type, &keyboard_layout);
|
||||||
|
|
||||||
if (g_strcmp0(context->layout->layout_name, keyboard_layout) != 0 || context->layout->overlay_name) {
|
if (g_strcmp0(context->layout->layout_name, keyboard_layout) != 0 || context->layout->overlay_name) {
|
||||||
@ -174,7 +185,8 @@ static void eekboard_context_service_update_settings_layout(EekboardContextServi
|
|||||||
context->layout->layout_name = g_strdup(keyboard_layout);
|
context->layout->layout_name = g_strdup(keyboard_layout);
|
||||||
}
|
}
|
||||||
// This must actually update the UI.
|
// This must actually update the UI.
|
||||||
eekboard_context_service_use_layout(context, context->layout);
|
uint32_t time = gdk_event_get_time(NULL);
|
||||||
|
eekboard_context_service_use_layout(context, context->layout, time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,7 +228,7 @@ eekboard_context_service_class_init (EekboardContextServiceClass *klass)
|
|||||||
g_signal_new (I_("destroyed"),
|
g_signal_new (I_("destroyed"),
|
||||||
G_TYPE_FROM_CLASS(gobject_class),
|
G_TYPE_FROM_CLASS(gobject_class),
|
||||||
G_SIGNAL_RUN_LAST,
|
G_SIGNAL_RUN_LAST,
|
||||||
G_STRUCT_OFFSET(EekboardContextServiceClass, destroyed),
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
g_cclosure_marshal_VOID__VOID,
|
g_cclosure_marshal_VOID__VOID,
|
||||||
@ -240,18 +252,21 @@ eekboard_context_service_class_init (EekboardContextServiceClass *klass)
|
|||||||
static void
|
static void
|
||||||
eekboard_context_service_init (EekboardContextService *self)
|
eekboard_context_service_init (EekboardContextService *self)
|
||||||
{
|
{
|
||||||
self->priv = EEKBOARD_CONTEXT_SERVICE_GET_PRIVATE(self);
|
|
||||||
const char *schema_name = "org.gnome.desktop.input-sources";
|
const char *schema_name = "org.gnome.desktop.input-sources";
|
||||||
GSettingsSchemaSource *ssrc = g_settings_schema_source_get_default();
|
GSettingsSchemaSource *ssrc = g_settings_schema_source_get_default();
|
||||||
if (ssrc) {
|
g_autoptr(GSettingsSchema) schema = NULL;
|
||||||
GSettingsSchema *schema = g_settings_schema_source_lookup(ssrc,
|
|
||||||
schema_name,
|
if (!ssrc) {
|
||||||
TRUE);
|
g_warning("No gsettings schemas installed. Layout switching unavailable.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
schema = g_settings_schema_source_lookup(ssrc, schema_name, TRUE);
|
||||||
if (schema) {
|
if (schema) {
|
||||||
// Not referencing the found schema directly,
|
// Not referencing the found schema directly,
|
||||||
// because it's not clear how...
|
// because it's not clear how...
|
||||||
self->priv->settings = g_settings_new (schema_name);
|
self->settings = g_settings_new (schema_name);
|
||||||
gulong conn_id = g_signal_connect(self->priv->settings, "change-event",
|
gulong conn_id = g_signal_connect(self->settings, "change-event",
|
||||||
G_CALLBACK(settings_handle_layout_changed),
|
G_CALLBACK(settings_handle_layout_changed),
|
||||||
self);
|
self);
|
||||||
if (conn_id == 0) {
|
if (conn_id == 0) {
|
||||||
@ -262,9 +277,6 @@ eekboard_context_service_init (EekboardContextService *self)
|
|||||||
g_warning("Gsettings schema %s is not installed on the system. "
|
g_warning("Gsettings schema %s is not installed on the system. "
|
||||||
"Layout switching unavailable", schema_name);
|
"Layout switching unavailable", schema_name);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
g_warning("No gsettings schemas installed. Layout switching unavailable.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -290,7 +302,7 @@ eekboard_context_service_destroy (EekboardContextService *context)
|
|||||||
LevelKeyboard *
|
LevelKeyboard *
|
||||||
eekboard_context_service_get_keyboard (EekboardContextService *context)
|
eekboard_context_service_get_keyboard (EekboardContextService *context)
|
||||||
{
|
{
|
||||||
return context->priv->keyboard;
|
return context->keyboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
|
void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
|
||||||
@ -299,7 +311,8 @@ void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
|
|||||||
if (context->layout->hint != hint || context->layout->purpose != purpose) {
|
if (context->layout->hint != hint || context->layout->purpose != purpose) {
|
||||||
context->layout->hint = hint;
|
context->layout->hint = hint;
|
||||||
context->layout->purpose = purpose;
|
context->layout->purpose = purpose;
|
||||||
eekboard_context_service_use_layout(context, context->layout);
|
uint32_t time = gdk_event_get_time(NULL);
|
||||||
|
eekboard_context_service_use_layout(context, context->layout, time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,7 +321,8 @@ eekboard_context_service_set_overlay(EekboardContextService *context, const char
|
|||||||
if (g_strcmp0(context->layout->overlay_name, name)) {
|
if (g_strcmp0(context->layout->overlay_name, name)) {
|
||||||
g_free(context->layout->overlay_name);
|
g_free(context->layout->overlay_name);
|
||||||
context->layout->overlay_name = g_strdup(name);
|
context->layout->overlay_name = g_strdup(name);
|
||||||
eekboard_context_service_use_layout(context, context->layout);
|
uint32_t time = gdk_event_get_time(NULL);
|
||||||
|
eekboard_context_service_use_layout(context, context->layout, time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,17 +336,19 @@ EekboardContextService *eekboard_context_service_new(struct squeek_layout_state
|
|||||||
EekboardContextService *context = g_object_new (EEKBOARD_TYPE_CONTEXT_SERVICE, NULL);
|
EekboardContextService *context = g_object_new (EEKBOARD_TYPE_CONTEXT_SERVICE, NULL);
|
||||||
context->layout = state;
|
context->layout = state;
|
||||||
eekboard_context_service_update_settings_layout(context);
|
eekboard_context_service_update_settings_layout(context);
|
||||||
eekboard_context_service_use_layout(context, context->layout);
|
uint32_t time = gdk_event_get_time(NULL);
|
||||||
|
eekboard_context_service_use_layout(context, context->layout, time);
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
void eekboard_context_service_set_submission(EekboardContextService *context, struct submission *submission) {
|
void eekboard_context_service_set_submission(EekboardContextService *context, struct submission *submission) {
|
||||||
context->priv->submission = submission;
|
context->submission = submission;
|
||||||
if (context->priv->submission) {
|
if (context->submission) {
|
||||||
submission_set_keyboard(context->priv->submission, context->priv->keyboard);
|
uint32_t time = gdk_event_get_time(NULL);
|
||||||
|
submission_set_keyboard(context->submission, context->keyboard, time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void eekboard_context_service_set_ui(EekboardContextService *context, ServerContextService *ui) {
|
void eekboard_context_service_set_ui(EekboardContextService *context, ServerContextService *ui) {
|
||||||
context->priv->ui = ui;
|
context->ui = ui;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,54 +34,9 @@ G_BEGIN_DECLS
|
|||||||
#define EEKBOARD_CONTEXT_SERVICE_INTERFACE "org.fedorahosted.Eekboard.Context"
|
#define EEKBOARD_CONTEXT_SERVICE_INTERFACE "org.fedorahosted.Eekboard.Context"
|
||||||
|
|
||||||
#define EEKBOARD_TYPE_CONTEXT_SERVICE (eekboard_context_service_get_type())
|
#define EEKBOARD_TYPE_CONTEXT_SERVICE (eekboard_context_service_get_type())
|
||||||
#define EEKBOARD_CONTEXT_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEKBOARD_TYPE_CONTEXT_SERVICE, EekboardContextService))
|
|
||||||
#define EEKBOARD_CONTEXT_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEKBOARD_TYPE_CONTEXT_SERVICE, EekboardContextServiceClass))
|
|
||||||
#define EEKBOARD_IS_CONTEXT_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEKBOARD_TYPE_CONTEXT_SERVICE))
|
|
||||||
#define EEKBOARD_IS_CONTEXT_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEKBOARD_TYPE_CONTEXT_SERVICE))
|
|
||||||
#define EEKBOARD_CONTEXT_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEKBOARD_TYPE_CONTEXT_SERVICE, EekboardContextServiceClass))
|
|
||||||
|
|
||||||
|
G_DECLARE_FINAL_TYPE(EekboardContextService, eekboard_context_service, EEKBOARD, CONTEXT_SERVICE, GObject)
|
||||||
|
|
||||||
typedef struct _EekboardContextServiceClass EekboardContextServiceClass;
|
|
||||||
typedef struct _EekboardContextServicePrivate EekboardContextServicePrivate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* EekboardContextService:
|
|
||||||
*
|
|
||||||
* Handles layout state, gsettings, and virtual-keyboard.
|
|
||||||
*
|
|
||||||
* TODO: Restrict to managing keyboard layouts, and maybe button repeats,
|
|
||||||
* and the virtual keyboard protocol.
|
|
||||||
*
|
|
||||||
* The #EekboardContextService structure contains only private data
|
|
||||||
* and should only be accessed using the provided API.
|
|
||||||
*/
|
|
||||||
struct _EekboardContextService {
|
|
||||||
GObject parent;
|
|
||||||
EekboardContextServicePrivate *priv;
|
|
||||||
struct squeek_layout_state *layout; // Unowned
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* EekboardContextServiceClass:
|
|
||||||
* @create_keyboard: virtual function for create a keyboard from string
|
|
||||||
* @enabled: class handler for #EekboardContextService::enabled signal
|
|
||||||
* @disabled: class handler for #EekboardContextService::disabled signal
|
|
||||||
*/
|
|
||||||
struct _EekboardContextServiceClass {
|
|
||||||
/*< private >*/
|
|
||||||
GObjectClass parent_class;
|
|
||||||
|
|
||||||
/*< public >*/
|
|
||||||
/* signals */
|
|
||||||
void (*destroyed) (EekboardContextService *self);
|
|
||||||
|
|
||||||
/*< private >*/
|
|
||||||
/* padding */
|
|
||||||
gpointer pdummy[24];
|
|
||||||
};
|
|
||||||
|
|
||||||
GType eekboard_context_service_get_type
|
|
||||||
(void) G_GNUC_CONST;
|
|
||||||
EekboardContextService *eekboard_context_service_new(struct squeek_layout_state *state);
|
EekboardContextService *eekboard_context_service_new(struct squeek_layout_state *state);
|
||||||
void eekboard_context_service_set_submission(EekboardContextService *context, struct submission *submission);
|
void eekboard_context_service_set_submission(EekboardContextService *context, struct submission *submission);
|
||||||
void eekboard_context_service_set_ui(EekboardContextService *context, ServerContextService *ui);
|
void eekboard_context_service_set_ui(EekboardContextService *context, ServerContextService *ui);
|
||||||
@ -95,6 +50,6 @@ void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
|
|||||||
uint32_t hint,
|
uint32_t hint,
|
||||||
uint32_t purpose);
|
uint32_t purpose);
|
||||||
void
|
void
|
||||||
eekboard_context_service_use_layout(EekboardContextService *context, struct squeek_layout_state *layout);
|
eekboard_context_service_use_layout(EekboardContextService *context, struct squeek_layout_state *layout, uint32_t timestamp);
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* EEKBOARD_CONTEXT_SERVICE_H */
|
#endif /* EEKBOARD_CONTEXT_SERVICE_H */
|
||||||
|
|||||||
@ -19,6 +19,14 @@ add_project_arguments(
|
|||||||
'-Werror=missing-field-initializers',
|
'-Werror=missing-field-initializers',
|
||||||
'-Werror=incompatible-pointer-types',
|
'-Werror=incompatible-pointer-types',
|
||||||
'-Werror=int-conversion',
|
'-Werror=int-conversion',
|
||||||
|
'-Wformat-nonliteral',
|
||||||
|
'-Wformat-security',
|
||||||
|
'-Winit-self',
|
||||||
|
'-Wmaybe-uninitialized',
|
||||||
|
'-Wold-style-definition',
|
||||||
|
'-Wredundant-decls',
|
||||||
|
'-Wstrict-prototypes',
|
||||||
|
'-Wunused-function',
|
||||||
],
|
],
|
||||||
language: 'c'
|
language: 'c'
|
||||||
)
|
)
|
||||||
|
|||||||
@ -43,7 +43,7 @@ bitflags!{
|
|||||||
|
|
||||||
/// When the submitted actions of keys need to be tracked,
|
/// When the submitted actions of keys need to be tracked,
|
||||||
/// they need a stable, comparable ID
|
/// they need a stable, comparable ID
|
||||||
#[derive(PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub struct KeyStateId(*const KeyState);
|
pub struct KeyStateId(*const KeyState);
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -192,7 +192,7 @@ pub fn generate_keymap(
|
|||||||
key <BackSpace> {{ [ BackSpace ] }};"
|
key <BackSpace> {{ [ BackSpace ] }};"
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
for (name, state) in keystates.iter() {
|
for (_name, state) in keystates.iter() {
|
||||||
if let Action::Submit { text: _, keys } = &state.action {
|
if let Action::Submit { text: _, keys } = &state.action {
|
||||||
for keysym in keys.iter() {
|
for keysym in keys.iter() {
|
||||||
write!(
|
write!(
|
||||||
|
|||||||
@ -107,8 +107,8 @@ pub mod c {
|
|||||||
|
|
||||||
impl Bounds {
|
impl Bounds {
|
||||||
pub fn contains(&self, point: &Point) -> bool {
|
pub fn contains(&self, point: &Point) -> bool {
|
||||||
(point.x > self.x && point.x < self.x + self.width
|
point.x > self.x && point.x < self.x + self.width
|
||||||
&& point.y > self.y && point.y < self.y + self.height)
|
&& point.y > self.y && point.y < self.y + self.height
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@ struct squeek_output_handle {
|
|||||||
struct squeek_outputs *outputs;
|
struct squeek_outputs *outputs;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct squeek_outputs *squeek_outputs_new();
|
struct squeek_outputs *squeek_outputs_new(void);
|
||||||
void squeek_outputs_free(struct squeek_outputs*);
|
void squeek_outputs_free(struct squeek_outputs*);
|
||||||
void squeek_outputs_register(struct squeek_outputs*, struct wl_output *output);
|
void squeek_outputs_register(struct squeek_outputs*, struct wl_output *output);
|
||||||
struct squeek_output_handle squeek_outputs_get_current(struct squeek_outputs*);
|
struct squeek_output_handle squeek_outputs_get_current(struct squeek_outputs*);
|
||||||
|
|||||||
@ -32,6 +32,7 @@ const KEYBOARDS: &[(*const str, *const str)] = &[
|
|||||||
("pl_wide", include_str!("../data/keyboards/pl_wide.yaml")),
|
("pl_wide", include_str!("../data/keyboards/pl_wide.yaml")),
|
||||||
("ru", include_str!("../data/keyboards/ru.yaml")),
|
("ru", include_str!("../data/keyboards/ru.yaml")),
|
||||||
("se", include_str!("../data/keyboards/se.yaml")),
|
("se", include_str!("../data/keyboards/se.yaml")),
|
||||||
|
("ua", include_str!("../data/keyboards/ua.yaml")),
|
||||||
// layout+overlay
|
// layout+overlay
|
||||||
("terminal", include_str!("../data/keyboards/terminal.yaml")),
|
("terminal", include_str!("../data/keyboards/terminal.yaml")),
|
||||||
// Overlays
|
// Overlays
|
||||||
|
|||||||
@ -34,8 +34,6 @@ enum {
|
|||||||
PROP_LAST
|
PROP_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _ServerContextServiceClass ServerContextServiceClass;
|
|
||||||
|
|
||||||
struct _ServerContextService {
|
struct _ServerContextService {
|
||||||
GObject parent;
|
GObject parent;
|
||||||
|
|
||||||
@ -52,39 +50,36 @@ struct _ServerContextService {
|
|||||||
guint last_requested_height;
|
guint last_requested_height;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _ServerContextServiceClass {
|
|
||||||
GObjectClass parent_class;
|
|
||||||
};
|
|
||||||
|
|
||||||
G_DEFINE_TYPE(ServerContextService, server_context_service, G_TYPE_OBJECT);
|
G_DEFINE_TYPE(ServerContextService, server_context_service, G_TYPE_OBJECT);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_destroy (GtkWidget *widget, gpointer user_data)
|
on_destroy (ServerContextService *self, GtkWidget *widget)
|
||||||
{
|
{
|
||||||
ServerContextService *context = user_data;
|
g_return_if_fail (SERVER_IS_CONTEXT_SERVICE (self));
|
||||||
|
|
||||||
g_assert (widget == GTK_WIDGET(context->window));
|
g_assert (widget == GTK_WIDGET(self->window));
|
||||||
|
|
||||||
context->window = NULL;
|
self->window = NULL;
|
||||||
context->widget = NULL;
|
self->widget = NULL;
|
||||||
|
|
||||||
//eekboard_context_service_destroy (EEKBOARD_CONTEXT_SERVICE (context));
|
//eekboard_context_service_destroy (EEKBOARD_CONTEXT_SERVICE (context));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_notify_map (GObject *object,
|
on_notify_map (ServerContextService *self, GtkWidget *widget)
|
||||||
ServerContextService *context)
|
|
||||||
{
|
{
|
||||||
g_object_set (context, "visible", TRUE, NULL);
|
g_return_if_fail (SERVER_IS_CONTEXT_SERVICE (self));
|
||||||
|
|
||||||
|
g_object_set (self, "visible", TRUE, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_notify_unmap (GObject *object,
|
on_notify_unmap (ServerContextService *self, GtkWidget *widget)
|
||||||
ServerContextService *context)
|
|
||||||
{
|
{
|
||||||
(void)object;
|
g_return_if_fail (SERVER_IS_CONTEXT_SERVICE (self));
|
||||||
g_object_set (context, "visible", FALSE, NULL);
|
|
||||||
|
g_object_set (self, "visible", FALSE, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
@ -100,10 +95,14 @@ calculate_height(int32_t width)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_surface_configure(PhoshLayerSurface *surface, ServerContextService *context)
|
on_surface_configure(ServerContextService *self, PhoshLayerSurface *surface)
|
||||||
{
|
{
|
||||||
gint width;
|
gint width;
|
||||||
gint height;
|
gint height;
|
||||||
|
|
||||||
|
g_return_if_fail (SERVER_IS_CONTEXT_SERVICE (self));
|
||||||
|
g_return_if_fail (PHOSH_IS_LAYER_SURFACE (surface));
|
||||||
|
|
||||||
g_object_get(G_OBJECT(surface),
|
g_object_get(G_OBJECT(surface),
|
||||||
"configured-width", &width,
|
"configured-width", &width,
|
||||||
"configured-height", &height,
|
"configured-height", &height,
|
||||||
@ -122,8 +121,8 @@ on_surface_configure(PhoshLayerSurface *surface, ServerContextService *context)
|
|||||||
// as it's likely to create pointless loops
|
// as it's likely to create pointless loops
|
||||||
// of request->reject->request_again->...
|
// of request->reject->request_again->...
|
||||||
if (desired_height != configured_height
|
if (desired_height != configured_height
|
||||||
&& context->last_requested_height != desired_height) {
|
&& self->last_requested_height != desired_height) {
|
||||||
context->last_requested_height = desired_height;
|
self->last_requested_height = desired_height;
|
||||||
phosh_layer_surface_set_size(surface, 0,
|
phosh_layer_surface_set_size(surface, 0,
|
||||||
(gint)desired_height);
|
(gint)desired_height);
|
||||||
phosh_layer_surface_set_exclusive_zone(surface, (gint)desired_height);
|
phosh_layer_surface_set_exclusive_zone(surface, (gint)desired_height);
|
||||||
@ -132,16 +131,16 @@ on_surface_configure(PhoshLayerSurface *surface, ServerContextService *context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
make_window (ServerContextService *context)
|
make_window (ServerContextService *self)
|
||||||
{
|
{
|
||||||
if (context->window)
|
if (self->window)
|
||||||
g_error("Window already present");
|
g_error("Window already present");
|
||||||
|
|
||||||
struct squeek_output_handle output = squeek_outputs_get_current(squeek_wayland->outputs);
|
struct squeek_output_handle output = squeek_outputs_get_current(squeek_wayland->outputs);
|
||||||
squeek_uiman_set_output(context->manager, output);
|
squeek_uiman_set_output(self->manager, output);
|
||||||
uint32_t height = squeek_uiman_get_perceptual_height(context->manager);
|
uint32_t height = squeek_uiman_get_perceptual_height(self->manager);
|
||||||
|
|
||||||
context->window = g_object_new (
|
self->window = g_object_new (
|
||||||
PHOSH_TYPE_LAYER_SURFACE,
|
PHOSH_TYPE_LAYER_SURFACE,
|
||||||
"layer-shell", squeek_wayland->layer_shell,
|
"layer-shell", squeek_wayland->layer_shell,
|
||||||
"wl-output", output.output,
|
"wl-output", output.output,
|
||||||
@ -156,11 +155,11 @@ make_window (ServerContextService *context)
|
|||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
g_object_connect (context->window,
|
g_object_connect (self->window,
|
||||||
"signal::destroy", G_CALLBACK(on_destroy), context,
|
"swapped-signal::destroy", G_CALLBACK(on_destroy), self,
|
||||||
"signal::map", G_CALLBACK(on_notify_map), context,
|
"swapped-signal::map", G_CALLBACK(on_notify_map), self,
|
||||||
"signal::unmap", G_CALLBACK(on_notify_unmap), context,
|
"swapped-signal::unmap", G_CALLBACK(on_notify_unmap), self,
|
||||||
"signal::configured", G_CALLBACK(on_surface_configure), context,
|
"swapped-signal::configured", G_CALLBACK(on_surface_configure), self,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
// The properties below are just to make hacking easier.
|
// The properties below are just to make hacking easier.
|
||||||
@ -168,87 +167,87 @@ make_window (ServerContextService *context)
|
|||||||
// and there's no space in the protocol for others.
|
// and there's no space in the protocol for others.
|
||||||
// Those may still be useful in the future,
|
// Those may still be useful in the future,
|
||||||
// or for hacks with regular windows.
|
// or for hacks with regular windows.
|
||||||
gtk_widget_set_can_focus (GTK_WIDGET(context->window), FALSE);
|
gtk_widget_set_can_focus (GTK_WIDGET(self->window), FALSE);
|
||||||
g_object_set (G_OBJECT(context->window), "accept_focus", FALSE, NULL);
|
g_object_set (G_OBJECT(self->window), "accept_focus", FALSE, NULL);
|
||||||
gtk_window_set_title (GTK_WINDOW(context->window),
|
gtk_window_set_title (GTK_WINDOW(self->window),
|
||||||
_("Squeekboard"));
|
_("Squeekboard"));
|
||||||
gtk_window_set_icon_name (GTK_WINDOW(context->window), "squeekboard");
|
gtk_window_set_icon_name (GTK_WINDOW(self->window), "squeekboard");
|
||||||
gtk_window_set_keep_above (GTK_WINDOW(context->window), TRUE);
|
gtk_window_set_keep_above (GTK_WINDOW(self->window), TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
destroy_window (ServerContextService *context)
|
destroy_window (ServerContextService *self)
|
||||||
{
|
{
|
||||||
gtk_widget_destroy (GTK_WIDGET (context->window));
|
gtk_widget_destroy (GTK_WIDGET (self->window));
|
||||||
context->window = NULL;
|
self->window = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
make_widget (ServerContextService *context)
|
make_widget (ServerContextService *self)
|
||||||
{
|
{
|
||||||
if (context->widget) {
|
if (self->widget) {
|
||||||
gtk_widget_destroy(context->widget);
|
gtk_widget_destroy(self->widget);
|
||||||
context->widget = NULL;
|
self->widget = NULL;
|
||||||
}
|
}
|
||||||
context->widget = eek_gtk_keyboard_new (context->state, context->submission, context->layout);
|
self->widget = eek_gtk_keyboard_new (self->state, self->submission, self->layout);
|
||||||
|
|
||||||
gtk_widget_set_has_tooltip (context->widget, TRUE);
|
gtk_widget_set_has_tooltip (self->widget, TRUE);
|
||||||
gtk_container_add (GTK_CONTAINER(context->window), context->widget);
|
gtk_container_add (GTK_CONTAINER(self->window), self->widget);
|
||||||
gtk_widget_show_all(context->widget);
|
gtk_widget_show_all(self->widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
on_hide (ServerContextService *context)
|
on_hide (ServerContextService *self)
|
||||||
{
|
{
|
||||||
gtk_widget_hide (GTK_WIDGET(context->window));
|
gtk_widget_hide (GTK_WIDGET(self->window));
|
||||||
context->hiding = 0;
|
self->hiding = 0;
|
||||||
|
|
||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
server_context_service_real_show_keyboard (ServerContextService *context)
|
server_context_service_real_show_keyboard (ServerContextService *self)
|
||||||
{
|
{
|
||||||
if (context->hiding) {
|
if (self->hiding) {
|
||||||
g_source_remove (context->hiding);
|
g_source_remove (self->hiding);
|
||||||
context->hiding = 0;
|
self->hiding = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!context->window)
|
if (!self->window)
|
||||||
make_window (context);
|
make_window (self);
|
||||||
if (!context->widget)
|
if (!self->widget)
|
||||||
make_widget (context);
|
make_widget (self);
|
||||||
|
|
||||||
context->visible = TRUE;
|
self->visible = TRUE;
|
||||||
gtk_widget_show (GTK_WIDGET(context->window));
|
gtk_widget_show (GTK_WIDGET(self->window));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
server_context_service_real_hide_keyboard (ServerContextService *context)
|
server_context_service_real_hide_keyboard (ServerContextService *self)
|
||||||
{
|
{
|
||||||
if (!context->hiding)
|
if (!self->hiding)
|
||||||
context->hiding = g_timeout_add (200, (GSourceFunc) on_hide, context);
|
self->hiding = g_timeout_add (200, (GSourceFunc) on_hide, self);
|
||||||
|
|
||||||
context->visible = FALSE;
|
self->visible = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
server_context_service_show_keyboard (ServerContextService *context)
|
server_context_service_show_keyboard (ServerContextService *self)
|
||||||
{
|
{
|
||||||
g_return_if_fail (SERVER_IS_CONTEXT_SERVICE(context));
|
g_return_if_fail (SERVER_IS_CONTEXT_SERVICE(self));
|
||||||
|
|
||||||
if (!context->visible) {
|
if (!self->visible) {
|
||||||
server_context_service_real_show_keyboard (context);
|
server_context_service_real_show_keyboard (self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
server_context_service_hide_keyboard (ServerContextService *context)
|
server_context_service_hide_keyboard (ServerContextService *self)
|
||||||
{
|
{
|
||||||
g_return_if_fail (SERVER_IS_CONTEXT_SERVICE(context));
|
g_return_if_fail (SERVER_IS_CONTEXT_SERVICE(self));
|
||||||
|
|
||||||
if (context->visible) {
|
if (self->visible) {
|
||||||
server_context_service_real_hide_keyboard (context);
|
server_context_service_real_hide_keyboard (self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,11 +257,11 @@ server_context_service_set_property (GObject *object,
|
|||||||
const GValue *value,
|
const GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
ServerContextService *context = SERVER_CONTEXT_SERVICE(object);
|
ServerContextService *self = SERVER_CONTEXT_SERVICE(object);
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_VISIBLE:
|
case PROP_VISIBLE:
|
||||||
context->visible = g_value_get_boolean (value);
|
self->visible = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -277,10 +276,10 @@ server_context_service_get_property (GObject *object,
|
|||||||
GValue *value,
|
GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
ServerContextService *context = SERVER_CONTEXT_SERVICE(object);
|
ServerContextService *self = SERVER_CONTEXT_SERVICE(object);
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_VISIBLE:
|
case PROP_VISIBLE:
|
||||||
g_value_set_boolean (value, context->visible);
|
g_value_set_boolean (value, self->visible);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
@ -291,10 +290,10 @@ server_context_service_get_property (GObject *object,
|
|||||||
static void
|
static void
|
||||||
server_context_service_dispose (GObject *object)
|
server_context_service_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
ServerContextService *context = SERVER_CONTEXT_SERVICE(object);
|
ServerContextService *self = SERVER_CONTEXT_SERVICE(object);
|
||||||
|
|
||||||
destroy_window (context);
|
destroy_window (self);
|
||||||
context->widget = NULL;
|
self->widget = NULL;
|
||||||
|
|
||||||
G_OBJECT_CLASS (server_context_service_parent_class)->dispose (object);
|
G_OBJECT_CLASS (server_context_service_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
@ -323,16 +322,16 @@ server_context_service_class_init (ServerContextServiceClass *klass)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
server_context_service_init (ServerContextService *state) {
|
server_context_service_init (ServerContextService *self) {
|
||||||
(void)state;
|
(void)self;
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerContextService *
|
ServerContextService *
|
||||||
server_context_service_new (EekboardContextService *state, struct submission *submission, struct squeek_layout_state *layout, struct ui_manager *uiman)
|
server_context_service_new (EekboardContextService *self, struct submission *submission, struct squeek_layout_state *layout, struct ui_manager *uiman)
|
||||||
{
|
{
|
||||||
ServerContextService *ui = g_object_new (SERVER_TYPE_CONTEXT_SERVICE, NULL);
|
ServerContextService *ui = g_object_new (SERVER_TYPE_CONTEXT_SERVICE, NULL);
|
||||||
ui->submission = submission;
|
ui->submission = submission;
|
||||||
ui->state = state;
|
ui->state = self;
|
||||||
ui->layout = layout;
|
ui->layout = layout;
|
||||||
ui->manager = uiman;
|
ui->manager = uiman;
|
||||||
return ui;
|
return ui;
|
||||||
|
|||||||
@ -25,22 +25,14 @@
|
|||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
#define SERVER_TYPE_CONTEXT_SERVICE (server_context_service_get_type())
|
#define SERVER_TYPE_CONTEXT_SERVICE (server_context_service_get_type())
|
||||||
#define SERVER_CONTEXT_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SERVER_TYPE_CONTEXT_SERVICE, ServerContextService))
|
|
||||||
#define SERVER_CONTEXT_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SERVER_TYPE_CONTEXT_SERVICE, ServerContextServiceClass))
|
|
||||||
#define SERVER_IS_CONTEXT_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SERVER_TYPE_CONTEXT_SERVICE))
|
|
||||||
#define SERVER_IS_CONTEXT_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SERVER_TYPE_CONTEXT_SERVICE))
|
|
||||||
#define SERVER_CONTEXT_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SERVER_TYPE_CONTEXT_SERVICE, ServerContextServiceClass))
|
|
||||||
|
|
||||||
/** Manages the lifecycle of the window displaying layouts. */
|
/** Manages the lifecycle of the window displaying layouts. */
|
||||||
typedef struct _ServerContextService ServerContextService;
|
G_DECLARE_FINAL_TYPE (ServerContextService, server_context_service, SERVER, CONTEXT_SERVICE, GObject)
|
||||||
|
|
||||||
GType server_context_service_get_type
|
ServerContextService *server_context_service_new(EekboardContextService *self, struct submission *submission, struct squeek_layout_state *layout, struct ui_manager *uiman);
|
||||||
(void) G_GNUC_CONST;
|
|
||||||
|
|
||||||
ServerContextService *server_context_service_new(EekboardContextService *state, struct submission *submission, struct squeek_layout_state *layout, struct ui_manager *uiman);
|
|
||||||
enum squeek_arrangement_kind server_context_service_get_layout_type(ServerContextService *);
|
enum squeek_arrangement_kind server_context_service_get_layout_type(ServerContextService *);
|
||||||
void server_context_service_show_keyboard (ServerContextService *context);
|
void server_context_service_show_keyboard (ServerContextService *self);
|
||||||
void server_context_service_hide_keyboard (ServerContextService *context);
|
void server_context_service_hide_keyboard (ServerContextService *self);
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
#endif /* SERVER_CONTEXT_SERVICE_H */
|
#endif /* SERVER_CONTEXT_SERVICE_H */
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,6 @@
|
|||||||
#define __STYLE_H
|
#define __STYLE_H
|
||||||
#include "gtk/gtk.h"
|
#include "gtk/gtk.h"
|
||||||
|
|
||||||
GtkCssProvider *squeek_load_style();
|
GtkCssProvider *squeek_load_style(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -15,5 +15,5 @@ struct submission* get_submission(struct zwp_input_method_manager_v2 *immanager,
|
|||||||
// Defined in Rust
|
// Defined in Rust
|
||||||
struct submission* submission_new(struct zwp_input_method_v2 *im, struct zwp_virtual_keyboard_v1 *vk, EekboardContextService *state);
|
struct submission* submission_new(struct zwp_input_method_v2 *im, struct zwp_virtual_keyboard_v1 *vk, EekboardContextService *state);
|
||||||
void submission_set_ui(struct submission *self, ServerContextService *ui_context);
|
void submission_set_ui(struct submission *self, ServerContextService *ui_context);
|
||||||
void submission_set_keyboard(struct submission *self, LevelKeyboard *keyboard);
|
void submission_set_keyboard(struct submission *self, LevelKeyboard *keyboard, uint32_t time);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -23,6 +23,7 @@ use ::action::Modifier;
|
|||||||
use ::imservice;
|
use ::imservice;
|
||||||
use ::imservice::IMService;
|
use ::imservice::IMService;
|
||||||
use ::keyboard::{ KeyCode, KeyStateId, Modifiers, PressType };
|
use ::keyboard::{ KeyCode, KeyStateId, Modifiers, PressType };
|
||||||
|
use ::layout::c::LevelKeyboard;
|
||||||
use ::util::vec_remove;
|
use ::util::vec_remove;
|
||||||
use ::vkeyboard::VirtualKeyboard;
|
use ::vkeyboard::VirtualKeyboard;
|
||||||
|
|
||||||
@ -36,7 +37,6 @@ pub mod c {
|
|||||||
use std::os::raw::c_void;
|
use std::os::raw::c_void;
|
||||||
|
|
||||||
use ::imservice::c::InputMethod;
|
use ::imservice::c::InputMethod;
|
||||||
use ::layout::c::LevelKeyboard;
|
|
||||||
use ::vkeyboard::c::ZwpVirtualKeyboardV1;
|
use ::vkeyboard::c::ZwpVirtualKeyboardV1;
|
||||||
|
|
||||||
// The following defined in C
|
// The following defined in C
|
||||||
@ -91,18 +91,23 @@ pub mod c {
|
|||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C"
|
pub extern "C"
|
||||||
fn submission_set_keyboard(submission: *mut Submission, keyboard: LevelKeyboard) {
|
fn submission_set_keyboard(
|
||||||
|
submission: *mut Submission,
|
||||||
|
keyboard: LevelKeyboard,
|
||||||
|
time: u32,
|
||||||
|
) {
|
||||||
if submission.is_null() {
|
if submission.is_null() {
|
||||||
panic!("Null submission pointer");
|
panic!("Null submission pointer");
|
||||||
}
|
}
|
||||||
let submission: &mut Submission = unsafe { &mut *submission };
|
let submission: &mut Submission = unsafe { &mut *submission };
|
||||||
submission.virtual_keyboard.update_keymap(keyboard);
|
submission.update_keymap(keyboard, Timestamp(time));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Timestamp(pub u32);
|
pub struct Timestamp(pub u32);
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
enum SubmittedAction {
|
enum SubmittedAction {
|
||||||
/// A collection of keycodes that were pressed
|
/// A collection of keycodes that were pressed
|
||||||
VirtualKeyboard(Vec<KeyCode>),
|
VirtualKeyboard(Vec<KeyCode>),
|
||||||
@ -243,4 +248,44 @@ impl Submission {
|
|||||||
self.modifiers_active.iter().map(|(_id, m)| m.clone())
|
self.modifiers_active.iter().map(|(_id, m)| m.clone())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clear_all_modifiers(&mut self) {
|
||||||
|
// Looks like an optimization,
|
||||||
|
// but preemptive cleaning is needed before setting a new keymap,
|
||||||
|
// so removing this check would break keymap setting.
|
||||||
|
if self.modifiers_active.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.modifiers_active = Vec::new();
|
||||||
|
self.virtual_keyboard.set_modifiers_state(Modifiers::empty())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn release_all_virtual_keys(&mut self, time: Timestamp) {
|
||||||
|
let virtual_pressed = self.pressed
|
||||||
|
.clone().into_iter()
|
||||||
|
.filter_map(|(id, action)| {
|
||||||
|
match action {
|
||||||
|
SubmittedAction::VirtualKeyboard(_) => Some(id),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
for id in virtual_pressed {
|
||||||
|
self.handle_release(id, time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Changes keymap and clears pressed keys and modifiers.
|
||||||
|
///
|
||||||
|
/// It's not obvious if clearing is the right thing to do,
|
||||||
|
/// but keymap update may (or may not) do that,
|
||||||
|
/// possibly putting self.modifiers_active and self.pressed out of sync,
|
||||||
|
/// so a consistent stance is adopted to avoid that.
|
||||||
|
/// Alternatively, modifiers could be restored on the new keymap.
|
||||||
|
/// That approach might be difficult
|
||||||
|
/// due to modifiers meaning different things in different keymaps.
|
||||||
|
pub fn update_keymap(&mut self, keyboard: LevelKeyboard, time: Timestamp) {
|
||||||
|
self.clear_all_modifiers();
|
||||||
|
self.release_all_virtual_keys(time);
|
||||||
|
self.virtual_keyboard.update_keymap(keyboard);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
struct ui_manager;
|
struct ui_manager;
|
||||||
|
|
||||||
struct ui_manager *squeek_uiman_new();
|
struct ui_manager *squeek_uiman_new(void);
|
||||||
void squeek_uiman_set_output(struct ui_manager *uiman, struct squeek_output_handle output);
|
void squeek_uiman_set_output(struct ui_manager *uiman, struct squeek_output_handle output);
|
||||||
uint32_t squeek_uiman_get_perceptual_height(struct ui_manager *uiman);
|
uint32_t squeek_uiman_get_perceptual_height(struct ui_manager *uiman);
|
||||||
|
|
||||||
|
|||||||
@ -63,6 +63,7 @@ foreach layout : [
|
|||||||
'pl', 'pl_wide',
|
'pl', 'pl_wide',
|
||||||
'ru',
|
'ru',
|
||||||
'se',
|
'se',
|
||||||
|
'ua',
|
||||||
'terminal',
|
'terminal',
|
||||||
|
|
||||||
'emoji',
|
'emoji',
|
||||||
|
|||||||
Reference in New Issue
Block a user