mirror of
https://github.com/davatorium/rofi.git
synced 2025-01-27 15:25:24 -05:00
First part of infrastructure for Issue: #131 customizable keybindings.
This commit is contained in:
parent
bee103aea8
commit
a70404f128
8 changed files with 148 additions and 24 deletions
|
@ -32,6 +32,7 @@ rofi_SOURCES=\
|
|||
source/history.c\
|
||||
config/config.c\
|
||||
source/helper.c\
|
||||
source/keyb.c\
|
||||
source/x11-helper.c\
|
||||
source/dialogs/dmenu.c\
|
||||
source/dialogs/run.c\
|
||||
|
@ -45,6 +46,7 @@ rofi_SOURCES=\
|
|||
include/history.h\
|
||||
include/textbox.h\
|
||||
include/helper.h\
|
||||
include/keyb.h\
|
||||
include/x11-helper.h\
|
||||
include/dialogs/run.h\
|
||||
include/dialogs/combi.h\
|
||||
|
@ -124,8 +126,12 @@ rofi_test_SOURCES=\
|
|||
textbox_test_SOURCES=\
|
||||
source/textbox.c\
|
||||
config/config.c\
|
||||
source/keyb.c\
|
||||
source/x11-helper.c\
|
||||
include/keyb.h\
|
||||
include/rofi.h\
|
||||
include/textbox.h\
|
||||
source/x11-helper.h\
|
||||
test/textbox-test.c
|
||||
|
||||
helper_test_SOURCES=\
|
||||
|
|
36
include/keyb.h
Normal file
36
include/keyb.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
#ifndef __KEYB_H__
|
||||
#define __KEYB_H__
|
||||
|
||||
typedef enum _KeyBindingAction
|
||||
{
|
||||
PASTE_PRIMARY = 0,
|
||||
PASTE_SECONDARY,
|
||||
CLEAR_LINE,
|
||||
MOVE_FRONT,
|
||||
MOVE_END,
|
||||
REMOVE_WORD_BACK,
|
||||
REMOVE_WORD_FORWARD,
|
||||
REMOVE_CHAR_FORWARD,
|
||||
NUM_ABE
|
||||
} KeyBindingAction;
|
||||
|
||||
|
||||
typedef struct _KeyBinding
|
||||
{
|
||||
unsigned int modmask;
|
||||
KeySym keysym;
|
||||
} KeyBinding;
|
||||
|
||||
typedef struct _ActionBindingEntry
|
||||
{
|
||||
const char *name;
|
||||
int num_bindings;
|
||||
KeyBinding *kb;
|
||||
} ActionBindingEntry;
|
||||
|
||||
|
||||
void setup_abe ( void );
|
||||
|
||||
extern ActionBindingEntry abe[NUM_ABE];
|
||||
int abe_test_action ( KeyBindingAction action, unsigned int mask, KeySym key );
|
||||
#endif // __KEYB_H__
|
|
@ -3,7 +3,7 @@
|
|||
#include <X11/X.h>
|
||||
#include <glib.h>
|
||||
#include <textbox.h>
|
||||
|
||||
#include "keyb.h"
|
||||
|
||||
/**
|
||||
* Pointer to xdg cache directory.
|
||||
|
|
83
source/keyb.c
Normal file
83
source/keyb.c
Normal file
|
@ -0,0 +1,83 @@
|
|||
#include "rofi.h"
|
||||
#include <X11/keysym.h>
|
||||
#include "x11-helper.h"
|
||||
|
||||
ActionBindingEntry abe[NUM_ABE];
|
||||
// Use this so we can ignore numlock mask.
|
||||
// TODO: maybe use something smarter here..
|
||||
extern unsigned int NumlockMask;
|
||||
const char *KeyBindingActionName[NUM_ABE] =
|
||||
{
|
||||
// PASTE_PRIMARY
|
||||
"primary-paste",
|
||||
// PASTE_SECONDARY
|
||||
"secondary-paste",
|
||||
// CLEAR_LINE
|
||||
"clear-line",
|
||||
// MOVE_FRONT
|
||||
"move-front",
|
||||
// MOVE_END
|
||||
"move-end",
|
||||
// REMOVE_WORD_BACK
|
||||
"remove-word-back",
|
||||
// REMOVE_WORD_FORWARD
|
||||
"remove-word-forward",
|
||||
// REMOVE_CHAR_FORWARD
|
||||
"remove-char-forward"
|
||||
};
|
||||
|
||||
const char *KeyBindingActionDefault[NUM_ABE] =
|
||||
{
|
||||
// PASTE_PRIMARY
|
||||
"Control+Shift+v,Shift+Insert",
|
||||
// PASTE_SECONDARY
|
||||
"Control+v,Insert",
|
||||
// CLEAR_LINE
|
||||
"Control+u",
|
||||
// MOVE_FRONT
|
||||
"Control+a",
|
||||
// MOVE_END
|
||||
"Control+e",
|
||||
// REMOVE_WORD_BACK
|
||||
"Control+Alt+h",
|
||||
// REMOVE_WORD_FORWARD
|
||||
"Control+Alt+d",
|
||||
// REMOVE_CHAR_FORWARD
|
||||
"Delete,Control+d",
|
||||
};
|
||||
|
||||
void setup_abe ( void )
|
||||
{
|
||||
for ( int iter = 0; iter < NUM_ABE; iter++ ) {
|
||||
char *keystr = g_strdup ( KeyBindingActionDefault[iter] );
|
||||
char *sp = NULL;
|
||||
// set pointer to name.
|
||||
abe[iter].name = KeyBindingActionName[iter];
|
||||
|
||||
// Iter over bindings.
|
||||
for ( char *entry = strtok_r ( keystr, ",", &sp ); entry != NULL; entry = strtok_r ( NULL, ",", &sp ) ) {
|
||||
abe[iter].kb = g_realloc ( abe[iter].kb, ( abe[iter].num_bindings + 1 ) * sizeof ( KeyBinding ) );
|
||||
KeyBinding *kb = &( abe[iter].kb[abe[iter].num_bindings] );
|
||||
x11_parse_key ( entry, &( kb->modmask ), &( kb->keysym ) );
|
||||
abe[iter].num_bindings++;
|
||||
}
|
||||
|
||||
g_free ( keystr );
|
||||
}
|
||||
}
|
||||
|
||||
int abe_test_action ( KeyBindingAction action, unsigned int mask, KeySym key )
|
||||
{
|
||||
ActionBindingEntry *akb = &( abe[action] );
|
||||
|
||||
for ( int iter = 0; iter < akb->num_bindings; iter++ ) {
|
||||
const KeyBinding * const kb = &( akb->kb[iter] );
|
||||
if ( kb->keysym == key ) {
|
||||
if ( ( mask & ~NumlockMask ) == kb->modmask ) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
|
@ -70,17 +70,15 @@ typedef enum _MainLoopEvent
|
|||
} MainLoopEvent;
|
||||
|
||||
// Pidfile.
|
||||
char *pidfile = NULL;
|
||||
const char *cache_dir = NULL;
|
||||
Display *display = NULL;
|
||||
char *display_str = NULL;
|
||||
|
||||
const char *netatom_names[] = { EWMH_ATOMS ( ATOM_CHAR ) };
|
||||
Atom netatoms[NUM_NETATOMS];
|
||||
char *pidfile = NULL;
|
||||
const char *cache_dir = NULL;
|
||||
Display *display = NULL;
|
||||
char *display_str = NULL;
|
||||
|
||||
extern Atom netatoms[NUM_NETATOMS];
|
||||
|
||||
// Array of switchers.
|
||||
Switcher **switchers = NULL;
|
||||
Switcher **switchers = NULL;
|
||||
// Number of switchers.
|
||||
unsigned int num_switchers = 0;
|
||||
// Current selected switcher.
|
||||
|
@ -1151,14 +1149,12 @@ MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prom
|
|||
KeySym key = XkbKeycodeToKeysym ( display, ev.xkey.keycode, 0, 0 );
|
||||
|
||||
// Handling of paste
|
||||
if ( ( ( ( ev.xkey.state & ControlMask ) == ControlMask ) && key == XK_v ) ) {
|
||||
XConvertSelection ( display, ( ev.xkey.state & ShiftMask ) ?
|
||||
XA_PRIMARY : netatoms[CLIPBOARD],
|
||||
if ( abe_test_action ( PASTE_PRIMARY, ev.xkey.state, key ) ) {
|
||||
XConvertSelection ( display, XA_PRIMARY,
|
||||
netatoms[UTF8_STRING], netatoms[UTF8_STRING], main_window, CurrentTime );
|
||||
}
|
||||
else if ( key == XK_Insert ) {
|
||||
XConvertSelection ( display, ( ev.xkey.state & ShiftMask ) ?
|
||||
XA_PRIMARY : netatoms[CLIPBOARD],
|
||||
else if ( abe_test_action ( PASTE_SECONDARY, ev.xkey.state, key ) ) {
|
||||
XConvertSelection ( display, netatoms[CLIPBOARD],
|
||||
netatoms[UTF8_STRING], netatoms[UTF8_STRING], main_window, CurrentTime );
|
||||
}
|
||||
else if ( ( ( ev.xkey.state & ShiftMask ) == ShiftMask ) && key == XK_Left ) {
|
||||
|
@ -1751,6 +1747,7 @@ int main ( int argc, char *argv[] )
|
|||
// Reload for dynamic part.
|
||||
load_configuration_dynamic ( display );
|
||||
|
||||
setup_abe ();
|
||||
// Dump.
|
||||
if ( find_arg ( "-dump-xresources" ) >= 0 ) {
|
||||
xresource_dump ();
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
#include "rofi.h"
|
||||
#include "textbox.h"
|
||||
#include "keyb.h"
|
||||
#include <glib.h>
|
||||
#define SIDE_MARGIN 1
|
||||
|
||||
|
@ -538,34 +539,31 @@ int textbox_keypress ( textbox *tb, XEvent *ev )
|
|||
}
|
||||
|
||||
// Ctrl-U: Kill from the beginning to the end of the line.
|
||||
else if ( ( ev->xkey.state & ControlMask ) && key == XK_u ) {
|
||||
else if ( abe_test_action ( CLEAR_LINE, ev->xkey.state, key ) ) {
|
||||
textbox_text ( tb, "" );
|
||||
return 1;
|
||||
}
|
||||
// Ctrl-A
|
||||
else if ( ( ev->xkey.state & ControlMask ) && key == XK_a ) {
|
||||
else if ( abe_test_action ( MOVE_FRONT, ev->xkey.state, key ) ) {
|
||||
textbox_cursor ( tb, 0 );
|
||||
return 1;
|
||||
}
|
||||
// Ctrl-E
|
||||
else if ( ( ev->xkey.state & ControlMask ) && key == XK_e ) {
|
||||
else if ( abe_test_action ( MOVE_END, ev->xkey.state, key ) ) {
|
||||
textbox_cursor_end ( tb );
|
||||
return 1;
|
||||
}
|
||||
// Ctrl-Alt-h
|
||||
else if ( ( ev->xkey.state & ControlMask ) &&
|
||||
( ev->xkey.state & Mod1Mask ) && key == XK_h ) {
|
||||
else if ( abe_test_action ( REMOVE_WORD_BACK, ev->xkey.state, key ) ) {
|
||||
textbox_cursor_bkspc_word ( tb );
|
||||
return 1;
|
||||
}
|
||||
// Ctrl-Alt-d
|
||||
else if ( ( ev->xkey.state & ControlMask ) &&
|
||||
( ev->xkey.state & Mod1Mask ) && key == XK_d ) {
|
||||
else if ( abe_test_action ( REMOVE_WORD_FORWARD, ev->xkey.state, key ) ) {
|
||||
textbox_cursor_del_word ( tb );
|
||||
return 1;
|
||||
} // Delete or Ctrl-D
|
||||
else if ( key == XK_Delete ||
|
||||
( ( ev->xkey.state & ControlMask ) && key == XK_d ) ) {
|
||||
else if ( abe_test_action ( REMOVE_CHAR_FORWARD, ev->xkey.state, key ) ) {
|
||||
textbox_cursor_del ( tb );
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -48,6 +48,8 @@
|
|||
#define INTERSECT( x, y, w, h, x1, y1, w1, h1 ) ( OVERLAP ( ( x ), ( w ), ( x1 ), ( w1 ) ) && OVERLAP ( ( y ), ( h ), ( y1 ), ( h1 ) ) )
|
||||
#include "x11-helper.h"
|
||||
|
||||
Atom netatoms[NUM_NETATOMS];
|
||||
const char *netatom_names[] = { EWMH_ATOMS ( ATOM_CHAR ) };
|
||||
// Mask indicating num-lock.
|
||||
unsigned int NumlockMask = 0;
|
||||
|
||||
|
|
|
@ -62,6 +62,8 @@ int main ( G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv )
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
create_visual_and_colormap();
|
||||
|
||||
setup_abe();
|
||||
TASSERT( display != NULL );
|
||||
XSetWindowAttributes attr;
|
||||
attr.colormap = map;
|
||||
|
|
Loading…
Add table
Reference in a new issue