30 #define G_LOG_DOMAIN "Rofi"
39 #include <sys/types.h>
45 #include <glib-unix.h>
47 #include <libgwater-xcb.h>
49 #ifdef USE_NK_GIT_VERSION
50 #include "nkutils-git-version.h"
52 #define GIT_VERSION NK_GIT_VERSION
56 #include "resources.h"
95 iter = g_list_next(iter)) {
96 g_string_free((GString *)iter->data, TRUE);
145 for (
unsigned int i = 0; i <
num_modi; i++) {
170 for (
unsigned int i = 0; i <
num_modi; i++) {
172 GString *str = g_string_new(
"Failed to initialize the mode: ");
173 g_string_append(str,
modi[i]->name);
174 g_string_append(str,
"\n");
177 g_string_free(str, FALSE);
190 if (
find_arg(
"-selected-row") >= 0) {
265 gboolean active = FALSE;
266 for (
unsigned int j = 0; j <
num_modi; j++) {
272 printf(
" * %s%s%s%s\n", active ?
"+" :
"",
279 "Do not load configuration, use default values.", NULL,
281 print_help_msg(
"-v,-version",
"",
"Print the version number and exit.", NULL,
283 print_help_msg(
"-dmenu",
"",
"Start in dmenu mode.", NULL, is_term);
284 print_help_msg(
"-display",
"[string]",
"X server to contact.",
"${DISPLAY}",
286 print_help_msg(
"-h,-help",
"",
"This help message.", NULL, is_term);
288 "Show a dialog displaying the passed message and exit.", NULL,
290 print_help_msg(
"-markup",
"",
"Enable pango markup where possible.", NULL,
293 "Behave as a normal window. (experimental)", NULL, is_term);
295 "Show the mode 'mode' and exit. The mode has to be enabled.",
298 "Disable lazy grab that, when fail to grab keyboard, does not "
299 "block but retry later.",
301 print_help_msg(
"-no-plugins",
"",
"Disable loading of external plugins.",
304 "Directory used to search for rofi plugins. *DEPRECATED*",
307 "Dump the current configuration in rasi format and exit.",
310 "Dump the current theme in rasi format and exit.", NULL,
313 static void help(G_GNUC_UNUSED
int argc,
char **argv) {
314 int is_term = isatty(fileno(stdout));
315 printf(
"%s usage:\n", argv[0]);
316 printf(
"\t%s [-options ...]\n\n", argv[0]);
317 printf(
"Command line only options:\n");
319 printf(
"DMENU command line options:\n");
321 printf(
"Global options:\n");
326 printf(
"Detected modi:\n");
329 printf(
"Compile time options:\n");
331 printf(
"\t* window %senabled%s\n", is_term ?
color_green :
"",
334 printf(
"\t* window %sdisabled%s\n", is_term ?
color_red :
"",
338 printf(
"\t* drun %senabled%s\n", is_term ?
color_green :
"",
341 printf(
"\t* drun %sdisabled%s\n", is_term ?
color_red :
"",
345 printf(
"\t* gcov %senabled%s\n", is_term ?
color_green :
"",
348 printf(
"\t* gcov %sdisabled%s\n", is_term ?
color_red :
"",
352 printf(
"\t* asan %senabled%s\n", is_term ?
color_green :
"",
355 printf(
"\t* asan %sdisabled%s\n", is_term ?
color_red :
"",
359 printf(
"For more information see: %sman rofi%s\n", is_term ?
color_bold :
"",
362 printf(
" Version: %s" GIT_VERSION
"%s\n",
365 printf(
" Version: %s" VERSION
"%s\n",
368 printf(
" Bugreports: %s" PACKAGE_BUGREPORT
"%s\n",
370 printf(
" Support: %s" PACKAGE_URL
"%s\n",
372 printf(
" %s#rofi @ libera.chat%s\n",
376 printf(
" Configuration file: %s%s%s\n", is_term ?
color_bold :
"",
380 printf(
" Configuration file: %sDisabled%s\n",
386 int is_term = isatty(fileno(stdout));
389 fprintf(stderr,
"Mode %s%s%s is not enabled. I have enabled it for now.\n",
392 "Please consider adding %s%s%s to the list of enabled modi: "
393 "%smodi: %s%s%s,%s%s.\n",
399 GString *str = g_string_new(
"");
400 g_string_printf(str,
"Mode %s is not found.\nThe following modi are known:\n",
403 gboolean active = FALSE;
404 for (
unsigned int j = 0; j <
num_modi; j++) {
410 g_string_append_printf(str,
" * %s%s\n", active ?
"+" :
"",
416 int is_term = isatty(fileno(stdout));
418 fprintf(stderr,
"Rofi is unsure what to show.\n");
419 fprintf(stderr,
"Please specify the mode you want to show.\n\n");
420 fprintf(stderr,
" %srofi%s -show %s{mode}%s\n\n",
423 fprintf(stderr,
"The following modi are enabled:\n");
424 for (
unsigned int j = 0; j <
num_modi; j++) {
425 fprintf(stderr,
" * %s%s%s\n", is_term ?
color_green :
"",
modi[j]->name,
428 fprintf(stderr,
"\nThe following can be enabled:\n");
430 gboolean active = FALSE;
431 for (
unsigned int j = 0; j <
num_modi; j++) {
438 fprintf(stderr,
" * %s%s%s\n", is_term ?
color_red :
"",
443 "\nTo activate a mode, add it to the list of modi in the %smodi%s "
452 for (
unsigned int i = 0; i <
num_modi; i++) {
518 g_debug(
"Looking into: %s for plugins", base_dir);
519 GDir *dir = g_dir_open(base_dir, 0, NULL);
521 const char *dn = NULL;
522 while ((dn = g_dir_read_name(dir))) {
523 if (!g_str_has_suffix(dn, G_MODULE_SUFFIX)) {
526 char *fn = g_build_filename(base_dir, dn, NULL);
527 g_debug(
"Trying to open: %s plugin", fn);
529 g_module_open(fn, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
532 if (g_module_symbol(mod,
"mode", (gpointer *)&m)) {
534 g_warning(
"ABI version of plugin: '%s' does not match: %08X "
545 g_warning(
"Symbol 'mode' not found in module: %s", dn);
549 g_warning(
"Failed to open 'mode' plugin: '%s', error: %s", dn,
580 const char *path = g_getenv(
"ROFI_PLUGIN_PATH");
582 gchar **paths = g_strsplit(path,
":", -1);
583 for (
unsigned int i = 0; paths[i]; i++) {
642 return (index ==
num_modi) ? -1 : (int)index;
645 const char *
const sep =
",#";
650 for (
char *token = strtok_r(switcher_str, sep, &savept); token != NULL;
651 token = strtok_r(NULL, sep, &savept)) {
657 g_free(switcher_str);
670 return G_SOURCE_CONTINUE;
674 g_string_new(
"The following errors were detected when starting rofi:\n");
677 for (; iter != NULL && index < 2; iter = g_list_next(iter)) {
678 GString *msg = (GString *)(iter->data);
679 g_string_append(emesg,
"\n\n");
680 g_string_append(emesg, msg->str);
683 if (g_list_length(iter) > 1) {
684 g_string_append_printf(emesg,
"\nThere are <b>%d</b> more errors.",
685 g_list_length(iter) - 1);
688 g_string_free(emesg, TRUE);
692 static gboolean
startup(G_GNUC_UNUSED gpointer data) {
699 if (
find_arg(
"-normal-window") >= 0) {
709 TICK_N(
"Config sanity check");
713 return G_SOURCE_REMOVE;
749 return G_SOURCE_REMOVE;
759 return G_SOURCE_REMOVE;
762 static gboolean
record(G_GNUC_UNUSED
void *data) {
764 return G_SOURCE_CONTINUE;
774 int main(
int argc,
char *argv[]) {
782 g_print(
"Version: " GIT_VERSION
"\n");
784 g_print(
"Version: " VERSION
"\n");
789 if (
find_arg(
"-rasi-validate") >= 0) {
797 fprintf(stderr,
"Usage: %s -rasi-validate my-theme.rasi", argv[0]);
802 const char *ro_pid = g_getenv(
"ROFI_OUTSIDE");
803 if (ro_pid != NULL) {
804 int ro_pidi = g_ascii_strtoll(ro_pid, NULL, 0);
805 if (kill(ro_pidi, 0) == 0) {
806 printf(
"Do not launch rofi from inside rofi.\r\n");
821 char *base_name = g_path_get_basename(argv[0]);
822 const char *
const dmenu_str =
"dmenu";
823 dmenu_mode = (strcmp(base_name, dmenu_str) == 0);
830 const char *path = g_get_user_runtime_dir();
832 if (g_mkdir_with_parents(path, 0700) < 0) {
833 g_warning(
"Failed to create user runtime directory: %s with error: %s",
834 path, g_strerror(errno));
835 pidfile = g_build_filename(g_get_home_dir(),
".rofi.pid", NULL);
837 pidfile = g_build_filename(path,
"rofi.pid", NULL);
844 if (
find_arg(
"-no-default-config") < 0) {
845 GBytes *theme_data = g_resource_lookup_data(
846 resources_get_resource(),
"/org/qtools/rofi/default_configuration.rasi",
847 G_RESOURCE_LOOKUP_FLAGS_NONE, NULL);
849 const char *theme = g_bytes_get_data(theme_data, NULL);
851 g_warning(
"Failed to parse default configuration. Giving up..");
854 iter = g_list_next(iter)) {
855 g_warning(
"Error: %s%s%s",
color_bold, ((GString *)iter->data)->str,
863 g_bytes_unref(theme_data);
868 const char *cpath = g_get_user_config_dir();
870 config_path = g_build_filename(cpath,
"rofi",
"config.rasi", NULL);
879 if (setlocale(LC_ALL,
"") == NULL) {
880 g_warning(
"Failed to set locale.");
891 main_loop = g_main_loop_new(NULL, FALSE);
899 g_warning(
"Connection has error");
911 gboolean found_system = FALSE;
912 const char *
const *dirs = g_get_system_config_dirs();
914 for (
unsigned int i = 0; !found_system && dirs[i]; i++) {
916 gchar *etc = g_build_filename(dirs[i],
"rofi.rasi", NULL);
917 g_debug(
"Look for default config file: %s", etc);
918 if (g_file_test(etc, G_FILE_TEST_IS_REGULAR)) {
919 g_debug(
"Parsing: %s", etc);
928 gchar *etc = g_build_filename(SYSCONFDIR,
"rofi.rasi", NULL);
929 g_debug(
"Look for default config file: %s", etc);
930 if (g_file_test(etc, G_FILE_TEST_IS_REGULAR)) {
931 g_debug(
"Look for default config file: %s", etc);
949 g_warning(
"Failed to parse theme: \"%s\"",
config.
theme);
958 TICK_N(
"Load cmd config ");
969 if (g_mkdir_with_parents(
cache_dir, 0700) < 0) {
970 g_warning(
"Failed to create cache directory: %s", g_strerror(errno));
975 char *windowid = NULL;
996 for (
int index = 0; theme_str && theme_str[index]; index++) {
998 g_warning(
"Failed to parse -theme-str option: \"%s\"",
1007 if (
find_arg(
"-dump-theme") >= 0) {
1010 return EXIT_SUCCESS;
1012 if (
find_arg(
"-dump-config") >= 0) {
1015 return EXIT_SUCCESS;
1023 return EXIT_SUCCESS;
1026 unsigned int interval = 1;
1028 g_timeout_add(1000 / (
double)interval,
record, NULL);
1030 if (
find_arg(
"-benchmark-ui") >= 0) {
1035 TICK_N(
"Workers initialize");
1037 TICK_N(
"Icon fetcher initialize");
1041 TICK_N(
"Pid file created");
1044 return EXIT_FAILURE;
1047 TICK_N(
"Text box setup");
1050 g_warning(
"Failed to properly finish display setup");
1052 return EXIT_FAILURE;
1054 TICK_N(
"Setup late Display");
1080 return EXIT_SUCCESS;
1084 iter = g_list_next(iter)) {
1085 fputs(((GString *)iter->data)->str, stderr);
1088 return EXIT_FAILURE;
void config_parse_cmd_options(void)
void config_parser_add_option(XrmOptionType type, const char *key, void **value, const char *comment)
void print_help_msg(const char *option, const char *type, const char *text, const char *def, int isatty)
void config_parse_dump_config_rasi_format(FILE *out, gboolean changes)
Dump configuration in rasi format.
void config_xresource_free(void)
void cmd_set_arguments(int argc, char **argv)
int create_pid_file(const char *pidfile)
const char ** find_arg_strv(const char *const key)
void remove_pid_file(int fd)
char * rofi_expand_path(const char *input)
int find_arg_str(const char *const key, char **val)
int find_arg_uint(const char *const key, unsigned int *val)
int find_arg(const char *const key)
int config_sanity_check(void)
void rofi_icon_fetcher_destroy(void)
void rofi_icon_fetcher_init(void)
gboolean parse_keys_abe(NkBindings *bindings)
void mode_destroy(Mode *mode)
int mode_init(Mode *mode)
void mode_free(Mode **mode)
ModeMode mode_result(Mode *mode, int menu_retv, char **input, unsigned int selected_line)
const char * mode_get_name(const Mode *mode)
void mode_set_config(Mode *mode)
void rofi_quit_main_loop(void)
Mode * rofi_collect_modi_search(const char *name)
void rofi_clear_error_messages(void)
void rofi_set_return_code(int code)
unsigned int rofi_get_num_enabled_modi(void)
const Mode * rofi_get_mode(unsigned int index)
void rofi_add_error_message(GString *str)
Mode * script_switcher_parse_setup(const char *str)
gboolean script_switcher_is_valid(const char *token)
void textbox_cleanup(void)
void textbox_cursor_end(textbox *tb)
void textbox_text(textbox *tb, const char *text)
void __create_window(MenuFlags menu_flags)
void rofi_view_clear_input(RofiViewState *state)
void rofi_view_switch_mode(RofiViewState *state, Mode *mode)
void rofi_view_remove_active(RofiViewState *state)
RofiViewState * rofi_view_get_active(void)
int rofi_view_error_dialog(const char *msg, int markup)
void rofi_view_set_active(RofiViewState *state)
MenuReturn rofi_view_get_return_value(const RofiViewState *state)
void rofi_view_set_selected_line(RofiViewState *state, unsigned int selected_line)
RofiViewState * rofi_view_create(Mode *sw, const char *input, MenuFlags menu_flags, void(*finalize)(RofiViewState *))
void rofi_view_free(RofiViewState *state)
const char * rofi_view_get_user_input(const RofiViewState *state)
unsigned int rofi_view_get_selected_line(const RofiViewState *state)
void rofi_capture_screenshot(void)
void rofi_view_workers_initialize(void)
void rofi_view_workers_finalize(void)
static void help(G_GNUC_UNUSED int argc, char **argv)
static void rofi_collect_modi_setup(void)
static void rofi_collect_modi_destroy(void)
int main(int argc, char *argv[])
GList * list_of_error_msgs
static int switcher_get(const char *name)
static gboolean record(G_GNUC_UNUSED void *data)
G_MODULE_EXPORT char * config_path
static void print_main_application_options(int is_term)
static void run_switcher(ModeMode mode)
static void help_print_mode_not_found(const char *mode)
static void print_list_of_modi(int is_term)
static void rofi_collect_modi_dir(const char *base_dir)
static gboolean startup(G_GNUC_UNUSED gpointer data)
static void rofi_collect_modi(void)
int rofi_theme_rasi_validate(const char *filename)
static void teardown(int pfd)
static void show_error_dialog()
void process_result(RofiViewState *state)
unsigned int num_available_modi
static int add_mode(const char *token)
static gboolean main_loop_signal_handler_int(G_GNUC_UNUSED gpointer data)
static gboolean setup_modi(void)
unsigned int curr_switcher
static void help_print_no_arguments(void)
static void help_print_disabled_mode(const char *mode)
static gboolean rofi_collect_modi_add(Mode *mode)
unsigned int sidebar_mode
void rofi_theme_parse_process_conditionals(void)
void rofi_theme_print(ThemeWidget *widget)
void rofi_theme_reset(void)
void rofi_theme_free(ThemeWidget *widget)
gboolean rofi_theme_parse_string(const char *string)
gboolean rofi_theme_parse_file(const char *file)
gboolean display_late_setup(void)
void display_early_cleanup(void)
void display_cleanup(void)
gboolean display_setup(GMainLoop *main_loop, NkBindings *bindings)
void display_dump_monitor_layout(void)
ThemeWidget * rofi_configuration