state: Store layout override
Not used for any externally observable effects
This commit is contained in:
@ -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,
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,6 +38,7 @@ mod manager;
|
||||
mod outputs;
|
||||
mod panel;
|
||||
mod popover;
|
||||
mod receiver;
|
||||
mod resources;
|
||||
mod state;
|
||||
mod style;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
15
src/receiver.rs
Normal 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;
|
||||
@ -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);
|
||||
|
||||
|
||||
17
src/state.rs
17
src/state.rs
@ -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
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user