Bindings for special keys

This commit makes it possible to define and use special keys
like <Space> on their own or in combination with a modifier:
<C-<Space>>.

In addition the evaluation of the keypress has been changed, so
that the order of the bindings do not matter any longer.
This commit is contained in:
Moritz Lipp 2010-06-18 12:58:20 +02:00
parent 5677083579
commit 0c0050b111
2 changed files with 91 additions and 26 deletions

View File

@ -286,3 +286,32 @@ ModeName mode_names[] = {
{"normal", NORMAL}, {"normal", NORMAL},
{"visual", VISUAL}, {"visual", VISUAL},
}; };
/* special keys */
GDKKey gdk_keys[] = {
{"<BackSpace>", GDK_BackSpace},
{"<CapsLock>", GDK_Caps_Lock},
{"<Down>", GDK_Down},
{"<Esc>", GDK_Escape},
{"<F10>", GDK_F10},
{"<F11>", GDK_F11},
{"<F12>", GDK_F12},
{"<F1>", GDK_F1},
{"<F2>", GDK_F2},
{"<F3>", GDK_F3},
{"<F4>", GDK_F4},
{"<F5>", GDK_F5},
{"<F6>", GDK_F6},
{"<F7>", GDK_F7},
{"<F8>", GDK_F8},
{"<F9>", GDK_F9},
{"<Left>", GDK_Left},
{"<PageDown>", GDK_Page_Down},
{"<PageUp>", GDK_Page_Up},
{"<Return>", GDK_Return},
{"<Right>", GDK_Right},
{"<Space>", GDK_space},
{"<Super>", GDK_Super_L},
{"<Tab>", GDK_Tab},
{"<Up>", GDK_Up},
};

View File

@ -143,6 +143,12 @@ struct SCList
typedef struct SCList ShortcutList; typedef struct SCList ShortcutList;
typedef struct
{
char* identifier;
int key;
} GDKKey;
typedef struct typedef struct
{ {
PopplerPage *page; PopplerPage *page;
@ -2820,35 +2826,69 @@ cmd_map(int argc, char** argv)
/* parse modifier and key */ /* parse modifier and key */
int mask = 0; int mask = 0;
int key = 0; int key = 0;
int keyl = strlen(ks);
int mode = NORMAL; int mode = NORMAL;
// single key (e.g.: g) // single key (e.g.: g)
if(strlen(ks) == 1) if(keyl == 1)
key = ks[0]; key = ks[0];
// modifier and key (e.g.: <S-g> // modifier and key (e.g.: <S-g>
if(strlen(ks) == 5 && ks[0] == '<' && ks[2] == '-' && ks[4] == '>') // special key or modifier and key/special key (e.g.: <S-g>, <Space>)
else if(keyl >= 3 && ks[0] == '<' && ks[keyl-1] == '>')
{ {
/* evaluate modifier */ char* specialkey = NULL;
switch(ks[1])
/* check for modifier */
if(keyl >= 5 && ks[2] == '-')
{ {
case 'S': /* evaluate modifier */
mask = GDK_SHIFT_MASK; switch(ks[1])
break; {
case 'C': case 'S':
mask = GDK_CONTROL_MASK; mask = GDK_SHIFT_MASK;
break;
case 'C':
mask = GDK_CONTROL_MASK;
break;
}
/* no valid modifier */
if(!mask)
{
notify(WARNING, "No valid modifier given.");
return FALSE;
}
/* modifier and special key */
if(keyl > 5)
specialkey = g_strndup(ks + 3, keyl - 4);
else
key = ks[3];
}
else
specialkey = ks;
/* search special key */
int g_c;
for(g_c = 0; specialkey && g_c < LENGTH(gdk_keys); g_c++)
{
if(!strcmp(specialkey, gdk_keys[g_c].identifier))
{
key = gdk_keys[g_c].key;
break; break;
}
} }
/* get key */ if(specialkey)
key = ks[3]; g_free(specialkey);
}
/* no valid modifier */ if(!key)
if(!mask) {
{ notify(WARNING, "No valid key binding given.");
notify(WARNING, "No valid modifier given."); return FALSE;
return FALSE;
}
} }
/* parse argument */ /* parse argument */
@ -2890,12 +2930,6 @@ cmd_map(int argc, char** argv)
} }
} }
if(!key)
{
notify(WARNING, "No valid key binding given.");
return FALSE;
}
/* search for existing binding to overwrite it */ /* search for existing binding to overwrite it */
ShortcutList* sc = Zathura.Bindings.sclist; ShortcutList* sc = Zathura.Bindings.sclist;
while(sc && sc->next != NULL) while(sc && sc->next != NULL)
@ -3836,9 +3870,11 @@ cb_view_kb_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
ShortcutList* sc = Zathura.Bindings.sclist; ShortcutList* sc = Zathura.Bindings.sclist;
while(sc) while(sc)
{ {
if (event->keyval == sc->element.key && if( event->state == sc->element.mask
(((event->state & sc->element.mask) == sc->element.mask) || sc->element.mask == 0) && event->keyval == sc->element.key
&& (Zathura.Global.mode == sc->element.mode || sc->element.mode == -1)) && (Zathura.Global.mode == sc->element.mode || sc->element.mode == -1)
&& sc->element.function
)
{ {
sc->element.function(&(sc->element.argument)); sc->element.function(&(sc->element.argument));
return TRUE; return TRUE;