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;
126 while (end < data + len && *end !=
'\0') {
129 if (end != data + len) {
130 data_len = end - data;
132 end + 1, len - data_len);
141 gpointer user_data) {
142 GDataInputStream *stream = (GDataInputStream *)source_object;
145 char *data = g_data_input_stream_read_upto_finish(stream, res, &len, NULL);
148 g_data_input_stream_read_byte(stream, NULL, NULL);
154 1, G_PRIORITY_LOW, pd->
cancel,
158 GError *error = NULL;
161 g_data_input_stream_read_byte(stream, NULL, &error);
174 if (!g_cancellable_is_cancelled(pd->
cancel)) {
176 g_debug(
"Clearing overlay");
178 g_input_stream_close_async(G_INPUT_STREAM(stream), G_PRIORITY_LOW,
184 G_GNUC_UNUSED gpointer data) {
185 g_debug(
"Cancelled the async read.");
189 while (sync_pre_read--) {
191 char *data = g_data_input_stream_read_upto(
194 g_input_stream_close_async(G_INPUT_STREAM(pd->
input_stream),
195 G_PRIORITY_LOW, pd->
cancel,
204 1, G_PRIORITY_LOW, pd->
cancel,
211 char *data = g_data_input_stream_read_upto(
220 g_input_stream_close_async(G_INPUT_STREAM(pd->
input_stream), G_PRIORITY_LOW,
233 return g_strdup(input);
239 for (; splitted && splitted[ns]; ns++) {
244 (
unsigned int)g_ascii_strtoull(pd->
columns[i], NULL, 10);
245 if (index < ns && index > 0) {
247 retv = g_strdup(splitted[index - 1]);
249 gchar *t = g_strjoin(
"\t", retv, splitted[index - 1], NULL);
255 g_strfreev(splitted);
256 return retv ? retv : g_strdup(
"");
259 static inline unsigned int get_index(
unsigned int length,
int index) {
263 if (((
unsigned int)-index) <= length) {
264 return length + index;
271 G_GNUC_UNUSED GList **list,
int get_entry) {
309 g_cancellable_cancel(pd->
cancel);
318 g_object_unref(pd->
cancel);
342 .cfg_name_key =
"display-combi",
350 ._get_completion = NULL,
351 ._preprocess_input = NULL,
353 .private_data = NULL,
355 .display_name =
"dmenu"};
396 p->
name = g_strdup(
"lines");
401 g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
404 g_hash_table_replace(table, p->
name, p);
406 g_hash_table_destroy(table);
427 int fd = STDIN_FILENO;
431 fd = open(str, O_RDONLY);
433 char *msg = g_markup_printf_escaped(
434 "Failed to open file: <b>%s</b>:\n\t<i>%s</i>", estr,
445 if (!(fd == STDIN_FILENO && isatty(fd) == 1)) {
446 pd->
cancel = g_cancellable_new();
449 pd->
input_stream = g_unix_input_stream_new(fd, fd != STDIN_FILENO);
452 gchar *columns = NULL;
454 pd->
columns = g_strsplit(columns,
",", 0);
462 unsigned int index) {
468 pango_parse_markup(rmpd->
cmd_list[index].
entry, -1, 0, NULL, &esc, NULL,
477 for (
int j = 0; match && tokens != NULL && tokens[j] != NULL; j++) {
481 if (test == tokens[j]->invert && rmpd->
cmd_list[index].
meta) {
505 unsigned int selected_line,
int height) {
507 g_return_val_if_fail(pd->
cmd_list != NULL, NULL);
522 }
else if (retv >= 10) {
544 const char *cmd = input;
576 restart = (
find_arg(
"-only-match") >= 0);
696 unsigned int pre_read = 25;
709 if (
find_arg(
"-multi-select") >= 0) {
713 if (
find_arg(
"-markup-rows") >= 0) {
718 if (cmd_list_length == 0) {
734 if (select != NULL) {
737 for (i = 0; i < cmd_list_length; i++) {
749 for (i = 0; i < cmd_list_length; i++) {
768 if (async && (pd->
cancel != NULL)) {
778 int is_term = isatty(fileno(stdout));
781 "Print a small user message under the prompt (uses pango markup)", NULL,
783 print_help_msg(
"-p",
"[string]",
"Prompt to display left of entry field",
785 print_help_msg(
"-selected-row",
"[integer]",
"Select row", NULL, is_term);
786 print_help_msg(
"-format",
"[string]",
"Output format string",
"s", is_term);
787 print_help_msg(
"-u",
"[list]",
"List of row indexes to mark urgent", NULL,
789 print_help_msg(
"-a",
"[list]",
"List of row indexes to mark active", NULL,
791 print_help_msg(
"-l",
"[integer] ",
"Number of rows to display", NULL,
793 print_help_msg(
"-window-title",
"[string] ",
"Set the dmenu window title",
795 print_help_msg(
"-i",
"",
"Set filter to be case insensitive", NULL, is_term);
797 "Force selection to be given entry, disallow no match", NULL,
799 print_help_msg(
"-no-custom",
"",
"Don't accept custom entry, allow no match",
801 print_help_msg(
"-select",
"[string]",
"Select the first row that matches",
804 "Do not show what the user inputs. Show '*' instead.", NULL,
807 "Allow and render pango markup as input data.", NULL, is_term);
808 print_help_msg(
"-sep",
"[char]",
"Element separator.",
"'\\n'", is_term);
810 "Read input from file instead from standard input.", NULL,
813 "Force dmenu to first read all input data, then show dialog.",
816 "Read several entries blocking before switching to async mode",
818 print_help_msg(
"-w",
"windowid",
"Position over window with X11 windowid.",
820 print_help_msg(
"-keep-right",
"",
"Set ellipsize to end.", NULL, is_term);