rofi 1.7.8
rofi.c
Go to the documentation of this file.
1/*
2 * rofi
3 *
4 * MIT/X11 License
5 * Copyright © 2012 Sean Pringle <sean.pringle@gmail.com>
6 * Copyright © 2013-2023 Qball Cow <qball@gmpclient.org>
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining
9 * a copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sublicense, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be
17 * included in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *
27 */
28
30#define G_LOG_DOMAIN "Rofi"
31
32#include "config.h"
33#include <errno.h>
34#include <gmodule.h>
35#include <locale.h>
36#include <stdint.h>
37#include <stdlib.h>
38#include <string.h>
39#include <sys/stat.h>
40#include <sys/types.h>
41#include <sysexits.h>
42#include <time.h>
43#include <unistd.h>
44#include <xcb/xcb.h>
45
46#include <glib-unix.h>
47
48#include <libgwater-xcb.h>
49
50#ifdef USE_NK_GIT_VERSION
51#include "nkutils-git-version.h"
52#ifdef NK_GIT_VERSION
53#define GIT_VERSION NK_GIT_VERSION
54#endif
55#endif
56
57#include "resources.h"
58
59#include "display.h"
60#include "rofi.h"
61#include "settings.h"
62
63#include "helper.h"
64#include "mode.h"
65#include "modes/modes.h"
66#include "widgets/textbox.h"
67#include "xrmoptions.h"
68
69#include "view-internal.h"
70#include "view.h"
71
72#include "rofi-icon-fetcher.h"
73#include "theme.h"
74
75#include "timings.h"
76
77// Plugin abi version.
78// TODO: move this check to mode.c
79#include "mode-private.h"
80
82char *pidfile = NULL;
84const char *cache_dir = NULL;
87char *cache_dir_alloc = NULL;
88
90GList *list_of_error_msgs = NULL;
93
94static void rofi_collectmodes_destroy(void);
95void rofi_add_error_message(GString *str) {
96 list_of_error_msgs = g_list_append(list_of_error_msgs, str);
97}
100 for (GList *iter = g_list_first(list_of_error_msgs); iter != NULL;
101 iter = g_list_next(iter)) {
102 g_string_free((GString *)iter->data, TRUE);
103 }
104 g_list_free(list_of_error_msgs);
105 list_of_error_msgs = NULL;
106 }
107}
108void rofi_add_warning_message(GString *str) {
109 list_of_warning_msgs = g_list_append(list_of_warning_msgs, str);
110}
113 for (GList *iter = g_list_first(list_of_warning_msgs); iter != NULL;
114 iter = g_list_next(iter)) {
115 g_string_free((GString *)iter->data, TRUE);
116 }
117 g_list_free(list_of_warning_msgs);
119 }
120}
121
123G_MODULE_EXPORT char *config_path = NULL;
126Mode **modes = NULL;
127
131unsigned int num_available_modes = 0;
133unsigned int num_modes = 0;
135unsigned int curr_mode = 0;
136
138NkBindings *bindings = NULL;
139
141GMainLoop *main_loop = NULL;
142
146int return_code = EXIT_SUCCESS;
147
148void process_result(RofiViewState *state);
149
150void rofi_set_return_code(int code) { return_code = code; }
151
152unsigned int rofi_get_num_enabled_modes(void) { return num_modes; }
153
154const Mode *rofi_get_mode(unsigned int index) { return modes[index]; }
155
163static int mode_lookup(const char *name) {
164 for (unsigned int i = 0; i < num_modes; i++) {
165 if (strcmp(mode_get_name(modes[i]), name) == 0) {
166 return i;
167 }
168 }
169 return -1;
170}
171
178static const Mode *mode_available_lookup(const char *name) {
179 for (unsigned int i = 0; i < num_available_modes; i++) {
180 if (strcmp(mode_get_name(available_modes[i]), name) == 0) {
181 return available_modes[i];
182 }
183 }
184 return NULL;
185}
186
190static void teardown(int pfd) {
191 g_debug("Teardown");
192 // Cleanup font setup.
194
196
197 // Cleanup view
199
200 // Cleanup pid file.
201 remove_pid_file(pfd);
202}
203static void run_mode_index(ModeMode mode) {
204 // Otherwise check if requested mode is enabled.
205 for (unsigned int i = 0; i < num_modes; i++) {
206 if (!mode_init(modes[i])) {
207 GString *str = g_string_new("Failed to initialize the mode: ");
208 g_string_append(str, modes[i]->name);
209 g_string_append(str, "\n");
210
212 g_string_free(str, FALSE);
213 break;
214 }
215 }
216 // Error dialog must have been created.
217 if (rofi_view_get_active() != NULL) {
218 return;
219 }
220 curr_mode = mode;
221 RofiViewState *state =
222 rofi_view_create(modes[mode], config.filter, 0, process_result);
223
224 // User can pre-select a row.
225 if (find_arg("-selected-row") >= 0) {
226 unsigned int sr = 0;
227 find_arg_uint("-selected-row", &(sr));
229 }
230 if (state) {
232 }
233 if (rofi_view_get_active() == NULL) {
234 g_main_loop_quit(main_loop);
235 }
236}
238 Mode *sw = state->sw;
239 // rofi_view_set_active ( NULL );
240 if (sw != NULL) {
241 unsigned int selected_line = rofi_view_get_selected_line(state);
242 ;
244 char *input = g_strdup(rofi_view_get_user_input(state));
245 ModeMode retv = mode_result(sw, mretv, &input, selected_line);
246 {
247 if (state->text) {
248 if (input == NULL) {
249 textbox_text(state->text, "");
250 } else if (strcmp(rofi_view_get_user_input(state), input) != 0) {
251 textbox_text(state->text, input);
252 textbox_cursor_end(state->text);
253 }
254 }
255 }
256 g_free(input);
257
258 ModeMode mode = curr_mode;
259 // Find next enabled
260 if (retv == NEXT_DIALOG) {
261 mode = (mode + 1) % num_modes;
262 } else if (retv == PREVIOUS_DIALOG) {
263 if (mode == 0) {
264 mode = num_modes - 1;
265 } else {
266 mode = (mode - 1) % num_modes;
267 }
268 } else if (retv == RELOAD_DIALOG) {
269 // do nothing.
270 } else if (retv == RESET_DIALOG) {
272 } else if (retv < MODE_EXIT) {
273 mode = (retv) % num_modes;
274 } else {
275 mode = retv;
276 }
277 if (mode != MODE_EXIT) {
281 rofi_view_switch_mode(state, modes[mode]);
282 curr_mode = mode;
283 return;
284 }
285 // On exit, free current view, and pop to one above.
287 rofi_view_free(state);
288 return;
289 }
290 // rofi_view_set_active ( NULL );
292 rofi_view_free(state);
293}
294
298static void print_list_of_modes(int is_term) {
299 for (unsigned int i = 0; i < num_available_modes; i++) {
300 gboolean active = FALSE;
301 for (unsigned int j = 0; j < num_modes; j++) {
302 if (modes[j] == available_modes[i]) {
303 active = TRUE;
304 break;
305 }
306 }
307 printf(" • %s%s%s%s\n", active ? "+" : "",
308 is_term ? (active ? color_green : color_red) : "",
309 available_modes[i]->name, is_term ? color_reset : "");
310 }
311}
312static void print_main_application_options(int is_term) {
313 print_help_msg("-config", "[file]", "Load an alternative configuration.",
314 NULL, is_term);
315 print_help_msg("-no-config", "",
316 "Do not load configuration, use default values.", NULL,
317 is_term);
318 print_help_msg("-v,-version", "", "Print the version number and exit.", NULL,
319 is_term);
320 print_help_msg("-dmenu", "", "Start in dmenu mode.", NULL, is_term);
321 print_help_msg("-display", "[string]", "X server to contact.", "${DISPLAY}",
322 is_term);
323 print_help_msg("-h,-help", "", "This help message.", NULL, is_term);
324 print_help_msg("-e", "[string]",
325 "Show a dialog displaying the passed message and exit.", NULL,
326 is_term);
327 print_help_msg("-markup", "", "Enable pango markup where possible.", NULL,
328 is_term);
329 print_help_msg("-normal-window", "",
330 "Behave as a normal window. (experimental)", NULL, is_term);
331 print_help_msg("-transient-window", "",
332 "Behave as a modal dialog that is transient to the currently "
333 "focused window. (experimental)",
334 NULL, is_term);
335 print_help_msg("-show", "[mode]",
336 "Show the mode 'mode' and exit. The mode has to be enabled.",
337 NULL, is_term);
338 print_help_msg("-no-lazy-grab", "",
339 "Disable lazy grab that, when fail to grab keyboard, does not "
340 "block but retry later.",
341 NULL, is_term);
342 print_help_msg("-no-plugins", "", "Disable loading of external plugins.",
343 NULL, is_term);
344 print_help_msg("-plugin-path", "",
345 "Directory used to search for rofi plugins. *DEPRECATED*",
346 NULL, is_term);
347 print_help_msg("-dump-config", "",
348 "Dump the current configuration in rasi format and exit.",
349 NULL, is_term);
350 print_help_msg("-dump-theme", "",
351 "Dump the current theme in rasi format and exit.", NULL,
352 is_term);
353 print_help_msg("-list-keybindings", "",
354 "Print a list of current keybindings and exit.", NULL,
355 is_term);
356}
357static void help(G_GNUC_UNUSED int argc, char **argv) {
358 int is_term = isatty(fileno(stdout));
359 printf("%s usage:\n", argv[0]);
360 printf("\t%s [-options ...]\n\n", argv[0]);
361 printf("Command line only options:\n");
363 printf("DMENU command line options:\n");
365 printf("Global options:\n");
367 printf("\n");
368 printf("Detected Window manager:\n");
370 if (wm) {
371 printf("\t• %s\n", wm);
372 g_free(wm);
373 } else {
374 printf("\t• No window manager detected.\n");
375 }
376 printf("\n");
378 printf("\n");
379 printf("Detected modes:\n");
380 print_list_of_modes(is_term);
381 printf("\n");
382 printf("Detected user scripts:\n");
383 script_user_list(is_term);
384 printf("\n");
385 printf("Compile time options:\n");
386 printf("\t• Pango version %s\n", pango_version_string());
387#ifdef WINDOW_MODE
388 printf("\t• window %senabled%s\n", is_term ? color_green : "",
389 is_term ? color_reset : "");
390#else
391 printf("\t• window %sdisabled%s\n", is_term ? color_red : "",
392 is_term ? color_reset : "");
393#endif
394#ifdef ENABLE_DRUN
395 printf("\t• drun %senabled%s\n", is_term ? color_green : "",
396 is_term ? color_reset : "");
397#else
398 printf("\t• drun %sdisabled%s\n", is_term ? color_red : "",
399 is_term ? color_reset : "");
400#endif
401#ifdef ENABLE_GCOV
402 printf("\t• gcov %senabled%s\n", is_term ? color_green : "",
403 is_term ? color_reset : "");
404#else
405 printf("\t• gcov %sdisabled%s\n", is_term ? color_red : "",
406 is_term ? color_reset : "");
407#endif
408#ifdef ENABLE_ASAN
409 printf("\t• asan %senabled%s\n", is_term ? color_green : "",
410 is_term ? color_reset : "");
411#else
412 printf("\t• asan %sdisabled%s\n", is_term ? color_red : "",
413 is_term ? color_reset : "");
414#endif
415#ifdef XCB_IMDKIT
416 printf("\t• imdkit %senabled%s\n", is_term ? color_green : "",
417 is_term ? color_reset : "");
418#else
419 printf("\t• imdkit %sdisabled%s\n", is_term ? color_red : "",
420 is_term ? color_reset : "");
421#endif
422 printf("\n");
423 printf("For more information see: %sman rofi%s\n", is_term ? color_bold : "",
424 is_term ? color_reset : "");
425#ifdef GIT_VERSION
426 printf(" Version: %s" GIT_VERSION "%s\n",
427 is_term ? color_bold : "", is_term ? color_reset : "");
428#else
429 printf(" Version: %s" VERSION "%s\n",
430 is_term ? color_bold : "", is_term ? color_reset : "");
431#endif
432 printf(" Bugreports: %s" PACKAGE_BUGREPORT "%s\n",
433 is_term ? color_bold : "", is_term ? color_reset : "");
434 printf(" Support: %s" PACKAGE_URL "%s\n",
435 is_term ? color_bold : "", is_term ? color_reset : "");
436 printf(" %s#rofi @ libera.chat%s\n",
437 is_term ? color_bold : "", is_term ? color_reset : "");
438 if (find_arg("-no-config") < 0) {
439 if (config_path) {
440 printf(" Configuration file: %s%s%s\n", is_term ? color_bold : "",
441 config_path, is_term ? color_reset : "");
442 }
443 } else {
444 printf(" Configuration file: %sDisabled%s\n",
445 is_term ? color_bold : "", is_term ? color_reset : "");
446 }
448}
449
450static void help_print_disabled_mode(const char *mode) {
451 int is_term = isatty(fileno(stdout));
452 // Only output to terminal
453 if (is_term) {
454 fprintf(stderr, "Mode %s%s%s is not enabled. I have enabled it for now.\n",
455 color_red, mode, color_reset);
456 fprintf(stderr,
457 "Please consider adding %s%s%s to the list of enabled modes: "
458 "%smodes: [%s%s%s,%s]%s.\n",
461 }
462}
463static void help_print_mode_not_found(const char *mode) {
464 GString *str = g_string_new("");
465 g_string_printf(
466 str, "Mode %s is not found.\nThe following modes are known:\n", mode);
467 for (unsigned int i = 0; i < num_available_modes; i++) {
468 gboolean active = FALSE;
469 for (unsigned int j = 0; j < num_modes; j++) {
470 if (modes[j] == available_modes[i]) {
471 active = TRUE;
472 break;
473 }
474 }
475 g_string_append_printf(str, " * %s%s\n", active ? "+" : "",
476 available_modes[i]->name);
477 }
479}
480static void help_print_no_arguments(void) {
481
482 GString *emesg = g_string_new(
483 "<span size=\"x-large\">Rofi is unsure what to show.</span>\n\n");
484 g_string_append(emesg, "Please specify the mode you want to show.\n\n");
485 g_string_append(
486 emesg, " <b>rofi</b> -show <span color=\"green\">{mode}</span>\n\n");
487 g_string_append(emesg, "The following modes are enabled:\n");
488 for (unsigned int j = 0; j < num_modes; j++) {
489 g_string_append_printf(emesg, " • <span color=\"green\">%s</span>\n",
490 modes[j]->name);
491 }
492 g_string_append(emesg, "\nThe following modes can be enabled:\n");
493 for (unsigned int i = 0; i < num_available_modes; i++) {
494 gboolean active = FALSE;
495 for (unsigned int j = 0; j < num_modes; j++) {
496 if (modes[j] == available_modes[i]) {
497 active = TRUE;
498 break;
499 }
500 }
501 if (!active) {
502 g_string_append_printf(emesg, " • <span color=\"red\">%s</span>\n",
503 available_modes[i]->name);
504 }
505 }
506 g_string_append(emesg, "\nTo activate a mode, add it to the list in "
507 "the <span color=\"green\">modes</span> "
508 "setting.\n");
510 rofi_set_return_code(EXIT_SUCCESS);
511}
512
516static void cleanup(void) {
517 for (unsigned int i = 0; i < num_modes; i++) {
519 }
521 if (main_loop != NULL) {
522 g_main_loop_unref(main_loop);
523 main_loop = NULL;
524 }
525 // Cleanup
527
528 nk_bindings_free(bindings);
529
530 // Cleaning up memory allocated by the Xresources file.
532 g_free(modes);
533
534 g_free(config_path);
535
538
539 if (rofi_theme) {
541 rofi_theme = NULL;
542 }
543 TIMINGS_STOP();
547
549 if (rofi_configuration) {
551 rofi_configuration = NULL;
552 }
553 // Cleanup memory allocated by rofi_expand_path
554 if (cache_dir_alloc) {
555 g_free(cache_dir_alloc);
556 cache_dir_alloc = NULL;
557 }
558}
559
563
564Mode *rofi_collect_modes_search(const char *name) {
565 for (unsigned int i = 0; i < num_available_modes; i++) {
566 if (g_strcmp0(name, available_modes[i]->name) == 0) {
567 return available_modes[i];
568 }
569 }
570 return NULL;
571}
572
577static gboolean rofi_collectmodes_add(Mode *mode) {
579 if (m == NULL) {
581 g_realloc(available_modes, sizeof(Mode *) * (num_available_modes + 1));
582 // Set mode.
585 return TRUE;
586 }
587 return FALSE;
588}
589
590static void rofi_collectmodes_dir(const char *base_dir) {
591 g_debug("Looking into: %s for plugins", base_dir);
592 GDir *dir = g_dir_open(base_dir, 0, NULL);
593 if (dir) {
594 const char *dn = NULL;
595 while ((dn = g_dir_read_name(dir))) {
596 if (!g_str_has_suffix(dn, G_MODULE_SUFFIX)) {
597 continue;
598 }
599 char *fn = g_build_filename(base_dir, dn, NULL);
600 g_debug("Trying to open: %s plugin", fn);
601 GModule *mod =
602 g_module_open(fn, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
603 if (mod) {
604 Mode *m = NULL;
605 if (g_module_symbol(mod, "mode", (gpointer *)&m)) {
606 if (m->abi_version != ABI_VERSION) {
607 g_warning("ABI version of plugin: '%s' does not match: %08X "
608 "expecting: %08X",
609 dn, m->abi_version, ABI_VERSION);
610 g_module_close(mod);
611 } else {
612 m->module = mod;
613 if (!rofi_collectmodes_add(m)) {
614 g_module_close(mod);
615 }
616 }
617 } else {
618 g_warning("Symbol 'mode' not found in module: %s", dn);
619 g_module_close(mod);
620 }
621 } else {
622 g_warning("Failed to open 'mode' plugin: '%s', error: %s", dn,
623 g_module_error());
624 }
625 g_free(fn);
626 }
627 g_dir_close(dir);
628 }
629}
630
634static void rofi_collect_modes(void) {
635#ifdef WINDOW_MODE
636 rofi_collectmodes_add(&window_mode);
637 rofi_collectmodes_add(&window_mode_cd);
638#endif
641#ifdef ENABLE_DRUN
642 rofi_collectmodes_add(&drun_mode);
643#endif
648
649 if (find_arg("-no-plugins") < 0) {
650 find_arg_str("-plugin-path", &(config.plugin_path));
651 g_debug("Parse plugin path: %s", config.plugin_path);
652 rofi_collectmodes_dir(config.plugin_path);
653 /* ROFI_PLUGIN_PATH */
654 const char *path = g_getenv("ROFI_PLUGIN_PATH");
655 if (path != NULL) {
656 gchar **paths = g_strsplit(path, ":", -1);
657 for (unsigned int i = 0; paths[i]; i++) {
658 rofi_collectmodes_dir(paths[i]);
659 }
660 g_strfreev(paths);
661 }
662 }
664}
665
669static void rofi_collectmodes_setup(void) {
670 for (unsigned int i = 0; i < num_available_modes; i++) {
672 }
673}
674static void rofi_collectmodes_destroy(void) {
675 for (unsigned int i = 0; i < num_available_modes; i++) {
676 if (available_modes[i]->module) {
677 GModule *mod = available_modes[i]->module;
678 available_modes[i] = NULL;
679 g_module_close(mod);
680 }
681 if (available_modes[i]) {
683 }
684 }
685 g_free(available_modes);
686 available_modes = NULL;
688}
689
697static int add_mode(const char *token) {
698 unsigned int index = num_modes;
699 // Resize and add entry.
700 modes = (Mode **)g_realloc(modes, sizeof(Mode *) * (num_modes + 1));
701
702 Mode *mode = rofi_collect_modes_search(token);
703 if (mode) {
704 modes[num_modes] = mode;
705 num_modes++;
706 } else if (script_mode_is_valid(token)) {
707 // If not build in, use custom mode.
708 Mode *sw = script_mode_parse_setup(token);
709 if (sw != NULL) {
710 // Add to available list, so combi can find it.
712 mode_set_config(sw);
713 modes[num_modes] = sw;
714 num_modes++;
715 }
716 }
717 return (index == num_modes) ? -1 : (int)index;
718}
719static gboolean setup_modes(void) {
720 const char *const sep = ",#";
721 char *savept = NULL;
722 // Make a copy, as strtok will modify it.
723 char *mode_str = g_strdup(config.modes);
724 // Split token on ','. This modifies mode_str.
725 for (char *token = strtok_r(mode_str, sep, &savept); token != NULL;
726 token = strtok_r(NULL, sep, &savept)) {
727 if (add_mode(token) == -1) {
729 }
730 }
731 // Free string that was modified by strtok_r
732 g_free(mode_str);
733 return FALSE;
734}
735
740void rofi_quit_main_loop(void) { g_main_loop_quit(main_loop); }
741
742static gboolean main_loop_signal_handler_int(G_GNUC_UNUSED gpointer data) {
743 // Break out of loop.
744 g_main_loop_quit(main_loop);
745 return G_SOURCE_CONTINUE;
746}
747static void show_error_dialog(void) {
748 GString *emesg =
749 g_string_new("The following errors were detected when starting rofi:\n");
750 GList *iter = g_list_first(list_of_error_msgs);
751 int index = 0;
752 for (; iter != NULL && index < 2; iter = g_list_next(iter)) {
753 GString *msg = (GString *)(iter->data);
754 g_string_append(emesg, "\n\n");
755 g_string_append(emesg, msg->str);
756 index++;
757 }
758 if (g_list_length(iter) > 1) {
759 g_string_append_printf(emesg, "\nThere are <b>%u</b> more errors.",
760 g_list_length(iter) - 1);
761 }
763 g_string_free(emesg, TRUE);
764 rofi_set_return_code(EX_DATAERR);
765}
766
767static gboolean startup(G_GNUC_UNUSED gpointer data) {
768 TICK_N("Startup");
769 // flags to run immediately and exit
770 char *sname = NULL;
771 char *msg = NULL;
772 MenuFlags window_flags = MENU_NORMAL;
773
774 if (find_arg("-normal-window") >= 0) {
775 window_flags |= MENU_NORMAL_WINDOW;
776 }
777 if (find_arg("-transient-window") >= 0) {
778 window_flags |= MENU_TRANSIENT_WINDOW;
779 }
780 TICK_N("Grab keyboard");
781 __create_window(window_flags);
782 TICK_N("Create Window");
783 // Parse the keybindings.
784 TICK_N("Parse ABE");
785 // Sanity check
787 TICK_N("Config sanity check");
788
789 if (list_of_error_msgs != NULL) {
791 return G_SOURCE_REMOVE;
792 }
793 if (list_of_warning_msgs != NULL) {
794 for (GList *iter = g_list_first(list_of_warning_msgs); iter != NULL;
795 iter = g_list_next(iter)) {
796 fputs(((GString *)iter->data)->str, stderr);
797 fputs("\n", stderr);
798 }
799 }
800 // Dmenu mode.
801 if (rofi_is_in_dmenu_mode == TRUE) {
802 // force off sidebar mode:
803 config.sidebar_mode = FALSE;
804 int retv = dmenu_mode_dialog();
805 if (retv) {
806 rofi_set_return_code(EXIT_SUCCESS);
807 // Directly exit.
808 g_main_loop_quit(main_loop);
809 }
810 } else if (find_arg_str("-e", &(msg))) {
811 int markup = FALSE;
812 if (find_arg("-markup") >= 0) {
813 markup = TRUE;
814 }
815 // When we pass -, we read from stdin.
816 if (g_strcmp0(msg, "-") == 0) {
817 size_t index = 0, i = 0;
818 size_t length = 1024;
819 msg = malloc(length * sizeof(char));
820 while ((i = fread(&msg[index], 1, 1024, stdin)) > 0) {
821 index += i;
822 length += i;
823 msg = realloc(msg, length * sizeof(char));
824 }
825
826 msg[index] = 0;
827
828 if (!rofi_view_error_dialog(msg, markup)) {
829 g_main_loop_quit(main_loop);
830 }
831 g_free(msg);
832 } else {
833 // Normal version
834 if (!rofi_view_error_dialog(msg, markup)) {
835 g_main_loop_quit(main_loop);
836 }
837 }
838 } else if (find_arg_str("-show", &sname) == TRUE) {
839 int index = mode_lookup(sname);
840 if (index < 0) {
841 // Add it to the list
842 index = add_mode(sname);
843 // Complain
844 if (index >= 0) {
846 }
847 // Run it anyway if found.
848 }
849 if (index >= 0) {
850 run_mode_index(index);
851 } else {
854 return G_SOURCE_REMOVE;
855 }
856 } else if (find_arg("-show") >= 0 && num_modes > 0) {
858 } else {
860
861 // g_main_loop_quit(main_loop);
862 }
863
864 return G_SOURCE_REMOVE;
865}
866
867static gboolean take_screenshot_quit(G_GNUC_UNUSED void *data) {
870 return G_SOURCE_REMOVE;
871}
872static gboolean record(G_GNUC_UNUSED void *data) {
874 return G_SOURCE_CONTINUE;
875}
876static void rofi_custom_log_function(const char *log_domain,
877 G_GNUC_UNUSED GLogLevelFlags log_level,
878 const gchar *message, gpointer user_data) {
879 int fp = GPOINTER_TO_INT(user_data);
880 dprintf(fp, "[%s]: %s\n", log_domain == NULL ? "default" : log_domain,
881 message);
882}
883
891int main(int argc, char *argv[]) {
892 cmd_set_arguments(argc, argv);
893 if (find_arg("-log") >= 0) {
894 char *logfile = NULL;
895 find_arg_str("-log", &logfile);
896 if (logfile != NULL) {
897 int fp = open(logfile, O_CLOEXEC | O_APPEND | O_CREAT | O_WRONLY,
898 S_IRUSR | S_IWUSR);
899 if (fp != -1) {
900 g_log_set_default_handler(rofi_custom_log_function,
901 GINT_TO_POINTER(fp));
902
903 } else {
904 g_error("Failed to open logfile '%s': %s.", logfile, strerror(errno));
905 }
906
907 } else {
908 g_warning("Option '-log' should pass in a filename.");
909 }
910 }
912
913 // Version
914 if (find_arg("-v") >= 0 || find_arg("-version") >= 0) {
915#ifdef GIT_VERSION
916 g_print("Version: " GIT_VERSION "\n");
917#else
918 g_print("Version: " VERSION "\n");
919#endif
920 return EXIT_SUCCESS;
921 }
922
923 if (find_arg("-rasi-validate") >= 0) {
924 char *str = NULL;
925 find_arg_str("-rasi-validate", &str);
926 if (str != NULL) {
927 int retv = rofi_theme_rasi_validate(str);
928 cleanup();
929 return retv;
930 }
931 fprintf(stderr, "Usage: %s -rasi-validate my-theme.rasi", argv[0]);
932 return EXIT_FAILURE;
933 }
934
935 {
936 const char *ro_pid = g_getenv("ROFI_OUTSIDE");
937 if (ro_pid != NULL) {
938 pid_t ro_pidi = (pid_t)g_ascii_strtoll(ro_pid, NULL, 0);
939 if (kill(ro_pidi, 0) == 0) {
940 printf("Do not launch rofi from inside rofi.\r\n");
941 return EXIT_FAILURE;
942 }
943 }
944 }
945
946 // Detect if we are in dmenu mode.
947 // This has two possible causes.
948 // 1 the user specifies it on the command-line.
949 if (find_arg("-dmenu") >= 0) {
951 }
952 // 2 the binary that executed is called dmenu (e.g. symlink to rofi)
953 else {
954 // Get the base name of the executable called.
955 char *base_name = g_path_get_basename(argv[0]);
956 const char *const dmenu_str = "dmenu";
957 rofi_is_in_dmenu_mode = (strcmp(base_name, dmenu_str) == 0);
958 // Free the basename for dmenu detection.
959 g_free(base_name);
960 }
961 TICK();
962
963 // Create pid file path.
964 const char *path = g_get_user_runtime_dir();
965 if (path) {
966 if (g_mkdir_with_parents(path, 0700) < 0) {
967 g_warning("Failed to create user runtime directory: %s with error: %s",
968 path, g_strerror(errno));
969 pidfile = g_build_filename(g_get_home_dir(), ".rofi.pid", NULL);
970 } else {
971 pidfile = g_build_filename(path, "rofi.pid", NULL);
972 }
973 }
975 "Pidfile location");
976
978 if (find_arg("-no-default-config") < 0) {
979 GBytes *theme_data = g_resource_lookup_data(
980 resources_get_resource(), "/org/qtools/rofi/default_configuration.rasi",
981 G_RESOURCE_LOOKUP_FLAGS_NONE, NULL);
982 if (theme_data) {
983 const char *theme = g_bytes_get_data(theme_data, NULL);
984 if (rofi_theme_parse_string((const char *)theme)) {
985 g_warning("Failed to parse default configuration. Giving up..");
986 if (list_of_error_msgs) {
987 for (GList *iter = g_list_first(list_of_error_msgs); iter != NULL;
988 iter = g_list_next(iter)) {
989 g_warning("Error: %s%s%s", color_bold, ((GString *)iter->data)->str,
991 }
992 }
993 rofi_configuration = NULL;
994 cleanup();
995 return EXIT_FAILURE;
996 }
997 g_bytes_unref(theme_data);
998 }
999 }
1000
1001 if (find_arg("-config") < 0) {
1002 const char *cpath = g_get_user_config_dir();
1003 if (cpath) {
1004 config_path = g_build_filename(cpath, "rofi", "config.rasi", NULL);
1005 }
1006 } else {
1007 char *c = NULL;
1008 find_arg_str("-config", &c);
1010 }
1011
1012 TICK();
1013 if (setlocale(LC_ALL, "") == NULL) {
1014 g_warning("Failed to set locale.");
1015 cleanup();
1016 return EXIT_FAILURE;
1017 }
1018
1019 TICK_N("Setup Locale");
1021 TICK_N("Collect MODES");
1023 TICK_N("Setup MODES");
1024
1025 main_loop = g_main_loop_new(NULL, FALSE);
1026
1027 TICK_N("Setup mainloop");
1028
1029 bindings = nk_bindings_new(0lu);
1030 TICK_N("NK Bindings");
1031
1033 g_warning("Connection has error");
1034 cleanup();
1035 return EXIT_FAILURE;
1036 }
1037 TICK_N("Setup Display");
1038
1039 // Setup keybinding
1040 setup_abe();
1041 TICK_N("Setup abe");
1042
1043 if (find_arg("-no-config") < 0) {
1044 // Load distro default settings
1045 gboolean found_system = FALSE;
1046 const char *const *dirs = g_get_system_config_dirs();
1047 if (dirs) {
1048 for (unsigned int i = 0; !found_system && dirs[i]; i++) {
1050 gchar *etc = g_build_filename(dirs[i], "rofi.rasi", NULL);
1051 g_debug("Look for default config file: %s", etc);
1052 if (g_file_test(etc, G_FILE_TEST_IS_REGULAR)) {
1053 g_debug("Parsing: %s", etc);
1055 found_system = TRUE;
1056 }
1057 g_free(etc);
1058 }
1059 }
1060 if (!found_system) {
1062 gchar *etc = g_build_filename(SYSCONFDIR, "rofi.rasi", NULL);
1063 g_debug("Look for default config file: %s", etc);
1064 if (g_file_test(etc, G_FILE_TEST_IS_REGULAR)) {
1065 g_debug("Look for default config file: %s", etc);
1067 }
1068 g_free(etc);
1069 }
1070
1071 if (config_path) {
1072 // Try to resolve the path.
1073 extern const char *rasi_theme_file_extensions[];
1074 char *file2 =
1075 helper_get_theme_path(config_path, rasi_theme_file_extensions, NULL);
1076 char *filename = rofi_theme_parse_prepare_file(file2);
1077 g_free(file2);
1078 if (filename && g_file_test(filename, G_FILE_TEST_EXISTS)) {
1079 if (rofi_theme_parse_file(filename)) {
1081 rofi_theme = NULL;
1082 }
1083 }
1084 g_free(filename);
1085 }
1086 }
1087 find_arg_str("-theme", &(config.theme));
1088 if (config.theme) {
1089 TICK_N("Parse theme");
1091 if (rofi_theme_parse_file(config.theme)) {
1092 g_warning("Failed to parse theme: \"%s\"", config.theme);
1093 // TODO: instantiate fallback theme.?
1095 rofi_theme = NULL;
1096 }
1097 TICK_N("Parsed theme");
1098 }
1099 // Parse command line for settings, independent of other -no-config.
1100 if (list_of_error_msgs == NULL) {
1101 // Only call this when there are no errors.
1102 // This might clear existing errors.
1104 }
1105
1106 if (rofi_theme == NULL || rofi_theme->num_widgets == 0) {
1107 g_debug("Failed to load theme. Try to load default: ");
1108 rofi_theme_parse_string("@theme \"default\"");
1109 }
1110 TICK_N("Load cmd config ");
1111
1112 // Get the path to the cache dir.
1113 cache_dir = g_get_user_cache_dir();
1114
1115 if (config.cache_dir != NULL) {
1117 }
1118
1119 if (g_mkdir_with_parents(cache_dir, 0700) < 0) {
1120 g_warning("Failed to create cache directory: %s", g_strerror(errno));
1121 return EXIT_FAILURE;
1122 }
1123
1125 char *windowid = NULL;
1126 if (!rofi_is_in_dmenu_mode) {
1127 // setup_modes
1128 if (setup_modes()) {
1129 cleanup();
1130 return EXIT_FAILURE;
1131 }
1132 TICK_N("Setup Modes");
1133 } else {
1134 // Hack for dmenu compatibility.
1135 if (find_arg_str("-w", &windowid) == TRUE) {
1136 config.monitor = g_strdup_printf("wid:%s", windowid);
1137 windowid = config.monitor;
1138 }
1139 }
1140
1144 const char **theme_str = find_arg_strv("-theme-str");
1145 if (theme_str) {
1146 for (int index = 0; theme_str[index]; index++) {
1147 if (rofi_theme_parse_string(theme_str[index])) {
1148 g_warning("Failed to parse -theme-str option: \"%s\"",
1149 theme_str[index]);
1151 rofi_theme = NULL;
1152 }
1153 }
1154 g_free(theme_str);
1155 }
1156
1158 if (find_arg("-dump-theme") >= 0) {
1160 cleanup();
1161 return EXIT_SUCCESS;
1162 }
1163 if (find_arg("-dump-processed-theme") >= 0) {
1166 cleanup();
1167 return EXIT_SUCCESS;
1168 }
1169 if (find_arg("-dump-config") >= 0) {
1171 cleanup();
1172 return EXIT_SUCCESS;
1173 }
1174 // Dump.
1175 // catch help request
1176 if (find_arg("-h") >= 0 || find_arg("-help") >= 0 ||
1177 find_arg("--help") >= 0) {
1178 help(argc, argv);
1179 cleanup();
1180 return EXIT_SUCCESS;
1181 }
1182 if (find_arg("-list-keybindings") >= 0) {
1183 int is_term = isatty(fileno(stdout));
1184 abe_list_all_bindings(is_term);
1185 return EXIT_SUCCESS;
1186 }
1187
1188 unsigned int interval = 1;
1189 if (find_arg_uint("-record-screenshots", &interval)) {
1190 g_timeout_add((guint)(1000 / (double)interval), record, NULL);
1191 }
1192 if (find_arg_uint("-take-screenshot-quit", &interval)) {
1193 g_timeout_add(interval, take_screenshot_quit, NULL);
1194 }
1195 if (find_arg("-benchmark-ui") >= 0) {
1196 config.benchmark_ui = TRUE;
1197 }
1198
1200 TICK_N("Workers initialize");
1202 TICK_N("Icon fetcher initialize");
1203
1204 gboolean kill_running = FALSE;
1205 if (find_arg("-replace") >= 0) {
1206 kill_running = TRUE;
1207 }
1208 // Create pid file
1209 int pfd = create_pid_file(pidfile, kill_running);
1210 TICK_N("Pid file created");
1211 if (pfd < 0) {
1212 cleanup();
1213 return EXIT_FAILURE;
1214 }
1215 textbox_setup();
1216 TICK_N("Text box setup");
1217
1218 if (!display_late_setup()) {
1219 g_warning("Failed to properly finish display setup");
1220 cleanup();
1221 return EXIT_FAILURE;
1222 }
1223 TICK_N("Setup late Display");
1224
1227 TICK_N("Theme setup");
1228
1229 // Setup signal handling sources.
1230 // SIGINT
1231 g_unix_signal_add(SIGINT, main_loop_signal_handler_int, NULL);
1232
1233 g_idle_add(startup, NULL);
1234
1235 // Start mainloop.
1236 g_main_loop_run(main_loop);
1237 teardown(pfd);
1238 cleanup();
1239
1240 /* dirty hack */
1241 g_free(windowid);
1242 return return_code;
1243}
1244
1246extern GList *list_of_error_msgs;
1247int rofi_theme_rasi_validate(const char *filename) {
1248 rofi_theme_parse_file(filename);
1250 if (list_of_error_msgs == NULL && list_of_warning_msgs == NULL) {
1251 return EXIT_SUCCESS;
1252 }
1253
1254 for (GList *iter = g_list_first(list_of_error_msgs); iter != NULL;
1255 iter = g_list_next(iter)) {
1256 fputs(((GString *)iter->data)->str, stderr);
1257 fputs("\n", stderr);
1258 }
1259 for (GList *iter = g_list_first(list_of_warning_msgs); iter != NULL;
1260 iter = g_list_next(iter)) {
1261 fputs(((GString *)iter->data)->str, stderr);
1262 fputs("\n", stderr);
1263 }
1264
1265 return EXIT_FAILURE;
1266}
1267
1269 const Mode *index = mode_available_lookup(config.completer_mode);
1270 if (index != NULL) {
1271 return index;
1272 }
1273 const char *name =
1274 config.completer_mode == NULL ? "(null)" : config.completer_mode;
1275 g_warning("Mode: %s not found or is not valid for use as completer.", name);
1276 return NULL;
1277}
Mode combi_mode
Definition combi.c:333
void config_parse_cmd_options(void)
Definition xrmoptions.c:576
void print_options(void)
Definition xrmoptions.c:975
void config_parser_add_option(XrmOptionType type, const char *key, void **value, const char *comment)
Definition xrmoptions.c:468
void print_help_msg(const char *option, const char *type, const char *text, const char *def, int isatty)
Definition xrmoptions.c:992
void config_parse_dump_config_rasi_format(FILE *out, gboolean changes)
Dump configuration in rasi format.
Definition xrmoptions.c:837
@ xrm_String
Definition xrmoptions.h:74
void config_xresource_free(void)
Definition xrmoptions.c:775
int dmenu_mode_dialog(void)
Definition dmenu.c:920
void print_dmenu_options(void)
Definition dmenu.c:1012
Mode recursive_browser_mode
Mode file_browser_mode
void cmd_set_arguments(int argc, char **argv)
Definition helper.c:71
const char ** find_arg_strv(const char *const key)
Definition helper.c:318
char * rofi_expand_path(const char *input)
Definition helper.c:738
void remove_pid_file(int fd)
Definition helper.c:618
int find_arg_str(const char *const key, char **val)
Definition helper.c:308
int find_arg_uint(const char *const key, unsigned int *val)
Definition helper.c:347
int find_arg(const char *const key)
Definition helper.c:299
int create_pid_file(const char *pidfile, gboolean kill_running)
Definition helper.c:559
int config_sanity_check(void)
Definition helper.c:645
Mode help_keys_mode
Definition help-keys.c:113
void rofi_icon_fetcher_destroy(void)
void rofi_icon_fetcher_init(void)
gboolean parse_keys_abe(NkBindings *bindings)
Definition keyb.c:437
void setup_abe(void)
Definition keyb.c:403
void abe_list_all_bindings(gboolean is_term)
Definition keyb.c:384
void mode_destroy(Mode *mode)
Definition mode.c:64
const char * mode_get_name(const Mode *mode)
Definition mode.c:157
int mode_init(Mode *mode)
Definition mode.c:44
struct rofi_mode Mode
Definition mode.h:44
void mode_free(Mode **mode)
Definition mode.c:162
ModeMode mode_result(Mode *mode, int menu_retv, char **input, unsigned int selected_line)
Definition mode.c:131
MenuReturn
Definition mode.h:65
ModeMode
Definition mode.h:49
void mode_set_config(Mode *mode)
Definition mode.c:200
@ MODE_EXIT
Definition mode.h:51
@ NEXT_DIALOG
Definition mode.h:53
@ RELOAD_DIALOG
Definition mode.h:55
@ PREVIOUS_DIALOG
Definition mode.h:57
@ RESET_DIALOG
Definition mode.h:59
const Mode * rofi_get_mode(unsigned int index)
Definition rofi.c:154
void rofi_quit_main_loop(void)
Definition rofi.c:740
#define color_reset
Definition rofi.h:115
#define color_bold
Definition rofi.h:117
unsigned int rofi_get_num_enabled_modes(void)
Definition rofi.c:152
void rofi_clear_error_messages(void)
Definition rofi.c:98
void rofi_clear_warning_messages(void)
Definition rofi.c:111
#define color_red
Definition rofi.h:123
#define ERROR_MSG_MARKUP
Definition rofi.h:136
void rofi_set_return_code(int code)
Definition rofi.c:150
const Mode * rofi_get_completer(void)
Definition rofi.c:1268
Mode * rofi_collect_modes_search(const char *name)
Definition rofi.c:564
const char * cache_dir
Definition rofi.c:84
void rofi_add_error_message(GString *str)
Definition rofi.c:95
#define color_green
Definition rofi.h:121
void rofi_add_warning_message(GString *str)
Definition rofi.c:108
Mode run_mode
Definition run.c:598
void script_mode_gather_user_scripts(void)
Definition script.c:552
gboolean script_mode_is_valid(const char *token)
Definition script.c:643
void script_user_list(gboolean is_term)
Definition script.c:650
void script_mode_cleanup(void)
Definition script.c:545
Mode * script_mode_parse_setup(const char *str)
Definition script.c:591
Mode ssh_mode
Definition ssh.c:637
#define TICK()
Definition timings.h:64
#define TIMINGS_START()
Definition timings.h:60
#define TIMINGS_STOP()
Definition timings.h:73
#define TICK_N(a)
Definition timings.h:69
void textbox_cleanup(void)
Definition textbox.c:976
void textbox_setup(void)
Definition textbox.c:944
void textbox_cursor_end(textbox *tb)
Definition textbox.c:716
void textbox_text(textbox *tb, const char *text)
Definition textbox.c:392
void rofi_view_cleanup(void)
Definition view.c:2624
void __create_window(MenuFlags menu_flags)
Definition view.c:1004
void rofi_view_clear_input(RofiViewState *state)
Definition view.c:2753
void rofi_view_switch_mode(RofiViewState *state, Mode *mode)
Definition view.c:2765
void rofi_view_remove_active(RofiViewState *state)
Definition view.c:609
int rofi_view_error_dialog(const char *msg, int markup)
Definition view.c:2574
void rofi_view_set_active(RofiViewState *state)
Definition view.c:616
RofiViewState * rofi_view_get_active(void)
Definition view.c:607
MenuFlags
Definition view.h:50
MenuReturn rofi_view_get_return_value(const RofiViewState *state)
Definition view.c:675
const char * rofi_view_get_user_input(const RofiViewState *state)
Definition view.c:696
void rofi_view_set_selected_line(RofiViewState *state, unsigned int selected_line)
Definition view.c:639
void rofi_view_free(RofiViewState *state)
Definition view.c:657
RofiViewState * rofi_view_create(Mode *sw, const char *input, MenuFlags menu_flags, void(*finalize)(RofiViewState *))
Definition view.c:2477
unsigned int rofi_view_get_selected_line(const RofiViewState *state)
Definition view.c:679
@ MENU_TRANSIENT_WINDOW
Definition view.h:60
@ MENU_NORMAL_WINDOW
Definition view.h:56
@ MENU_NORMAL
Definition view.h:52
void rofi_capture_screenshot(void)
Definition view.c:218
void rofi_view_workers_initialize(void)
Definition view.c:2701
void rofi_view_workers_finalize(void)
Definition view.c:2730
char * helper_get_theme_path(const char *file, const char **ext, const char *parent_file)
Definition helper.c:1154
#define ABI_VERSION
static void help(G_GNUC_UNUSED int argc, char **argv)
Definition rofi.c:357
static void rofi_collect_modes(void)
Definition rofi.c:634
int main(int argc, char *argv[])
Definition rofi.c:891
GList * list_of_warning_msgs
Definition rofi.c:92
GList * list_of_error_msgs
Definition rofi.c:90
static gboolean record(G_GNUC_UNUSED void *data)
Definition rofi.c:872
G_MODULE_EXPORT char * config_path
Definition rofi.c:123
NkBindings * bindings
Definition rofi.c:138
static void print_main_application_options(int is_term)
Definition rofi.c:312
static void print_list_of_modes(int is_term)
Definition rofi.c:298
static void run_mode_index(ModeMode mode)
Definition rofi.c:203
static void rofi_custom_log_function(const char *log_domain, G_GNUC_UNUSED GLogLevelFlags log_level, const gchar *message, gpointer user_data)
Definition rofi.c:876
static void help_print_mode_not_found(const char *mode)
Definition rofi.c:463
static void cleanup(void)
Definition rofi.c:516
Mode ** modes
Definition rofi.c:126
static gboolean startup(G_GNUC_UNUSED gpointer data)
Definition rofi.c:767
static gboolean setup_modes(void)
Definition rofi.c:719
Mode ** available_modes
Definition rofi.c:129
int rofi_theme_rasi_validate(const char *filename)
Definition rofi.c:1247
unsigned int num_modes
Definition rofi.c:133
static void rofi_collectmodes_setup(void)
Definition rofi.c:669
GMainLoop * main_loop
Definition rofi.c:141
static void teardown(int pfd)
Definition rofi.c:190
static gboolean rofi_collectmodes_add(Mode *mode)
Definition rofi.c:577
static gboolean take_screenshot_quit(G_GNUC_UNUSED void *data)
Definition rofi.c:867
static void rofi_collectmodes_destroy(void)
Definition rofi.c:674
char * pidfile
Definition rofi.c:82
int return_code
Definition rofi.c:146
void process_result(RofiViewState *state)
Definition rofi.c:237
static const Mode * mode_available_lookup(const char *name)
Definition rofi.c:178
static int add_mode(const char *token)
Definition rofi.c:697
static gboolean main_loop_signal_handler_int(G_GNUC_UNUSED gpointer data)
Definition rofi.c:742
static void show_error_dialog(void)
Definition rofi.c:747
char * cache_dir_alloc
Definition rofi.c:87
int rofi_is_in_dmenu_mode
Definition rofi.c:144
static void help_print_no_arguments(void)
Definition rofi.c:480
static int mode_lookup(const char *name)
Definition rofi.c:163
static void help_print_disabled_mode(const char *mode)
Definition rofi.c:450
unsigned int num_available_modes
Definition rofi.c:131
static void rofi_collectmodes_dir(const char *base_dir)
Definition rofi.c:590
unsigned int curr_mode
Definition rofi.c:135
Settings config
textbox * text
unsigned int abi_version
GModule * module
char * name
void rofi_theme_free_parsed_files(void)
Definition theme.c:54
void rofi_theme_print_parsed_files(gboolean is_term)
Definition theme.c:64
void rofi_theme_print(ThemeWidget *wid)
Definition theme.c:593
void rofi_theme_parse_process_links(void)
Definition theme.c:1598
void rofi_theme_parse_process_conditionals(void)
Definition theme.c:1602
void rofi_theme_free(ThemeWidget *wid)
Definition theme.c:240
char * rofi_theme_parse_prepare_file(const char *file)
Definition theme.c:1418
void rofi_theme_reset(void)
Definition theme.c:234
gboolean rofi_theme_parse_string(const char *string)
gboolean rofi_theme_parse_file(const char *file)
ThemeWidget * rofi_theme
Definition theme.h:43
gboolean display_late_setup(void)
Definition xcb.c:1908
void display_early_cleanup(void)
Definition xcb.c:1943
void display_cleanup(void)
Definition xcb.c:1949
char * x11_helper_get_window_manager(void)
Definition xcb.c:1626
gboolean display_setup(GMainLoop *main_loop, NkBindings *bindings)
Definition xcb.c:1671
void display_dump_monitor_layout(void)
Definition xcb.c:695
ThemeWidget * rofi_configuration
Definition xrmoptions.c:46