summaryrefslogtreecommitdiff
path: root/libcaribou
diff options
context:
space:
mode:
authorEitan Isaacson <eitan@monotonous.org>2011-07-06 14:44:39 -0500
committerEitan Isaacson <eitan@monotonous.org>2011-07-18 10:07:40 -0700
commit148a3d8a064a211a8ef0e332cbf21e8612106787 (patch)
tree531c43caa1924efe01d8e5691b719328b20c10e0 /libcaribou
parent0e2226cb0c0b7434a57f1357489af11e365beb13 (diff)
downloadcaribou-148a3d8a064a211a8ef0e332cbf21e8612106787.tar.gz
Add Ctrl/Alt functionality
Based on a patch by Nohemi Fernandez <nf68@cornell.edu>.
Diffstat (limited to 'libcaribou')
-rw-r--r--libcaribou/column-model.vala4
-rw-r--r--libcaribou/external-libs.vapi9
-rw-r--r--libcaribou/group-model.vala6
-rw-r--r--libcaribou/ikeyboard-object.vala6
-rw-r--r--libcaribou/key-model.vala90
-rw-r--r--libcaribou/keyboard-model.vala31
-rw-r--r--libcaribou/level-model.vala8
-rw-r--r--libcaribou/row-model.vala5
-rw-r--r--libcaribou/xadapter.vala10
9 files changed, 139 insertions, 30 deletions
diff --git a/libcaribou/column-model.vala b/libcaribou/column-model.vala
index b1db3cb..f127a10 100644
--- a/libcaribou/column-model.vala
+++ b/libcaribou/column-model.vala
@@ -10,7 +10,9 @@ namespace Caribou {
}
internal void add_key (KeyModel key) {
- key.key_activated.connect ((k) => { key_activated (k); });
+ key.key_clicked.connect ((k) => { key_clicked (k); });
+ key.key_pressed.connect ((k) => { key_pressed (k); });
+ key.key_released.connect ((k) => { key_released (k); });
keys.add (key);
}
diff --git a/libcaribou/external-libs.vapi b/libcaribou/external-libs.vapi
index bab3978..078126e 100644
--- a/libcaribou/external-libs.vapi
+++ b/libcaribou/external-libs.vapi
@@ -38,6 +38,11 @@ namespace Xkb {
public void latch_modifiers (X.Display dpy, uint device_spec, uint affect,
uint values);
+ [CCode (cname = "XkbLockModifiers")]
+ public void lock_modifiers (X.Display dpy, uint device_spec, uint affect,
+ uint values);
+
+
[Compact]
[CCode (cname = "XkbAnyEvent", free_function = "")]
public struct AnyEvent {
@@ -86,7 +91,7 @@ namespace Xkb {
public ushort flags;
public ushort device_spec;
public char min_key_code;
- public char max_key_code;
+ public char max_key_code;
public Controls ctrls;
public ServerMap server;
public ClientMap map;
@@ -231,4 +236,4 @@ namespace Xkb {
[CCode (cname = "XkbAllMapComponentsMask")]
public int AllMapComponentsMask;
-} \ No newline at end of file
+}
diff --git a/libcaribou/group-model.vala b/libcaribou/group-model.vala
index 6b578d4..479ed52 100644
--- a/libcaribou/group-model.vala
+++ b/libcaribou/group-model.vala
@@ -26,7 +26,9 @@ namespace Caribou {
internal void add_level (string lname, LevelModel level) {
levels.set (lname, level);
level.level_toggled.connect (on_level_toggled);
- level.key_activated.connect ((k) => { key_activated (k); });
+ level.key_clicked.connect ((k) => { key_clicked (k); });
+ level.key_pressed.connect ((k) => { key_pressed (k); });
+ level.key_released.connect ((k) => { key_released (k); });
if (level.mode == "default") {
default_level = lname;
active_level = lname;
@@ -53,4 +55,4 @@ namespace Caribou {
}
}
-} \ No newline at end of file
+}
diff --git a/libcaribou/ikeyboard-object.vala b/libcaribou/ikeyboard-object.vala
index f227492..ce865d0 100644
--- a/libcaribou/ikeyboard-object.vala
+++ b/libcaribou/ikeyboard-object.vala
@@ -2,7 +2,9 @@ namespace Caribou {
public interface IKeyboardObject : Object {
public abstract IKeyboardObject[] get_children ();
- public signal void key_activated (KeyModel key);
+ public signal void key_clicked (KeyModel key);
+ public signal void key_pressed (KeyModel key);
+ public signal void key_released (KeyModel key);
public virtual KeyModel[] get_keys () {
Gee.ArrayList<KeyModel> keys = new Gee.ArrayList<KeyModel> ();
@@ -15,4 +17,4 @@ namespace Caribou {
return (KeyModel[]) keys.to_array ();
}
}
-} \ No newline at end of file
+}
diff --git a/libcaribou/key-model.vala b/libcaribou/key-model.vala
index 7153bc6..9525ecb 100644
--- a/libcaribou/key-model.vala
+++ b/libcaribou/key-model.vala
@@ -6,6 +6,17 @@ namespace Caribou {
public double width { get; set; default = 1.0; }
public string toggle { get; set; default = ""; }
+ private Gdk.ModifierType mod_mask;
+ public bool is_modifier {
+ get {
+ return (mod_mask != 0);
+ }
+
+ set {}
+ }
+
+ public ModifierState modifier_state;
+
public bool show_subkeys { get; private set; default = false; }
public string name { get; private set; }
public uint keyval { get; private set; }
@@ -28,43 +39,79 @@ namespace Caribou {
private XAdapter xadapter;
private Gee.ArrayList<KeyModel> extended_keys;
- public signal void key_pressed ();
- public signal void key_released ();
public signal void key_hold_end ();
public signal void key_hold ();
+ private const ModifierMapEntry mod_map[] = {
+ { "Control_L", Gdk.ModifierType.CONTROL_MASK },
+ { "Alt_L", Gdk.ModifierType.MOD1_MASK },
+ { null, 0 }
+ };
+
public KeyModel (string name) {
this.name = name;
+ mod_mask = (Gdk.ModifierType) 0;
+
+ int i = 0;
+ for (ModifierMapEntry entry=mod_map[i];
+ entry.name != null;
+ entry=mod_map[++i]) {
+ if (name == entry.name)
+ mod_mask = entry.mask;
+ }
+
+ if (mod_mask == 0)
+ keyval = Gdk.keyval_from_name (name);
+
xadapter = XAdapter.get_default();
- keyval = Gdk.keyval_from_name (name);
extended_keys = new Gee.ArrayList<KeyModel> ();
}
internal void add_subkey (KeyModel key) {
- key.key_activated.connect(on_subkey_activated);
+ key.key_clicked.connect(on_subkey_clicked);
extended_keys.add (key);
}
- private void on_subkey_activated (KeyModel key) {
- key_activated (key);
+ private void on_subkey_clicked (KeyModel key) {
+ key_clicked (key);
show_subkeys = false;
}
public void press () {
+ if (is_modifier) {
+ if (modifier_state == ModifierState.NONE) {
+ modifier_state = ModifierState.LATCHED;
+ xadapter.mod_lock(mod_mask);
+ } else {
+ modifier_state = ModifierState.NONE;
+ }
+ }
hold_tid = GLib.Timeout.add(1000, on_key_held);
- key_pressed();
+ key_pressed(this);
}
public void release () {
- key_released();
- if (hold_tid != 0) {
+ if (hold_tid != 0)
GLib.Source.remove (hold_tid);
- hold_tid = 0;
- key_activated (this);
- if (keyval != 0) {
- xadapter.keyval_press(keyval);
- xadapter.keyval_release(keyval);
+
+ if (is_modifier) {
+ if (modifier_state == ModifierState.NONE) {
+ xadapter.mod_unlock(mod_mask);
+ } else {
+ return;
}
+ }
+
+ if (keyval != 0) {
+ xadapter.keyval_press(keyval);
+ xadapter.keyval_release(keyval);
+ }
+
+ key_released(this);
+
+ if (hold_tid != 0) {
+ key_clicked (this);
+ hold_tid = 0;
} else {
key_hold_end ();
}
@@ -74,6 +121,8 @@ namespace Caribou {
hold_tid = 0;
if (extended_keys.size != 0)
show_subkeys = true;
+ if (is_modifier && modifier_state == ModifierState.LATCHED)
+ modifier_state = ModifierState.LOCKED;
key_hold ();
return false;
}
@@ -98,4 +147,15 @@ namespace Caribou {
GLib.Timeout.add(200, () => { release (); return false; });
}
}
-} \ No newline at end of file
+
+ public enum ModifierState {
+ NONE,
+ LATCHED,
+ LOCKED
+ }
+
+ private struct ModifierMapEntry {
+ string name;
+ Gdk.ModifierType mask;
+ }
+}
diff --git a/libcaribou/keyboard-model.vala b/libcaribou/keyboard-model.vala
index 0b7bea0..ef31235 100644
--- a/libcaribou/keyboard-model.vala
+++ b/libcaribou/keyboard-model.vala
@@ -8,6 +8,7 @@ namespace Caribou {
private XAdapter xadapter;
private Gee.HashMap<string, GroupModel> groups;
private KeyModel last_activated_key;
+ private Gee.HashSet<KeyModel> active_mod_keys;
construct {
uint grpid;
@@ -29,6 +30,8 @@ namespace Caribou {
grpid = xadapter.get_current_group (out group, out variant);
on_group_changed (grpid, group, variant);
+
+ active_mod_keys = new Gee.HashSet<KeyModel> ();
}
private void populate_group (string group, string variant) {
@@ -36,17 +39,37 @@ namespace Caribou {
group, variant);
if (grp != null) {
groups.set (GroupModel.create_group_name (group, variant), grp);
- grp.key_activated.connect (on_key_activated);
+ grp.key_clicked.connect (on_key_clicked);
+ grp.key_pressed.connect (on_key_pressed);
+ grp.key_released.connect (on_key_released);
}
}
- private void on_key_activated (KeyModel key) {
+ private void on_key_clicked (KeyModel key) {
if (key.name == "Caribou_Repeat")
last_activated_key.activate ();
else
last_activated_key = key;
- key_activated (key);
+ key_clicked (key);
+ }
+
+ private void on_key_pressed (KeyModel key) {
+ if (key.is_modifier && key.modifier_state == ModifierState.LATCHED) {
+ active_mod_keys.add(key);
+ }
+ }
+
+ private void on_key_released (KeyModel key) {
+ if (!key.is_modifier) {
+ KeyModel[] modifiers = (KeyModel[]) active_mod_keys.to_array ();
+ foreach (KeyModel modifier in modifiers) {
+ if (modifier.modifier_state == ModifierState.LATCHED) {
+ modifier.modifier_state = ModifierState.NONE;
+ modifier.release ();
+ }
+ }
+ }
}
public string[] get_groups () {
@@ -70,4 +93,4 @@ namespace Caribou {
return (IKeyboardObject[]) groups.values.to_array ();
}
}
-} \ No newline at end of file
+}
diff --git a/libcaribou/level-model.vala b/libcaribou/level-model.vala
index 981a3c0..6c526b9 100644
--- a/libcaribou/level-model.vala
+++ b/libcaribou/level-model.vala
@@ -13,7 +13,9 @@ namespace Caribou {
}
internal void add_row (RowModel row) {
- row.key_activated.connect (on_key_activated);
+ row.key_clicked.connect (on_key_clicked);
+ row.key_pressed.connect ((k) => { key_pressed (k); });
+ row.key_released.connect ((k) => { key_released (k); });
rows.add(row);
}
@@ -21,12 +23,12 @@ namespace Caribou {
return (RowModel[]) rows.to_array ();
}
- private void on_key_activated (KeyModel key) {
+ private void on_key_clicked (KeyModel key) {
if (key.toggle != "")
level_toggled (key.toggle);
else if (mode == "latched")
level_toggled ("default");
- key_activated (key);
+ key_clicked (key);
}
public override IScannableItem[] get_scan_children () {
diff --git a/libcaribou/row-model.vala b/libcaribou/row-model.vala
index fcc4713..e74d887 100644
--- a/libcaribou/row-model.vala
+++ b/libcaribou/row-model.vala
@@ -10,7 +10,10 @@ namespace Caribou {
}
internal void add_column (ColumnModel column) {
- column.key_activated.connect ((k) => { key_activated (k); });
+ column.key_clicked.connect ((k) => { key_clicked (k); });
+ column.key_pressed.connect ((k) => { key_pressed (k); });
+ column.key_released.connect ((k) => { key_released (k); });
+
columns.add(column);
}
diff --git a/libcaribou/xadapter.vala b/libcaribou/xadapter.vala
index 8b6b196..7c725b0 100644
--- a/libcaribou/xadapter.vala
+++ b/libcaribou/xadapter.vala
@@ -226,6 +226,16 @@ namespace Caribou {
this.xdisplay.flush ();
}
+ public void mod_lock (uint mask) {
+ Xkb.lock_modifiers (this.xdisplay, Xkb.UseCoreKbd, mask, mask);
+ this.xdisplay.flush ();
+ }
+
+ public void mod_unlock (uint mask) {
+ Xkb.lock_modifiers (this.xdisplay, Xkb.UseCoreKbd, mask, 0);
+ this.xdisplay.flush();
+ }
+
public void mod_latch (uint mask) {
Xkb.latch_modifiers (this.xdisplay, Xkb.UseCoreKbd, mask, mask);
this.xdisplay.flush ();