state: Store layout override
Not used for any externally observable effects
This commit is contained in:
		@ -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