state: Record layout choice

This does not get plugged into anything but debug prints yet.
This commit is contained in:
Dorota Czaplejewicz
2022-06-01 18:15:21 +00:00
parent af716f72da
commit 82774d2315
7 changed files with 69 additions and 7 deletions

View File

@ -56,6 +56,8 @@ static guint signals[LAST_SIGNAL] = { 0, };
struct _EekboardContextService {
GObject parent;
struct squeek_layout_state *layout; // Unowned
// FIXME: replaces layout
struct squeek_state_manager *state_manager; // shared reference
LevelKeyboard *keyboard; // currently used keyboard
GSettings *settings; // Owned reference
@ -169,6 +171,8 @@ static void eekboard_context_service_update_settings_layout(EekboardContextServi
settings_get_layout(context->settings,
&keyboard_type, &keyboard_layout);
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;
@ -325,10 +329,11 @@ eekboard_context_service_get_overlay(EekboardContextService *context) {
return context->layout->overlay_name;
}
EekboardContextService *eekboard_context_service_new(struct squeek_layout_state *state)
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);
context->layout = state;
context->state_manager = state_manager;
eekboard_context_service_update_settings_layout(context);
uint32_t time = gdk_event_get_time(NULL);
eekboard_context_service_use_layout(context, context->layout, time);

View File

@ -24,6 +24,7 @@
#include "src/submission.h"
#include "src/layout.h"
#include "src/main.h"
#include "virtual-keyboard-unstable-v1-client-protocol.h"
#include "text-input-unstable-v3-client-protocol.h"
@ -37,7 +38,7 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE(EekboardContextService, eekboard_context_service, EEKBOARD, CONTEXT_SERVICE, GObject)
EekboardContextService *eekboard_context_service_new(struct squeek_layout_state *state);
EekboardContextService *eekboard_context_service_new(struct squeek_state_manager *state_manager, struct squeek_layout_state *state);
void eekboard_context_service_set_submission(EekboardContextService *context, struct submission *submission);
void eekboard_context_service_destroy (EekboardContextService *context);
LevelKeyboard *eekboard_context_service_get_keyboard(EekboardContextService *context);

View File

@ -39,7 +39,9 @@ type UISender = glib::Sender<Commands>;
/// It sends outcomes to the glib main loop using a channel.
/// The outcomes are applied by the UI end of the channel in the `main` module.
// This could still be reasonably tested,
// by creating a glib::Sender and checking what messages it receives.
/// by creating a glib::Sender and checking what messages it receives.
// This can/should be abstracted over Event and Commands,
// so that the C call-ins can be thrown away from here and defined near events.
#[derive(Clone)]
pub struct Threaded {
thread: Sender,
@ -108,8 +110,11 @@ mod c {
use super::*;
use crate::state::Presence;
use crate::state::LayoutChoice;
use crate::state::visibility;
use crate::util;
use crate::util::c::Wrapped;
use std::os::raw::c_char;
#[no_mangle]
pub extern "C"
@ -140,4 +145,28 @@ mod c {
sender.send(Event::PhysicalKeyboard(state))
.or_warn(&mut logging::Print, logging::Problem::Warning, "Can't send to state manager");
}
#[no_mangle]
pub extern "C"
fn squeek_state_send_layout_set(
sender: Wrapped<Threaded>,
name: *const c_char,
source: *const c_char,
// TODO: use when synthetic events are needed
_timestamp: u32,
) {
let sender = sender.clone_ref();
let sender = sender.borrow();
let string_or_empty = |v| String::from(
util::c::as_str(v)
.unwrap_or(Some(""))
.unwrap_or("")
);
sender
.send(Event::LayoutChoice(LayoutChoice {
name: string_or_empty(&name),
source: string_or_empty(&source).into(),
}))
.or_warn(&mut logging::Print, logging::Problem::Warning, "Can't send to state manager");
}
}

View File

@ -33,3 +33,4 @@ void squeek_state_send_force_visible(struct squeek_state_manager *state);
void squeek_state_send_force_hidden(struct squeek_state_manager *state);
void squeek_state_send_keyboard_present(struct squeek_state_manager *state, uint32_t keyboard_present);
void squeek_state_send_layout_set(struct squeek_state_manager *state, char *name, char *layout, uint32_t timestamp);

View File

@ -1,5 +1,5 @@
/*! Procedures relating to the management of the switching of layouts */
use ::util;
use crate::util;
pub mod c {
use std::os::raw::{c_char, c_void};

View File

@ -400,7 +400,7 @@ main (int argc, char **argv)
// Also initializes wayland
struct rsobjects rsobjects = squeek_init();
instance.settings_context = eekboard_context_service_new(&instance.layout_choice);
instance.settings_context = eekboard_context_service_new(rsobjects.state_manager, &instance.layout_choice);
// set up dbus

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2021 Purism SPC
/* Copyright (C) 2021,2022 Purism SPC
* SPDX-License-Identifier: GPL-3.0+
*/
@ -37,6 +37,29 @@ pub enum InputMethod {
InactiveSince(Instant),
}
#[derive(Clone, Debug)]
pub enum LayoutSource {
Xkb,
Other(String),
}
impl From<String> for LayoutSource {
fn from(v: String) -> Self {
if v.as_str() == "xkb" {
LayoutSource::Xkb
} else {
LayoutSource::Other(v)
}
}
}
/// The user's preferred layout
#[derive(Clone, Debug)]
pub struct LayoutChoice {
pub name: String,
pub source: LayoutSource,
}
/// Incoming events.
/// This contains events that cause a change to the internal state.
#[derive(Clone, Debug)]
@ -45,6 +68,7 @@ pub enum Event {
Visibility(visibility::Event),
PhysicalKeyboard(Presence),
Output(outputs::Event),
LayoutChoice(LayoutChoice),
Debug(debug::Event),
/// Event triggered because a moment in time passed.
/// Use to animate state transitions.
@ -257,7 +281,9 @@ impl Application {
im: InputMethod::InactiveSince(old),
..self
},
}
},
Event::LayoutChoice(LayoutChoice { name, source }) => self,
};
if state.debug_mode_enabled {