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},
{"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
{
char* identifier;
int key;
} GDKKey;
typedef struct
{
PopplerPage *page;
@ -2820,14 +2826,22 @@ cmd_map(int argc, char** argv)
/* parse modifier and key */
int mask = 0;
int key = 0;
int keyl = strlen(ks);
int mode = NORMAL;
// single key (e.g.: g)
if(strlen(ks) == 1)
if(keyl == 1)
key = ks[0];
// 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] == '>')
{
char* specialkey = NULL;
/* check for modifier */
if(keyl >= 5 && ks[2] == '-')
{
/* evaluate modifier */
switch(ks[1])
@ -2840,15 +2854,41 @@ cmd_map(int argc, char** argv)
break;
}
/* get key */
key = ks[3];
/* 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;
}
}
if(specialkey)
g_free(specialkey);
}
if(!key)
{
notify(WARNING, "No valid key binding given.");
return FALSE;
}
/* 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 */
ShortcutList* sc = Zathura.Bindings.sclist;
while(sc && sc->next != NULL)
@ -3836,9 +3870,11 @@ cb_view_kb_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
ShortcutList* sc = Zathura.Bindings.sclist;
while(sc)
{
if (event->keyval == sc->element.key &&
(((event->state & sc->element.mask) == sc->element.mask) || sc->element.mask == 0)
&& (Zathura.Global.mode == sc->element.mode || sc->element.mode == -1))
if( event->state == sc->element.mask
&& event->keyval == sc->element.key
&& (Zathura.Global.mode == sc->element.mode || sc->element.mode == -1)
&& sc->element.function
)
{
sc->element.function(&(sc->element.argument));
return TRUE;