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:
Dorota Czaplejewicz
2022-06-04 13:40:30 +00:00
parent 30141db28d
commit c1ceec3673
19 changed files with 137 additions and 277 deletions

View File

@ -4,10 +4,10 @@ use gio;
use gtk;
use std::ffi::CString;
use std::cmp::Ordering;
use crate::actors;
use crate::layout::c::{ Bounds, EekGtkKeyboard };
use crate::locale::{ OwnedTranslation, compare_current_locale };
use crate::logging;
use crate::manager;
use crate::receiver;
use crate::resources;
use crate::state;
@ -129,9 +129,11 @@ fn get_settings(schema_name: &str) -> Option<gio::Settings> {
.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");
if let Some(settings) = settings {
let kind = String::from(kind);
let name = String::from(name);
#[cfg(feature = "glib_v0_14")]
let inputs = settings.value("sources");
#[cfg(not(feature = "glib_v0_14"))]
@ -172,40 +174,23 @@ impl LayoutId {
}
fn set_visible_layout(
manager: manager::c::Manager,
layout_id: LayoutId,
layout_id: &LayoutId,
) {
match layout_id {
LayoutId::System { kind, name } => {
unsafe {
use std::ptr;
manager::c::eekboard_context_service_set_overlay(
manager,
ptr::null(),
);
}
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
fn get_current_layout(
manager: manager::c::Manager,
popover: &actors::popover::State,
system_layouts: &Vec<LayoutId>,
) -> Option<LayoutId> {
match manager::get_overlay(manager) {
Some(name) => Some(LayoutId::Local(name)),
match &popover.overlay {
Some(name) => Some(LayoutId::Local(name.into())),
None => system_layouts.get(0).map(LayoutId::clone),
}
}
@ -249,7 +234,7 @@ fn translate_layout_names(layouts: &Vec<LayoutId>) -> Vec<OwnedTranslation> {
pub fn show(
window: EekGtkKeyboard,
position: Bounds,
manager: manager::c::Manager,
popover: &actors::popover::State,
app_state: receiver::State,
) {
unsafe { gtk::set_initialized() };
@ -330,7 +315,7 @@ pub fn show(
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()
.find(
|l| l.get_name() == current_layout.get_name()
@ -365,10 +350,7 @@ pub fn show(
logging::Problem::Bug,
&format!("Can't send to state"),
);
set_visible_layout(
manager,
layout.clone(),
)
set_visible_layout(layout)
});
},
None => log_print!(