diff --git a/config/config.c b/config/config.c index ce6fc1c6..da2fd797 100644 --- a/config/config.c +++ b/config/config.c @@ -118,6 +118,7 @@ Settings config = { .matching_method = MM_NORMAL, /** Desktop entry fields to match*/ .drun_match_fields = "name,generic,exec,categories", + .drun_categories = NULL, /** Desktop format display */ .drun_display_format = "{name} [({generic})]", /** Desktop entry show actions */ diff --git a/doc/old-theme-convert-output.rasi b/doc/old-theme-convert-output.rasi index 60ad5dd7..6edfa3a4 100644 --- a/doc/old-theme-convert-output.rasi +++ b/doc/old-theme-convert-output.rasi @@ -2,39 +2,39 @@ * rofi -dump-theme output. **/ * { + selected-normal-foreground: rgba ( 2, 20, 63, 100 % ); + foreground: rgba ( 219, 223, 188, 100 % ); + normal-foreground: var(foreground); + alternate-normal-background: rgba ( 0, 0, 0, 0 % ); red: rgba ( 220, 50, 47, 100 % ); - selected-active-foreground: rgba ( 2, 20, 63, 100 % ); - lightfg: rgba ( 88, 104, 117, 100 % ); - separatorcolor: rgba ( 219, 223, 188, 100 % ); + selected-urgent-foreground: rgba ( 2, 20, 63, 100 % ); + blue: rgba ( 38, 139, 210, 100 % ); urgent-foreground: rgba ( 255, 129, 255, 100 % ); alternate-urgent-background: rgba ( 0, 0, 0, 0 % ); - lightbg: rgba ( 238, 232, 213, 100 % ); - background-color: rgba ( 0, 0, 0, 0 % ); - border-color: rgba ( 219, 223, 188, 100 % ); - normal-background: rgba ( 0, 0, 0, 0 % ); - selected-urgent-background: rgba ( 255, 129, 127, 100 % ); - alternate-active-background: rgba ( 0, 0, 0, 0 % ); - spacing: 2; - blue: rgba ( 38, 139, 210, 100 % ); - alternate-normal-foreground: var(foreground); - urgent-background: rgba ( 0, 0, 0, 0 % ); - selected-normal-foreground: rgba ( 2, 20, 63, 100 % ); active-foreground: rgba ( 138, 196, 255, 100 % ); + lightbg: rgba ( 238, 232, 213, 100 % ); + selected-active-foreground: rgba ( 2, 20, 63, 100 % ); + alternate-active-background: rgba ( 0, 0, 0, 0 % ); background: rgba ( 0, 0, 33, 87 % ); - selected-active-background: rgba ( 138, 196, 255, 100 % ); - active-background: rgba ( 0, 0, 0, 0 % ); + alternate-normal-foreground: var(foreground); + normal-background: rgba ( 0, 0, 0, 0 % ); + lightfg: rgba ( 88, 104, 117, 100 % ); selected-normal-background: rgba ( 219, 223, 188, 100 % ); - alternate-normal-background: rgba ( 0, 0, 0, 0 % ); - foreground: rgba ( 219, 223, 188, 100 % ); - selected-urgent-foreground: rgba ( 2, 20, 63, 100 % ); - normal-foreground: var(foreground); + border-color: rgba ( 219, 223, 188, 100 % ); + spacing: 2; + separatorcolor: rgba ( 219, 223, 188, 100 % ); + urgent-background: rgba ( 0, 0, 0, 0 % ); + selected-urgent-background: rgba ( 255, 129, 127, 100 % ); alternate-urgent-foreground: var(urgent-foreground); + background-color: rgba ( 0, 0, 0, 0 % ); alternate-active-foreground: var(active-foreground); + active-background: rgba ( 0, 0, 0, 0 % ); + selected-active-background: rgba ( 138, 196, 255, 100 % ); } element { - padding: 1px ; - spacing: 5px ; border: 0; + spacing: 5px ; + padding: 1px ; } element normal.normal { background-color: var(normal-background); @@ -80,16 +80,41 @@ element-icon { background-color: rgba ( 0, 0, 0, 0 % ); text-color: inherit; } +window { + background-color: var(background); + border: 1; + padding: 5; +} +mainbox { + border: 0; + padding: 0; +} +message { + border: 2px 0px 0px ; + border-color: var(separatorcolor); + padding: 1px ; +} +textbox { + text-color: var(foreground); +} +listview { + fixed-height: 0; + border: 2px 0px 0px ; + border-color: var(separatorcolor); + spacing: 2px ; + scrollbar: true; + padding: 2px 0px 0px ; +} scrollbar { width: 4px ; - padding: 0; - handle-width: 8px ; border: 0; handle-color: var(normal-foreground); + handle-width: 8px ; + padding: 0; } -mode-switcher { +sidebar { + border: 2px dash 0px 0px ; border-color: var(separatorcolor); - border: 2px 0px 0px ; } button { spacing: 0; @@ -100,10 +125,10 @@ button selected { text-color: var(selected-normal-foreground); } inputbar { - padding: 1px ; spacing: 0px ; text-color: var(normal-foreground); - children: [ prompt,textbox-prompt-colon,entry,overlay,case-indicator ]; + padding: 1px ; + children: [ prompt,textbox-prompt-colon,entry,case-indicator ]; } case-indicator { spacing: 0; @@ -118,25 +143,11 @@ prompt { text-color: var(normal-foreground); } textbox-prompt-colon { - margin: 0px 0.3000em 0.0000em 0.0000em ; expand: false; str: ":"; + margin: 0px 0.3000em 0.0000em 0.0000em ; text-color: inherit; } -error-message { - background-color: rgba ( 0, 0, 0, 0 % ); - text-color: var(normal-foreground); -} -window { - padding: 5; - border: 1; -} -listview { - scrollbar: true; - spacing: 2px ; - border: 2px 0px 0px ; -} -message { - padding: 1px ; - border: 2px 0px 0px ; +mode-switcher { + border: 2px 0px 0px ; } diff --git a/doc/rofi.1 b/doc/rofi.1 index 0e0cdb98..9198e598 100644 --- a/doc/rofi.1 +++ b/doc/rofi.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "ROFI" "1" "June 2019" "" "" +.TH "ROFI" "1" "August 2019" "" "" . .SH "NAME" \fBrofi\fR \- A window switcher, application launcher, ssh dialog and dmenu replacement @@ -401,6 +401,12 @@ Note: glob matching might be slow for larger lists Tokenize the input\. . .P +\fB\-drun\-categories\fR \fIcategory\fR,\fIcategory\fR +. +.P +Only show desktop files that are present in the listed categories\. +. +.P \fB\-drun\-match\-fields\fR \fIfield1\fR,\fIfield2\fR,\.\.\. . .P @@ -998,29 +1004,30 @@ Makes dmenu searches case\-insensitive \fB\-a\fR \fIX\fR . .P -Active row, mark \fIX\fR as active. Where \fIX\fR is a comma-separated list of python(1)-style indices and ranges, e.g. -indices start at \fB0\fR, \fB\-1\fR refers to the last row with \fB\-2\fR preceding it, ranges are left-open and right-close, and so on. You can specify: +Active row, mark \fIX\fR as active\. Where \fIX\fR is a comma\-separated list of python(1)\-style indices and ranges, e\.g\. indices start at 0, \-1 refers to the last row with \-2 preceding it, ranges are left\-open and right\-close, and so on\. You can specify: . .IP "\(bu" 4 -A single row: \'\fB5\fR\' +A single row: \'5\' . .IP "\(bu" 4 -A range of (last 3) rows: \'\fB\-3:\fR\' +A range of (last 3) rows: \'\-3:\' . .IP "\(bu" 4 -4 rows starting from row 7: \'\fB7:11\fR\' (or in legacy notation: \'\fB7\-10\fR\') +4 rows starting from row 7: \'7:11\' (or in legacy notation: \'7\-10\') . .IP "\(bu" 4 -A set of rows: \'\fB2,0,\-9\fR\' +A set of rows: \'2,0,\-9\' . .IP "\(bu" 4 -Or any combination: \'\fB\5,-3:,7:11,2,0,\-9\fR\' +Or any combination: \'5,\-3:,7:11,2,0,\-9\' +. +.IP "" 0 . .P \fB\-u\fR \fIX\fR . .P -Urgent row, mark \fIX\fR as urgent\. See \fB\-a\fR option\ for details. +Urgent row, mark \fIX\fR as urgent\. See \fB\-a\fR option for details\. . .P \fB\-only\-match\fR diff --git a/doc/rofi.1.markdown b/doc/rofi.1.markdown index e4225ee3..b32cdbee 100644 --- a/doc/rofi.1.markdown +++ b/doc/rofi.1.markdown @@ -233,6 +233,10 @@ Note: glob matching might be slow for larger lists Tokenize the input. +`-drun-categories` *category*,*category* + +Only show desktop files that are present in the listed categories. + `-drun-match-fields` *field1*,*field2*,... When using drun, match only with the specified Desktop entry fields. diff --git a/doc/test_xr.txt b/doc/test_xr.txt index 98edf508..6adc7202 100644 --- a/doc/test_xr.txt +++ b/doc/test_xr.txt @@ -42,6 +42,8 @@ rofi.window-command: xkill -id {window} ! rofi.icon-theme: ! "Desktop entry fields to match in drun" Set from: Default ! rofi.drun-match-fields: name,generic,exec,categories +! "Only show Desktop entry from these categories" Set from: Default +! rofi.drun-categories: ! "Desktop entry show actions." Set from: Default ! rofi.drun-show-actions: false ! "DRUN format string. (Supports: generic,name,comment,exec,categories)" Set from: Default diff --git a/include/settings.h b/include/settings.h index e6aebc8b..213800f8 100644 --- a/include/settings.h +++ b/include/settings.h @@ -118,6 +118,8 @@ typedef struct char * sorting_method; /** Desktop entries to match in drun */ char * drun_match_fields; + /** Only show entries in this category */ + char * drun_categories; /** Desktop entry show actions */ unsigned int drun_show_actions; /** Desktop entry show */ diff --git a/source/dialogs/drun.c b/source/dialogs/drun.c index 832a50dd..c8b7ab8c 100644 --- a/source/dialogs/drun.c +++ b/source/dialogs/drun.c @@ -138,6 +138,9 @@ struct _DRunModePrivateData unsigned int disabled_entries_length; unsigned int expected_line_height; + + char **show_categories; + // Theme const gchar *icon_theme; // DE @@ -257,6 +260,19 @@ static void exec_cmd_entry ( DRunModeEntry *e ) g_free ( exec_path ); g_free ( str ); } + + +static gboolean rofi_strv_contains ( const char * const *categories, const char *const *field ) +{ + for ( int i = 0; categories && categories[i] ; i++ ){ + for ( int j = 0; field[j] ; j++ ){ + if ( g_str_equal ( categories[i], field[j] ) ) { + return TRUE; + } + } + } + return FALSE; +} /** * This function absorbs/freeÅ› path, so this is no longer available afterwards. */ @@ -397,6 +413,16 @@ static void read_desktop_file ( DRunModePrivateData *pd, const char *root, const g_free ( te ); } + char **categories = NULL; + if ( pd->show_categories ) { + categories = g_key_file_get_locale_string_list ( kf, DRUN_GROUP_NAME, "Categories", NULL, NULL, NULL ); + if ( !rofi_strv_contains( (const char * const *)categories, (const char *const *)pd->show_categories ) ){ + g_strfreev(categories); + g_key_file_free ( kf ); + return ; + } + } + size_t nl = ( ( pd->cmd_list_length ) + 1 ); if ( nl >= pd->cmd_list_length_actual ) { pd->cmd_list_length_actual += 256; @@ -430,11 +456,18 @@ static void read_desktop_file ( DRunModePrivateData *pd, const char *root, const gchar *gn = g_key_file_get_locale_string ( kf, DRUN_GROUP_NAME, "GenericName", NULL, NULL ); pd->entry_list[pd->cmd_list_length].generic_name = gn; if ( matching_entry_fields[DRUN_MATCH_FIELD_CATEGORIES].enabled ) { - pd->entry_list[pd->cmd_list_length].categories = g_key_file_get_locale_string_list ( kf, DRUN_GROUP_NAME, "Categories", NULL, NULL, NULL ); + if ( categories ) { + pd->entry_list[pd->cmd_list_length].categories = categories; + categories = NULL; + } else { + pd->entry_list[pd->cmd_list_length].categories = g_key_file_get_locale_string_list ( kf, DRUN_GROUP_NAME, "Categories", NULL, NULL, NULL ); + } } else { pd->entry_list[pd->cmd_list_length].categories = NULL; } + g_strfreev(categories); + pd->entry_list[pd->cmd_list_length].exec = g_key_file_get_string ( kf, action, "Exec", NULL ); if ( matching_entry_fields[DRUN_MATCH_FIELD_COMMENT].enabled ) { @@ -668,6 +701,10 @@ static int drun_mode_init ( Mode *sw ) const char *current_desktop = g_getenv ( "XDG_CURRENT_DESKTOP" ); pd->current_desktop_list = current_desktop ? g_strsplit ( current_desktop, ":", 0 ) : NULL; + if ( config.drun_categories && *(config.drun_categories) ){ + pd->show_categories = g_strsplit(config.drun_categories, ",",0); + } + drun_mode_parse_entry_fields (); get_apps ( pd ); return TRUE; @@ -741,6 +778,7 @@ static void drun_mode_destroy ( Mode *sw ) g_free ( rmpd->entry_list ); g_strfreev ( rmpd->current_desktop_list ); + g_strfreev ( rmpd->show_categories ); g_free ( rmpd ); mode_set_private_data ( sw, NULL ); } diff --git a/source/xrmoptions.c b/source/xrmoptions.c index fde3fa2a..cc4a2bfd 100644 --- a/source/xrmoptions.c +++ b/source/xrmoptions.c @@ -135,6 +135,9 @@ static XrmOption xrmOptions[] = { { xrm_String, "drun-match-fields", { .str = &config.drun_match_fields }, NULL, "Desktop entry fields to match in drun", CONFIG_DEFAULT }, + + { xrm_String, "drun-categories", { .str = &config.drun_categories }, NULL, + "Only show Desktop entry from these categories", CONFIG_DEFAULT }, { xrm_Boolean, "drun-show-actions", { .num = &config.drun_show_actions }, NULL, "Desktop entry show actions.", CONFIG_DEFAULT }, { xrm_String, "drun-display-format", { .str = &config.drun_display_format }, NULL,