Skip to content

Commit

Permalink
New text commiting strategy for Firefox
Browse files Browse the repository at this point in the history
  • Loading branch information
lewtds committed May 30, 2015
1 parent 7eb9866 commit ff5b98f
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 36 deletions.
151 changes: 116 additions & 35 deletions main.vala
Original file line number Diff line number Diff line change
Expand Up @@ -16,49 +16,108 @@ namespace Bogo {
}
}

public class BogoIMContext : Gtk.IMContext {
private Gdk.Window client_window;
private uint32 last_event_time;
private string prgname;
private uint pending_fake_backspaces;
private string delayed_commit_text = "";
private Bogo.InputContext input_ctx;
private string composition = "";

public BogoIMContext(string program_name, Bogo.InputContext ctx) {
debug("prgname: %s", program_name);
prgname = program_name;

input_ctx = ctx;
// This class will both commit and delete previous text by forwarding key events.
public class ForwardKeyEventIMContext : BogoIMContext {
public ForwardKeyEventIMContext(string program_name, Bogo.InputContext ctx) {
base(program_name, ctx);
input_ctx.composition_updated.connect(update_composition);
}

~BogoIMContext() {
debug("destroyed()");
}
public override bool filter_keypress(Gdk.EventKey event) {
last_event_time = event.time;

public override void set_client_window(Gdk.Window window) {
client_window = window;
if (is_fake_event(event)) {
return false;
}

if (event.type != Gdk.EventType.KEY_PRESS) {
return false;
}

debug(@"KEY_PRESS: $(event.keyval)");
bool swallowed = input_ctx.process_key(event.keyval, event.state);
return swallowed;
}

public override void focus_in() {
private void update_composition(string text, uint chars_to_delete) {
debug(@"update_composition($text, $chars_to_delete)");
delete_with_backspace(chars_to_delete);
commit_by_forwarding(text);
}

public override void focus_out() {
private void commit_by_forwarding(string text) {
unichar c;
for (int i = 0; text.get_next_char(ref i, out c);) {
uint keysym = unichar_to_keysym(c);

debug("Send fake key 0x%x".printf(keysym));

fake_key(keysym, 0);
}
}

public override void reset() {
private uint unichar_to_keysym(unichar c) {
unichar[] chars =
{'', '', '', '', '', '', '', '', '', '',
'', '', '', '', '', '', '', '', '', '',
'', '', '', '', '', '', '', '', '', '',
'', 'ế', '', '', '', '', '', '', '', '',
'', '', '', '', '', '', '', '', '', '',
'', '', '', '', '', '', '', '', '', '',
'', '', '', '', '', '', '', '', '', '',
'', '', '', '', '', '', '', '', '', '',
'', '', '', '', '', '', '', '', 'Ơ', 'ơ',
'Ư', 'ư', 'ă', 'Ă', '', '', 'Đ', 'đ', 'Ĩ', 'ĩ',
'Ũ', 'ũ'};

int[] keysyms =
{0x1001ea0, 0x1001ea1, 0x1001ea2, 0x1001ea3,
0x1001ea4, 0x1001ea5, 0x1001ea6, 0x1001ea7,
0x1001ea8, 0x1001ea9, 0x1001eaa, 0x1001eab,
0x1001eac, 0x1001ead, 0x1001eae, 0x1001eaf,
0x1001eb0, 0x1001eb1, 0x1001eb2, 0x1001eb3,
0x1001eb4, 0x1001eb5, 0x1001eb6, 0x1001eb7,
0x1001eb8, 0x1001eb9, 0x1001eba, 0x1001ebb,
0x1001ebc, 0x1001ebd, 0x1001ebe, 0x1001ebf,
0x1001ec0, 0x1001ec1, 0x1001ec2, 0x1001ec3,
0x1001ec4, 0x1001ec5, 0x1001ec6, 0x1001ec7,
0x1001ec8, 0x1001ec9, 0x1001eca, 0x1001ecb,
0x1001ecc, 0x1001ecd, 0x1001ece, 0x1001ecf,
0x1001ed0, 0x1001ed1, 0x1001ed2, 0x1001ed3,
0x1001ed4, 0x1001ed5, 0x1001ed6, 0x1001ed7,
0x1001ed8, 0x1001ed9, 0x1001eda, 0x1001edb,
0x1001edc, 0x1001edd, 0x1001ede, 0x1001edf,
0x1001ee0, 0x1001ee1, 0x1001ee2, 0x1001ee3,
0x1001ee4, 0x1001ee5, 0x1001ee6, 0x1001ee7,
0x1001ee8, 0x1001ee9, 0x1001eea, 0x1001eeb,
0x1001eec, 0x1001eed, 0x1001eee, 0x1001eef,
0x1001ef0, 0x1001ef1, 0x1001ef4, 0x1001ef5,
0x1001ef6, 0x1001ef7, 0x1001ef8, 0x1001ef9,
0x10001a0, 0x10001a1, 0x10001af, 0x10001b0,
0x01e3, 0x01c3, 0x1001ef2, 0x1001ef3,
0x01d0, 0x01f0, 0x03a5, 0x03b5,
0x03dd, 0x03fd};

for (int i = 0; i < chars.length; i++) {
if (chars[i] == c) {
return keysyms[i];
}
}

// Firefox will throws reset() when it sees our fake key so we
// will not actually reset if we're still waiting for the
// delayed commit.
// if (!has_delayed_commit()) {
// input_ctx.reset();
// }
return c;
}
}

// This class deletes previous text by sending backspaces
// but uses Gtk.IMContext.commit()
public class BackspaceRealCommitIMContext : BogoIMContext {
private string composition = "";
private string delayed_commit_text = "";

public override void set_cursor_location(Gdk.Rectangle area) {
debug("set_cursor_location()");
public BackspaceRealCommitIMContext(string program_name, Bogo.InputContext ctx) {
base(program_name, ctx);
input_ctx.composition_updated.connect(update_composition);
}

public override bool filter_keypress(Gdk.EventKey event) {
Expand Down Expand Up @@ -176,7 +235,29 @@ public class BogoIMContext : Gtk.IMContext {
}
}

private void delete_with_backspace(uint count) {
private bool has_delayed_commit() {
return delayed_commit_text != "";
}
}

public class BogoIMContext : Gtk.IMContext {
protected Gdk.Window client_window;
protected uint32 last_event_time;
protected string prgname;
protected Bogo.InputContext input_ctx;
protected uint pending_fake_backspaces;

public BogoIMContext(string program_name, Bogo.InputContext ctx) {
debug("prgname: %s", program_name);
prgname = program_name;
input_ctx = ctx;
}

~BogoIMContext() {
debug("destroyed()");
}

protected void delete_with_backspace(uint count) {
for (int i = 0; i < count; i++) {
send_backspace();
}
Expand All @@ -190,7 +271,7 @@ public class BogoIMContext : Gtk.IMContext {
fake_key(0xff08, 0);
}

private void fake_key(uint keysym, Gdk.ModifierType modifiers) {
protected void fake_key(uint keysym, Gdk.ModifierType modifiers) {
// Convert keysym to keycode
var keymap = Gdk.Keymap.get_default();
Gdk.KeymapKey[] keys;
Expand Down Expand Up @@ -232,11 +313,11 @@ public class BogoIMContext : Gtk.IMContext {
}
}

private bool has_delayed_commit() {
return delayed_commit_text != "";
protected bool is_fake_event(Gdk.EventKey e) {
return (e.state & (1 << 25)) != 0;
}

private bool is_fake_event(Gdk.EventKey e) {
return (e.state & (1 << 25)) != 0;
public override void set_client_window(Gdk.Window window) {
client_window = window;
}
}
7 changes: 6 additions & 1 deletion module.vala
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@ public Gtk.IMContext? im_module_create (string context_id) {
@"/input_context/$ctx_id");

string prgname = Environment.get_prgname();
return new BogoIMContext(prgname, input_ctx);

if (true) {
return new ForwardKeyEventIMContext(prgname, input_ctx);
} else {
return new BackspaceRealCommitIMContext(prgname, input_ctx);
}
} catch (IOError e) {
warning("Cannot connect to bogo server");
}
Expand Down

0 comments on commit ff5b98f

Please sign in to comment.