mirror of
https://github.com/davatorium/rofi.git
synced 2024-11-18 13:54:36 -05:00
parent
0058088962
commit
4538303be6
9 changed files with 79 additions and 15 deletions
|
@ -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 */
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
18
doc/rofi.1
18
doc/rofi.1
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue