Skip to content

Commit

Permalink
feat(chord_composer): support chording with function keys
Browse files Browse the repository at this point in the history
  • Loading branch information
lotem committed Dec 25, 2016
1 parent 79a32b2 commit 48424d3
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 27 deletions.
2 changes: 2 additions & 0 deletions include/rime/gear/chord_composer.h
Expand Up @@ -23,6 +23,8 @@ class ChordComposer : public Processor {
virtual ProcessResult ProcessKeyEvent(const KeyEvent& key_event);

protected:
ProcessResult ProcessChordingKey(const KeyEvent& key_event);
ProcessResult ProcessFunctionKey(const KeyEvent& key_event);
string SerializeChord();
void UpdateChord();
void FinishChord();
Expand Down
67 changes: 40 additions & 27 deletions src/gear/chord_composer.cc
Expand Up @@ -18,7 +18,6 @@ static const char* kZeroWidthSpace = "\xef\xbb\xbf"; //"\xe2\x80\x8b";

namespace rime {


ChordComposer::ChordComposer(const Ticket& ticket) : Processor(ticket) {
if (!engine_)
return;
Expand All @@ -44,55 +43,49 @@ ChordComposer::~ChordComposer() {
unhandled_key_connection_.disconnect();
}

ProcessResult ChordComposer::ProcessKeyEvent(const KeyEvent& key_event) {
if (pass_thru_)
ProcessResult ChordComposer::ProcessFunctionKey(const KeyEvent& key_event) {
if (key_event.release()) {
return kNoop;
bool chording = !chord_.empty();
if (key_event.shift() || key_event.ctrl() || key_event.alt()) {
ClearChord();
return chording ? kAccepted : kNoop;
}
bool is_key_up = key_event.release();
int ch = key_event.keycode();
Context* ctx = engine_->context();
if (!is_key_up && ch == XK_Return) {
if (ch == XK_Return) {
if (!raw_sequence_.empty()) {
// commit raw input
ctx->set_input(raw_sequence_);
engine_->context()->set_input(raw_sequence_);
// then the sequence should not be used again
raw_sequence_.clear();
}
ClearChord();
return kNoop;
}
if (!is_key_up && ch == XK_BackSpace) {
} else if (ch == XK_BackSpace) {
// invalidate raw sequence
raw_sequence_.clear();
ClearChord();
if (DeleteLastSyllable()) {
return kAccepted;
}
return kNoop;
}
if (!is_key_up && ch == XK_Escape) {
} else if (ch == XK_Escape) {
// clear the raw sequence
raw_sequence_.clear();
ClearChord();
return kNoop;
}
if (!is_key_up && ch >= 0x20 && ch <= 0x7e) {
// save raw input
if (!ctx->IsComposing() || !raw_sequence_.empty()) {
raw_sequence_.push_back(ch);
DLOG(INFO) << "update raw sequence: " << raw_sequence_;
}
return kNoop;
}

ProcessResult ChordComposer::ProcessChordingKey(const KeyEvent& key_event) {
bool chording = !chord_.empty();
if (key_event.shift() || key_event.ctrl() || key_event.alt()) {
ClearChord();
return chording ? kAccepted : kNoop;
}
bool is_key_up = key_event.release();
int ch = key_event.keycode();
// non chording key
if (std::find(chording_keys_.begin(),
chording_keys_.end(),
KeyEvent{ch, 0}) == chording_keys_.end()) {
return chording ? kAccepted : kNoop;
}
// in alphabet
// chording key
if (is_key_up) {
if (pressed_.erase(ch) != 0 && pressed_.empty()) {
FinishChord();
Expand All @@ -107,6 +100,26 @@ ProcessResult ChordComposer::ProcessKeyEvent(const KeyEvent& key_event) {
return kAccepted;
}

ProcessResult ChordComposer::ProcessKeyEvent(const KeyEvent& key_event) {
if (pass_thru_) {
return ProcessFunctionKey(key_event);
}
bool is_key_up = key_event.release();
int ch = key_event.keycode();
if (!is_key_up && ch >= 0x20 && ch <= 0x7e) {
// save raw input
if (!engine_->context()->IsComposing() || !raw_sequence_.empty()) {
raw_sequence_.push_back(ch);
DLOG(INFO) << "update raw sequence: " << raw_sequence_;
}
}
auto result = ProcessChordingKey(key_event);
if (result != kNoop) {
return result;
}
return ProcessFunctionKey(key_event);
}

string ChordComposer::SerializeChord() {
KeySequence key_sequence;
for (KeyEvent key : chording_keys_) {
Expand Down Expand Up @@ -208,7 +221,7 @@ void ChordComposer::OnContextUpdate(Context* ctx) {
else if (composing_) {
composing_ = false;
raw_sequence_.clear();
DLOG(INFO) << "clear sequence.";
DLOG(INFO) << "clear raw sequence.";
}
}

Expand All @@ -219,7 +232,7 @@ void ChordComposer::OnUnhandledKey(Context* ctx, const KeyEvent& key) {
if ((key.modifier() & ~kShiftMask) == 0 &&
key.keycode() >= 0x20 && key.keycode() <= 0x7e) {
raw_sequence_.clear();
DLOG(INFO) << "clear sequence.";
DLOG(INFO) << "clear raw sequence.";
}
}

Expand Down

0 comments on commit 48424d3

Please sign in to comment.