Commit cb802cfb authored by Dorota Czaplejewicz's avatar Dorota Czaplejewicz
Browse files

layout: Improve press handling

Makes it more similar to release handling, removes some redundant checks.

This makes it easier to integrate modifiers in the future.
parent da1f480f
......@@ -46,6 +46,14 @@ impl KeyState {
}
}
#[must_use]
pub fn into_pressed(self) -> KeyState {
KeyState {
pressed: PressType::Pressed,
..self
}
}
/// KeyStates instances are the unique identifiers of pressed keys,
/// and the actions submitted with them.
pub fn get_id(keystate: &Rc<RefCell<KeyState>>) -> KeyStateId {
......
......@@ -26,10 +26,10 @@ use std::vec::Vec;
use ::action::Action;
use ::drawing;
use ::keyboard::{ KeyState, PressType };
use ::keyboard::KeyState;
use ::logging;
use ::manager;
use ::submission::{ Submission, Timestamp };
use ::submission::{ Submission, SubmitData, Timestamp };
use ::util::find_max_double;
// Traits
......@@ -916,9 +916,38 @@ mod seat {
"Key {:?} was already pressed", rckey,
);
}
let mut key = rckey.borrow_mut();
submission.handle_press(&key, KeyState::get_id(rckey), time);
key.pressed = PressType::Pressed;
let key: KeyState = {
RefCell::borrow(rckey).clone()
};
let action = key.action.clone();
match action {
Action::Submit {
text: Some(text),
keys: _,
} => submission.handle_press(
KeyState::get_id(rckey),
SubmitData::Text(&text),
&key.keycodes,
time,
),
Action::Submit {
text: None,
keys: _,
} => submission.handle_press(
KeyState::get_id(rckey),
SubmitData::Keycodes,
&key.keycodes,
time,
),
Action::Erase => submission.handle_press(
KeyState::get_id(rckey),
SubmitData::Erase,
&key.keycodes,
time,
),
_ => {},
};
RefCell::replace(rckey, key.into_pressed());
}
pub fn handle_release_key(
......@@ -1006,6 +1035,7 @@ mod test {
use super::*;
use std::ffi::CString;
use ::keyboard::PressType;
pub fn make_state() -> Rc<RefCell<::keyboard::KeyState>> {
Rc::new(RefCell::new(::keyboard::KeyState {
......
......@@ -17,11 +17,11 @@
* and those events SHOULD NOT cause any lost events.
* */
use ::action::Action;
use std::ffi::CString;
use ::imservice;
use ::imservice::IMService;
use ::keyboard::{ KeyCode, KeyState, KeyStateId, PressType };
use ::logging;
use ::keyboard::{ KeyCode, KeyStateId, PressType };
use ::vkeyboard::VirtualKeyboard;
/// Gathers stuff defined in C or called by C
......@@ -109,59 +109,66 @@ pub struct Submission {
pressed: Vec<(KeyStateId, SubmittedAction)>,
}
pub enum SubmitData<'a> {
Text(&'a CString),
Erase,
Keycodes,
}
impl Submission {
/// Sends a submit text event if possible;
/// otherwise sends key press and makes a note of it
pub fn handle_press(
&mut self,
key: &KeyState, key_id: KeyStateId,
key_id: KeyStateId,
data: SubmitData,
keycodes: &Vec<KeyCode>,
time: Timestamp,
) {
match &key.action {
Action::Submit { text: _, keys: _ }
| Action::Erase
=> (),
_ => {
log_print!(
logging::Level::Bug,
"Submitted key with action other than Submit or Erase",
);
return;
},
};
let was_committed_as_text = match &mut self.imservice {
Some(imservice) => {
enum Outcome {
Submitted(Result<(), imservice::SubmitError>),
NotSubmitted,
};
let submit_outcome = match data {
SubmitData::Text(text) => {
Outcome::Submitted(imservice.commit_string(text))
},
SubmitData::Erase => {
/* Delete_surrounding_text takes byte offsets,
* so cannot work without get_surrounding_text.
* This is a bug in the protocol.
*/
// imservice.delete_surrounding_text(1, 0),
Outcome::NotSubmitted
},
SubmitData::Keycodes => Outcome::NotSubmitted,
};
let was_committed_as_text = match (&mut self.imservice, &key.action) {
(Some(imservice), Action::Submit { text: Some(text), keys: _ }) => {
let submit_result = imservice.commit_string(text)
.and_then(|_| imservice.commit());
match submit_result {
Ok(()) => true,
Err(imservice::SubmitError::NotActive) => false,
match submit_outcome {
Outcome::Submitted(result) => {
match result.and_then(|()| imservice.commit()) {
Ok(()) => true,
Err(imservice::SubmitError::NotActive) => false,
}
},
Outcome::NotSubmitted => false,
}
},
/* Delete_surrounding_text takes byte offsets,
* so cannot work without get_surrounding_text.
* This is a bug in the protocol.
(Some(imservice), Action::Erase) => {
let submit_result = imservice.delete_surrounding_text(1, 0)
.and_then(|_| imservice.commit());
match submit_result {
Ok(()) => true,
Err(imservice::SubmitError::NotActive) => false,
}
}*/
(_, _) => false,
_ => false,
};
let submit_action = match was_committed_as_text {
true => SubmittedAction::IMService,
false => {
self.virtual_keyboard.switch(
&key.keycodes,
keycodes,
PressType::Pressed,
time,
);
SubmittedAction::VirtualKeyboard(key.keycodes.clone())
SubmittedAction::VirtualKeyboard(keycodes.clone())
},
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment