Added support for custom key binding

This commit is contained in:
Scoopta 2020-02-15 21:53:02 -08:00
parent d69e4b416f
commit 459639cd7e
3 changed files with 4642 additions and 32 deletions

4545
man/wofi-keys.7 Normal file

File diff suppressed because it is too large Load Diff

View File

@ -117,6 +117,30 @@ Specifies the rate at which search results are updated in milliseconds, default
.TP
.B image_size=\fISIZE\fR
Specifies the size of images in pixels when images are enabled, default is 32.
.TP
.B key_up=\fIKEY\fR
Specifies the key to use in order to move up. Default is Up(Up arrow). See \fBwofi\-keys\fR(7) for the key codes.
.TP
.B key_down=\fIKEY\fR
Sepcifies the key to use in order to move down. Default is Down(Down arrow). See \fBwofi\-keys\fR(7) for the key codes.
.TP
.B key_left=\fIKEY\fR
Specifies the key to use in order to move left. Default is Left(Left arrow). See \fBwofi\-keys\fR(7) for the key codes.
.TP
.B key_right=\fIKEY\fR
Specifies the key to use in order to move right. Default is Right(Right arrow). See \fBwofi\-keys\fR(7) for the key codes.
.TP
.B key_forward=\fIKEY\fR
Specifies the key to use in order to move forward. Default is Tab. See \fBwofi\-keys\fR(7) for the key codes.
.TP
.B key_backward=\fIKEY\fR
Specifies the key to use in order to move backward. Default is ISO_Left_Tab(Shift+Tab). See \fBwofi\-keys\fR(7) for the key codes.
.TP
.B key_submit=\fIKEY\fR
Specifies the key to use in order to submit an action. Default is Return. See \fBwofi\-keys\fR(7) for the key codes.
.TP
.B key_exit=\fIKEY\fR
Specifies the key to use in order to exit wofi. Default is Escape. See \fBwofi\-keys\fR(7) for the key codes.
.SH CSS SELECTORS
Any GTK widget can be selected by using the name of its CSS node, these however might change with updates and are not guarenteed to stay constant. Wofi also provides certain widgets with names and classes which can be referenced from CSS to give access to the most important widgets easily. \fBwofi\fR(7) contains the current widget layout used by wofi so if you want to get into CSS directly using GTK widget names look there for info.

View File

@ -70,6 +70,7 @@ static uint16_t widget_count = 0;
static enum sort_order sort_order;
static int64_t min_height = INT64_MAX;
static uint64_t lines;
static char* key_up, *key_down, *key_left, *key_right, *key_forward, *key_backward, *key_submit, *key_exit;
static struct wl_display* wl = NULL;
static struct wl_surface* wl_surface;
@ -881,14 +882,58 @@ static gint do_sort(GtkFlowBoxChild* child1, GtkFlowBoxChild* child2, gpointer d
}
}
static void select_first(void) {
GtkFlowBoxChild* child = gtk_flow_box_get_child_at_index(GTK_FLOW_BOX(inner_box), 0);
gtk_widget_grab_focus(GTK_WIDGET(child));
gtk_flow_box_select_child(GTK_FLOW_BOX(inner_box), GTK_FLOW_BOX_CHILD(child));
}
static gboolean key_press(GtkWidget* widget, GdkEvent* event, gpointer data) {
(void) widget;
(void) data;
switch(event->key.keyval) {
case GDK_KEY_Escape:
exit(1);
break;
case GDK_KEY_Return:
gchar* name = gdk_keyval_name(event->key.keyval);
bool printable = strlen(name) == 1 && isprint(name[0]);
bool use_first = gtk_widget_has_focus(entry) || gtk_widget_has_focus(scroll);
if(gtk_widget_has_focus(entry) && printable) {
return FALSE;
}
if(event->key.keyval == gdk_keyval_from_name(key_up)) {
user_moved = true;
gtk_widget_child_focus(window, GTK_DIR_UP);
} else if(event->key.keyval == gdk_keyval_from_name(key_down)) {
user_moved = true;
if(outer_orientation == GTK_ORIENTATION_VERTICAL) {
if(use_first) {
select_first();
return TRUE;
}
}
gtk_widget_child_focus(window, GTK_DIR_DOWN);
} else if(event->key.keyval == gdk_keyval_from_name(key_left)) {
user_moved = true;
gtk_widget_child_focus(window, GTK_DIR_LEFT);
} else if(event->key.keyval == gdk_keyval_from_name(key_right)) {
user_moved = true;
if(outer_orientation == GTK_ORIENTATION_HORIZONTAL) {
if(use_first) {
select_first();
return TRUE;
}
}
gtk_widget_child_focus(window, GTK_DIR_RIGHT);
} else if(event->key.keyval == gdk_keyval_from_name(key_forward)) {
user_moved = true;
if(use_first) {
select_first();
return TRUE;
}
gtk_widget_child_focus(window, GTK_DIR_TAB_FORWARD);
} else if(event->key.keyval == gdk_keyval_from_name(key_backward)) {
user_moved = true;
gtk_widget_child_focus(window, GTK_DIR_TAB_BACKWARD);
} else if(event->key.keyval == gdk_keyval_from_name(key_submit)) {
mod_shift = (event->key.state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK;
mod_ctrl = (event->key.state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK;
if(mod_shift) {
@ -900,38 +945,26 @@ static gboolean key_press(GtkWidget* widget, GdkEvent* event, gpointer data) {
if(gtk_widget_has_focus(scroll)) {
gtk_entry_grab_focus_without_selecting(GTK_ENTRY(entry));
}
break;
case GDK_KEY_Tab:
case GDK_KEY_Down:
case GDK_KEY_Right:
if(event->key.keyval == GDK_KEY_Down && outer_orientation == GTK_ORIENTATION_HORIZONTAL) {
return FALSE;
} else if(event->key.keyval == GDK_KEY_Right && outer_orientation == GTK_ORIENTATION_VERTICAL) {
return FALSE;
GList* children = gtk_flow_box_get_selected_children(GTK_FLOW_BOX(inner_box));
if(gtk_widget_has_focus(entry)) {
g_signal_emit_by_name(entry, "activate", entry, NULL);
} else if(gtk_widget_has_focus(inner_box) || (children->data != NULL && gtk_widget_has_focus(children->data))) {
if(children->data != NULL) {
g_signal_emit_by_name(children->data, "activate", children->data, NULL);
}
user_moved = true;
if(gtk_widget_has_focus(entry) || gtk_widget_has_focus(scroll)) {
GtkFlowBoxChild* child = gtk_flow_box_get_child_at_index(GTK_FLOW_BOX(inner_box), 0);
gtk_widget_grab_focus(GTK_WIDGET(child));
gtk_flow_box_select_child(GTK_FLOW_BOX(inner_box), GTK_FLOW_BOX_CHILD(child));
return TRUE;
}
break;
case GDK_KEY_Up:
case GDK_KEY_Left:
case GDK_KEY_Shift_L:
case GDK_KEY_Shift_R:
case GDK_KEY_Control_L:
case GDK_KEY_Control_R:
case GDK_KEY_ISO_Left_Tab:
break;
default:
g_list_free(children);
} else if(event->key.keyval == gdk_keyval_from_name(key_exit)) {
exit(1);
} else if(event->key.keyval == GDK_KEY_Shift_L || event->key.keyval == GDK_KEY_Control_L) {
} else if(event->key.keyval == GDK_KEY_Shift_R || event->key.keyval == GDK_KEY_Control_R) {
} else {
if(!gtk_widget_has_focus(entry)) {
gtk_entry_grab_focus_without_selecting(GTK_ENTRY(entry));
}
break;
}
return FALSE;
}
return TRUE;
}
static gboolean focus(GtkWidget* widget, GdkEvent* event, gpointer data) {
@ -1089,6 +1122,14 @@ void wofi_init(struct map* _config) {
lines = strtol(config_get(config, "lines", "0"), NULL, 10);
columns = strtol(config_get(config, "columns", "1"), NULL, 10);
sort_order = config_get_mnemonic(config, "sort_order", "default", 2, "default", "alphabetical");
key_up = config_get(config, "key_up", "Up");
key_down = config_get(config, "key_down", "Down");
key_left = config_get(config, "key_left", "Left");
key_right = config_get(config, "key_right", "Right");
key_forward = config_get(config, "key_forward", "Tab");
key_backward = config_get(config, "key_backward", "ISO_Left_Tab");
key_submit = config_get(config, "key_submit", "Return");
key_exit = config_get(config, "key_exit", "Escape");
modes = map_init_void();
if(lines > 0) {