Skip to content

Commit

Permalink
Only commit after a sentinel is received
Browse files Browse the repository at this point in the history
  • Loading branch information
lewtds committed Apr 8, 2015
1 parent 8208f84 commit 96cfc68
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 48 deletions.
69 changes: 42 additions & 27 deletions main.vala
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,12 @@ public class BogoIMContext : Gtk.IMContext {
}

public override void focus_in() {
debug("focus_in()");
}

public override void focus_out() {
debug("focus_out()");
}

public override void reset() {
debug("reset()");

// Firefox will throws reset() when it sees our fake key so we
// will not actually reset if we're still waiting for the
Expand All @@ -67,18 +64,41 @@ public class BogoIMContext : Gtk.IMContext {
public override bool filter_keypress(Gdk.EventKey event) {
last_event_time = event.time;

if (event.type == Gdk.EventType.KEY_RELEASE &&
event.keyval == 0xff08 &&
is_fake_event(event)) {
if (event.hardware_keycode == 255 &&
(event.state & (1 << 24)) != 0) {
// Sentinel received, commit
debug(@"delayed commit: $delayed_commit_text");
commit(delayed_commit_text);
delayed_commit_text = "";
return true;
}

debug("fake release");
debug(@"filter($(event.keyval))");

if (pending_fake_backspaces == 0 &&
delayed_commit_text != "") {
if (event.keyval == 0xff08 &&
is_fake_event(event)) {

debug(@"delayed commit: $delayed_commit_text");
commit(delayed_commit_text);
delayed_commit_text = "";
if (event.type == Gdk.EventType.KEY_RELEASE) {
pending_fake_backspaces--;

if (pending_fake_backspaces == 0 &&
delayed_commit_text != "") {
// Last fake backspace release received
// Send a sentinel event to trigger the delayed commit
debug("Last fake release, sending sentinel");

Gdk.EventKey* sentinel =
(Gdk.EventKey*) new Gdk.Event(Gdk.EventType.KEY_PRESS);
sentinel->window = client_window;
sentinel->state = (Gdk.ModifierType) 1 << 24;
sentinel->time = last_event_time + 1;
sentinel->hardware_keycode = 255;
sentinel->send_event = 1;
sentinel->str = "";
sentinel->group = 0;
sentinel->is_modifier = 0;
((Gdk.Event*) sentinel)->put();
}
}

return false;
Expand All @@ -88,12 +108,6 @@ public class BogoIMContext : Gtk.IMContext {
return false;
}

if (event.keyval == 0xff08 && is_fake_event(event)) {
debug("fake_release");
pending_fake_backspaces--;
return false;
}

bool swallowed = input_ctx.process_key(event.keyval, event.state);
return swallowed;
}
Expand Down Expand Up @@ -150,15 +164,16 @@ public class BogoIMContext : Gtk.IMContext {

debug(@"delete($count)");

if (is_app_blacklisted()) {
delete_with_backspace(count);
} else {
var deleted = delete_surrounding(-(int) count, (int) count);
if (!deleted) {
debug("delete_surrounding() failed.");
delete_with_backspace(count);
}
}
delete_with_backspace(count);
// if (is_app_blacklisted()) {
// delete_with_backspace(count);
// } else {
// var deleted = delete_surrounding(-(int) count, (int) count);
// if (!deleted) {
// debug("delete_surrounding() failed.");
// delete_with_backspace(count);
// }
// }
}

private void delete_with_backspace(uint count) {
Expand Down
61 changes: 40 additions & 21 deletions tests/test.vala
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class FakeInputContext : Bogo.InputContext, Object {
}

void add_foo_tests () {
Test.add_func("/bogoimcontext/delay committing until the last fake backspace release gets fed back", () => {
Test.add_func("/bogoimcontext/delay committing until all fake backspaces are released", () => {
var ic = new FakeInputContext();
var ctx = new BogoIMContext("myapp", ic);

Expand All @@ -55,13 +55,20 @@ void add_foo_tests () {
};
ctx.filter_keypress(create_event('w', true, 0));

ctx.filter_keypress(create_event(0xff08, true, (Gdk.ModifierType) 1 << 25));
ctx.filter_keypress((Gdk.EventKey) Gdk.Event.get());
ctx.filter_keypress((Gdk.EventKey) Gdk.Event.get());
ctx.filter_keypress((Gdk.EventKey) Gdk.Event.get());
ctx.filter_keypress((Gdk.EventKey) Gdk.Event.get());
assert(commit_count == 0);
ctx.filter_keypress(create_event(0xff08, false, (Gdk.ModifierType) 1 << 25));
assert(commit_count == 0);
ctx.filter_keypress(create_event(0xff08, true, (Gdk.ModifierType) 1 << 25));
assert(commit_count == 0);
ctx.filter_keypress(create_event(0xff08, false, (Gdk.ModifierType) 1 << 25));

Gdk.EventKey e = (Gdk.EventKey) Gdk.Event.get();
assert(e != null);
assert(e.type == Gdk.EventType.KEY_PRESS);
assert(e.hardware_keycode == 255);
assert((e.state & (1 << 24)) != 0);

// Sentinel key event
ctx.filter_keypress(e);
assert(commit_count == 1);
});

Expand All @@ -83,7 +90,6 @@ void add_foo_tests () {

ctx.filter_keypress(create_event('w', true, 0));

assert(delete_surrounding_count == 1);

var e = Gdk.Event.get();
assert(e != null);
Expand Down Expand Up @@ -121,12 +127,20 @@ void add_foo_tests () {
ic.composition_updated("ươi", 3);
return true;
};

ctx.filter_keypress(create_event('i', true, 0));

ctx.filter_keypress(create_event(0xff08, true, (Gdk.ModifierType) 1 << 25));
ctx.filter_keypress(create_event(0xff08, true, (Gdk.ModifierType) 1 << 25));
ctx.filter_keypress(create_event(0xff08, true, (Gdk.ModifierType) 1 << 25));
ctx.filter_keypress(create_event(0xff08, false, Gdk.ModifierType.RELEASE_MASK | 1 << 25));
// 3 backspaces -> 6 events
ctx.filter_keypress((Gdk.EventKey) Gdk.Event.get());
ctx.filter_keypress((Gdk.EventKey) Gdk.Event.get());
ctx.filter_keypress((Gdk.EventKey) Gdk.Event.get());
ctx.filter_keypress((Gdk.EventKey) Gdk.Event.get());
ctx.filter_keypress((Gdk.EventKey) Gdk.Event.get());
ctx.filter_keypress((Gdk.EventKey) Gdk.Event.get());
assert(commit_count == 0);

// Sentinel
ctx.filter_keypress((Gdk.EventKey) Gdk.Event.get());

assert(committed_string == "ươi");
assert(commit_count == 1);
Expand All @@ -149,25 +163,30 @@ void add_foo_tests () {
ic.composition_updated("êt", 2);
return true;
};

// After this call, there should be 2 pending backspaces
// and a delayed commit text of "êt"
ctx.filter_keypress(create_event('a', true, 0));

ctx.filter_keypress((Gdk.EventKey) Gdk.Event.get());
ctx.filter_keypress((Gdk.EventKey) Gdk.Event.get());
ctx.filter_keypress((Gdk.EventKey) Gdk.Event.get());

// The last fake backspace release is not fed back yet.
// Meanwhile, another key is pressed

ic.process_key_real = () => {
// This should replace the pending êt with ết
ic.composition_updated("ết", 2);
return true;
};
ctx.filter_keypress(create_event('s', true, 0));

assert(commit_count == 0);

ctx.filter_keypress(create_event('a', true, 0));
// The 2 fake backspaces from êt are fed back
ctx.filter_keypress((Gdk.EventKey) Gdk.Event.get());
assert(commit_count == 0);

// The 2 fake backspaces from êt are fed back and triggers the delayed commit
ctx.filter_keypress(create_event(0xff08, true, (Gdk.ModifierType) 1 << 25));
ctx.filter_keypress(create_event(0xff08, false, Gdk.ModifierType.RELEASE_MASK | 1 << 25));
ctx.filter_keypress(create_event(0xff08, true, (Gdk.ModifierType) 1 << 25));
ctx.filter_keypress(create_event(0xff08, false, Gdk.ModifierType.RELEASE_MASK | 1 << 25));
// Sentinel
ctx.filter_keypress((Gdk.EventKey) Gdk.Event.get());

assert(committed_string == "ết");
assert(committed_string != "êtết");
Expand Down

0 comments on commit 96cfc68

Please sign in to comment.