state: Store layout override

Not used for any externally observable effects
This commit is contained in:
Dorota Czaplejewicz
2022-06-03 16:32:42 +00:00
parent 8ff72f312a
commit 590cd71f49
11 changed files with 101 additions and 38 deletions

View File

@ -48,6 +48,7 @@ typedef struct _EekGtkKeyboardPrivate
struct render_geometry render_geometry; // mutable
EekboardContextService *eekboard_context; // unowned reference
struct squeek_state_manager *state_manager; // shared reference
struct submission *submission; // unowned reference
struct squeek_layout_state *layout; // unowned
@ -158,6 +159,7 @@ on_event_triggered (LfbEvent *event,
GAsyncResult *res,
gpointer unused)
{
(void)unused;
g_autoptr (GError) err = NULL;
if (!lfb_event_trigger_feedback_finish (event, res, &err)) {
@ -188,7 +190,7 @@ static void drag(EekGtkKeyboard *self,
squeek_layout_drag(eekboard_context_service_get_keyboard(priv->eekboard_context)->layout,
priv->submission,
x, y, priv->render_geometry.widget_to_layout, time,
priv->eekboard_context, self);
priv->eekboard_context, priv->state_manager, self);
}
static void release(EekGtkKeyboard *self, guint32 time)
@ -199,7 +201,7 @@ static void release(EekGtkKeyboard *self, guint32 time)
}
squeek_layout_release(eekboard_context_service_get_keyboard(priv->eekboard_context)->layout,
priv->submission, priv->render_geometry.widget_to_layout, time,
priv->eekboard_context, self);
priv->eekboard_context, priv->state_manager, self);
}
static gboolean
@ -406,13 +408,14 @@ on_notify_keyboard (GObject *object,
GtkWidget *
eek_gtk_keyboard_new (EekboardContextService *eekservice,
struct submission *submission,
struct squeek_layout_state *layout)
struct squeek_layout_state *layout, struct squeek_state_manager *state_manager)
{
EekGtkKeyboard *ret = EEK_GTK_KEYBOARD(g_object_new (EEK_TYPE_GTK_KEYBOARD, NULL));
EekGtkKeyboardPrivate *priv = (EekGtkKeyboardPrivate*)eek_gtk_keyboard_get_instance_private (ret);
priv->eekboard_context = eekservice;
priv->submission = submission;
priv->layout = layout;
priv->state_manager = state_manager;
priv->renderer = NULL;
// This should really be done on initialization.
// Before the widget is allocated,

View File

@ -30,6 +30,7 @@
#include "eek/eek-renderer.h"
#include "eek/eek-types.h"
#include "src/main.h"
struct submission;
struct squeek_layout_state;
@ -48,7 +49,7 @@ struct _EekGtkKeyboardClass
gpointer pdummy[24];
};
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, struct squeek_state_manager *state_manager);
void eek_gtk_keyboard_emit_feedback (EekGtkKeyboard *self);
G_END_DECLS

View File

@ -7,6 +7,7 @@
#include "eek/eek-gtk-keyboard.h"
#include "eek/eek-renderer.h"
#include "eek/eek-types.h"
#include "src/main.h"
#include "src/submission.h"
#include "virtual-keyboard-unstable-v1-client-protocol.h"
#include "text-input-unstable-v3-client-protocol.h"
@ -41,6 +42,7 @@ void squeek_layout_release(struct squeek_layout *layout,
struct transformation widget_to_layout,
uint32_t timestamp,
EekboardContextService *manager,
struct squeek_state_manager *state,
EekGtkKeyboard *ui_keyboard);
void squeek_layout_release_all_only(struct squeek_layout *layout,
struct submission *submission,
@ -55,6 +57,7 @@ void squeek_layout_drag(struct squeek_layout *layout,
double x_widget, double y_widget,
struct transformation widget_to_layout,
uint32_t timestamp, EekboardContextService *manager,
struct squeek_state_manager *state,
EekGtkKeyboard *ui_keyboard);
void squeek_layout_draw_all_changed(struct squeek_layout *layout, EekRenderer* renderer, cairo_t *cr, struct submission *submission);
void squeek_draw_layout_base_view(struct squeek_layout *layout, EekRenderer* renderer, cairo_t *cr);

View File

@ -25,31 +25,37 @@ use std::fmt;
use std::rc::Rc;
use std::vec::Vec;
use ::action::Action;
use ::drawing;
use ::float_ord::FloatOrd;
use ::keyboard::KeyState;
use ::logging;
use ::manager;
use ::submission::{ Submission, SubmitData, Timestamp };
use ::util::find_max_double;
use crate::action::Action;
use crate::drawing;
use crate::event_loop::driver::Threaded as AppState;
use crate::float_ord::FloatOrd;
use crate::keyboard::KeyState;
use crate::logging;
use crate::manager;
use crate::popover;
use crate::receiver;
use crate::submission::{ Submission, SubmitData, Timestamp };
use crate::util::find_max_double;
use ::imservice::ContentPurpose;
use crate::imservice::ContentPurpose;
// Traits
use std::borrow::Borrow;
use ::logging::Warn;
use crate::logging::Warn;
/// Gathers stuff defined in C or called by C
pub mod c {
use super::*;
use gtk_sys;
use std::os::raw::c_void;
use crate::receiver;
use crate::submission::c::Submission as CSubmission;
use gtk_sys;
use std::ops::{ Add, Sub };
use std::os::raw::c_void;
use crate::util::CloneOwned;
// The following defined in C
#[repr(transparent)]
#[derive(Copy, Clone)]
@ -216,12 +222,15 @@ pub mod c {
widget_to_layout: Transformation,
time: u32,
manager: manager::c::Manager,
app_state: receiver::c::State,
ui_keyboard: EekGtkKeyboard,
) {
let time = Timestamp(time);
let layout = unsafe { &mut *layout };
let submission = submission.clone_ref();
let mut submission = submission.borrow_mut();
let app_state = app_state.clone_owned();
let ui_backend = UIBackend {
widget_to_layout,
keyboard: ui_keyboard,
@ -236,7 +245,7 @@ pub mod c {
&mut submission,
Some(&ui_backend),
time,
Some(manager),
Some((manager, app_state.clone())),
key,
);
}
@ -316,12 +325,14 @@ pub mod c {
widget_to_layout: Transformation,
time: u32,
manager: manager::c::Manager,
app_state: receiver::c::State,
ui_keyboard: EekGtkKeyboard,
) {
let time = Timestamp(time);
let layout = unsafe { &mut *layout };
let submission = submission.clone_ref();
let mut submission = submission.borrow_mut();
let app_state = app_state.clone_owned();
let ui_backend = UIBackend {
widget_to_layout,
keyboard: ui_keyboard,
@ -352,7 +363,7 @@ pub mod c {
&mut submission,
Some(&ui_backend),
time,
Some(manager),
Some((manager, app_state.clone())),
key,
);
}
@ -377,7 +388,7 @@ pub mod c {
&mut submission,
Some(&ui_backend),
time,
Some(manager),
Some((manager, app_state.clone())),
key,
);
}
@ -1035,7 +1046,11 @@ mod seat {
submission: &mut Submission,
ui: Option<&UIBackend>,
time: Timestamp,
manager: Option<manager::c::Manager>,
// TODO: intermediate measure:
// passing state conditionally because it's only used for popover.
// Eventually, it should be used for sumitting button events,
// and passed always.
manager: Option<(manager::c::Manager, receiver::State)>,
rckey: &Rc<RefCell<KeyState>>,
) {
let key: KeyState = {
@ -1070,7 +1085,7 @@ mod seat {
// only show when UI is present
Action::ShowPreferences => if let Some(ui) = &ui {
// only show when layout manager is available
if let Some(manager) = manager {
if let Some((manager, app_state)) = manager {
let view = layout.get_current_view();
let places = ::layout::procedures::find_key_places(
view, &rckey,
@ -1085,10 +1100,11 @@ mod seat {
width: button.size.width,
height: button.size.height,
};
::popover::show(
popover::show(
ui.keyboard,
ui.widget_to_layout.reverse_bounds(bounds),
manager,
app_state,
);
}
}

View File

@ -38,6 +38,7 @@ mod manager;
mod outputs;
mod panel;
mod popover;
mod receiver;
mod resources;
mod state;
mod style;

View File

@ -52,7 +52,7 @@ make_widget (struct panel_manager *self)
if (self->widget) {
g_error("Widget already present");
}
self->widget = eek_gtk_keyboard_new (self->state, self->submission, self->layout);
self->widget = eek_gtk_keyboard_new (self->state, self->submission, self->layout, self->state_manager);
gtk_widget_set_has_tooltip (self->widget, TRUE);
gtk_container_add (GTK_CONTAINER(self->window), self->widget);
@ -116,7 +116,7 @@ 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 panel_manager panel_manager_new(EekboardContextService *state, struct submission *submission, struct squeek_layout_state *layout, struct squeek_state_manager *state_manager)
{
struct panel_manager mgr = {
.state = state,
@ -125,6 +125,7 @@ struct panel_manager panel_manager_new(EekboardContextService *state, struct sub
.window = NULL,
.widget = NULL,
.current_output = NULL,
.state_manager = state_manager,
};
return mgr;
}

View File

@ -2,12 +2,14 @@
#include "eek/layersurface.h"
#include "src/layout.h"
#include "src/main.h"
#include "src/submission.h"
// Stores the objects that the panel and its widget will refer to
struct panel_manager {
EekboardContextService *state; // unowned
/// Needed for instantiating the widget
struct squeek_state_manager *state_manager; // shared reference
struct submission *submission; // unowned
struct squeek_layout_state *layout;
@ -18,4 +20,4 @@ struct panel_manager {
struct wl_output *current_output;
};
struct panel_manager panel_manager_new(EekboardContextService *state, struct submission *submission, struct squeek_layout_state *layout);
struct panel_manager panel_manager_new(EekboardContextService *state, struct submission *submission, struct squeek_layout_state *layout, struct squeek_state_manager *state_manager);

View File

@ -4,11 +4,13 @@ use gio;
use gtk;
use std::ffi::CString;
use std::cmp::Ordering;
use ::layout::c::{ Bounds, EekGtkKeyboard };
use ::locale::{ OwnedTranslation, compare_current_locale };
use ::logging;
use ::manager;
use ::resources;
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;
// Traits
use gio::prelude::ActionMapExt;
@ -16,7 +18,7 @@ use gio::prelude::SettingsExt;
use glib::translate::FromGlibPtrNone;
use glib::variant::ToVariant;
use gtk::prelude::*;
use ::logging::Warn;
use crate::logging::Warn;
mod c {
use std::os::raw::c_char;
@ -150,7 +152,7 @@ fn set_layout(kind: String, name: String) {
/// A reference to what the user wants to see
#[derive(PartialEq, Clone, Debug)]
enum LayoutId {
pub enum LayoutId {
/// Affects the layout in system settings
System {
kind: String,
@ -248,6 +250,7 @@ pub fn show(
window: EekGtkKeyboard,
position: Bounds,
manager: manager::c::Manager,
app_state: receiver::State,
) {
unsafe { gtk::set_initialized() };
let window = unsafe { gtk::Widget::from_glib_none(window.0) };
@ -356,6 +359,12 @@ pub fn show(
.find(
|choices| state == choices.get_name()
).unwrap();
app_state
.send(state::Event::OverlayChanged(layout.clone()))
.or_print(
logging::Problem::Bug,
&format!("Can't send to state"),
);
set_visible_layout(
manager,
layout.clone(),

15
src/receiver.rs Normal file
View File

@ -0,0 +1,15 @@
/*! Defines the application-wide message bus for updating state.*/
use crate::event_loop::driver::Threaded;
pub mod c {
use super::*;
use crate::util::c::Wrapped;
pub type State = Wrapped<Threaded>;
}
// The state receiver is an endpoint of a channel, so it's safely cloneable.
// There's no need to keep it in a Rc.
// The C version uses Wrapped with an underlying Rc,
// because Wrapped is well-tested already.
pub type State = Threaded;

View File

@ -450,7 +450,8 @@ main (int argc, char **argv)
instance.panel_manager = panel_manager_new(instance.settings_context,
rsobjects.submission,
&instance.layout_choice);
&instance.layout_choice,
rsobjects.state_manager);
register_ui_loop_handler(rsobjects.receiver, &instance.panel_manager, instance.settings_context, instance.dbus_handler);

View File

@ -13,6 +13,7 @@ use crate::outputs;
use crate::outputs::{Millimeter, OutputId, OutputState};
use crate::panel;
use crate::panel::PixelSize;
use crate::popover;
use crate::util::Rational;
use std::cmp;
use std::collections::HashMap;
@ -53,7 +54,7 @@ impl From<String> for LayoutSource {
}
}
/// The user's preferred layout
/// The user's preferred system layout
#[derive(Clone, Debug)]
pub struct LayoutChoice {
pub name: String,
@ -69,6 +70,7 @@ pub enum Event {
PhysicalKeyboard(Presence),
Output(outputs::Event),
LayoutChoice(LayoutChoice),
OverlayChanged(popover::LayoutId),
Debug(debug::Event),
/// Event triggered because a moment in time passed.
/// Use to animate state transitions.
@ -188,6 +190,8 @@ pub struct Application {
/// and we might not receive one at all (gsettings missing).
/// Then a default is used.
pub layout_choice: LayoutChoice,
/// Manual override of the system layout
pub overlay_layout: Option<popover::LayoutId>,
}
impl Application {
@ -209,6 +213,7 @@ impl Application {
name: String::from("us"),
source: LayoutSource::Xkb,
},
overlay_layout: None,
}
}
@ -295,8 +300,14 @@ impl Application {
},
},
Event::LayoutChoice(choice) => Self {
layout_choice: choice,
Event::LayoutChoice(layout_choice) => Self {
layout_choice,
overlay_layout: None,
..self
},
Event::OverlayChanged(overlay_layout) => Self {
overlay_layout: Some(overlay_layout),
..self
},
};