29 #define G_LOG_DOMAIN "Dialogs.DMenu"
43 #include <gio/gunixinputstream.h>
50 #include <sys/types.h>
59 unsigned int selected_line,
int height);
62 static inline unsigned int bitget(uint32_t *array,
unsigned int index) {
63 uint32_t bit = index % 32;
64 uint32_t val = array[index / 32];
65 return (val >> bit) & 1;
68 static inline void bittoggle(uint32_t *array,
unsigned int index) {
69 uint32_t bit = index % 32;
70 uint32_t *v = &array[index / 32];
107 G_GNUC_UNUSED gpointer user_data) {
108 g_input_stream_close_finish(G_INPUT_STREAM(source_object), res, NULL);
109 g_debug(
"Closing data stream.");
113 gsize data_len = len;
125 while (end < data + len && *end !=
'\0') {
128 if (end != data + len) {
129 data_len = end - data;
131 end + 1, len - data_len);
140 gpointer user_data) {
141 GDataInputStream *stream = (GDataInputStream *)source_object;
144 char *data = g_data_input_stream_read_upto_finish(stream, res, &len, NULL);
147 g_data_input_stream_read_byte(stream, NULL, NULL);
153 1, G_PRIORITY_LOW, pd->
cancel,
157 GError *error = NULL;
160 g_data_input_stream_read_byte(stream, NULL, &error);
173 if (!g_cancellable_is_cancelled(pd->
cancel)) {
175 g_debug(
"Clearing overlay");
177 g_input_stream_close_async(G_INPUT_STREAM(stream), G_PRIORITY_LOW,
183 G_GNUC_UNUSED gpointer data) {
184 g_debug(
"Cancelled the async read.");
188 while (sync_pre_read--) {
190 char *data = g_data_input_stream_read_upto(
193 g_input_stream_close_async(G_INPUT_STREAM(pd->
input_stream),
194 G_PRIORITY_LOW, pd->
cancel,
203 1, G_PRIORITY_LOW, pd->
cancel,
210 char *data = g_data_input_stream_read_upto(
219 g_input_stream_close_async(G_INPUT_STREAM(pd->
input_stream), G_PRIORITY_LOW,
232 return g_strdup(input);
238 for (; splitted && splitted[ns]; ns++) {
243 (
unsigned int)g_ascii_strtoull(pd->
columns[i], NULL, 10);
244 if (index < ns && index > 0) {
246 retv = g_strdup(splitted[index - 1]);
248 gchar *t = g_strjoin(
"\t", retv, splitted[index - 1], NULL);
254 g_strfreev(splitted);
255 return retv ? retv : g_strdup(
"");
258 static inline unsigned int get_index(
unsigned int length,
int index) {
262 if (((
unsigned int)-index) <= length) {
263 return length + index;
270 G_GNUC_UNUSED GList **list,
int get_entry) {
308 g_cancellable_cancel(pd->
cancel);
317 g_object_unref(pd->
cancel);
341 .cfg_name_key =
"display-combi",
349 ._get_completion = NULL,
350 ._preprocess_input = NULL,
352 .private_data = NULL,
354 .display_name =
"dmenu"};
395 p->
name = g_strdup(
"lines");
400 g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
403 g_hash_table_replace(table, p->
name, p);
405 g_hash_table_destroy(table);
426 int fd = STDIN_FILENO;
430 fd = open(str, O_RDONLY);
432 char *msg = g_markup_printf_escaped(
433 "Failed to open file: <b>%s</b>:\n\t<i>%s</i>", estr,
444 if (!(fd == STDIN_FILENO && isatty(fd) == 1)) {
445 pd->
cancel = g_cancellable_new();
448 pd->
input_stream = g_unix_input_stream_new(fd, fd != STDIN_FILENO);
451 gchar *columns = NULL;
453 pd->
columns = g_strsplit(columns,
",", 0);
461 unsigned int index) {
467 pango_parse_markup(rmpd->
cmd_list[index].
entry, -1, 0, NULL, &esc, NULL,
476 for (
int j = 0; match && tokens != NULL && tokens[j] != NULL; j++) {
480 if (test == tokens[j]->invert && rmpd->
cmd_list[index].
meta) {
504 unsigned int selected_line,
int height) {
506 g_return_val_if_fail(pd->
cmd_list != NULL, NULL);
521 }
else if (retv >= 10) {
543 const char *cmd = input;
573 restart = (
find_arg(
"-only-match") >= 0);
693 unsigned int pre_read = 25;
706 if (
find_arg(
"-multi-select") >= 0) {
710 if (
find_arg(
"-markup-rows") >= 0) {
715 if (cmd_list_length == 0) {
731 if (select != NULL) {
734 for (i = 0; i < cmd_list_length; i++) {
746 for (i = 0; i < cmd_list_length; i++) {
765 if (async && (pd->
cancel != NULL)) {
775 int is_term = isatty(fileno(stdout));
778 "Print a small user message under the prompt (uses pango markup)", NULL,
780 print_help_msg(
"-p",
"[string]",
"Prompt to display left of entry field",
782 print_help_msg(
"-selected-row",
"[integer]",
"Select row", NULL, is_term);
783 print_help_msg(
"-format",
"[string]",
"Output format string",
"s", is_term);
784 print_help_msg(
"-u",
"[list]",
"List of row indexes to mark urgent", NULL,
786 print_help_msg(
"-a",
"[list]",
"List of row indexes to mark active", NULL,
788 print_help_msg(
"-l",
"[integer] ",
"Number of rows to display", NULL,
790 print_help_msg(
"-window-title",
"[string] ",
"Set the dmenu window title",
792 print_help_msg(
"-i",
"",
"Set filter to be case insensitive", NULL, is_term);
794 "Force selection to be given entry, disallow no match", NULL,
796 print_help_msg(
"-no-custom",
"",
"Don't accept custom entry, allow no match",
798 print_help_msg(
"-select",
"[string]",
"Select the first row that matches",
801 "Do not show what the user inputs. Show '*' instead.", NULL,
804 "Allow and render pango markup as input data.", NULL, is_term);
805 print_help_msg(
"-sep",
"[char]",
"Element separator.",
"'\\n'", is_term);
807 "Read input from file instead from standard input.", NULL,
810 "Force dmenu to first read all input data, then show dialog.",
813 "Read several entries blocking before switching to async mode",
815 print_help_msg(
"-w",
"windowid",
"Position over window with X11 windowid.",
817 print_help_msg(
"-keep-right",
"",
"Set ellipsize to end.", NULL, is_term);
void print_help_msg(const char *option, const char *type, const char *text, const char *def, int isatty)
void parse_ranges(char *input, rofi_range_pair **list, unsigned int *length)
int find_arg_char(const char *const key, char *val)
void helper_tokenize_free(rofi_int_matcher **tokens)
void rofi_output_formatted_line(const char *format, const char *string, int selected_line, const char *filter)
char * rofi_expand_path(const char *input)
int find_arg_str(const char *const key, char **val)
rofi_int_matcher ** helper_tokenize(const char *input, int case_sensitive)
int find_arg_uint(const char *const key, unsigned int *val)
int find_arg(const char *const key)
int helper_token_match(rofi_int_matcher *const *tokens, const char *input)
char * rofi_force_utf8(const gchar *data, ssize_t length)
cairo_surface_t * rofi_icon_fetcher_get(const uint32_t uid)
uint32_t rofi_icon_fetcher_query(const char *name, const int size)
void mode_destroy(Mode *mode)
int mode_init(Mode *mode)
void mode_set_private_data(Mode *mode, void *pd)
void * mode_get_private_data(const Mode *mode)
void rofi_set_return_code(int code)
void rofi_view_set_overlay(RofiViewState *state, const char *text)
void rofi_view_reload(void)
Mode * rofi_view_get_mode(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)
void rofi_view_restart(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)
unsigned int rofi_view_get_next_position(const RofiViewState *state)
void rofi_view_ellipsize_start(RofiViewState *state)
void dmenuscript_parse_entry_extras(G_GNUC_UNUSED Mode *sw, DmenuScriptEntry *entry, char *buffer, G_GNUC_UNUSED size_t length)
#define DEFAULT_MENU_LINES
unsigned int case_sensitive
Property * rofi_theme_property_create(PropertyType type)
void rofi_theme_widget_add_properties(ThemeWidget *widget, GHashTable *table)
ThemeWidget * rofi_theme_find_or_create_name(ThemeWidget *base, const char *name)
void rofi_theme_property_free(Property *p)