state: Become the source of layout choice
A redesign of popover was needed: it can no longer query the application state directly due to current state being its own actor, so instead the popover gets a dedicated copy of the relevant state. I'm not entirely happy with the extra complexity of having an extra actor just for 1 string, but at least the duplication between C and Rust and mutual calls have been reduced.
This commit is contained in:
@ -35,6 +35,7 @@
|
|||||||
|
|
||||||
#include "eekboard/eekboard-context-service.h"
|
#include "eekboard/eekboard-context-service.h"
|
||||||
#include "src/layout.h"
|
#include "src/layout.h"
|
||||||
|
#include "src/popover.h"
|
||||||
#include "src/submission.h"
|
#include "src/submission.h"
|
||||||
|
|
||||||
#define LIBFEEDBACK_USE_UNSTABLE_API
|
#define LIBFEEDBACK_USE_UNSTABLE_API
|
||||||
@ -48,6 +49,7 @@ typedef struct _EekGtkKeyboardPrivate
|
|||||||
struct render_geometry render_geometry; // mutable
|
struct render_geometry render_geometry; // mutable
|
||||||
|
|
||||||
EekboardContextService *eekboard_context; // unowned reference
|
EekboardContextService *eekboard_context; // unowned reference
|
||||||
|
struct squeek_popover *popover; // shared reference
|
||||||
struct squeek_state_manager *state_manager; // shared reference
|
struct squeek_state_manager *state_manager; // shared reference
|
||||||
struct submission *submission; // unowned reference
|
struct submission *submission; // unowned reference
|
||||||
|
|
||||||
@ -119,15 +121,6 @@ eek_gtk_keyboard_real_draw (GtkWidget *self,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Units of virtual pixels size
|
|
||||||
static enum squeek_arrangement_kind get_type(uint32_t width, uint32_t height) {
|
|
||||||
(void)height;
|
|
||||||
if (width < 540) {
|
|
||||||
return ARRANGEMENT_KIND_BASE;
|
|
||||||
}
|
|
||||||
return ARRANGEMENT_KIND_WIDE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
eek_gtk_keyboard_real_size_allocate (GtkWidget *self,
|
eek_gtk_keyboard_real_size_allocate (GtkWidget *self,
|
||||||
GtkAllocation *allocation)
|
GtkAllocation *allocation)
|
||||||
@ -135,15 +128,6 @@ eek_gtk_keyboard_real_size_allocate (GtkWidget *self,
|
|||||||
EekGtkKeyboard *keyboard = EEK_GTK_KEYBOARD (self);
|
EekGtkKeyboard *keyboard = EEK_GTK_KEYBOARD (self);
|
||||||
EekGtkKeyboardPrivate *priv =
|
EekGtkKeyboardPrivate *priv =
|
||||||
eek_gtk_keyboard_get_instance_private (keyboard);
|
eek_gtk_keyboard_get_instance_private (keyboard);
|
||||||
// check if the change would switch types
|
|
||||||
enum squeek_arrangement_kind new_type = get_type(
|
|
||||||
(uint32_t)(allocation->width - allocation->x),
|
|
||||||
(uint32_t)(allocation->height - allocation->y));
|
|
||||||
if (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, time);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->renderer) {
|
if (priv->renderer) {
|
||||||
set_allocation_size (keyboard, priv->keyboard->layout,
|
set_allocation_size (keyboard, priv->keyboard->layout,
|
||||||
@ -190,7 +174,7 @@ static void drag(EekGtkKeyboard *self,
|
|||||||
squeek_layout_drag(eekboard_context_service_get_keyboard(priv->eekboard_context)->layout,
|
squeek_layout_drag(eekboard_context_service_get_keyboard(priv->eekboard_context)->layout,
|
||||||
priv->submission,
|
priv->submission,
|
||||||
x, y, priv->render_geometry.widget_to_layout, time,
|
x, y, priv->render_geometry.widget_to_layout, time,
|
||||||
priv->eekboard_context, priv->state_manager, self);
|
priv->popover, priv->state_manager, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void release(EekGtkKeyboard *self, guint32 time)
|
static void release(EekGtkKeyboard *self, guint32 time)
|
||||||
@ -201,7 +185,7 @@ static void release(EekGtkKeyboard *self, guint32 time)
|
|||||||
}
|
}
|
||||||
squeek_layout_release(eekboard_context_service_get_keyboard(priv->eekboard_context)->layout,
|
squeek_layout_release(eekboard_context_service_get_keyboard(priv->eekboard_context)->layout,
|
||||||
priv->submission, priv->render_geometry.widget_to_layout, time,
|
priv->submission, priv->render_geometry.widget_to_layout, time,
|
||||||
priv->eekboard_context, priv->state_manager, self);
|
priv->popover, priv->state_manager, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -408,13 +392,14 @@ on_notify_keyboard (GObject *object,
|
|||||||
GtkWidget *
|
GtkWidget *
|
||||||
eek_gtk_keyboard_new (EekboardContextService *eekservice,
|
eek_gtk_keyboard_new (EekboardContextService *eekservice,
|
||||||
struct submission *submission,
|
struct submission *submission,
|
||||||
struct squeek_layout_state *layout, struct squeek_state_manager *state_manager)
|
struct squeek_state_manager *state_manager,
|
||||||
|
struct squeek_popover *popover)
|
||||||
{
|
{
|
||||||
EekGtkKeyboard *ret = EEK_GTK_KEYBOARD(g_object_new (EEK_TYPE_GTK_KEYBOARD, NULL));
|
EekGtkKeyboard *ret = EEK_GTK_KEYBOARD(g_object_new (EEK_TYPE_GTK_KEYBOARD, NULL));
|
||||||
EekGtkKeyboardPrivate *priv = (EekGtkKeyboardPrivate*)eek_gtk_keyboard_get_instance_private (ret);
|
EekGtkKeyboardPrivate *priv = (EekGtkKeyboardPrivate*)eek_gtk_keyboard_get_instance_private (ret);
|
||||||
|
priv->popover = popover;
|
||||||
priv->eekboard_context = eekservice;
|
priv->eekboard_context = eekservice;
|
||||||
priv->submission = submission;
|
priv->submission = submission;
|
||||||
priv->layout = layout;
|
|
||||||
priv->state_manager = state_manager;
|
priv->state_manager = state_manager;
|
||||||
priv->renderer = NULL;
|
priv->renderer = NULL;
|
||||||
// This should really be done on initialization.
|
// This should really be done on initialization.
|
||||||
|
|||||||
@ -31,6 +31,7 @@
|
|||||||
#include "eek/eek-renderer.h"
|
#include "eek/eek-renderer.h"
|
||||||
#include "eek/eek-types.h"
|
#include "eek/eek-types.h"
|
||||||
#include "src/main.h"
|
#include "src/main.h"
|
||||||
|
#include "src/popover.h"
|
||||||
|
|
||||||
struct submission;
|
struct submission;
|
||||||
struct squeek_layout_state;
|
struct squeek_layout_state;
|
||||||
@ -49,7 +50,7 @@ struct _EekGtkKeyboardClass
|
|||||||
gpointer pdummy[24];
|
gpointer pdummy[24];
|
||||||
};
|
};
|
||||||
|
|
||||||
GtkWidget *eek_gtk_keyboard_new (EekboardContextService *eekservice, struct submission *submission, struct squeek_layout_state *layout, struct squeek_state_manager *state_manager);
|
GtkWidget *eek_gtk_keyboard_new (EekboardContextService *eekservice, struct submission *submission, struct squeek_state_manager *state_manager, struct squeek_popover *popover);
|
||||||
void eek_gtk_keyboard_emit_feedback (EekGtkKeyboard *self);
|
void eek_gtk_keyboard_emit_feedback (EekGtkKeyboard *self);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|||||||
@ -55,8 +55,6 @@ static guint signals[LAST_SIGNAL] = { 0, };
|
|||||||
*/
|
*/
|
||||||
struct _EekboardContextService {
|
struct _EekboardContextService {
|
||||||
GObject parent;
|
GObject parent;
|
||||||
struct squeek_layout_state *layout; // Unowned
|
|
||||||
// FIXME: replaces layout
|
|
||||||
struct squeek_state_manager *state_manager; // shared reference
|
struct squeek_state_manager *state_manager; // shared reference
|
||||||
|
|
||||||
LevelKeyboard *keyboard; // currently used keyboard
|
LevelKeyboard *keyboard; // currently used keyboard
|
||||||
@ -128,29 +126,6 @@ settings_get_layout(GSettings *settings, char **type, char **layout)
|
|||||||
g_variant_unref(inputs);
|
g_variant_unref(inputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void eekboard_context_service_set_layout(EekboardContextService *context, struct squeek_layout *layout, uint32_t timestamp);
|
|
||||||
|
|
||||||
void
|
|
||||||
eekboard_context_service_use_layout(EekboardContextService *context, struct squeek_layout_state *state, uint32_t timestamp) {
|
|
||||||
gchar *layout_name = state->layout_name;
|
|
||||||
gchar *overlay_name = state->overlay_name;
|
|
||||||
|
|
||||||
// try to get the best keyboard layout
|
|
||||||
if (layout_name == NULL) {
|
|
||||||
layout_name = "us";
|
|
||||||
}
|
|
||||||
|
|
||||||
// overlay is "Normal" for most layouts, we will only look for "terminal" in rust code.
|
|
||||||
// for now just avoid passing a null pointer
|
|
||||||
if (overlay_name == NULL) {
|
|
||||||
overlay_name = ""; // fallback to Normal
|
|
||||||
}
|
|
||||||
|
|
||||||
// generic part follows
|
|
||||||
struct squeek_layout *layout = squeek_load_layout(layout_name, state->arrangement, state->purpose, overlay_name);
|
|
||||||
eekboard_context_service_set_layout(context, layout, timestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void eekboard_context_service_set_layout(EekboardContextService *context, struct squeek_layout *layout, uint32_t timestamp) {
|
void eekboard_context_service_set_layout(EekboardContextService *context, struct squeek_layout *layout, uint32_t timestamp) {
|
||||||
LevelKeyboard *keyboard = level_keyboard_new(layout);
|
LevelKeyboard *keyboard = level_keyboard_new(layout);
|
||||||
// set as current
|
// set as current
|
||||||
@ -178,18 +153,6 @@ static void eekboard_context_service_update_settings_layout(EekboardContextServi
|
|||||||
&keyboard_type, &keyboard_layout);
|
&keyboard_type, &keyboard_layout);
|
||||||
|
|
||||||
squeek_state_send_layout_set(context->state_manager, keyboard_layout, keyboard_type, gdk_event_get_time(NULL));
|
squeek_state_send_layout_set(context->state_manager, keyboard_layout, keyboard_type, gdk_event_get_time(NULL));
|
||||||
|
|
||||||
if (g_strcmp0(context->layout->layout_name, keyboard_layout) != 0 || context->layout->overlay_name) {
|
|
||||||
g_free(context->layout->overlay_name);
|
|
||||||
context->layout->overlay_name = NULL;
|
|
||||||
if (keyboard_layout) {
|
|
||||||
g_free(context->layout->layout_name);
|
|
||||||
context->layout->layout_name = g_strdup(keyboard_layout);
|
|
||||||
}
|
|
||||||
// This must actually update the UI.
|
|
||||||
uint32_t time = gdk_event_get_time(NULL);
|
|
||||||
eekboard_context_service_use_layout(context, context->layout, time);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -307,48 +270,17 @@ eekboard_context_service_get_keyboard (EekboardContextService *context)
|
|||||||
return context->keyboard;
|
return context->keyboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used from Rust.
|
EekboardContextService *eekboard_context_service_new(struct squeek_state_manager *state_manager)
|
||||||
// TODO: move hint management to Rust entirely
|
|
||||||
void eekboard_context_service_set_hint_purpose(EekboardContextService *context,
|
|
||||||
uint32_t hint, uint32_t purpose)
|
|
||||||
{
|
|
||||||
if (context->layout->hint != hint || context->layout->purpose != purpose) {
|
|
||||||
context->layout->hint = hint;
|
|
||||||
context->layout->purpose = purpose;
|
|
||||||
uint32_t time = gdk_event_get_time(NULL);
|
|
||||||
eekboard_context_service_use_layout(context, context->layout, time);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
eekboard_context_service_set_overlay(EekboardContextService *context, const char* name) {
|
|
||||||
if (g_strcmp0(context->layout->overlay_name, name)) {
|
|
||||||
g_free(context->layout->overlay_name);
|
|
||||||
context->layout->overlay_name = g_strdup(name);
|
|
||||||
uint32_t time = gdk_event_get_time(NULL);
|
|
||||||
eekboard_context_service_use_layout(context, context->layout, time);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char*
|
|
||||||
eekboard_context_service_get_overlay(EekboardContextService *context) {
|
|
||||||
return context->layout->overlay_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
EekboardContextService *eekboard_context_service_new(struct squeek_state_manager *state_manager, struct squeek_layout_state *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->state_manager = state_manager;
|
context->state_manager = state_manager;
|
||||||
eekboard_context_service_update_settings_layout(context);
|
eekboard_context_service_update_settings_layout(context);
|
||||||
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->submission = submission;
|
context->submission = submission;
|
||||||
if (context->submission) {
|
if (context->submission && context->keyboard) {
|
||||||
uint32_t time = gdk_event_get_time(NULL);
|
uint32_t time = gdk_event_get_time(NULL);
|
||||||
submission_use_layout(context->submission, context->keyboard->layout, time);
|
submission_use_layout(context->submission, context->keyboard->layout, time);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,7 +38,7 @@ G_BEGIN_DECLS
|
|||||||
|
|
||||||
G_DECLARE_FINAL_TYPE(EekboardContextService, eekboard_context_service, EEKBOARD, CONTEXT_SERVICE, GObject)
|
G_DECLARE_FINAL_TYPE(EekboardContextService, eekboard_context_service, EEKBOARD, CONTEXT_SERVICE, GObject)
|
||||||
|
|
||||||
EekboardContextService *eekboard_context_service_new(struct squeek_state_manager *state_manager, struct squeek_layout_state *state);
|
EekboardContextService *eekboard_context_service_new(struct squeek_state_manager *state_manager);
|
||||||
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_destroy (EekboardContextService *context);
|
void eekboard_context_service_destroy (EekboardContextService *context);
|
||||||
LevelKeyboard *eekboard_context_service_get_keyboard(EekboardContextService *context);
|
LevelKeyboard *eekboard_context_service_get_keyboard(EekboardContextService *context);
|
||||||
@ -46,7 +46,5 @@ LevelKeyboard *eekboard_context_service_get_keyboard(EekboardContextService *con
|
|||||||
void eekboard_context_service_set_keymap(EekboardContextService *context,
|
void eekboard_context_service_set_keymap(EekboardContextService *context,
|
||||||
const LevelKeyboard *keyboard);
|
const LevelKeyboard *keyboard);
|
||||||
|
|
||||||
void
|
|
||||||
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 */
|
||||||
|
|||||||
23
src/actors/mod.rs
Normal file
23
src/actors/mod.rs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/* Copyright (C) 2022 Purism SPC
|
||||||
|
* SPDX-License-Identifier: GPL-3.0+
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! Actors are parts of Squeekboard containing state independent from the main application state.
|
||||||
|
|
||||||
|
Because main application state is meant to be immutable,
|
||||||
|
it cannot be referenced directly by pieces of logic
|
||||||
|
interacting with the environment.
|
||||||
|
|
||||||
|
Such impure logic is split away (actor's logic)
|
||||||
|
and combined with relevant pieces of state (actor state),
|
||||||
|
thus preserving the purity (and sometimes simplicity) of the main state.
|
||||||
|
|
||||||
|
Actors can communicate with the main state by sending it messages,
|
||||||
|
and by receiving updates from it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TODO: move crate::panel into crate::actors::panel.
|
||||||
|
// Panel contains state and logic to protect the main state from getting flooded
|
||||||
|
// with low-level wayland and gtk sizing events.
|
||||||
|
|
||||||
|
pub mod popover;
|
||||||
40
src/actors/popover.rs
Normal file
40
src/actors/popover.rs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/* Copyright (C) 2022 Purism SPC
|
||||||
|
* SPDX-License-Identifier: GPL-3.0+
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! The popover is opened directly by the GTK surface,
|
||||||
|
without bouncing click events off the main state.
|
||||||
|
Then it must accurately show which layout has been selected.
|
||||||
|
It can get the system layout directly from gsettings on open,
|
||||||
|
but it cannot get the user-selected overlay, because it's stored in state.
|
||||||
|
|
||||||
|
To solve this, overlay will be cached in the popover actor,
|
||||||
|
and updated by main state every time it changes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
pub mod c {
|
||||||
|
use super::*;
|
||||||
|
use crate::util::c::Wrapped;
|
||||||
|
/// The mutable instance of state
|
||||||
|
pub type Actor = Wrapped<State>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct State {
|
||||||
|
pub overlay: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl State {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self { overlay: None }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_overlay(
|
||||||
|
actor: &c::Actor,
|
||||||
|
overlay: Option<String>,
|
||||||
|
) {
|
||||||
|
let actor = actor.clone_ref();
|
||||||
|
let mut actor = actor.borrow_mut();
|
||||||
|
actor.overlay = overlay;
|
||||||
|
}
|
||||||
@ -7,69 +7,16 @@
|
|||||||
use std::env;
|
use std::env;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::convert::TryFrom;
|
|
||||||
|
|
||||||
use super::{ Error, LoadError };
|
use super::{ Error, LoadError };
|
||||||
use super::parsing;
|
use super::parsing;
|
||||||
|
|
||||||
use crate::layout;
|
use crate::layout;
|
||||||
use ::layout::ArrangementKind;
|
use crate::layout::ArrangementKind;
|
||||||
use ::logging;
|
use crate::logging;
|
||||||
use ::util::c::as_str;
|
use crate::xdg;
|
||||||
use ::xdg;
|
use crate::imservice::ContentPurpose;
|
||||||
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 forces a variant other than specified
|
|
||||||
// (typically "terminal", "emoji")
|
|
||||||
overlay: *const c_char,
|
|
||||||
) -> *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),
|
|
||||||
};
|
|
||||||
|
|
||||||
dbg!(&name, type_, variant, overlay_str);
|
|
||||||
|
|
||||||
let (kind, layout) = load_layout_data_with_fallback(&name, type_, variant, overlay_str);
|
|
||||||
let layout = layout::Layout::new(layout, kind, variant);
|
|
||||||
Box::into_raw(Box::new(layout))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const FALLBACK_LAYOUT_NAME: &str = "us";
|
const FALLBACK_LAYOUT_NAME: &str = "us";
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
#include "eek/eek-renderer.h"
|
#include "eek/eek-renderer.h"
|
||||||
#include "eek/eek-types.h"
|
#include "eek/eek-types.h"
|
||||||
#include "src/main.h"
|
#include "src/main.h"
|
||||||
|
#include "src/popover.h"
|
||||||
#include "src/submission.h"
|
#include "src/submission.h"
|
||||||
#include "virtual-keyboard-unstable-v1-client-protocol.h"
|
#include "virtual-keyboard-unstable-v1-client-protocol.h"
|
||||||
#include "text-input-unstable-v3-client-protocol.h"
|
#include "text-input-unstable-v3-client-protocol.h"
|
||||||
@ -41,7 +42,7 @@ void squeek_layout_release(struct squeek_layout *layout,
|
|||||||
struct submission *submission,
|
struct submission *submission,
|
||||||
struct transformation widget_to_layout,
|
struct transformation widget_to_layout,
|
||||||
uint32_t timestamp,
|
uint32_t timestamp,
|
||||||
EekboardContextService *manager,
|
struct squeek_popover *popover,
|
||||||
struct squeek_state_manager *state,
|
struct squeek_state_manager *state,
|
||||||
EekGtkKeyboard *ui_keyboard);
|
EekGtkKeyboard *ui_keyboard);
|
||||||
void squeek_layout_release_all_only(struct squeek_layout *layout,
|
void squeek_layout_release_all_only(struct squeek_layout *layout,
|
||||||
@ -56,7 +57,7 @@ void squeek_layout_drag(struct squeek_layout *layout,
|
|||||||
struct submission *submission,
|
struct submission *submission,
|
||||||
double x_widget, double y_widget,
|
double x_widget, double y_widget,
|
||||||
struct transformation widget_to_layout,
|
struct transformation widget_to_layout,
|
||||||
uint32_t timestamp, EekboardContextService *manager,
|
uint32_t timestamp, struct squeek_popover *popover,
|
||||||
struct squeek_state_manager *state,
|
struct squeek_state_manager *state,
|
||||||
EekGtkKeyboard *ui_keyboard);
|
EekGtkKeyboard *ui_keyboard);
|
||||||
void squeek_layout_draw_all_changed(struct squeek_layout *layout, EekRenderer* renderer, cairo_t *cr, struct submission *submission);
|
void squeek_layout_draw_all_changed(struct squeek_layout *layout, EekRenderer* renderer, cairo_t *cr, struct submission *submission);
|
||||||
|
|||||||
@ -26,12 +26,11 @@ use std::rc::Rc;
|
|||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
|
|
||||||
use crate::action::Action;
|
use crate::action::Action;
|
||||||
|
use crate::actors;
|
||||||
use crate::drawing;
|
use crate::drawing;
|
||||||
use crate::event_loop::driver::Threaded as AppState;
|
|
||||||
use crate::float_ord::FloatOrd;
|
use crate::float_ord::FloatOrd;
|
||||||
use crate::keyboard::KeyState;
|
use crate::keyboard::KeyState;
|
||||||
use crate::logging;
|
use crate::logging;
|
||||||
use crate::manager;
|
|
||||||
use crate::popover;
|
use crate::popover;
|
||||||
use crate::receiver;
|
use crate::receiver;
|
||||||
use crate::submission::{ Submission, SubmitData, Timestamp };
|
use crate::submission::{ Submission, SubmitData, Timestamp };
|
||||||
@ -221,7 +220,7 @@ pub mod c {
|
|||||||
submission: CSubmission,
|
submission: CSubmission,
|
||||||
widget_to_layout: Transformation,
|
widget_to_layout: Transformation,
|
||||||
time: u32,
|
time: u32,
|
||||||
manager: manager::c::Manager,
|
popover: actors::popover::c::Actor,
|
||||||
app_state: receiver::c::State,
|
app_state: receiver::c::State,
|
||||||
ui_keyboard: EekGtkKeyboard,
|
ui_keyboard: EekGtkKeyboard,
|
||||||
) {
|
) {
|
||||||
@ -230,6 +229,7 @@ pub mod c {
|
|||||||
let submission = submission.clone_ref();
|
let submission = submission.clone_ref();
|
||||||
let mut submission = submission.borrow_mut();
|
let mut submission = submission.borrow_mut();
|
||||||
let app_state = app_state.clone_owned();
|
let app_state = app_state.clone_owned();
|
||||||
|
let popover_state = popover.clone_owned();
|
||||||
|
|
||||||
let ui_backend = UIBackend {
|
let ui_backend = UIBackend {
|
||||||
widget_to_layout,
|
widget_to_layout,
|
||||||
@ -245,7 +245,7 @@ pub mod c {
|
|||||||
&mut submission,
|
&mut submission,
|
||||||
Some(&ui_backend),
|
Some(&ui_backend),
|
||||||
time,
|
time,
|
||||||
Some((manager, app_state.clone())),
|
Some((&popover_state, app_state.clone())),
|
||||||
key,
|
key,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -324,7 +324,7 @@ pub mod c {
|
|||||||
x_widget: f64, y_widget: f64,
|
x_widget: f64, y_widget: f64,
|
||||||
widget_to_layout: Transformation,
|
widget_to_layout: Transformation,
|
||||||
time: u32,
|
time: u32,
|
||||||
manager: manager::c::Manager,
|
popover: actors::popover::c::Actor,
|
||||||
app_state: receiver::c::State,
|
app_state: receiver::c::State,
|
||||||
ui_keyboard: EekGtkKeyboard,
|
ui_keyboard: EekGtkKeyboard,
|
||||||
) {
|
) {
|
||||||
@ -332,6 +332,9 @@ pub mod c {
|
|||||||
let layout = unsafe { &mut *layout };
|
let layout = unsafe { &mut *layout };
|
||||||
let submission = submission.clone_ref();
|
let submission = submission.clone_ref();
|
||||||
let mut submission = submission.borrow_mut();
|
let mut submission = submission.borrow_mut();
|
||||||
|
// We only need to query state here, not update.
|
||||||
|
// A copy is enough.
|
||||||
|
let popover_state = popover.clone_owned();
|
||||||
let app_state = app_state.clone_owned();
|
let app_state = app_state.clone_owned();
|
||||||
let ui_backend = UIBackend {
|
let ui_backend = UIBackend {
|
||||||
widget_to_layout,
|
widget_to_layout,
|
||||||
@ -363,7 +366,7 @@ pub mod c {
|
|||||||
&mut submission,
|
&mut submission,
|
||||||
Some(&ui_backend),
|
Some(&ui_backend),
|
||||||
time,
|
time,
|
||||||
Some((manager, app_state.clone())),
|
Some((&popover_state, app_state.clone())),
|
||||||
key,
|
key,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -388,7 +391,7 @@ pub mod c {
|
|||||||
&mut submission,
|
&mut submission,
|
||||||
Some(&ui_backend),
|
Some(&ui_backend),
|
||||||
time,
|
time,
|
||||||
Some((manager, app_state.clone())),
|
Some((&popover_state, app_state.clone())),
|
||||||
key,
|
key,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1050,7 +1053,7 @@ mod seat {
|
|||||||
// passing state conditionally because it's only used for popover.
|
// passing state conditionally because it's only used for popover.
|
||||||
// Eventually, it should be used for sumitting button events,
|
// Eventually, it should be used for sumitting button events,
|
||||||
// and passed always.
|
// and passed always.
|
||||||
manager: Option<(manager::c::Manager, receiver::State)>,
|
manager: Option<(&actors::popover::State, receiver::State)>,
|
||||||
rckey: &Rc<RefCell<KeyState>>,
|
rckey: &Rc<RefCell<KeyState>>,
|
||||||
) {
|
) {
|
||||||
let key: KeyState = {
|
let key: KeyState = {
|
||||||
|
|||||||
@ -23,6 +23,7 @@ mod assert_matches;
|
|||||||
mod logging;
|
mod logging;
|
||||||
|
|
||||||
mod action;
|
mod action;
|
||||||
|
mod actors;
|
||||||
mod animation;
|
mod animation;
|
||||||
pub mod data;
|
pub mod data;
|
||||||
mod debug;
|
mod debug;
|
||||||
@ -34,7 +35,6 @@ mod keyboard;
|
|||||||
mod layout;
|
mod layout;
|
||||||
mod locale;
|
mod locale;
|
||||||
mod main;
|
mod main;
|
||||||
mod manager;
|
|
||||||
mod outputs;
|
mod outputs;
|
||||||
mod panel;
|
mod panel;
|
||||||
mod popover;
|
mod popover;
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
#include "eek/eek-types.h"
|
#include "eek/eek-types.h"
|
||||||
#include "dbus.h"
|
#include "dbus.h"
|
||||||
#include "panel.h"
|
#include "panel.h"
|
||||||
|
#include "src/popover.h"
|
||||||
|
|
||||||
|
|
||||||
struct receiver;
|
struct receiver;
|
||||||
@ -23,9 +24,10 @@ struct rsobjects {
|
|||||||
struct squeek_state_manager *state_manager;
|
struct squeek_state_manager *state_manager;
|
||||||
struct submission *submission;
|
struct submission *submission;
|
||||||
struct squeek_wayland *wayland;
|
struct squeek_wayland *wayland;
|
||||||
|
struct squeek_popover *popover;
|
||||||
};
|
};
|
||||||
|
|
||||||
void register_ui_loop_handler(struct receiver *receiver, struct panel_manager *panel, EekboardContextService *hint_manager, DBusHandler *dbus_handler);
|
void register_ui_loop_handler(struct receiver *receiver, struct panel_manager *panel, struct squeek_popover *popover, EekboardContextService *hint_manager, DBusHandler *dbus_handler);
|
||||||
|
|
||||||
struct rsobjects squeek_init(void);
|
struct rsobjects squeek_init(void);
|
||||||
|
|
||||||
|
|||||||
30
src/main.rs
30
src/main.rs
@ -3,11 +3,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*! Glue for the main loop. */
|
/*! Glue for the main loop. */
|
||||||
|
use crate::actors;
|
||||||
use crate::animation;
|
use crate::animation;
|
||||||
use crate::debug;
|
use crate::debug;
|
||||||
use crate::data::loading;
|
use crate::data::loading;
|
||||||
use crate::panel;
|
use crate::panel;
|
||||||
use crate::state;
|
|
||||||
use glib::{Continue, MainContext, PRIORITY_DEFAULT, Receiver};
|
use glib::{Continue, MainContext, PRIORITY_DEFAULT, Receiver};
|
||||||
|
|
||||||
|
|
||||||
@ -49,6 +49,7 @@ mod c {
|
|||||||
submission: Wrapped<Submission>,
|
submission: Wrapped<Submission>,
|
||||||
/// Not wrapped, because C needs to access this.
|
/// Not wrapped, because C needs to access this.
|
||||||
wayland: *mut Wayland,
|
wayland: *mut Wayland,
|
||||||
|
popover: actors::popover::c::Actor,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Corresponds to wayland.h::squeek_wayland.
|
/// Corresponds to wayland.h::squeek_wayland.
|
||||||
@ -81,7 +82,6 @@ mod c {
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#[allow(improper_ctypes)]
|
#[allow(improper_ctypes)]
|
||||||
fn init_wayland(wayland: *mut Wayland);
|
fn init_wayland(wayland: *mut Wayland);
|
||||||
fn eekboard_context_service_set_hint_purpose(service: HintManager, hint: u32, purpose: u32);
|
|
||||||
#[allow(improper_ctypes)]
|
#[allow(improper_ctypes)]
|
||||||
fn eekboard_context_service_set_layout(service: HintManager, layout: *const layout::Layout, timestamp: u32);
|
fn eekboard_context_service_set_layout(service: HintManager, layout: *const layout::Layout, timestamp: u32);
|
||||||
// This should probably only get called from the gtk main loop,
|
// This should probably only get called from the gtk main loop,
|
||||||
@ -121,6 +121,7 @@ mod c {
|
|||||||
state_manager: Wrapped::new(state_manager),
|
state_manager: Wrapped::new(state_manager),
|
||||||
receiver: Wrapped::new(receiver),
|
receiver: Wrapped::new(receiver),
|
||||||
wayland: Box::into_raw(wayland),
|
wayland: Box::into_raw(wayland),
|
||||||
|
popover: Wrapped::new(actors::popover::State::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,6 +131,7 @@ mod c {
|
|||||||
fn register_ui_loop_handler(
|
fn register_ui_loop_handler(
|
||||||
receiver: Wrapped<Receiver<Commands>>,
|
receiver: Wrapped<Receiver<Commands>>,
|
||||||
panel_manager: panel::c::PanelManager,
|
panel_manager: panel::c::PanelManager,
|
||||||
|
popover: actors::popover::c::Actor,
|
||||||
hint_manager: HintManager,
|
hint_manager: HintManager,
|
||||||
dbus_handler: *const DBusHandler,
|
dbus_handler: *const DBusHandler,
|
||||||
) {
|
) {
|
||||||
@ -142,7 +144,13 @@ mod c {
|
|||||||
receiver.attach(
|
receiver.attach(
|
||||||
Some(&ctx),
|
Some(&ctx),
|
||||||
move |msg| {
|
move |msg| {
|
||||||
main_loop_handle_message(msg, panel_manager.clone(), hint_manager, dbus_handler);
|
main_loop_handle_message(
|
||||||
|
msg,
|
||||||
|
panel_manager.clone(),
|
||||||
|
&popover,
|
||||||
|
hint_manager,
|
||||||
|
dbus_handler,
|
||||||
|
);
|
||||||
Continue(true)
|
Continue(true)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -157,6 +165,7 @@ mod c {
|
|||||||
fn main_loop_handle_message(
|
fn main_loop_handle_message(
|
||||||
msg: Commands,
|
msg: Commands,
|
||||||
panel_manager: Wrapped<panel::Manager>,
|
panel_manager: Wrapped<panel::Manager>,
|
||||||
|
popover: &actors::popover::c::Actor,
|
||||||
hint_manager: HintManager,
|
hint_manager: HintManager,
|
||||||
dbus_handler: *const DBusHandler,
|
dbus_handler: *const DBusHandler,
|
||||||
) {
|
) {
|
||||||
@ -169,29 +178,19 @@ mod c {
|
|||||||
unsafe { dbus_handler_set_visible(dbus_handler, visible as u8) };
|
unsafe { dbus_handler_set_visible(dbus_handler, visible as u8) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(hints) = msg.layout_hint_set {
|
|
||||||
unsafe {
|
|
||||||
eekboard_context_service_set_hint_purpose(
|
|
||||||
hint_manager,
|
|
||||||
hints.hint.bits(),
|
|
||||||
hints.purpose.clone() as u32,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(commands::SetLayout { description }) = msg.layout_selection {
|
if let Some(commands::SetLayout { description }) = msg.layout_selection {
|
||||||
dbg!(&description);
|
|
||||||
let animation::Contents {
|
let animation::Contents {
|
||||||
name,
|
name,
|
||||||
kind,
|
kind,
|
||||||
overlay_name,
|
overlay_name,
|
||||||
purpose,
|
purpose,
|
||||||
} = description;
|
} = description;
|
||||||
|
actors::popover::set_overlay(popover, overlay_name.clone());
|
||||||
let layout = loading::load_layout(name, kind, purpose, overlay_name);
|
let layout = loading::load_layout(name, kind, purpose, overlay_name);
|
||||||
let layout = Box::into_raw(Box::new(layout));
|
let layout = Box::into_raw(Box::new(layout));
|
||||||
unsafe {
|
unsafe {
|
||||||
//eekboard_context_service_set_layout(hint_manager, layout, 0);
|
eekboard_context_service_set_layout(hint_manager, layout, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,7 +209,6 @@ pub mod commands {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Commands {
|
pub struct Commands {
|
||||||
pub panel_visibility: Option<panel::Command>,
|
pub panel_visibility: Option<panel::Command>,
|
||||||
pub layout_hint_set: Option<state::InputMethodDetails>,
|
|
||||||
pub dbus_visible_set: Option<bool>,
|
pub dbus_visible_set: Option<bool>,
|
||||||
pub layout_selection: Option<commands::SetLayout>,
|
pub layout_selection: Option<commands::SetLayout>,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,33 +0,0 @@
|
|||||||
/*! Procedures relating to the management of the switching of layouts */
|
|
||||||
use crate::util;
|
|
||||||
|
|
||||||
pub mod c {
|
|
||||||
use std::os::raw::{c_char, c_void};
|
|
||||||
|
|
||||||
/// EekboardContextService*
|
|
||||||
#[repr(transparent)]
|
|
||||||
#[derive(Clone, Copy)]
|
|
||||||
pub struct Manager(*const c_void);
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
pub fn eekboard_context_service_set_overlay(
|
|
||||||
manager: Manager,
|
|
||||||
name: *const c_char,
|
|
||||||
);
|
|
||||||
|
|
||||||
pub fn eekboard_context_service_get_overlay(
|
|
||||||
manager: Manager,
|
|
||||||
) -> *const c_char;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the overlay name.
|
|
||||||
/// The result lifetime is "as long as the C copy lives"
|
|
||||||
pub fn get_overlay(manager: c::Manager) -> Option<String> {
|
|
||||||
let raw_str = unsafe {
|
|
||||||
c::eekboard_context_service_get_overlay(manager)
|
|
||||||
};
|
|
||||||
// this string is generated from Rust, should never be invalid
|
|
||||||
util::c::as_str(&raw_str).unwrap()
|
|
||||||
.map(String::from)
|
|
||||||
}
|
|
||||||
@ -52,7 +52,7 @@ make_widget (struct panel_manager *self)
|
|||||||
if (self->widget) {
|
if (self->widget) {
|
||||||
g_error("Widget already present");
|
g_error("Widget already present");
|
||||||
}
|
}
|
||||||
self->widget = eek_gtk_keyboard_new (self->state, self->submission, self->layout, self->state_manager);
|
self->widget = eek_gtk_keyboard_new (self->state, self->submission, self->state_manager, self->popover);
|
||||||
|
|
||||||
gtk_widget_set_has_tooltip (self->widget, TRUE);
|
gtk_widget_set_has_tooltip (self->widget, TRUE);
|
||||||
gtk_container_add (GTK_CONTAINER(self->window), self->widget);
|
gtk_container_add (GTK_CONTAINER(self->window), self->widget);
|
||||||
@ -116,16 +116,16 @@ panel_manager_resize (struct panel_manager *self, uint32_t height)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct panel_manager panel_manager_new(EekboardContextService *state, struct submission *submission, struct squeek_layout_state *layout, struct squeek_state_manager *state_manager)
|
struct panel_manager panel_manager_new(EekboardContextService *state, struct submission *submission, struct squeek_state_manager *state_manager, struct squeek_popover *popover)
|
||||||
{
|
{
|
||||||
struct panel_manager mgr = {
|
struct panel_manager mgr = {
|
||||||
.state = state,
|
.state = state,
|
||||||
.submission = submission,
|
.submission = submission,
|
||||||
.layout = layout,
|
|
||||||
.window = NULL,
|
.window = NULL,
|
||||||
.widget = NULL,
|
.widget = NULL,
|
||||||
.current_output = NULL,
|
.current_output = NULL,
|
||||||
.state_manager = state_manager,
|
.state_manager = state_manager,
|
||||||
|
.popover = popover,
|
||||||
};
|
};
|
||||||
return mgr;
|
return mgr;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,8 +10,8 @@ struct panel_manager {
|
|||||||
EekboardContextService *state; // unowned
|
EekboardContextService *state; // unowned
|
||||||
/// Needed for instantiating the widget
|
/// Needed for instantiating the widget
|
||||||
struct squeek_state_manager *state_manager; // shared reference
|
struct squeek_state_manager *state_manager; // shared reference
|
||||||
|
struct squeek_popover *popover; // shared reference
|
||||||
struct submission *submission; // unowned
|
struct submission *submission; // unowned
|
||||||
struct squeek_layout_state *layout;
|
|
||||||
|
|
||||||
PhoshLayerSurface *window;
|
PhoshLayerSurface *window;
|
||||||
GtkWidget *widget; // nullable
|
GtkWidget *widget; // nullable
|
||||||
@ -20,4 +20,4 @@ struct panel_manager {
|
|||||||
struct wl_output *current_output;
|
struct wl_output *current_output;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct panel_manager panel_manager_new(EekboardContextService *state, struct submission *submission, struct squeek_layout_state *layout, struct squeek_state_manager *state_manager);
|
struct panel_manager panel_manager_new(EekboardContextService *state, struct submission *submission, struct squeek_state_manager *state_manager, struct squeek_popover *popover);
|
||||||
|
|||||||
5
src/popover.h
Normal file
5
src/popover.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
/// Popover state.
|
||||||
|
/// Wrapped<actors::popover::State>
|
||||||
|
struct squeek_popover;
|
||||||
|
|
||||||
@ -4,10 +4,10 @@ use gio;
|
|||||||
use gtk;
|
use gtk;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
use crate::actors;
|
||||||
use crate::layout::c::{ Bounds, EekGtkKeyboard };
|
use crate::layout::c::{ Bounds, EekGtkKeyboard };
|
||||||
use crate::locale::{ OwnedTranslation, compare_current_locale };
|
use crate::locale::{ OwnedTranslation, compare_current_locale };
|
||||||
use crate::logging;
|
use crate::logging;
|
||||||
use crate::manager;
|
|
||||||
use crate::receiver;
|
use crate::receiver;
|
||||||
use crate::resources;
|
use crate::resources;
|
||||||
use crate::state;
|
use crate::state;
|
||||||
@ -129,9 +129,11 @@ fn get_settings(schema_name: &str) -> Option<gio::Settings> {
|
|||||||
.map(|_sschema| gio::Settings::new(schema_name))
|
.map(|_sschema| gio::Settings::new(schema_name))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_layout(kind: String, name: String) {
|
fn set_layout(kind: &str, name: &str) {
|
||||||
let settings = get_settings("org.gnome.desktop.input-sources");
|
let settings = get_settings("org.gnome.desktop.input-sources");
|
||||||
if let Some(settings) = settings {
|
if let Some(settings) = settings {
|
||||||
|
let kind = String::from(kind);
|
||||||
|
let name = String::from(name);
|
||||||
#[cfg(feature = "glib_v0_14")]
|
#[cfg(feature = "glib_v0_14")]
|
||||||
let inputs = settings.value("sources");
|
let inputs = settings.value("sources");
|
||||||
#[cfg(not(feature = "glib_v0_14"))]
|
#[cfg(not(feature = "glib_v0_14"))]
|
||||||
@ -172,40 +174,23 @@ impl LayoutId {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn set_visible_layout(
|
fn set_visible_layout(
|
||||||
manager: manager::c::Manager,
|
layout_id: &LayoutId,
|
||||||
layout_id: LayoutId,
|
|
||||||
) {
|
) {
|
||||||
match layout_id {
|
match layout_id {
|
||||||
LayoutId::System { kind, name } => {
|
LayoutId::System { kind, name } => {
|
||||||
unsafe {
|
|
||||||
use std::ptr;
|
|
||||||
manager::c::eekboard_context_service_set_overlay(
|
|
||||||
manager,
|
|
||||||
ptr::null(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
set_layout(kind, name);
|
set_layout(kind, name);
|
||||||
}
|
|
||||||
LayoutId::Local(name) => {
|
|
||||||
let name = CString::new(name.as_str()).unwrap();
|
|
||||||
let name_ptr = name.as_ptr();
|
|
||||||
unsafe {
|
|
||||||
manager::c::eekboard_context_service_set_overlay(
|
|
||||||
manager,
|
|
||||||
name_ptr,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
_ => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Takes into account first any overlays, then system layouts from the list
|
/// Takes into account first any overlays, then system layouts from the list
|
||||||
fn get_current_layout(
|
fn get_current_layout(
|
||||||
manager: manager::c::Manager,
|
popover: &actors::popover::State,
|
||||||
system_layouts: &Vec<LayoutId>,
|
system_layouts: &Vec<LayoutId>,
|
||||||
) -> Option<LayoutId> {
|
) -> Option<LayoutId> {
|
||||||
match manager::get_overlay(manager) {
|
match &popover.overlay {
|
||||||
Some(name) => Some(LayoutId::Local(name)),
|
Some(name) => Some(LayoutId::Local(name.into())),
|
||||||
None => system_layouts.get(0).map(LayoutId::clone),
|
None => system_layouts.get(0).map(LayoutId::clone),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -249,7 +234,7 @@ fn translate_layout_names(layouts: &Vec<LayoutId>) -> Vec<OwnedTranslation> {
|
|||||||
pub fn show(
|
pub fn show(
|
||||||
window: EekGtkKeyboard,
|
window: EekGtkKeyboard,
|
||||||
position: Bounds,
|
position: Bounds,
|
||||||
manager: manager::c::Manager,
|
popover: &actors::popover::State,
|
||||||
app_state: receiver::State,
|
app_state: receiver::State,
|
||||||
) {
|
) {
|
||||||
unsafe { gtk::set_initialized() };
|
unsafe { gtk::set_initialized() };
|
||||||
@ -330,7 +315,7 @@ pub fn show(
|
|||||||
|
|
||||||
let action_group = gio::SimpleActionGroup::new();
|
let action_group = gio::SimpleActionGroup::new();
|
||||||
|
|
||||||
if let Some(current_layout) = get_current_layout(manager, &system_layouts) {
|
if let Some(current_layout) = get_current_layout(popover, &system_layouts) {
|
||||||
let current_layout_name = all_layouts.iter()
|
let current_layout_name = all_layouts.iter()
|
||||||
.find(
|
.find(
|
||||||
|l| l.get_name() == current_layout.get_name()
|
|l| l.get_name() == current_layout.get_name()
|
||||||
@ -365,10 +350,7 @@ pub fn show(
|
|||||||
logging::Problem::Bug,
|
logging::Problem::Bug,
|
||||||
&format!("Can't send to state"),
|
&format!("Can't send to state"),
|
||||||
);
|
);
|
||||||
set_visible_layout(
|
set_visible_layout(layout)
|
||||||
manager,
|
|
||||||
layout.clone(),
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
None => log_print!(
|
None => log_print!(
|
||||||
|
|||||||
@ -56,8 +56,6 @@ struct squeekboard {
|
|||||||
/// Gsettings hook for visibility. TODO: this does not belong in gsettings.
|
/// Gsettings hook for visibility. TODO: this does not belong in gsettings.
|
||||||
ServerContextService *settings_handler;
|
ServerContextService *settings_handler;
|
||||||
struct panel_manager panel_manager; // Controls the shape of the panel.
|
struct panel_manager panel_manager; // Controls the shape of the panel.
|
||||||
/// Currently wanted layout. TODO: merge into state::Application
|
|
||||||
struct squeek_layout_state layout_choice;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -400,7 +398,7 @@ main (int argc, char **argv)
|
|||||||
// Also initializes wayland
|
// Also initializes wayland
|
||||||
struct rsobjects rsobjects = squeek_init();
|
struct rsobjects rsobjects = squeek_init();
|
||||||
|
|
||||||
instance.settings_context = eekboard_context_service_new(rsobjects.state_manager, &instance.layout_choice);
|
instance.settings_context = eekboard_context_service_new(rsobjects.state_manager);
|
||||||
|
|
||||||
// set up dbus
|
// set up dbus
|
||||||
|
|
||||||
@ -450,10 +448,10 @@ main (int argc, char **argv)
|
|||||||
|
|
||||||
instance.panel_manager = panel_manager_new(instance.settings_context,
|
instance.panel_manager = panel_manager_new(instance.settings_context,
|
||||||
rsobjects.submission,
|
rsobjects.submission,
|
||||||
&instance.layout_choice,
|
rsobjects.state_manager,
|
||||||
rsobjects.state_manager);
|
rsobjects.popover);
|
||||||
|
|
||||||
register_ui_loop_handler(rsobjects.receiver, &instance.panel_manager, instance.settings_context, instance.dbus_handler);
|
register_ui_loop_handler(rsobjects.receiver, &instance.panel_manager, rsobjects.popover, instance.settings_context, instance.dbus_handler);
|
||||||
|
|
||||||
session_register();
|
session_register();
|
||||||
|
|
||||||
|
|||||||
22
src/state.rs
22
src/state.rs
@ -126,27 +126,6 @@ impl Outcome {
|
|||||||
/// The receivers of the commands bear the burden
|
/// The receivers of the commands bear the burden
|
||||||
/// of checking if the commands end up being no-ops.
|
/// of checking if the commands end up being no-ops.
|
||||||
pub fn get_commands_to_reach(&self, new_state: &Self) -> Commands {
|
pub fn get_commands_to_reach(&self, new_state: &Self) -> Commands {
|
||||||
let layout_hint_set = match new_state {
|
|
||||||
Outcome {
|
|
||||||
panel: animation::Outcome::Visible{..},
|
|
||||||
im: InputMethod::Active(hints),
|
|
||||||
..
|
|
||||||
} => Some(hints.clone()),
|
|
||||||
|
|
||||||
Outcome {
|
|
||||||
panel: animation::Outcome::Visible{..},
|
|
||||||
im: InputMethod::InactiveSince(_),
|
|
||||||
..
|
|
||||||
} => Some(InputMethodDetails {
|
|
||||||
hint: ContentHint::NONE,
|
|
||||||
purpose: ContentPurpose::Normal,
|
|
||||||
}),
|
|
||||||
|
|
||||||
Outcome {
|
|
||||||
panel: animation::Outcome::Hidden,
|
|
||||||
..
|
|
||||||
} => None,
|
|
||||||
};
|
|
||||||
// FIXME: handle switching outputs
|
// FIXME: handle switching outputs
|
||||||
let (dbus_visible_set, panel_visibility) = match new_state.panel {
|
let (dbus_visible_set, panel_visibility) = match new_state.panel {
|
||||||
animation::Outcome::Visible{output, height, ..}
|
animation::Outcome::Visible{output, height, ..}
|
||||||
@ -179,7 +158,6 @@ impl Outcome {
|
|||||||
|
|
||||||
Commands {
|
Commands {
|
||||||
panel_visibility,
|
panel_visibility,
|
||||||
layout_hint_set,
|
|
||||||
dbus_visible_set,
|
dbus_visible_set,
|
||||||
layout_selection,
|
layout_selection,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user