rofi 1.7.5
keyb.c
Go to the documentation of this file.
1/*
2 * rofi
3 *
4 * MIT/X11 License
5 * Copyright © 2013-2022 Qball Cow <qball@gmpclient.org>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 */
27
28#include <glib.h>
29#include "nkutils-bindings.h"
30#include "rofi.h"
31#include "xrmoptions.h"
32#include <string.h>
33
34typedef struct {
35 guint id;
36 guint scope;
37 char *name;
38 char *binding;
39 char *comment;
41
46 {.id = PASTE_PRIMARY,
47 .name = "kb-primary-paste",
48 .binding = "Control+V,Shift+Insert",
49 .comment = "Paste primary selection"},
50 {.id = PASTE_SECONDARY,
51 .name = "kb-secondary-paste",
52 .binding = "Control+v,Insert",
53 .comment = "Paste clipboard"},
54 {.id = CLEAR_LINE,
55 .name = "kb-clear-line",
56 .binding = "Control+w",
57 .comment = "Clear input line"},
58 {.id = MOVE_FRONT,
59 .name = "kb-move-front",
60 .binding = "Control+a",
61 .comment = "Beginning of line"},
62 {.id = MOVE_END,
63 .name = "kb-move-end",
64 .binding = "Control+e",
65 .comment = "End of line"},
66 {.id = MOVE_WORD_BACK,
67 .name = "kb-move-word-back",
68 .binding = "Alt+b,Control+Left",
69 .comment = "Move back one word"},
70 {.id = MOVE_WORD_FORWARD,
71 .name = "kb-move-word-forward",
72 .binding = "Alt+f,Control+Right",
73 .comment = "Move forward one word"},
74 {.id = MOVE_CHAR_BACK,
75 .name = "kb-move-char-back",
76 .binding = "Left,Control+b",
77 .comment = "Move back one char"},
78 {.id = MOVE_CHAR_FORWARD,
79 .name = "kb-move-char-forward",
80 .binding = "Right,Control+f",
81 .comment = "Move forward one char"},
82 {.id = REMOVE_WORD_BACK,
83 .name = "kb-remove-word-back",
84 .binding = "Control+Alt+h,Control+BackSpace",
85 .comment = "Delete previous word"},
87 .name = "kb-remove-word-forward",
88 .binding = "Control+Alt+d",
89 .comment = "Delete next word"},
91 .name = "kb-remove-char-forward",
92 .binding = "Delete,Control+d",
93 .comment = "Delete next char"},
94 {.id = REMOVE_CHAR_BACK,
95 .name = "kb-remove-char-back",
96 .binding = "BackSpace,Shift+BackSpace,Control+h",
97 .comment = "Delete previous char"},
98 {.id = REMOVE_TO_EOL,
99 .name = "kb-remove-to-eol",
100 .binding = "Control+k",
101 .comment = "Delete till the end of line"},
102 {.id = REMOVE_TO_SOL,
103 .name = "kb-remove-to-sol",
104 .binding = "Control+u",
105 .comment = "Delete till the start of line"},
106 {.id = ACCEPT_ENTRY,
107 .name = "kb-accept-entry",
108 .binding = "Control+j,Control+m,Return,KP_Enter",
109 .comment = "Accept entry"},
110 {.id = ACCEPT_CUSTOM,
111 .name = "kb-accept-custom",
112 .binding = "Control+Return",
113 .comment = "Use entered text as command (in ssh/run modes)"},
114 {.id = ACCEPT_CUSTOM_ALT,
115 .name = "kb-accept-custom-alt",
116 .binding = "Control+Shift+Return",
117 .comment = "Use entered text as command (in ssh/run modes)"},
118 {.id = ACCEPT_ALT,
119 .name = "kb-accept-alt",
120 .binding = "Shift+Return",
121 .comment = "Use alternate accept command."},
122 {.id = DELETE_ENTRY,
123 .name = "kb-delete-entry",
124 .binding = "Shift+Delete",
125 .comment = "Delete entry from history"},
126 {.id = MODE_NEXT,
127 .name = "kb-mode-next",
128 .binding = "Shift+Right,Control+Tab",
129 .comment = "Switch to the next mode."},
130 {.id = MODE_PREVIOUS,
131 .name = "kb-mode-previous",
132 .binding = "Shift+Left,Control+ISO_Left_Tab",
133 .comment = "Switch to the previous mode."},
134 {.id = MODE_COMPLETE,
135 .name = "kb-mode-complete",
136 .binding = "Control+l",
137 .comment = "Start completion for mode."},
138 {.id = ROW_LEFT,
139 .name = "kb-row-left",
140 .binding = "Control+Page_Up",
141 .comment = "Go to the previous column"},
142 {.id = ROW_RIGHT,
143 .name = "kb-row-right",
144 .binding = "Control+Page_Down",
145 .comment = "Go to the next column"},
146 {.id = ROW_UP,
147 .name = "kb-row-up",
148 .binding = "Up,Control+p",
149 .comment = "Select previous entry"},
150 {.id = ROW_DOWN,
151 .name = "kb-row-down",
152 .binding = "Down,Control+n",
153 .comment = "Select next entry"},
154 {.id = ROW_TAB,
155 .name = "kb-row-tab",
156 .binding = "",
157 .comment =
158 "Go to next row, if one left, accept it, if no left next mode."},
159 {.id = ELEMENT_NEXT,
160 .name = "kb-element-next",
161 .binding = "Tab",
162 .comment = "Go to next element (in logical order)."},
163 {.id = ELEMENT_PREV,
164 .name = "kb-element-prev",
165 .binding = "ISO_Left_Tab",
166 .comment = "Go to next previous element (in logical order)."},
167 {.id = PAGE_PREV,
168 .name = "kb-page-prev",
169 .binding = "Page_Up",
170 .comment = "Go to the previous page"},
171 {.id = PAGE_NEXT,
172 .name = "kb-page-next",
173 .binding = "Page_Down",
174 .comment = "Go to the next page"},
175 {.id = ROW_FIRST,
176 .name = "kb-row-first",
177 .binding = "Home,KP_Home",
178 .comment = "Go to the first entry"},
179 {.id = ROW_LAST,
180 .name = "kb-row-last",
181 .binding = "End,KP_End",
182 .comment = "Go to the last entry"},
183 {.id = ROW_SELECT,
184 .name = "kb-row-select",
185 .binding = "Control+space",
186 .comment = "Set selected item as input text"},
187 {.id = SCREENSHOT,
188 .name = "kb-screenshot",
189 .binding = "Alt+S",
190 .comment = "Take a screenshot of the rofi window"},
191 {.id = CHANGE_ELLIPSIZE,
192 .name = "kb-ellipsize",
193 .binding = "Alt+period",
194 .comment = "Toggle between ellipsize modes for displayed data"},
196 .name = "kb-toggle-case-sensitivity",
197 .binding = "grave,dead_grave",
198 .comment = "Toggle case sensitivity"},
199 {.id = TOGGLE_SORT,
200 .name = "kb-toggle-sort",
201 .binding = "Alt+grave",
202 .comment = "Toggle sort"},
203 {.id = CANCEL,
204 .name = "kb-cancel",
205 .binding = "Escape,Control+g,Control+bracketleft",
206 .comment = "Quit rofi"},
207 {.id = CUSTOM_1,
208 .name = "kb-custom-1",
209 .binding = "Alt+1",
210 .comment = "Custom keybinding 1"},
211 {.id = CUSTOM_2,
212 .name = "kb-custom-2",
213 .binding = "Alt+2",
214 .comment = "Custom keybinding 2"},
215 {.id = CUSTOM_3,
216 .name = "kb-custom-3",
217 .binding = "Alt+3",
218 .comment = "Custom keybinding 3"},
219 {.id = CUSTOM_4,
220 .name = "kb-custom-4",
221 .binding = "Alt+4",
222 .comment = "Custom keybinding 4"},
223 {.id = CUSTOM_5,
224 .name = "kb-custom-5",
225 .binding = "Alt+5",
226 .comment = "Custom Keybinding 5"},
227 {.id = CUSTOM_6,
228 .name = "kb-custom-6",
229 .binding = "Alt+6",
230 .comment = "Custom keybinding 6"},
231 {.id = CUSTOM_7,
232 .name = "kb-custom-7",
233 .binding = "Alt+7",
234 .comment = "Custom Keybinding 7"},
235 {.id = CUSTOM_8,
236 .name = "kb-custom-8",
237 .binding = "Alt+8",
238 .comment = "Custom keybinding 8"},
239 {.id = CUSTOM_9,
240 .name = "kb-custom-9",
241 .binding = "Alt+9",
242 .comment = "Custom keybinding 9"},
243 {.id = CUSTOM_10,
244 .name = "kb-custom-10",
245 .binding = "Alt+0",
246 .comment = "Custom keybinding 10"},
247 {.id = CUSTOM_11,
248 .name = "kb-custom-11",
249 .binding = "Alt+exclam",
250 .comment = "Custom keybinding 11"},
251 {.id = CUSTOM_12,
252 .name = "kb-custom-12",
253 .binding = "Alt+at",
254 .comment = "Custom keybinding 12"},
255 {.id = CUSTOM_13,
256 .name = "kb-custom-13",
257 .binding = "Alt+numbersign",
258 .comment = "Custom keybinding 13"},
259 {.id = CUSTOM_14,
260 .name = "kb-custom-14",
261 .binding = "Alt+dollar",
262 .comment = "Custom keybinding 14"},
263 {.id = CUSTOM_15,
264 .name = "kb-custom-15",
265 .binding = "Alt+percent",
266 .comment = "Custom keybinding 15"},
267 {.id = CUSTOM_16,
268 .name = "kb-custom-16",
269 .binding = "Alt+dead_circumflex",
270 .comment = "Custom keybinding 16"},
271 {.id = CUSTOM_17,
272 .name = "kb-custom-17",
273 .binding = "Alt+ampersand",
274 .comment = "Custom keybinding 17"},
275 {.id = CUSTOM_18,
276 .name = "kb-custom-18",
277 .binding = "Alt+asterisk",
278 .comment = "Custom keybinding 18"},
279 {.id = CUSTOM_19,
280 .name = "kb-custom-19",
281 .binding = "Alt+parenleft",
282 .comment = "Custom Keybinding 19"},
283 {.id = SELECT_ELEMENT_1,
284 .name = "kb-select-1",
285 .binding = "Super+1",
286 .comment = "Select row 1"},
287 {.id = SELECT_ELEMENT_2,
288 .name = "kb-select-2",
289 .binding = "Super+2",
290 .comment = "Select row 2"},
291 {.id = SELECT_ELEMENT_3,
292 .name = "kb-select-3",
293 .binding = "Super+3",
294 .comment = "Select row 3"},
295 {.id = SELECT_ELEMENT_4,
296 .name = "kb-select-4",
297 .binding = "Super+4",
298 .comment = "Select row 4"},
299 {.id = SELECT_ELEMENT_5,
300 .name = "kb-select-5",
301 .binding = "Super+5",
302 .comment = "Select row 5"},
303 {.id = SELECT_ELEMENT_6,
304 .name = "kb-select-6",
305 .binding = "Super+6",
306 .comment = "Select row 6"},
307 {.id = SELECT_ELEMENT_7,
308 .name = "kb-select-7",
309 .binding = "Super+7",
310 .comment = "Select row 7"},
311 {.id = SELECT_ELEMENT_8,
312 .name = "kb-select-8",
313 .binding = "Super+8",
314 .comment = "Select row 8"},
315 {.id = SELECT_ELEMENT_9,
316 .name = "kb-select-9",
317 .binding = "Super+9",
318 .comment = "Select row 9"},
319 {.id = SELECT_ELEMENT_10,
320 .name = "kb-select-10",
321 .binding = "Super+0",
322 .comment = "Select row 10"},
323
324 /* Mouse-aware bindings */
325
326 {.id = SCROLL_LEFT,
327 .scope = SCOPE_MOUSE_LISTVIEW,
328 .name = "ml-row-left",
329 .binding = "ScrollLeft",
330 .comment = "Go to the previous column"},
331 {.id = SCROLL_RIGHT,
332 .scope = SCOPE_MOUSE_LISTVIEW,
333 .name = "ml-row-right",
334 .binding = "ScrollRight",
335 .comment = "Go to the next column"},
336 {.id = SCROLL_UP,
337 .scope = SCOPE_MOUSE_LISTVIEW,
338 .name = "ml-row-up",
339 .binding = "ScrollUp",
340 .comment = "Select previous entry"},
341 {.id = SCROLL_DOWN,
342 .scope = SCOPE_MOUSE_LISTVIEW,
343 .name = "ml-row-down",
344 .binding = "ScrollDown",
345 .comment = "Select next entry"},
346
349 .name = "me-select-entry",
350 .binding = "MousePrimary",
351 .comment = "Select hovered row"},
354 .name = "me-accept-entry",
355 .binding = "MouseDPrimary",
356 .comment = "Accept hovered row"},
359 .name = "me-accept-custom",
360 .binding = "Control+MouseDPrimary",
361 .comment = "Accept hovered row with custom action"},
362};
363
365static const gchar *mouse_default_bindings[] = {
366 [MOUSE_CLICK_DOWN] = "MousePrimary",
367 [MOUSE_CLICK_UP] = "!MousePrimary",
368 [MOUSE_DCLICK_DOWN] = "MouseDPrimary",
369 [MOUSE_DCLICK_UP] = "!MouseDPrimary",
370};
371
372void setup_abe(void) {
373 for (gsize i = 0; i < G_N_ELEMENTS(rofi_bindings); ++i) {
375 b->binding = g_strdup(b->binding);
377 b->comment);
378 }
379}
380
381static gboolean binding_check_action(guint64 scope,
382 G_GNUC_UNUSED gpointer target,
383 gpointer user_data) {
385 GPOINTER_TO_UINT(user_data))
386 ? NK_BINDINGS_BINDING_TRIGGERED
387 : NK_BINDINGS_BINDING_NOT_TRIGGERED;
388}
389
390static void binding_trigger_action(guint64 scope, G_GNUC_UNUSED gpointer target,
391 gpointer user_data) {
393 GPOINTER_TO_UINT(user_data));
394}
395
396guint key_binding_get_action_from_name(const char *name) {
397 for (gsize i = 0; i < G_N_ELEMENTS(rofi_bindings); ++i) {
399 if (g_strcmp0(b->name, name) == 0) {
400 return b->id;
401 }
402 }
403 return UINT32_MAX;
404}
405
406gboolean parse_keys_abe(NkBindings *bindings) {
407 GError *error = NULL;
408 GString *error_msg = g_string_new("");
409 for (gsize i = 0; i < G_N_ELEMENTS(rofi_bindings); ++i) {
411 char *keystr = g_strdup(b->binding);
412 char *sp = NULL;
413
414 // Iter over bindings.
415 const char *const sep = ",";
416 for (char *entry = strtok_r(keystr, sep, &sp); entry != NULL;
417 entry = strtok_r(NULL, sep, &sp)) {
418 if (!nk_bindings_add_binding(bindings, b->scope, entry,
420 GUINT_TO_POINTER(b->id), NULL, &error)) {
421 char *str = g_markup_printf_escaped(
422 "Failed to set binding <i>%s</i> for: <i>%s (%s)</i>:\n\t<span "
423 "size=\"smaller\" style=\"italic\">%s</span>\n",
424 b->binding, b->comment, b->name, error->message);
425 g_string_append(error_msg, str);
426 g_free(str);
427 g_clear_error(&error);
428 }
429 }
430
431 g_free(keystr);
432 }
433 if (error_msg->len > 0) {
434 // rofi_view_error_dialog ( error_msg->str, TRUE );
435 rofi_add_error_message(error_msg);
436 // g_string_free ( error_msg, TRUE );
437 return FALSE;
438 }
439
440 for (gsize i = SCOPE_MIN_FIXED; i <= SCOPE_MAX_FIXED; ++i) {
441 for (gsize j = 1; j < G_N_ELEMENTS(mouse_default_bindings); ++j) {
442 nk_bindings_add_binding(bindings, i, mouse_default_bindings[j],
444 GSIZE_TO_POINTER(j), NULL, NULL);
445 }
446 }
447
448 g_string_free(error_msg, TRUE);
449 return TRUE;
450}
void config_parser_add_option(XrmOptionType type, const char *key, void **value, const char *comment)
Definition xrmoptions.c:455
@ xrm_String
Definition xrmoptions.h:74
gboolean parse_keys_abe(NkBindings *bindings)
Definition keyb.c:406
guint key_binding_get_action_from_name(const char *name)
Definition keyb.c:396
void setup_abe(void)
Definition keyb.c:372
@ SCOPE_MOUSE_LISTVIEW_ELEMENT
Definition keyb.h:46
@ SCOPE_MOUSE_LISTVIEW
Definition keyb.h:45
@ ROW_LAST
Definition keyb.h:109
@ CUSTOM_4
Definition keyb.h:115
@ CUSTOM_17
Definition keyb.h:128
@ CUSTOM_12
Definition keyb.h:123
@ CUSTOM_9
Definition keyb.h:120
@ REMOVE_TO_SOL
Definition keyb.h:88
@ ROW_RIGHT
Definition keyb.h:100
@ ROW_UP
Definition keyb.h:101
@ CUSTOM_8
Definition keyb.h:119
@ SELECT_ELEMENT_9
Definition keyb.h:142
@ MOVE_FRONT
Definition keyb.h:66
@ REMOVE_WORD_FORWARD
Definition keyb.h:80
@ CHANGE_ELLIPSIZE
Definition keyb.h:132
@ ACCEPT_CUSTOM_ALT
Definition keyb.h:93
@ REMOVE_WORD_BACK
Definition keyb.h:78
@ TOGGLE_SORT
Definition keyb.h:133
@ ACCEPT_ENTRY
Definition keyb.h:90
@ ROW_TAB
Definition keyb.h:103
@ PAGE_NEXT
Definition keyb.h:107
@ TOGGLE_CASE_SENSITIVITY
Definition keyb.h:97
@ ELEMENT_NEXT
Definition keyb.h:104
@ MOVE_CHAR_FORWARD
Definition keyb.h:76
@ MOVE_WORD_FORWARD
Definition keyb.h:72
@ MODE_COMPLETE
Definition keyb.h:95
@ CUSTOM_1
Definition keyb.h:112
@ SELECT_ELEMENT_6
Definition keyb.h:139
@ CUSTOM_18
Definition keyb.h:129
@ CUSTOM_15
Definition keyb.h:126
@ CUSTOM_11
Definition keyb.h:122
@ ACCEPT_CUSTOM
Definition keyb.h:92
@ CUSTOM_5
Definition keyb.h:116
@ CUSTOM_19
Definition keyb.h:130
@ REMOVE_TO_EOL
Definition keyb.h:86
@ SELECT_ELEMENT_3
Definition keyb.h:136
@ ROW_SELECT
Definition keyb.h:110
@ PASTE_PRIMARY
Definition keyb.h:60
@ ROW_DOWN
Definition keyb.h:102
@ CUSTOM_13
Definition keyb.h:124
@ PASTE_SECONDARY
Definition keyb.h:62
@ SELECT_ELEMENT_10
Definition keyb.h:143
@ PAGE_PREV
Definition keyb.h:106
@ CUSTOM_3
Definition keyb.h:114
@ CUSTOM_7
Definition keyb.h:118
@ SELECT_ELEMENT_5
Definition keyb.h:138
@ ROW_FIRST
Definition keyb.h:108
@ CUSTOM_6
Definition keyb.h:117
@ ROW_LEFT
Definition keyb.h:99
@ CUSTOM_14
Definition keyb.h:125
@ SELECT_ELEMENT_4
Definition keyb.h:137
@ MOVE_WORD_BACK
Definition keyb.h:70
@ MOVE_END
Definition keyb.h:68
@ CUSTOM_10
Definition keyb.h:121
@ MODE_NEXT
Definition keyb.h:94
@ REMOVE_CHAR_BACK
Definition keyb.h:84
@ DELETE_ENTRY
Definition keyb.h:98
@ SELECT_ELEMENT_1
Definition keyb.h:134
@ CLEAR_LINE
Definition keyb.h:64
@ CUSTOM_2
Definition keyb.h:113
@ SELECT_ELEMENT_2
Definition keyb.h:135
@ SCREENSHOT
Definition keyb.h:131
@ CANCEL
Definition keyb.h:111
@ ELEMENT_PREV
Definition keyb.h:105
@ MODE_PREVIOUS
Definition keyb.h:96
@ ACCEPT_ALT
Definition keyb.h:91
@ SELECT_ELEMENT_7
Definition keyb.h:140
@ MOVE_CHAR_BACK
Definition keyb.h:74
@ SELECT_ELEMENT_8
Definition keyb.h:141
@ REMOVE_CHAR_FORWARD
Definition keyb.h:82
@ CUSTOM_16
Definition keyb.h:127
@ ACCEPT_HOVERED_ENTRY
Definition keyb.h:161
@ ACCEPT_HOVERED_CUSTOM
Definition keyb.h:162
@ SELECT_HOVERED_ENTRY
Definition keyb.h:160
@ SCROLL_LEFT
Definition keyb.h:150
@ SCROLL_DOWN
Definition keyb.h:152
@ SCROLL_RIGHT
Definition keyb.h:151
@ SCROLL_UP
Definition keyb.h:153
@ MOUSE_CLICK_DOWN
Definition keyb.h:169
@ MOUSE_DCLICK_UP
Definition keyb.h:172
@ MOUSE_CLICK_UP
Definition keyb.h:170
@ MOUSE_DCLICK_DOWN
Definition keyb.h:171
void rofi_add_error_message(GString *str)
Definition rofi.c:90
RofiViewState * rofi_view_get_active(void)
Definition view.c:549
void rofi_view_trigger_action(RofiViewState *state, BindingsScope scope, guint action)
Definition view.c:1607
gboolean rofi_view_check_action(RofiViewState *state, BindingsScope scope, guint action)
Definition view.c:1576
ActionBindingEntry rofi_bindings[]
Definition keyb.c:45
static void binding_trigger_action(guint64 scope, G_GNUC_UNUSED gpointer target, gpointer user_data)
Definition keyb.c:390
static gboolean binding_check_action(guint64 scope, G_GNUC_UNUSED gpointer target, gpointer user_data)
Definition keyb.c:381
static const gchar * mouse_default_bindings[]
Definition keyb.c:365
#define SCOPE_MAX_FIXED
Definition keyb.h:52
#define SCOPE_MIN_FIXED
Definition keyb.h:48
NkBindings * bindings
Definition rofi.c:133
char * name
Definition keyb.c:37
char * comment
Definition keyb.c:39
char * binding
Definition keyb.c:38