added support for --pre-display-cmd / -r. also removed some compile-time warnings of unused variables by fact-checking runtime errors

This commit is contained in:
mazunki 2021-10-29 21:34:49 +02:00
parent dab17466a0
commit c597c088d6
4 changed files with 104 additions and 39 deletions

View File

@ -112,6 +112,10 @@ Specifies something to search for immediately on opening
.TP .TP
.B \-o, \-\-monitor .B \-o, \-\-monitor
Sets the monitor to open on Sets the monitor to open on
.TP
.B \-r, \-\-pre\-display\-cmd
If set, the selectable entry won't be displayed as-is, but will instead be displayed based on the output of this command, which can be anything. Suggested to use with \fB"echo %s | some_cmd"\fR or \fB"some_cmd %s"\fR, as the string gets replaced in a printf-like fashion. This will not affect the output of wofi once a selection has been done, allowing you to display something else than the original output.
.SH CONFIGURATION .SH CONFIGURATION
Wofi has 3 main files used for configuration. All files are completely optional. Wofi has 3 main files used for configuration. All files are completely optional.

View File

@ -183,6 +183,8 @@ Specifies the layer to open on. The options are background, bottom, top, and ove
.TP .TP
.B copy_exec=\fIPATH\fR .B copy_exec=\fIPATH\fR
Specifies the executable to pipe copy data into. $PATH will be scanned, this is not passed to a shell and must be an executable. Default is wl-copy. Specifies the executable to pipe copy data into. $PATH will be scanned, this is not passed to a shell and must be an executable. Default is wl-copy.
.B pre_display_cmd=\fSTR\fR
Specifies a printf-like string which is used on the entries prior to displaying them. This command is only used to represent the label widget's string, and won't affect the the output of the selected label.
.SH CSS SELECTORS .SH CSS SELECTORS
Any GTK widget can be selected by using the name of its CSS node, these however might change with updates and are not guaranteed to stay constant. Wofi also provides certain widgets with names and classes which can be referenced from CSS to give access to the most important widgets easily. \fBwofi\fR(7) contains the current widget layout used by wofi so if you want to get into CSS directly using GTK widget names look there for info. Any GTK widget can be selected by using the name of its CSS node, these however might change with updates and are not guaranteed to stay constant. Wofi also provides certain widgets with names and classes which can be referenced from CSS to give access to the most important widgets easily. \fBwofi\fR(7) contains the current widget layout used by wofi so if you want to get into CSS directly using GTK widget names look there for info.

View File

@ -63,39 +63,40 @@ static char* get_exec_name(char* path) {
static void print_usage(char** argv) { static void print_usage(char** argv) {
printf("%s [options]\n", get_exec_name(argv[0])); printf("%s [options]\n", get_exec_name(argv[0]));
printf("Options:\n"); printf("Options:\n");
printf("--help\t\t-h\tDisplays this help message\n"); printf("--help\t\t\t-h\tDisplays this help message\n");
printf("--fork\t\t-f\tForks the menu so you can close the terminal\n"); printf("--fork\t\t\t-f\tForks the menu so you can close the terminal\n");
printf("--conf\t\t-c\tSelects a config file to use\n"); printf("--conf\t\t\t-c\tSelects a config file to use\n");
printf("--style\t\t-s\tSelects a stylesheet to use\n"); printf("--style\t\t\t-s\tSelects a stylesheet to use\n");
printf("--color\t\t-C\tSelects a colors file to use\n"); printf("--color\t\t\t-C\tSelects a colors file to use\n");
printf("--dmenu\t\t-d\tRuns in dmenu mode\n"); printf("--dmenu\t\t\t-d\tRuns in dmenu mode\n");
printf("--show\t\t-S\tSpecifies the mode to run in\n"); printf("--show\t\t\t-S\tSpecifies the mode to run in\n");
printf("--width\t\t-W\tSpecifies the surface width\n"); printf("--width\t\t\t-W\tSpecifies the surface width\n");
printf("--height\t-H\tSpecifies the surface height\n"); printf("--height\t\t-H\tSpecifies the surface height\n");
printf("--prompt\t-p\tPrompt to display\n"); printf("--prompt\t\t-p\tPrompt to display\n");
printf("--xoffset\t-x\tThe x offset\n"); printf("--xoffset\t\t-x\tThe x offset\n");
printf("--yoffset\t-y\tThe y offset\n"); printf("--yoffset\t\t-y\tThe y offset\n");
printf("--normal-window\t-n\tRender to a normal window\n"); printf("--normal-window\t\t-n\tRender to a normal window\n");
printf("--allow-images\t-I\tAllows images to be rendered\n"); printf("--allow-images\t\t-I\tAllows images to be rendered\n");
printf("--allow-markup\t-m\tAllows pango markup\n"); printf("--allow-markup\t\t-m\tAllows pango markup\n");
printf("--cache-file\t-k\tSets the cache file to use\n"); printf("--cache-file\t\t-k\tSets the cache file to use\n");
printf("--term\t\t-t\tSpecifies the terminal to use when running in a term\n"); printf("--term\t\t\t-t\tSpecifies the terminal to use when running in a term\n");
printf("--password\t-P\tRuns in password mode\n"); printf("--password\t\t-P\tRuns in password mode\n");
printf("--exec-search\t-e\tMakes enter always use the search contents not the first result\n"); printf("--exec-search\t\t-e\tMakes enter always use the search contents not the first result\n");
printf("--hide-scroll\t-b\tHides the scroll bars\n"); printf("--hide-scroll\t\t-b\tHides the scroll bars\n");
printf("--matching\t-M\tSets the matching method, default is contains\n"); printf("--matching\t\t-M\tSets the matching method, default is contains\n");
printf("--insensitive\t-i\tAllows case insensitive searching\n"); printf("--insensitive\t\t-i\tAllows case insensitive searching\n");
printf("--parse-search\t-q\tParses the search text removing image escapes and pango\n"); printf("--parse-search\t\t-q\tParses the search text removing image escapes and pango\n");
printf("--version\t-v\tPrints the version and then exits\n"); printf("--version\t\t-v\tPrints the version and then exits\n");
printf("--location\t-l\tSets the location\n"); printf("--location\t\t-l\tSets the location\n");
printf("--no-actions\t-a\tDisables multiple actions for modes that support it\n"); printf("--no-actions\t\t-a\tDisables multiple actions for modes that support it\n");
printf("--define\t-D\tSets a config option\n"); printf("--define\t\t-D\tSets a config option\n");
printf("--lines\t\t-L\tSets the height in number of lines\n"); printf("--lines\t\t\t-L\tSets the height in number of lines\n");
printf("--columns\t-w\tSets the number of columns to display\n"); printf("--columns\t\t-w\tSets the number of columns to display\n");
printf("--sort-order\t-O\tSets the sort order\n"); printf("--sort-order\t\t-O\tSets the sort order\n");
printf("--gtk-dark\t-G\tUses the dark variant of the current GTK theme\n"); printf("--gtk-dark\t\t-G\tUses the dark variant of the current GTK theme\n");
printf("--search\t-Q\tSearch for something immediately on open\n"); printf("--search\t\t-Q\tSearch for something immediately on open\n");
printf("--monitor\t-o\tSets the monitor to open on\n"); printf("--monitor\t\t-o\tSets the monitor to open on\n");
printf("--pre-display-cmd\t-r\tRuns command for the displayed entries, without changing the output. %%s for the real string\n");
exit(0); exit(0);
} }
@ -106,7 +107,10 @@ void wofi_load_css(bool nyan) {
ssize_t size = ftell(file); ssize_t size = ftell(file);
fseek(file, 0, SEEK_SET); fseek(file, 0, SEEK_SET);
char* data = malloc(size + 1); char* data = malloc(size + 1);
fread(data, 1, size, file); if (fread(data, 1, size, file) != 0) {
printf("failed to read stylesheet data from file");
exit(EXIT_FAILURE);
}
fclose(file); fclose(file);
data[size] = 0; data[size] = 0;
@ -421,6 +425,12 @@ int main(int argc, char** argv) {
.flag = NULL, .flag = NULL,
.val = 'o' .val = 'o'
}, },
{
.name = "pre-display-cmd",
.has_arg = required_argument,
.flag = NULL,
.val = 'r'
},
{ {
.name = NULL, .name = NULL,
.has_arg = 0, .has_arg = 0,
@ -457,13 +467,14 @@ int main(int argc, char** argv) {
char* gtk_dark = NULL; char* gtk_dark = NULL;
char* search = NULL; char* search = NULL;
char* monitor = NULL; char* monitor = NULL;
char* pre_display_cmd = NULL;
struct wl_list options; struct wl_list options;
wl_list_init(&options); wl_list_init(&options);
struct option_node* node; struct option_node* node;
int opt; int opt;
while((opt = getopt_long(argc, argv, "hfc:s:C:dS:W:H:p:x:y:nImk:t:P::ebM:iqvl:aD:L:w:O:GQ:o:", opts, NULL)) != -1) { while((opt = getopt_long(argc, argv, "hfc:s:C:dS:W:H:p:x:y:nImk:t:P::ebM:iqvl:aD:L:w:O:GQ:o:r:", opts, NULL)) != -1) {
switch(opt) { switch(opt) {
case 'h': case 'h':
print_usage(argv); print_usage(argv);
@ -572,6 +583,9 @@ int main(int argc, char** argv) {
case 'o': case 'o':
monitor = optarg; monitor = optarg;
break; break;
case 'r':
pre_display_cmd = optarg;
break;
} }
} }
@ -761,6 +775,9 @@ int main(int argc, char** argv) {
if(monitor != NULL) { if(monitor != NULL) {
map_put(config, "monitor", monitor); map_put(config, "monitor", monitor);
} }
if(pre_display_cmd != NULL) {
map_put(config, "pre_display_cmd", pre_display_cmd);
}
struct sigaction sigact = {0}; struct sigaction sigact = {0};
sigact.sa_handler = sig; sigact.sa_handler = sig;

View File

@ -106,6 +106,7 @@ static struct wl_list mode_list;
static pthread_t mode_thread; static pthread_t mode_thread;
static bool has_joined_mode = false; static bool has_joined_mode = false;
static char* copy_exec = NULL; static char* copy_exec = NULL;
static char* pre_display_cmd = NULL;
static struct map* keys; static struct map* keys;
@ -536,6 +537,40 @@ static gboolean _insert_widget(gpointer data) {
if(node == NULL) { if(node == NULL) {
return FALSE; return FALSE;
} }
char* nodetext = NULL;
if (!(pre_display_cmd == NULL)) {
FILE *fp_labeltext;
char *cmd_labeltext;
char line[128]; // you'd think this caps the line's length to 128, but it's just a buffer which due to the nature of fgets() splits on lines
unsigned int size = 0;
// first, prepare cmd_labeltext to be each entry's actual comamand to run, aka replacing 'cat %s' to be 'cat filename'
if ((asprintf(&cmd_labeltext, pre_display_cmd, node->text[0])) == -1) {
printf("error parsing pre_display_cmd to run\n");
exit(EXIT_FAILURE);
}
// then, run the command
fp_labeltext = popen(cmd_labeltext, "r");
if (fp_labeltext == NULL) {
printf("error executing '%s'\n", cmd_labeltext);
exit(EXIT_FAILURE);
} else if (fgets(line, sizeof(line), fp_labeltext)) {
// lastly, read the output of said command, and put it into the text variable to be used for the label widgets
// consider using 'printf %.10s as your --pre-display-cmd to limit a string to a determined width. 10 here is an example
size += strlen(line+1); // we need place for the \0 of strcpy
nodetext = (char *) realloc(nodetext, size);
strcpy(nodetext, line);
while (fgets(line, sizeof(line), fp_labeltext)) {
size += strlen(line);
nodetext = (char *) realloc(nodetext, size);
strncat(nodetext, line, size);
}
}
pclose(fp_labeltext);
} else {
nodetext = *(node->text);
}
GtkWidget* parent; GtkWidget* parent;
if(node->action_count > 1 && !no_actions) { if(node->action_count > 1 && !no_actions) {
@ -543,7 +578,7 @@ static gboolean _insert_widget(gpointer data) {
g_signal_connect(parent, "activate", G_CALLBACK(expand), NULL); g_signal_connect(parent, "activate", G_CALLBACK(expand), NULL);
GtkWidget* box; GtkWidget* box;
if(node->builder == NULL) { if(node->builder == NULL) {
box = create_label(node->mode, node->text[0], node->search_text, node->actions[0]); box = create_label(node->mode, nodetext, node->search_text, node->actions[0]);
} else { } else {
box = GTK_WIDGET(node->builder->box); box = GTK_WIDGET(node->builder->box);
setup_label(node->builder->mode->name, WOFI_PROPERTY_BOX(box)); setup_label(node->builder->mode->name, WOFI_PROPERTY_BOX(box));
@ -570,7 +605,7 @@ static gboolean _insert_widget(gpointer data) {
} }
} else { } else {
if(node->builder == NULL) { if(node->builder == NULL) {
parent = create_label(node->mode, node->text[0], node->search_text, node->actions[0]); parent = create_label(node->mode, nodetext, node->search_text, node->actions[0]);
} else { } else {
parent = GTK_WIDGET(node->builder->box); parent = GTK_WIDGET(node->builder->box);
setup_label(node->builder->mode->name, WOFI_PROPERTY_BOX(parent)); setup_label(node->builder->mode->name, WOFI_PROPERTY_BOX(parent));
@ -1234,7 +1269,10 @@ static void do_copy(void) {
} }
int fds[2]; int fds[2];
pipe(fds); if (pipe(fds) == -1) {
perror("pipe broken");
exit(EXIT_FAILURE);
}
if(fork() == 0) { if(fork() == 0) {
close(fds[1]); close(fds[1]);
dup2(fds[0], STDIN_FILENO); dup2(fds[0], STDIN_FILENO);
@ -1244,7 +1282,9 @@ static void do_copy(void) {
} }
close(fds[0]); close(fds[0]);
write(fds[1], action, strlen(action)); if (!(write(fds[1], action, strlen(action)) == 0)) {
printf("fd pipe failed to write");
}
close(fds[1]); close(fds[1]);
@ -1675,6 +1715,8 @@ void wofi_init(struct map* _config) {
char* layer = config_get(config, "layer", "top"); char* layer = config_get(config, "layer", "top");
copy_exec = config_get(config, "copy_exec", "wl-copy"); copy_exec = config_get(config, "copy_exec", "wl-copy");
pre_display_cmd = map_get(config, "pre_display_cmd");
keys = map_init_void(); keys = map_init_void();