diff --git a/.gitignore b/.gitignore index 495644bc..ac7472d9 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,7 @@ /doc/*.html /doc/*.doxy /gitconfig.h +test/output.txt # I want to ignore log files *.log diff --git a/include/dialogs/dmenuscriptshared.h b/include/dialogs/dmenuscriptshared.h index 16400e0a..31e8aae5 100644 --- a/include/dialogs/dmenuscriptshared.h +++ b/include/dialogs/dmenuscriptshared.h @@ -8,6 +8,8 @@ typedef struct { char *icon_name; /** Async icon fetch handler. */ uint32_t icon_fetch_uid; + /** Hidden meta keywords. */ + char *meta; } DmenuScriptEntry; /** * @param sw Unused diff --git a/source/dialogs/dmenu.c b/source/dialogs/dmenu.c index fee6e5d4..96eddf57 100644 --- a/source/dialogs/dmenu.c +++ b/source/dialogs/dmenu.c @@ -122,6 +122,7 @@ static void read_add ( DmenuModePrivateData * pd, char *data, gsize len ) // Init. pd->cmd_list[pd->cmd_list_length].icon_fetch_uid = 0; pd->cmd_list[pd->cmd_list_length].icon_name = NULL; + pd->cmd_list[pd->cmd_list_length].meta = NULL; char *end = strchr(data, '\0'); if ( end != NULL ) { data_len = end-data; @@ -309,6 +310,7 @@ static void dmenu_mode_free ( Mode *sw ) if ( pd->cmd_list[i].entry ) { g_free ( pd->cmd_list[i].entry ); g_free ( pd->cmd_list[i].icon_name ); + g_free ( pd->cmd_list[i].meta ); } } g_free ( pd->cmd_list ); diff --git a/source/dialogs/script.c b/source/dialogs/script.c index d52df371..514e43ba 100644 --- a/source/dialogs/script.c +++ b/source/dialogs/script.c @@ -87,6 +87,9 @@ void dmenuscript_parse_entry_extras ( G_GNUC_UNUSED Mode *sw, DmenuScriptEntry * if ( strcasecmp(buffer, "icon" ) == 0 ) { entry->icon_name = g_strdup(value); } + if ( strcasecmp(buffer, "meta" ) == 0 ) { + entry->meta = g_strdup(value); + } } } @@ -171,6 +174,7 @@ static DmenuScriptEntry *get_script_output ( Mode *sw, char *command, char *arg, size_t buf_length = strlen(buffer)+1; retv[( *length )].entry = g_memdup ( buffer, buf_length); retv[( *length )].icon_name = NULL; + retv[( *length )].meta = NULL; retv[(*length)].icon_fetch_uid = 0; if ( buf_length > 0 && (read_length > (ssize_t)buf_length) ) { dmenuscript_parse_entry_extras ( sw, &(retv[(*length)]), buffer+buf_length, read_length-buf_length); @@ -264,6 +268,7 @@ static ModeMode script_mode_result ( Mode *sw, int mretv, char **input, unsigned for ( unsigned int i = 0; i < rmpd->cmd_list_length; i++ ){ g_free ( rmpd->cmd_list[i].entry ); g_free ( rmpd->cmd_list[i].icon_name ); + g_free ( rmpd->cmd_list[i].meta ); } g_free ( rmpd->cmd_list ); @@ -281,6 +286,7 @@ static void script_mode_destroy ( Mode *sw ) for ( unsigned int i = 0; i < rmpd->cmd_list_length; i++ ){ g_free ( rmpd->cmd_list[i].entry ); g_free ( rmpd->cmd_list[i].icon_name ); + g_free ( rmpd->cmd_list[i].meta ); } g_free ( rmpd->cmd_list ); g_free ( rmpd->message ); @@ -324,7 +330,22 @@ static char *_get_display_value ( const Mode *sw, unsigned int selected_line, G_ static int script_token_match ( const Mode *sw, rofi_int_matcher **tokens, unsigned int index ) { ScriptModePrivateData *rmpd = sw->private_data; - return helper_token_match ( tokens, rmpd->cmd_list[index].entry ); + int match = 1; + if ( tokens ) { + for ( int j = 0; match && tokens != NULL && tokens[j] != NULL; j++ ) { + rofi_int_matcher *ftokens[2] = { tokens[j], NULL }; + int test = 0; + test = helper_token_match ( ftokens, rmpd->cmd_list[index].entry ); + if ( test == tokens[j]->invert && rmpd->cmd_list[index].meta ) { + test = helper_token_match ( ftokens, rmpd->cmd_list[index].meta); + } + + if ( test == 0 ) { + match = 0; + } + } + } + return match; } static char *script_get_message ( const Mode *sw ) { diff --git a/test/run_all_tests.sh b/test/run_all_tests.sh index 94427e9f..8d619ab0 100755 --- a/test/run_all_tests.sh +++ b/test/run_all_tests.sh @@ -7,6 +7,7 @@ tests=( run_dmenu_custom_test run_run_test run_script_test + run_script_meta_test run_issue_256 run_issue_275 run_dmenu_empty diff --git a/test/run_script_meta_test.sh b/test/run_script_meta_test.sh new file mode 100755 index 00000000..cb570dae --- /dev/null +++ b/test/run_script_meta_test.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +SP=$(readlink -f "$0") +DIR=$(dirname "$SP") +echo "$DIR/test_script.sh" +# wait till it is up, run rofi with error message +sleep 1; +rofi -modi "custom:$DIR/test_script.sh" -show custom & +RPID=$! + +# send enter. +sleep 5; +xdotool key 'z' +sleep 0.4 +xdotool key Return + +# Get result, kill xvfb +wait ${RPID} +RETV=$? +OUTPUT=$( tr '\n' ' ' < output.txt ) +echo ${OUTPUT} +if [ "${OUTPUT}" != 'mies ' ] +then + exit 1 +fi +exit ${RETV} diff --git a/test/test_script.sh b/test/test_script.sh index c4021380..4aab2db8 100755 --- a/test/test_script.sh +++ b/test/test_script.sh @@ -4,7 +4,7 @@ if [ -z "$1" ] then echo "aap" echo "noot" - echo "mies" + echo -ne "mies\0meta\x1fzoom\n" else echo $1 > output.txt fi