Thread: [Vimprobable-users] [PATCH] Ignore irrelevant modifiers in key events.
Vimprobable is a lean web browser optimised for full keyboard control
Brought to you by:
hanness
|
From: Hans-Peter D. <hpd...@gm...> - 2011-09-22 15:23:06
|
Modifiers that change the key's symbol shouldn't be considered when
comparing keys, because they can vary between different keyboard
layouts. For example, the semicolon is shifted on DE keyboards and
isn't on US keyboards, so we should just use ';' for the binding and
ignore the shift modifier in the key event handler.
NOTE: Keybindings like 'S-x' in vimprobablerc will stop working and
should now be written as simply 'X'.
---
keymap.h | 39 +++++++++++++++++++--------------------
main.c | 14 ++++++++++++--
2 files changed, 31 insertions(+), 22 deletions(-)
diff --git a/keymap.h b/keymap.h
index 4a2cece..e501794 100644
--- a/keymap.h
+++ b/keymap.h
@@ -26,9 +26,9 @@ Key keys[] = {
{ 0, GDK_q, GDK_8, quickmark, { .s = "8" } },
{ 0, GDK_q, GDK_9, quickmark, { .s = "9" } },
{ 0, 0, GDK_0, scroll, {ScrollJumpTo | DirectionLeft} },
- { GDK_SHIFT_MASK, 0, GDK_dollar, scroll, {ScrollJumpTo | DirectionRight} },
+ { 0, 0, GDK_dollar, scroll, {ScrollJumpTo | DirectionRight} },
{ 0, GDK_g, GDK_g, scroll, {ScrollJumpTo | DirectionTop} },
- { GDK_SHIFT_MASK, 0, GDK_G, scroll, {ScrollJumpTo | DirectionBottom} },
+ { 0, 0, GDK_G, scroll, {ScrollJumpTo | DirectionBottom} },
{ 0, 0, GDK_h, scroll, {ScrollMove | DirectionLeft | UnitLine} },
{ 0, 0, GDK_j, scroll, {ScrollMove | DirectionBottom | UnitLine} },
{ 0, 0, GDK_k, scroll, {ScrollMove | DirectionTop | UnitLine} },
@@ -43,7 +43,7 @@ Key keys[] = {
{ GDK_CONTROL_MASK, 0, GDK_y, scroll, {ScrollMove | DirectionTop | UnitLine} },
{ 0, GDK_g, GDK_t, fake_key_event, { .s = "l", .i = ShiftMask + ControlMask } },
- { GDK_SHIFT_MASK, GDK_g, GDK_T, fake_key_event, { .s = "h", .i = ShiftMask + ControlMask } },
+ { 0, GDK_g, GDK_T, fake_key_event, { .s = "h", .i = ShiftMask + ControlMask } },
{ 0, GDK_g, GDK_1, fake_key_event, { .s = "1", .i = ControlMask } },
{ 0, GDK_g, GDK_2, fake_key_event, { .s = "2", .i = ControlMask } },
{ 0, GDK_g, GDK_3, fake_key_event, { .s = "3", .i = ControlMask } },
@@ -57,10 +57,10 @@ Key keys[] = {
{ GDK_CONTROL_MASK, 0, GDK_i, navigate, {NavigationBack} },
{ GDK_CONTROL_MASK, 0, GDK_o, navigate, {NavigationForward} },
- { GDK_SHIFT_MASK, 0, GDK_H, navigate, {NavigationBack} },
- { GDK_SHIFT_MASK, 0, GDK_L, navigate, {NavigationForward} },
+ { 0, 0, GDK_H, navigate, {NavigationBack} },
+ { 0, 0, GDK_L, navigate, {NavigationForward} },
{ 0, 0, GDK_r, navigate, {NavigationReload} },
- { GDK_SHIFT_MASK, 0, GDK_R, navigate, {NavigationForceReload} },
+ { 0, 0, GDK_R, navigate, {NavigationForceReload} },
{ GDK_CONTROL_MASK, 0, GDK_c, navigate, {NavigationCancel} },
{ 0, 0, GDK_plus, zoom, {ZoomIn | ZoomText} },
@@ -70,37 +70,36 @@ Key keys[] = {
{ 0, GDK_z, GDK_i, zoom, {ZoomIn | ZoomText} },
{ 0, GDK_z, GDK_o, zoom, {ZoomOut | ZoomText} },
{ 0, GDK_z, GDK_z, zoom, {ZoomReset | ZoomText} },
- { GDK_SHIFT_MASK, GDK_z, GDK_I, zoom, {ZoomIn | ZoomFullContent} },
- { GDK_SHIFT_MASK, GDK_z, GDK_O, zoom, {ZoomOut | ZoomFullContent} },
- { GDK_SHIFT_MASK, GDK_z, GDK_Z, zoom, {ZoomReset | ZoomFullContent} },
+ { 0, GDK_z, GDK_I, zoom, {ZoomIn | ZoomFullContent} },
+ { 0, GDK_z, GDK_O, zoom, {ZoomOut | ZoomFullContent} },
+ { 0, GDK_z, GDK_Z, zoom, {ZoomReset | ZoomFullContent} },
{ 0, 0, GDK_y, yank, {SourceURL | ClipboardPrimary | ClipboardGTK} },
- { GDK_SHIFT_MASK, 0, GDK_Y, yank, {SourceSelection| ClipboardPrimary | ClipboardGTK} },
+ { 0, 0, GDK_Y, yank, {SourceSelection| ClipboardPrimary | ClipboardGTK} },
{ 0, GDK_g, GDK_u, descend, {NthSubdir} },
- { GDK_SHIFT_MASK, GDK_g, GDK_U, descend, {Rootdir} },
+ { 0, GDK_g, GDK_U, descend, {Rootdir} },
{ 0, GDK_g, GDK_h, open_arg, {TargetCurrent, startpage} },
- { GDK_SHIFT_MASK, GDK_g, GDK_H, open_arg, {TargetNew, startpage} },
+ { 0, GDK_g, GDK_H, open_arg, {TargetNew, startpage} },
{ 0, 0, GDK_p, paste, {TargetCurrent | ClipboardPrimary | ClipboardGTK} },
- { GDK_SHIFT_MASK, 0, GDK_P, paste, {TargetNew | ClipboardPrimary | ClipboardGTK} },
+ { 0, 0, GDK_P, paste, {TargetNew | ClipboardPrimary | ClipboardGTK} },
{ GDK_CONTROL_MASK, 0, GDK_a, number, {Increment} },
{ GDK_CONTROL_MASK, 0, GDK_x, number, {Decrement} },
{ 0, 0, GDK_n, search, {DirectionNext | CaseInsensitive | Wrapping} },
- { GDK_SHIFT_MASK, 0, GDK_N, search, {DirectionPrev | CaseInsensitive | Wrapping} },
+ { 0, 0, GDK_N, search, {DirectionPrev | CaseInsensitive | Wrapping} },
- { GDK_SHIFT_MASK, 0, GDK_colon, input, {.s = ":" } },
+ { 0, 0, GDK_colon, input, {.s = ":" } },
{ 0, 0, GDK_o, input, {.s = ":open "} },
- { GDK_SHIFT_MASK, 0, GDK_O, input, {.s = ":open ", .i = InsertCurrentURL} },
+ { 0, 0, GDK_O, input, {.s = ":open ", .i = InsertCurrentURL} },
{ 0, 0, GDK_t, input, {.s = ":tabopen "} },
- { GDK_SHIFT_MASK, 0, GDK_T, input, {.s = ":tabopen ", .i = InsertCurrentURL} },
+ { 0, 0, GDK_T, input, {.s = ":tabopen ", .i = InsertCurrentURL} },
{ 0, 0, GDK_slash, input, {.s = "/"} },
- { GDK_SHIFT_MASK, 0, GDK_slash, input, {.s = "/"} },
{ 0, 0, GDK_KP_Divide, input, {.s = "/"} },
- { GDK_SHIFT_MASK, 0, GDK_question, input, {.s = "?"} },
+ { 0, 0, GDK_question, input, {.s = "?"} },
{ 0, 0, GDK_period, input, {.s = "."} },
{ 0, 0, GDK_comma, input, {.s = ","} },
@@ -110,7 +109,7 @@ Key keys[] = {
{ GDK_CONTROL_MASK, 0, GDK_z, set, {ModePassThrough} },
{ GDK_CONTROL_MASK, 0, GDK_v, set, {ModeSendKey} },
{ 0, 0, GDK_f, input, {.s = "."} },
- { GDK_SHIFT_MASK, 0, GDK_F, input, {.s = ","} },
+ { 0, 0, GDK_F, input, {.s = ","} },
{ 0, GDK_g, GDK_i, focus_input,{} },
{ 0, 0, GDK_u, revive, {} },
diff --git a/main.c b/main.c
index 9520ca6..58a94d2 100644
--- a/main.c
+++ b/main.c
@@ -120,6 +120,7 @@ static GtkWidget *status_state;
static WebKitWebView *webview;
static SoupSession *session;
static GtkClipboard *clipboards[2];
+static GdkKeymap *keymap;
static char **args;
static unsigned int mode = ModeNormal;
@@ -329,14 +330,21 @@ download_progress(WebKitDownload *d, GParamSpec *pspec) {
gboolean
process_keypress(GdkEventKey *event) {
KeyList *current;
+ guint keyval;
+ GdkModifierType irrelevant;
+
+ /* Get a mask of modifiers that shouldn't be considered for this event.
+ * E.g.: It shouldn't matter whether ';' is shifted or not. */
+ gdk_keymap_translate_keyboard_state(keymap, event->hardware_keycode,
+ event->state, event->group, &keyval, NULL, NULL, &irrelevant);
current = keylistroot;
while (current != NULL) {
- if (current->Element.mask == CLEAN(event->state)
+ if (current->Element.mask == (CLEAN(event->state) & ~irrelevant)
&& (current->Element.modkey == current_modkey
|| (!current->Element.modkey && !current_modkey)
|| current->Element.modkey == GDK_VoidSymbol ) /* wildcard */
- && current->Element.key == event->keyval
+ && current->Element.key == keyval
&& current->Element.func)
if (current->Element.func(¤t->Element.arg)) {
current_modkey = count = 0;
@@ -2082,6 +2090,8 @@ setup_gui() {
gtk_widget_set_name(GTK_WIDGET(window), "Vimprobable2");
gtk_window_set_geometry_hints(window, NULL, &hints, GDK_HINT_MIN_SIZE);
+ keymap = gdk_keymap_get_default();
+
#ifdef DISABLE_SCROLLBAR
viewport = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(viewport), GTK_POLICY_NEVER, GTK_POLICY_NEVER);
--
1.7.3.4
|
|
From: Daniel C. <dan...@gm...> - 2011-09-22 19:54:26
|
Hi! On Thu, Sep 22, 2011 at 05:25:23PM +0200, Hans-Peter Deifel wrote: > Modifiers that change the key's symbol shouldn't be considered when > comparing keys, because they can vary between different keyboard > layouts. For example, the semicolon is shifted on DE keyboards and > isn't on US keyboards, so we should just use ';' for the binding and > ignore the shift modifier in the key event handler. This works for me, but I have also a german layout. Daniel |
|
From: Hans-Peter D. <hpd...@gm...> - 2011-10-04 23:54:15
|
Hi, On 17:25 Thu 22 Sep , Hans-Peter Deifel wrote: > NOTE: Keybindings like 'S-x' in vimprobablerc will stop working and > should now be written as simply 'X'. I think I need to elaborate on this one: Unfortunately, gdk_keymap_translate_keyboard_state doesn't allow us to strip irrelevant modifiers from the event _and_ the stored key binding. Thus, bindings with such modifiers will be considered different from their counterparts without the modifiers (and the actual events). The example in the commit message illustrates this. Note, that this renders the "Shift"-modifier almost useless for 'map'-bindings, because the only keys that don't change their symbol with shift cannot be bound with 'map'. (E.g. Space, Return, etc.) The vimprobablerc(1) man page currently has some examples using "S-something". Those need to be either removed or adapted, but I didn't want to change the man page before the move to section 5 is merged. I think we should also make it possible to bind to keys like Space or Return with 'map'. Generally map should accept a sufficiently large subset of Vim's own map-bindings. Unfortunately I don't have the time to implement this myself right now, but it should definitely stay on the To-do list. Regards, HP |
|
From: Hannes S. <ha...@yl...> - 2011-10-29 09:19:32
Attachments:
signature.asc
|
Applied |