1
0
Fork 0
mirror of https://github.com/davatorium/rofi.git synced 2024-11-18 13:54:36 -05:00

[DRUN] Add option to show actions in drun.

Fixes: #836
This commit is contained in:
Dave Davenport 2018-07-28 11:12:11 +02:00
parent 0058088962
commit 4538303be6
9 changed files with 79 additions and 15 deletions

View file

@ -116,6 +116,9 @@ Settings config = {
.matching_method = MM_NORMAL, .matching_method = MM_NORMAL,
/** Desktop entry fields to match*/ /** Desktop entry fields to match*/
.drun_match_fields = "name,generic,exec,categories", .drun_match_fields = "name,generic,exec,categories",
/** Desktop entry show actions */
.drun_show_actions = FALSE,
/** Desktop entry show actions */
/** Window fields to match in window mode*/ /** Window fields to match in window mode*/
.window_match_fields = "all", .window_match_fields = "all",
/** Monitor */ /** Monitor */

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "ROFI\-THEME\-SELECTOR" "1" "January 2018" "" "" .TH "ROFI\-THEME\-SELECTOR" "1" "May 2018" "" ""
. .
.SH "NAME" .SH "NAME"
\fBrofi\-theme\-selector\fR \- Preview and apply themes for \fBrofi\fR \fBrofi\-theme\-selector\fR \- Preview and apply themes for \fBrofi\fR

View file

@ -7,12 +7,12 @@
\fBrofi\-theme\fR \- Rofi theme format files \fBrofi\-theme\fR \- Rofi theme format files
. .
.SH "DESCRIPTION" .SH "DESCRIPTION"
The need for a new theme format was motivated by the fact that the way rofi handled widgets has changed\. From a very static drawing of lines and text to a nice structured form of packing widgets\. This change made it possible to provide a more flexible theme framework\. The old theme format and config file are not flexible enough to expose these options in a user\-friendly way\. Therefore, a new file format has been created, replacing the old one\. The need for a new theme format was motivated by the fact that the way rofi handled widgets has changed\. From a very static drawing of lines and text to a nice structured form of packing widgets\. This change made it possible to provide a more flexible theme framework\. The old theme format and config file are not flexible enough to expose these options in a user\-friendly way\. Therefor, a new file format has been created, replacing the old one\.
. .
.SH "FORMAT SPECIFICATION" .SH "FORMAT SPECIFICATION"
. .
.SH "Encoding" .SH "Encoding"
The encoding of the file is utf\-8\. Both unix (\fB\en\fR) and windows (\fB\er\en\fR) newline formats are supported, though unix is preferred\. The encoding of the file is utf\-8\. Both unix (\fB\en\fR) and windows (\fB\er\en\fR) newlines format are supported\. But unix is preferred\.
. .
.SH "Comments" .SH "Comments"
C and C++ file comments are supported\. C and C++ file comments are supported\.
@ -121,7 +121,7 @@ It is advised to define the \fIglobal properties section\fR on top of the file t
If there are multiple sections with the same name, they are merged\. Duplicate properties are overwritten and the last parsed entry kept\. If there are multiple sections with the same name, they are merged\. Duplicate properties are overwritten and the last parsed entry kept\.
. .
.SH "Global properties section" .SH "Global properties section"
A theme can have one or more global properties sections\. If there are more than one, they will be merged\. A theme can have one or more global properties sections\. If there is more than one, they will be merged\.
. .
.P .P
The global properties section denotes the defaults for each element\. Each property of this section can be referenced with \fB@{identifier}\fR (See Properties section) The global properties section denotes the defaults for each element\. Each property of this section can be referenced with \fB@{identifier}\fR (See Properties section)

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "ROFI" "1" "June 2018" "" "" .TH "ROFI" "1" "July 2018" "" ""
. .
.SH "NAME" .SH "NAME"
\fBrofi\fR \- A window switcher, application launcher, ssh dialog and dmenu replacement \fBrofi\fR \- A window switcher, application launcher, ssh dialog and dmenu replacement
@ -414,6 +414,22 @@ Default: \fIname,generic,exec,categories\fR
.IP "" 0 .IP "" 0
. .
.P .P
\fB\-[no\-]drun\-show\-actions\fR
.
.P
Show actions present in the Desktop files\.
.
.IP "" 4
.
.nf
Default: false
.
.fi
.
.IP "" 0
.
.P
\fB\-window\-match\-fields\fR \fIfield1\fR,\fIfield2\fR,\.\.\. \fB\-window\-match\-fields\fR \fIfield1\fR,\fIfield2\fR,\.\.\.
. .
.P .P

View file

@ -239,6 +239,12 @@ The different fields are:
Default: *name,generic,exec,categories* Default: *name,generic,exec,categories*
`-[no-]drun-show-actions`
Show actions present in the Desktop files.
Default: false
`-window-match-fields` *field1*,*field2*,... `-window-match-fields` *field1*,*field2*,...
When using window mode, match only with the specified fields. When using window mode, match only with the specified fields.

View file

@ -42,6 +42,8 @@ rofi.window-command: xkill -id {window}
! rofi.icon-theme: ! rofi.icon-theme:
! "Desktop entry fields to match in drun" Set from: Default ! "Desktop entry fields to match in drun" Set from: Default
! rofi.drun-match-fields: name,generic,exec,categories ! rofi.drun-match-fields: name,generic,exec,categories
! "Desktop entry show actions." Set from: Default
! rofi.drun-show-actions: false
! "Disable history in run/ssh" Set from: File ! "Disable history in run/ssh" Set from: File
rofi.disable-history: false rofi.disable-history: false
! "Use sorting" Set from: Default ! "Use sorting" Set from: Default

View file

@ -116,6 +116,8 @@ typedef struct
char * sorting_method; char * sorting_method;
/** Desktop entries to match in drun */ /** Desktop entries to match in drun */
char * drun_match_fields; char * drun_match_fields;
/** Desktop entry show actions */
unsigned int drun_show_actions;
/** Search case sensitivity */ /** Search case sensitivity */
unsigned int case_sensitive; unsigned int case_sensitive;
/** Cycle through in the element list */ /** Cycle through in the element list */

View file

@ -57,7 +57,7 @@
#define DRUN_CACHE_FILE "rofi3.druncache" #define DRUN_CACHE_FILE "rofi3.druncache"
#define DRUN_GROUP_NAME "Desktop Entry" char *DRUN_GROUP_NAME = "Desktop Entry";
typedef struct _DRunModePrivateData DRunModePrivateData; typedef struct _DRunModePrivateData DRunModePrivateData;
@ -69,6 +69,8 @@ typedef struct
{ {
thread_state st; thread_state st;
DRunModePrivateData *pd; DRunModePrivateData *pd;
/* category */
char *action;
/* Root */ /* Root */
char *root; char *root;
/* Path to desktop file */ /* Path to desktop file */
@ -226,7 +228,7 @@ static void exec_cmd_entry ( DRunModeEntry *e )
} }
const gchar *fp = g_strstrip ( str ); const gchar *fp = g_strstrip ( str );
gchar *exec_path = g_key_file_get_string ( e->key_file, DRUN_GROUP_NAME, "Path", NULL ); gchar *exec_path = g_key_file_get_string ( e->key_file, e->action, "Path", NULL );
if ( exec_path != NULL && strlen ( exec_path ) == 0 ) { if ( exec_path != NULL && strlen ( exec_path ) == 0 ) {
// If it is empty, ignore this property. (#529) // If it is empty, ignore this property. (#529)
g_free ( exec_path ); g_free ( exec_path );
@ -238,14 +240,14 @@ static void exec_cmd_entry ( DRunModeEntry *e )
.icon = e->icon_name, .icon = e->icon_name,
.app_id = e->app_id, .app_id = e->app_id,
}; };
gboolean sn = g_key_file_get_boolean ( e->key_file, DRUN_GROUP_NAME, "StartupNotify", NULL ); gboolean sn = g_key_file_get_boolean ( e->key_file, e->action, "StartupNotify", NULL );
gchar *wmclass = NULL; gchar *wmclass = NULL;
if ( sn && g_key_file_has_key ( e->key_file, DRUN_GROUP_NAME, "StartupWMClass", NULL ) ) { if ( sn && g_key_file_has_key ( e->key_file, e->action, "StartupWMClass", NULL ) ) {
context.wmclass = wmclass = g_key_file_get_string ( e->key_file, DRUN_GROUP_NAME, "StartupWMClass", NULL ); context.wmclass = wmclass = g_key_file_get_string ( e->key_file, e->action, "StartupWMClass", NULL );
} }
// Returns false if not found, if key not found, we don't want run in terminal. // Returns false if not found, if key not found, we don't want run in terminal.
gboolean terminal = g_key_file_get_boolean ( e->key_file, DRUN_GROUP_NAME, "Terminal", NULL ); gboolean terminal = g_key_file_get_boolean ( e->key_file, e->action, "Terminal", NULL );
if ( helper_execute_command ( exec_path, fp, terminal, sn ? &context : NULL ) ) { if ( helper_execute_command ( exec_path, fp, terminal, sn ? &context : NULL ) ) {
char *path = g_build_filename ( cache_dir, DRUN_CACHE_FILE, NULL ); char *path = g_build_filename ( cache_dir, DRUN_CACHE_FILE, NULL );
// Store it based on the unique identifiers (desktop_id). // Store it based on the unique identifiers (desktop_id).
@ -259,8 +261,9 @@ static void exec_cmd_entry ( DRunModeEntry *e )
/** /**
* This function absorbs/freeś path, so this is no longer available afterwards. * This function absorbs/freeś path, so this is no longer available afterwards.
*/ */
static gboolean read_desktop_file ( DRunModePrivateData *pd, const char *root, const char *path, const gchar *basename ) static gboolean read_desktop_file ( DRunModePrivateData *pd, const char *root, const char *path, const gchar *basename, char *action )
{ {
int parse_action = ( config.drun_show_actions && action != DRUN_GROUP_NAME );
// Create ID on stack. // Create ID on stack.
// We know strlen (path ) > strlen(root)+1 // We know strlen (path ) > strlen(root)+1
const ssize_t id_len = strlen ( path ) - strlen ( root ); const ssize_t id_len = strlen ( path ) - strlen ( root );
@ -273,7 +276,7 @@ static gboolean read_desktop_file ( DRunModePrivateData *pd, const char *root, c
} }
// Check if item is on disabled list. // Check if item is on disabled list.
if ( g_hash_table_contains ( pd->disabled_entries, id ) ) { if ( g_hash_table_contains ( pd->disabled_entries, id ) && !parse_action ) {
g_debug ( "[%s] [%s] Skipping, was previously seen.", id, path ); g_debug ( "[%s] [%s] Skipping, was previously seen.", id, path );
return TRUE; return TRUE;
} }
@ -287,6 +290,13 @@ static gboolean read_desktop_file ( DRunModePrivateData *pd, const char *root, c
g_key_file_free ( kf ); g_key_file_free ( kf );
return FALSE; return FALSE;
} }
if ( g_key_file_has_group ( kf, action ) == FALSE ) {
// No type? ignore.
g_debug ( "[%s] [%s] Invalid desktop file: No %s group", id, path, action );
g_key_file_free ( kf );
return FALSE;
}
// Skip non Application entries. // Skip non Application entries.
gchar *key = g_key_file_get_string ( kf, DRUN_GROUP_NAME, "Type", NULL ); gchar *key = g_key_file_get_string ( kf, DRUN_GROUP_NAME, "Type", NULL );
if ( key == NULL ) { if ( key == NULL ) {
@ -409,7 +419,15 @@ static gboolean read_desktop_file ( DRunModePrivateData *pd, const char *root, c
pd->entry_list[pd->cmd_list_length].desktop_id = g_strdup ( id ); pd->entry_list[pd->cmd_list_length].desktop_id = g_strdup ( id );
pd->entry_list[pd->cmd_list_length].app_id = g_strndup ( basename, strlen ( basename ) - strlen ( ".desktop" ) ); pd->entry_list[pd->cmd_list_length].app_id = g_strndup ( basename, strlen ( basename ) - strlen ( ".desktop" ) );
gchar *n = g_key_file_get_locale_string ( kf, DRUN_GROUP_NAME, "Name", NULL, NULL ); gchar *n = g_key_file_get_locale_string ( kf, DRUN_GROUP_NAME, "Name", NULL, NULL );
if ( action != DRUN_GROUP_NAME ){
gchar *na = g_key_file_get_locale_string ( kf, action, "Name", NULL, NULL );
gchar *l = g_strdup_printf("%s - %s", n, na);
g_free(n);
n = l;
}
pd->entry_list[pd->cmd_list_length].name = n; pd->entry_list[pd->cmd_list_length].name = n;
pd->entry_list[pd->cmd_list_length].action = DRUN_GROUP_NAME;
gchar *gn = g_key_file_get_locale_string ( kf, DRUN_GROUP_NAME, "GenericName", NULL, NULL ); 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; pd->entry_list[pd->cmd_list_length].generic_name = gn;
if ( matching_entry_fields[DRUN_MATCH_FIELD_CATEGORIES].enabled ) { if ( matching_entry_fields[DRUN_MATCH_FIELD_CATEGORIES].enabled ) {
@ -418,7 +436,7 @@ static gboolean read_desktop_file ( DRunModePrivateData *pd, const char *root, c
else { else {
pd->entry_list[pd->cmd_list_length].categories = NULL; pd->entry_list[pd->cmd_list_length].categories = NULL;
} }
pd->entry_list[pd->cmd_list_length].exec = g_key_file_get_string ( kf, DRUN_GROUP_NAME, "Exec", NULL ); 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 ) { if ( matching_entry_fields[DRUN_MATCH_FIELD_COMMENT].enabled ) {
pd->entry_list[pd->cmd_list_length].comment = g_key_file_get_locale_string ( kf, pd->entry_list[pd->cmd_list_length].comment = g_key_file_get_locale_string ( kf,
@ -441,6 +459,18 @@ static gboolean read_desktop_file ( DRunModePrivateData *pd, const char *root, c
g_hash_table_add ( pd->disabled_entries, g_strdup ( id ) ); g_hash_table_add ( pd->disabled_entries, g_strdup ( id ) );
g_debug ( "[%s] Using file %s.", id, path ); g_debug ( "[%s] Using file %s.", id, path );
( pd->cmd_list_length )++; ( pd->cmd_list_length )++;
if ( !parse_action ) {
gsize actions_length = 0;
char **actions = g_key_file_get_string_list ( kf, DRUN_GROUP_NAME, "Actions", &actions_length, NULL );
for ( gsize iter = 0; iter < actions_length; iter++ ){
char *new_action = g_strdup_printf("Desktop Action %s", actions[iter]);
if (! read_desktop_file ( pd, root, path, basename, new_action ) ){
g_free ( new_action );
}
}
g_strfreev(actions);
}
return TRUE; return TRUE;
} }
@ -495,7 +525,7 @@ static void walk_dir ( DRunModePrivateData *pd, const char *root, const char *di
case DT_REG: case DT_REG:
// Skip files not ending on .desktop. // Skip files not ending on .desktop.
if ( g_str_has_suffix ( file->d_name, ".desktop" ) ) { if ( g_str_has_suffix ( file->d_name, ".desktop" ) ) {
read_desktop_file ( pd, root, filename, file->d_name ); read_desktop_file ( pd, root, filename, file->d_name, DRUN_GROUP_NAME );
} }
break; break;
case DT_DIR: case DT_DIR:
@ -655,6 +685,9 @@ static void drun_entry_clear ( DRunModeEntry *e )
g_free ( e->name ); g_free ( e->name );
g_free ( e->generic_name ); g_free ( e->generic_name );
g_free ( e->comment ); g_free ( e->comment );
if ( e->action != DRUN_GROUP_NAME ) {
g_free ( e->action );
}
g_strfreev ( e->categories ); g_strfreev ( e->categories );
g_key_file_free ( e->key_file ); g_key_file_free ( e->key_file );
} }

View file

@ -135,6 +135,8 @@ static XrmOption xrmOptions[] = {
{ xrm_String, "drun-match-fields", { .str = &config.drun_match_fields }, NULL, { xrm_String, "drun-match-fields", { .str = &config.drun_match_fields }, NULL,
"Desktop entry fields to match in drun", CONFIG_DEFAULT }, "Desktop entry fields to match in drun", CONFIG_DEFAULT },
{ xrm_Boolean, "drun-show-actions", { .num = &config.drun_show_actions }, NULL,
"Desktop entry show actions.", CONFIG_DEFAULT },
{ xrm_Boolean, "disable-history", { .num = &config.disable_history }, NULL, { xrm_Boolean, "disable-history", { .num = &config.disable_history }, NULL,
"Disable history in run/ssh", CONFIG_DEFAULT }, "Disable history in run/ssh", CONFIG_DEFAULT },
{ xrm_Boolean, "sort", { .num = &config.sort }, NULL, { xrm_Boolean, "sort", { .num = &config.sort }, NULL,