views: Change based on layout file
This commit is contained in:
		@ -40,7 +40,9 @@ views:
 | 
				
			|||||||
buttons:
 | 
					buttons:
 | 
				
			||||||
    Shift_L:
 | 
					    Shift_L:
 | 
				
			||||||
        action:
 | 
					        action:
 | 
				
			||||||
            set_view: "upper"
 | 
					            locking:
 | 
				
			||||||
 | 
					                lock_view: "upper"
 | 
				
			||||||
 | 
					                unlock_view: "base"
 | 
				
			||||||
        outline: "altline"
 | 
					        outline: "altline"
 | 
				
			||||||
        icon: "key-shift"
 | 
					        icon: "key-shift"
 | 
				
			||||||
    BackSpace:
 | 
					    BackSpace:
 | 
				
			||||||
 | 
				
			|||||||
@ -49,64 +49,47 @@ eek_modifier_key_free (EekModifierKey *modkey)
 | 
				
			|||||||
    g_slice_free (EekModifierKey, modkey);
 | 
					    g_slice_free (EekModifierKey, modkey);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Updates the state of locked keys based on the key that was activated
 | 
					void
 | 
				
			||||||
/// FIXME: make independent of what the key are named,
 | 
					eek_keyboard_set_button_locked (LevelKeyboard    *keyboard,
 | 
				
			||||||
/// and instead refer to the contained symbols
 | 
					                                struct squeek_button *button)
 | 
				
			||||||
static guint
 | 
					 | 
				
			||||||
set_key_states (LevelKeyboard    *keyboard,
 | 
					 | 
				
			||||||
                struct squeek_button *button,
 | 
					 | 
				
			||||||
                guint new_level)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    // Keys locking rules hardcoded for the time being...
 | 
					 | 
				
			||||||
    const gchar *name = squeek_button_get_name(button);
 | 
					 | 
				
			||||||
    // Lock the shift whenever it's pressed on the baselevel
 | 
					 | 
				
			||||||
    // TODO: need to lock shift on the destination level
 | 
					 | 
				
			||||||
    if (g_strcmp0(name, "Shift_L") == 0 && squeek_layout_get_level(keyboard->layout) == 0) {
 | 
					 | 
				
			||||||
    EekModifierKey *modifier_key = g_slice_new (EekModifierKey);
 | 
					    EekModifierKey *modifier_key = g_slice_new (EekModifierKey);
 | 
				
			||||||
    modifier_key->modifiers = 0;
 | 
					    modifier_key->modifiers = 0;
 | 
				
			||||||
    modifier_key->button = button;
 | 
					    modifier_key->button = button;
 | 
				
			||||||
    keyboard->locked_buttons =
 | 
					    keyboard->locked_buttons =
 | 
				
			||||||
            g_list_prepend (keyboard->locked_buttons, modifier_key);
 | 
					            g_list_prepend (keyboard->locked_buttons, modifier_key);
 | 
				
			||||||
        struct squeek_key *key = squeek_button_get_key(button);
 | 
					}
 | 
				
			||||||
        squeek_key_set_locked(key, true);
 | 
					
 | 
				
			||||||
    }
 | 
					/// Unlock all locked keys.
 | 
				
			||||||
    if (squeek_layout_get_level(keyboard->layout) == 1) {
 | 
					/// All locked keys will unlock at the next keypress (should be called "stuck")
 | 
				
			||||||
        // Only shift is locked in this state, unlock on any key press
 | 
					/// Returns the number of handled keys
 | 
				
			||||||
 | 
					/// TODO: may need to check key type in order to chain locks
 | 
				
			||||||
 | 
					/// before pressing an "emitting" key
 | 
				
			||||||
 | 
					static int unlock_keys(LevelKeyboard *keyboard) {
 | 
				
			||||||
 | 
					    int handled = 0;
 | 
				
			||||||
    for (GList *head = keyboard->locked_buttons; head; ) {
 | 
					    for (GList *head = keyboard->locked_buttons; head; ) {
 | 
				
			||||||
        EekModifierKey *modifier_key = head->data;
 | 
					        EekModifierKey *modifier_key = head->data;
 | 
				
			||||||
        GList *next = g_list_next (head);
 | 
					        GList *next = g_list_next (head);
 | 
				
			||||||
        keyboard->locked_buttons =
 | 
					        keyboard->locked_buttons =
 | 
				
			||||||
                g_list_remove_link (keyboard->locked_buttons, head);
 | 
					                g_list_remove_link (keyboard->locked_buttons, head);
 | 
				
			||||||
            squeek_key_set_locked(squeek_button_get_key(modifier_key->button), false);
 | 
					        //squeek_key_set_locked(squeek_button_get_key(modifier_key->button), false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        squeek_layout_set_state_from_press(keyboard->layout, keyboard, modifier_key->button);
 | 
				
			||||||
        g_list_free1 (head);
 | 
					        g_list_free1 (head);
 | 
				
			||||||
        head = next;
 | 
					        head = next;
 | 
				
			||||||
 | 
					        handled++;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
        return 0;
 | 
					    return handled;
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return new_level;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// FIXME: unhardcode, parse some user information as to which key triggers which view (level)
 | 
					 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
set_level_from_press (LevelKeyboard *keyboard, struct squeek_button *button)
 | 
					set_level_from_press (LevelKeyboard *keyboard, struct squeek_button *button)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /* The levels are: 0 Letters, 1 Upper case letters, 2 Numbers, 3 Symbols */
 | 
					    // If the currently locked key was already handled in the unlock phase,
 | 
				
			||||||
    guint level = squeek_layout_get_level(keyboard->layout);
 | 
					    // then skip
 | 
				
			||||||
    /* Handle non-emitting keys */
 | 
					    if (unlock_keys(keyboard) == 0) {
 | 
				
			||||||
    if (button) {
 | 
					        squeek_layout_set_state_from_press(keyboard->layout, keyboard, button);
 | 
				
			||||||
        const gchar *name = squeek_button_get_name(button);
 | 
					 | 
				
			||||||
        if (g_strcmp0(name, "show_numbers") == 0) {
 | 
					 | 
				
			||||||
            level = 2;
 | 
					 | 
				
			||||||
        } else if (g_strcmp0(name, "show_letters") == 0) {
 | 
					 | 
				
			||||||
            level = 0;
 | 
					 | 
				
			||||||
        } else if (g_strcmp0(name, "show_symbols") == 0) {
 | 
					 | 
				
			||||||
            level = 3;
 | 
					 | 
				
			||||||
        } else if (g_strcmp0(name, "Shift_L") == 0) {
 | 
					 | 
				
			||||||
            level ^= 1;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    squeek_layout_set_level(keyboard->layout, set_key_states(keyboard, button, level));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void eek_keyboard_press_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp) {
 | 
					void eek_keyboard_press_button(LevelKeyboard *keyboard, struct squeek_button *button, guint32 timestamp) {
 | 
				
			||||||
 | 
				
			|||||||
@ -90,12 +90,9 @@ send_fake_key (SeatEmitter *emitter,
 | 
				
			|||||||
               gboolean pressed,
 | 
					               gboolean pressed,
 | 
				
			||||||
               uint32_t timestamp)
 | 
					               uint32_t timestamp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    guint level = squeek_layout_get_level(keyboard->layout);
 | 
					    zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, 0, 0, 0, 0);
 | 
				
			||||||
    uint32_t group = (level / 2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, 0, 0, 0, group);
 | 
					 | 
				
			||||||
    send_virtual_keyboard_key (emitter->virtual_keyboard, keycode - 8, (unsigned)pressed, timestamp);
 | 
					    send_virtual_keyboard_key (emitter->virtual_keyboard, keycode - 8, (unsigned)pressed, timestamp);
 | 
				
			||||||
    zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, 0, 0, 0, group);
 | 
					    zwp_virtual_keyboard_v1_modifiers(emitter->virtual_keyboard, 0, 0, 0, 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										68
									
								
								src/data.rs
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								src/data.rs
									
									
									
									
									
								
							@ -205,7 +205,8 @@ struct ButtonMeta {
 | 
				
			|||||||
#[derive(Debug, Deserialize, PartialEq)]
 | 
					#[derive(Debug, Deserialize, PartialEq)]
 | 
				
			||||||
#[serde(deny_unknown_fields)]
 | 
					#[serde(deny_unknown_fields)]
 | 
				
			||||||
enum Action {
 | 
					enum Action {
 | 
				
			||||||
    /// FIXME: start using it
 | 
					    #[serde(rename="locking")]
 | 
				
			||||||
 | 
					    Locking { lock_view: String, unlock_view: String },
 | 
				
			||||||
    #[serde(rename="set_view")]
 | 
					    #[serde(rename="set_view")]
 | 
				
			||||||
    SetView(String),
 | 
					    SetView(String),
 | 
				
			||||||
    #[serde(rename="show_prefs")]
 | 
					    #[serde(rename="show_prefs")]
 | 
				
			||||||
@ -274,14 +275,11 @@ impl Layout {
 | 
				
			|||||||
                pressed: false,
 | 
					                pressed: false,
 | 
				
			||||||
                locked: false,
 | 
					                locked: false,
 | 
				
			||||||
                keycode: keycodes.get(*name).map(|k| *k),
 | 
					                keycode: keycodes.get(*name).map(|k| *k),
 | 
				
			||||||
                symbol: ::symbol::Symbol {
 | 
					                symbol: create_symbol(
 | 
				
			||||||
                    // FIXME: allow user to switch views
 | 
					                    &self.buttons,
 | 
				
			||||||
                    action: ::symbol::Action::Submit {
 | 
					                    name,
 | 
				
			||||||
                        text: None,
 | 
					                    self.views.keys().collect()
 | 
				
			||||||
                        // TODO: derive keysym name & value from button name
 | 
					                ),
 | 
				
			||||||
                        keys: vec!(),
 | 
					 | 
				
			||||||
                    },
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
            }))
 | 
					            }))
 | 
				
			||||||
        )});
 | 
					        )});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -334,6 +332,58 @@ impl Layout {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn create_symbol(
 | 
				
			||||||
 | 
					    button_info: &HashMap<String, ButtonMeta>,
 | 
				
			||||||
 | 
					    name: &str,
 | 
				
			||||||
 | 
					    view_names: Vec<&String>,
 | 
				
			||||||
 | 
					) -> ::symbol::Symbol {
 | 
				
			||||||
 | 
					    let default_meta = ButtonMeta::default();
 | 
				
			||||||
 | 
					    let symbol_meta = button_info.get(name)
 | 
				
			||||||
 | 
					        .unwrap_or(&default_meta);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    fn filter_view_name(
 | 
				
			||||||
 | 
					        button_name: &str,
 | 
				
			||||||
 | 
					        view_name: String,
 | 
				
			||||||
 | 
					        view_names: &Vec<&String>
 | 
				
			||||||
 | 
					    ) -> String {
 | 
				
			||||||
 | 
					        if view_names.contains(&&view_name) {
 | 
				
			||||||
 | 
					            view_name
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            eprintln!(
 | 
				
			||||||
 | 
					                "Button {} switches to missing view {}",
 | 
				
			||||||
 | 
					                button_name,
 | 
				
			||||||
 | 
					                view_name
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            "base".into()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    match &symbol_meta.action {
 | 
				
			||||||
 | 
					        Some(Action::SetView(view_name)) => ::symbol::Symbol {
 | 
				
			||||||
 | 
					            action: ::symbol::Action::SetLevel(
 | 
				
			||||||
 | 
					                filter_view_name(name, view_name.clone(), &view_names)
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        Some(Action::Locking { lock_view, unlock_view }) => ::symbol::Symbol {
 | 
				
			||||||
 | 
					            action: ::symbol::Action::LockLevel {
 | 
				
			||||||
 | 
					                lock: filter_view_name(name, lock_view.clone(), &view_names),
 | 
				
			||||||
 | 
					                unlock: filter_view_name(
 | 
				
			||||||
 | 
					                    name,
 | 
				
			||||||
 | 
					                    unlock_view.clone(),
 | 
				
			||||||
 | 
					                    &view_names
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        _ => ::symbol::Symbol {
 | 
				
			||||||
 | 
					            action: ::symbol::Action::Submit {
 | 
				
			||||||
 | 
					                text: None,
 | 
				
			||||||
 | 
					                // TODO: derive keysym name & value from button name
 | 
				
			||||||
 | 
					                keys: vec!(),
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// TODO: Since this will receive user-provided data,
 | 
					/// TODO: Since this will receive user-provided data,
 | 
				
			||||||
/// all .expect() on them should be turned into soft fails
 | 
					/// all .expect() on them should be turned into soft fails
 | 
				
			||||||
fn create_button(
 | 
					fn create_button(
 | 
				
			||||||
 | 
				
			|||||||
@ -55,8 +55,8 @@ struct squeek_button *squeek_view_find_button_by_position(struct squeek_view *vi
 | 
				
			|||||||
void
 | 
					void
 | 
				
			||||||
squeek_layout_place_contents(struct squeek_layout*);
 | 
					squeek_layout_place_contents(struct squeek_layout*);
 | 
				
			||||||
struct squeek_view *squeek_layout_get_current_view(struct squeek_layout*);
 | 
					struct squeek_view *squeek_layout_get_current_view(struct squeek_layout*);
 | 
				
			||||||
uint32_t squeek_layout_get_level(struct squeek_layout*);
 | 
					void squeek_layout_set_state_from_press(struct squeek_layout* layout, LevelKeyboard *keyboard, struct squeek_button* button);
 | 
				
			||||||
void squeek_layout_set_level(struct squeek_layout* layout, uint32_t level);
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct squeek_layout *squeek_load_layout(const char *type);
 | 
					struct squeek_layout *squeek_load_layout(const char *type);
 | 
				
			||||||
const char *squeek_layout_get_keymap(const struct squeek_layout*);
 | 
					const char *squeek_layout_get_keymap(const struct squeek_layout*);
 | 
				
			||||||
 | 
				
			|||||||
@ -224,33 +224,6 @@ pub mod c {
 | 
				
			|||||||
            .as_ref() as *const View
 | 
					            .as_ref() as *const View
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// FIXME: very temporary way to minimize level impact
 | 
					 | 
				
			||||||
    #[no_mangle]
 | 
					 | 
				
			||||||
    pub extern "C"
 | 
					 | 
				
			||||||
    fn squeek_layout_get_level(layout: *const Layout) -> u32 {
 | 
					 | 
				
			||||||
        let layout = unsafe { &*layout };
 | 
					 | 
				
			||||||
        match layout.current_view.as_str() {
 | 
					 | 
				
			||||||
            "base" => 0,
 | 
					 | 
				
			||||||
            "upper" => 1,
 | 
					 | 
				
			||||||
            "numbers" => 2,
 | 
					 | 
				
			||||||
            "symbols" => 3,
 | 
					 | 
				
			||||||
            _ => 0
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[no_mangle]
 | 
					 | 
				
			||||||
    pub extern "C"
 | 
					 | 
				
			||||||
    fn squeek_layout_set_level(layout: *mut Layout, level: u32) {
 | 
					 | 
				
			||||||
        let mut layout = unsafe { &mut*layout };
 | 
					 | 
				
			||||||
        layout.current_view = String::from(match level {
 | 
					 | 
				
			||||||
            0 => "base",
 | 
					 | 
				
			||||||
            1 => "upper",
 | 
					 | 
				
			||||||
            2 => "numbers",
 | 
					 | 
				
			||||||
            3 => "symbols",
 | 
					 | 
				
			||||||
            _ => "base",
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[no_mangle]
 | 
					    #[no_mangle]
 | 
				
			||||||
    pub extern "C"
 | 
					    pub extern "C"
 | 
				
			||||||
    fn squeek_layout_get_keymap(layout: *const Layout) -> *const c_char {
 | 
					    fn squeek_layout_get_keymap(layout: *const Layout) -> *const c_char {
 | 
				
			||||||
@ -276,6 +249,9 @@ pub mod c {
 | 
				
			|||||||
            button: *const Button,
 | 
					            button: *const Button,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        #[repr(transparent)]
 | 
				
			||||||
 | 
					        pub struct LevelKeyboard(*const c_void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #[no_mangle]
 | 
					        #[no_mangle]
 | 
				
			||||||
        extern "C" {
 | 
					        extern "C" {
 | 
				
			||||||
            /// Checks if point falls within bounds,
 | 
					            /// Checks if point falls within bounds,
 | 
				
			||||||
@ -285,6 +261,53 @@ pub mod c {
 | 
				
			|||||||
                origin: Point,
 | 
					                origin: Point,
 | 
				
			||||||
                angle: i32
 | 
					                angle: i32
 | 
				
			||||||
            ) -> u32;
 | 
					            ) -> u32;
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            pub fn eek_keyboard_set_button_locked(
 | 
				
			||||||
 | 
					                keyboard: *mut LevelKeyboard,
 | 
				
			||||||
 | 
					                button: *const Button
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        #[no_mangle]
 | 
				
			||||||
 | 
					        pub extern "C"
 | 
				
			||||||
 | 
					        fn squeek_layout_set_state_from_press(
 | 
				
			||||||
 | 
					            layout: *mut Layout,
 | 
				
			||||||
 | 
					            keyboard: *mut LevelKeyboard,
 | 
				
			||||||
 | 
					            button_ptr: *const Button,
 | 
				
			||||||
 | 
					        ) {
 | 
				
			||||||
 | 
					            let layout = unsafe { &mut *layout };
 | 
				
			||||||
 | 
					            let button = unsafe { &*button_ptr };
 | 
				
			||||||
 | 
					            // don't want to leave this borrowed in the function body
 | 
				
			||||||
 | 
					            let state = {
 | 
				
			||||||
 | 
					                let state = button.state.borrow();
 | 
				
			||||||
 | 
					                state.clone()
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let view_name = match state.symbol.action {
 | 
				
			||||||
 | 
					                ::symbol::Action::SetLevel(name) => {
 | 
				
			||||||
 | 
					                    Some(name.clone())
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                ::symbol::Action::LockLevel { lock, unlock } => {
 | 
				
			||||||
 | 
					                    let mut current_state = button.state.borrow_mut();
 | 
				
			||||||
 | 
					                    current_state.locked ^= true;
 | 
				
			||||||
 | 
					                    if current_state.locked {
 | 
				
			||||||
 | 
					                        unsafe {
 | 
				
			||||||
 | 
					                            eek_keyboard_set_button_locked(
 | 
				
			||||||
 | 
					                                keyboard,
 | 
				
			||||||
 | 
					                                button_ptr
 | 
				
			||||||
 | 
					                            )
 | 
				
			||||||
 | 
					                        };
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    Some(if state.locked { unlock } else { lock }.clone())
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                _ => None,
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if let Some(view_name) = view_name {
 | 
				
			||||||
 | 
					                if let Err(_e) = layout.set_view(view_name.clone()) {
 | 
				
			||||||
 | 
					                    eprintln!("No such view: {}, ignoring switch", view_name)
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// Places each button in order, starting from 0 on the left,
 | 
					        /// Places each button in order, starting from 0 on the left,
 | 
				
			||||||
@ -464,7 +487,7 @@ pub mod c {
 | 
				
			|||||||
                locked: false,
 | 
					                locked: false,
 | 
				
			||||||
                keycode: None,
 | 
					                keycode: None,
 | 
				
			||||||
                symbol: Symbol {
 | 
					                symbol: Symbol {
 | 
				
			||||||
                    action: Action::SetLevel(0),
 | 
					                    action: Action::SetLevel("default".into()),
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }))
 | 
					            }))
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -710,6 +733,19 @@ pub struct Layout {
 | 
				
			|||||||
    pub keymap_str: CString,
 | 
					    pub keymap_str: CString,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct NoSuchView;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Layout {
 | 
				
			||||||
 | 
					    fn set_view(&mut self, view: String) -> Result<(), NoSuchView> {
 | 
				
			||||||
 | 
					        if self.views.contains_key(&view) {
 | 
				
			||||||
 | 
					            self.current_view = view;
 | 
				
			||||||
 | 
					            Ok(())
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            Err(NoSuchView)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mod procedures {
 | 
					mod procedures {
 | 
				
			||||||
    use super::*;
 | 
					    use super::*;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
				
			|||||||
@ -22,7 +22,7 @@ impl KeySym {
 | 
				
			|||||||
pub struct XKeySym(pub u32);
 | 
					pub struct XKeySym(pub u32);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Use to switch layouts
 | 
					/// Use to switch layouts
 | 
				
			||||||
type Level = u8;
 | 
					type Level = String;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Use to send modified keypresses
 | 
					/// Use to send modified keypresses
 | 
				
			||||||
#[derive(Debug, Clone)]
 | 
					#[derive(Debug, Clone)]
 | 
				
			||||||
@ -34,8 +34,14 @@ pub enum Modifier {
 | 
				
			|||||||
/// Action to perform on the keypress and, in reverse, on keyrelease
 | 
					/// Action to perform on the keypress and, in reverse, on keyrelease
 | 
				
			||||||
#[derive(Debug, Clone)]
 | 
					#[derive(Debug, Clone)]
 | 
				
			||||||
pub enum Action {
 | 
					pub enum Action {
 | 
				
			||||||
    /// Switch to this level TODO: reverse?
 | 
					    /// Switch to this view
 | 
				
			||||||
    SetLevel(Level),
 | 
					    SetLevel(Level),
 | 
				
			||||||
 | 
					    /// Switch to a view and latch
 | 
				
			||||||
 | 
					    LockLevel {
 | 
				
			||||||
 | 
					        lock: Level,
 | 
				
			||||||
 | 
					        /// When unlocked by pressing it or emitting a key
 | 
				
			||||||
 | 
					        unlock: Level,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    /// Set this modifier TODO: release?
 | 
					    /// Set this modifier TODO: release?
 | 
				
			||||||
    SetModifier(Modifier),
 | 
					    SetModifier(Modifier),
 | 
				
			||||||
    /// Submit some text
 | 
					    /// Submit some text
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user