Merge tag '1.7.3' into wayland

This commit is contained in:
Jakub Jirutka 2022-01-29 20:53:22 +01:00
commit d34e827dd0
46 changed files with 3816 additions and 2110 deletions

View file

@ -1,3 +1,18 @@
v1.7.3: Sturtled!
- [Help] Print out the parsed config/theme files in -help output.
- [Keybindings] Fix keybindings being modified by -theme-str
- [Doc] Add rofi-dmenu manpage.
- [XCB] Cache lookup of monitor.
- Add -replace option (#568)
- Fix memory leak.
- [1566] Add extra debug for resolving monitors.
- [Theme] Add round,floor,ceil function in @calc (#1569)
- [Doc] Explain icon lookup.
- [Combi] Add -combi-display-format (#1570) (thanks to Jakub)
- [Theme] Expand list type ([]) for more data types.
- [Theme] Add support for tab-stops on textbox. (#1571) (thanks to Jakub)
- [Theme] Testing direct access to widgets via cmdline option (-theme+widget+property value)
v1.7.2: Shellebrations! v1.7.2: Shellebrations!
- [Build] Fix building without window mode enabled. - [Build] Fix building without window mode enabled.
- [Config] Do not print out the 'theme' field in configuration on dump. - [Config] Do not print out the 'theme' field in configuration on dump.

View file

@ -177,11 +177,15 @@ dist_man1_MANS=\
dist_man5_MANS=\ dist_man5_MANS=\
doc/rofi-theme.5\ doc/rofi-theme.5\
doc/rofi-keys.5\
doc/rofi-dmenu.5\
doc/rofi-script.5 doc/rofi-script.5
EXTRA_DIST += \ EXTRA_DIST += \
doc/rofi-theme.5.markdown \ doc/rofi-theme.5.markdown \
doc/rofi-script.5.markdown \ doc/rofi-script.5.markdown \
doc/rofi-keys.5.markdown \
doc/rofi-dmenu.5.markdown \
doc/rofi-theme-selector.1.markdown \ doc/rofi-theme-selector.1.markdown \
doc/rofi-sensible-terminal.1.markdown \ doc/rofi-sensible-terminal.1.markdown \
doc/rofi.1.markdown\ doc/rofi.1.markdown\
@ -245,11 +249,13 @@ EXTRA_DIST+=\
# Indent # Indent
## ##
update-manpage: $(top_srcdir)/doc/rofi-theme-selector.1.markdown $(top_srcdir)/doc/rofi.1.markdown $(top_srcdir)/doc/rofi-theme.5.markdown $(top_srcdir)/doc/rofi-script.5.markdown ${top_srcdir}/doc/rofi-sensible-terminal.1.markdown update-manpage: $(top_srcdir)/doc/rofi-theme-selector.1.markdown $(top_srcdir)/doc/rofi.1.markdown $(top_srcdir)/doc/rofi-theme.5.markdown $(top_srcdir)/doc/rofi-script.5.markdown ${top_srcdir}/doc/rofi-sensible-terminal.1.markdown ${top_srcdir}/doc/rofi-keys.5.markdown ${top_srcdir}/doc/rofi-dmenu.5.markdown
go-md2man -in $(top_srcdir)/doc/rofi.1.markdown -out $(top_srcdir)/doc/rofi.1 go-md2man -in $(top_srcdir)/doc/rofi.1.markdown -out $(top_srcdir)/doc/rofi.1
go-md2man -in $(top_srcdir)/doc/rofi-theme-selector.1.markdown -out $(top_srcdir)/doc/rofi-theme-selector.1 go-md2man -in $(top_srcdir)/doc/rofi-theme-selector.1.markdown -out $(top_srcdir)/doc/rofi-theme-selector.1
go-md2man -in $(top_srcdir)/doc/rofi-theme.5.markdown -out $(top_srcdir)/doc/rofi-theme.5 go-md2man -in $(top_srcdir)/doc/rofi-theme.5.markdown -out $(top_srcdir)/doc/rofi-theme.5
go-md2man -in $(top_srcdir)/doc/rofi-keys.5.markdown -out $(top_srcdir)/doc/rofi-keys.5
go-md2man -in $(top_srcdir)/doc/rofi-script.5.markdown -out $(top_srcdir)/doc/rofi-script.5 go-md2man -in $(top_srcdir)/doc/rofi-script.5.markdown -out $(top_srcdir)/doc/rofi-script.5
go-md2man -in $(top_srcdir)/doc/rofi-dmenu.5.markdown -out $(top_srcdir)/doc/rofi-dmenu.5
go-md2man -in $(top_srcdir)/doc/rofi-sensible-terminal.1.markdown -out $(top_srcdir)/doc/rofi-sensible-terminal.1 go-md2man -in $(top_srcdir)/doc/rofi-sensible-terminal.1.markdown -out $(top_srcdir)/doc/rofi-sensible-terminal.1
## ##

View file

@ -188,7 +188,8 @@ Please see the [configuration guide](https://github.com/davatorium/rofi/blob/nex
## Themes ## Themes
Please see the [themes](https://github.com/davatorium/rofi/wiki/themes) section from the [wiki](https://github.com/davatorium/rofi/wiki) for brief reference. More detailed options are provided in the [themes manpages](https://github.com/davatorium/rofi/blob/next/doc/rofi-theme.5.markdown). Please see the [themes manpages](https://github.com/davatorium/rofi/blob/next/doc/rofi-theme.5.markdown) for a detailed description.
The latest bundled themes can be found [here](https://github.com/davatorium/rofi/tree/next/themes). The latest bundled themes can be found [here](https://github.com/davatorium/rofi/tree/next/themes).
@ -233,3 +234,8 @@ for discussions.
* [GitHub Discussions](https://github.com/davatorium/rofi/discussions) * [GitHub Discussions](https://github.com/davatorium/rofi/discussions)
* IRC (#rofi on irc.libera.chat) * IRC (#rofi on irc.libera.chat)
* [Reddit](https://reddit.com/r/qtools/) * [Reddit](https://reddit.com/r/qtools/)
## Stargazers over time
[![Stargazers over time](https://starchart.cc/davatorium/rofi.svg)](https://starchart.cc/davatorium/rofi)

View file

@ -139,6 +139,7 @@ Settings config = {
.plugin_path = PLUGIN_PATH, .plugin_path = PLUGIN_PATH,
.max_history_size = 25, .max_history_size = 25,
.combi_hide_mode_prefix = FALSE, .combi_hide_mode_prefix = FALSE,
.combi_display_format = "{mode} {text}",
.matching_negate_char = '-', .matching_negate_char = '-',

View file

@ -1,4 +1,4 @@
AC_INIT([rofi], [1.7.2], [https://github.com/davatorium/rofi/],[],[https://reddit.com/r/qtools/]) AC_INIT([rofi], [1.7.3], [https://github.com/davatorium/rofi/],[],[https://reddit.com/r/qtools/])
AC_CONFIG_SRCDIR([source/rofi.c]) AC_CONFIG_SRCDIR([source/rofi.c])
AC_CONFIG_HEADER([config.h]) AC_CONFIG_HEADER([config.h])
@ -124,6 +124,7 @@ AC_CHECK_FUNC([readdir],, AC_MSG_ERROR("Could not find readdir in c library"))
AC_CHECK_HEADER([math.h],, AC_MSG_ERROR("Could not find math.h header file")) AC_CHECK_HEADER([math.h],, AC_MSG_ERROR("Could not find math.h header file"))
AC_SEARCH_LIBS([floor],[m],, AC_MSG_ERROR("Could not find floor in math library")) AC_SEARCH_LIBS([floor],[m],, AC_MSG_ERROR("Could not find floor in math library"))
AC_SEARCH_LIBS([ceil], [m],, AC_MSG_ERROR("Could not find ceil in math library")) AC_SEARCH_LIBS([ceil], [m],, AC_MSG_ERROR("Could not find ceil in math library"))
AC_SEARCH_LIBS([round], [m],, AC_MSG_ERROR("Could not find round in math library"))
AC_CHECK_HEADER([sysexits.h],, AC_MSG_ERROR("Could not find the sysexists.h header file")) AC_CHECK_HEADER([sysexits.h],, AC_MSG_ERROR("Could not find the sysexists.h header file"))
AC_CHECK_HEADER([setjmp.h],, AC_MSG_ERROR("Could not find the setjmp.h header file")) AC_CHECK_HEADER([setjmp.h],, AC_MSG_ERROR("Could not find the setjmp.h header file"))

View file

@ -5,6 +5,8 @@ if gomd2man.found()
'rofi.1.markdown', 'rofi.1.markdown',
'rofi-theme-selector.1.markdown', 'rofi-theme-selector.1.markdown',
'rofi-theme.5.markdown', 'rofi-theme.5.markdown',
'rofi-dmenu.5.markdown',
'rofi-keys.5.markdown',
'rofi-script.5.markdown', 'rofi-script.5.markdown',
'rofi-sensible-terminal.1.markdown' 'rofi-sensible-terminal.1.markdown'
)] )]

310
doc/rofi-dmenu.5 Normal file
View file

@ -0,0 +1,310 @@
.TH ROFI\-DMENU 5 rofi\-dmenu
.SH NAME
.PP
\fBrofi dmenu mode\fP \- Rofi dmenu emulation
.SH DESCRIPTION
.PP
To integrate \fBrofi\fP into scripts as simple selection dialogs,
\fBrofi\fP supports emulating \fBdmenu(1)\fP (A dynamic menu for X11).
.PP
The website for \fB\fCdmenu\fR can be found here
\[la]http://tools.suckless.org/dmenu/\[ra]\&.
.PP
\fBrofi\fP does not aim to be 100% compatible with \fB\fCdmenu\fR\&. There are simply too many flavors of \fB\fCdmenu\fR\&.
The idea is that the basic usage command\-line flags are obeyed, theme\-related flags are not.
Besides, \fBrofi\fP offers some extended features (like multi\-select, highlighting, message bar, extra key bindings).
.SH BASIC CONCEPT
.PP
In \fB\fCdmenu\fR mode, \fBrofi\fP reads data from standard in, splits them into separate entries and displays them.
If the user selects an row, this is printed out to standard out, allow the script to process it further.
.PP
By default separation of rows is done on new lines, making it easy to pipe the output a one application into
\fBrofi\fP and the output of rofi into the next.
.SH USAGE
.PP
By launching \fBrofi\fP with the \fB\fC\-dmenu\fR flag it will go into dmenu emulation mode.
.PP
.RS
.nf
ls | rofi \-dmenu
.fi
.RE
.SS DMENU DROP\-IN REPLACEMENT
.PP
If \fB\fCargv[0]\fR (calling command) is dmenu, \fBrofi\fP will start in dmenu mode.
This way, it can be used as a drop\-in replacement for dmenu. Just copy or symlink \fBrofi\fP to dmenu in \fB\fC$PATH\fR\&.
.PP
.RS
.nf
ln \-s /usr/bin/rofi /usr/bin/dmenu
.fi
.RE
.SS DMENU VS SCRIPT MODE
.PP
Script mode is used to extend \fBrofi\fP, dmenu mode is used to extend a script.
The two do share much of the same input format. Please see the \fBrofi\-script(5)\fP manpage for more information.
.SS DMENU SPECIFIC COMMANDLINE FLAGS
.PP
A lot of these options can also be modified by the script using special input. See the \fBrofi\-script(5)\fP manpage
for more information about this syntax.
.PP
\fB\fC\-sep\fR \fIseparator\fP
.PP
Separator for \fB\fCdmenu\fR\&. Example: To show a list of 'a' to 'e' with '|' as a separator:
.PP
.RS
.nf
echo "a|b|c|d|e" | rofi \-sep '|' \-dmenu
.fi
.RE
.PP
\fB\fC\-p\fR \fIprompt\fP
.PP
Specify the prompt to show in \fB\fCdmenu\fR mode. For example, select 'monkey', a,b,c,d, or e.
.PP
.RS
.nf
echo "a|b|c|d|e" | rofi \-sep '|' \-dmenu \-p "monkey"
.fi
.RE
.PP
Default: \fIdmenu\fP
.PP
\fB\fC\-l\fR \fInumber of lines to show\fP
.PP
Maximum number of lines the menu may show before scrolling.
.PP
.RS
.nf
rofi \-dmenu \-l 25
.fi
.RE
.PP
Default: \fI15\fP
.PP
\fB\fC\-i\fR
.PP
Makes \fB\fCdmenu\fR searches case\-insensitive
.PP
\fB\fC\-a\fR \fIX\fP
.PP
Active row, mark \fIX\fP as active. Where \fIX\fP 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:
.RS
.IP \(bu 2
A single row: '5'
.IP \(bu 2
A range of (last 3) rows: '\-3:'
.IP \(bu 2
4 rows starting from row 7: '7:11' (or in legacy notation: '7\-10')
.IP \(bu 2
A set of rows: '2,0,\-9'
.IP \(bu 2
Or any combination: '5,\-3:,7:11,2,0,\-9'
.RE
.PP
\fB\fC\-u\fR \fIX\fP
.PP
Urgent row, mark \fIX\fP as urgent. See \fB\fC\-a\fR option for details.
.PP
\fB\fC\-only\-match\fR
.PP
Only return a selected item, do not allow custom entry.
This mode always returns an entry. It will not return if no matching entry is
selected.
.PP
\fB\fC\-no\-custom\fR
.PP
Only return a selected item, do not allow custom entry.
This mode returns directly when no entries given.
.PP
\fB\fC\-format\fR \fIformat\fP
.PP
Allows the output of dmenu to be customized (N is the total number of input entries):
.RS
.IP \(bu 2
\&'s' selected string
.IP \(bu 2
\&'i' index (0 \-\& (N\-\&1))
.IP \(bu 2
\&'d' index (1 \-\& N)
.IP \(bu 2
\&'q' quote string
.IP \(bu 2
\&'p' Selected string stripped from Pango markup (Needs to be a valid string)
.IP \(bu 2
\&'f' filter string (user input)
.IP \(bu 2
\&'F' quoted filter string (user input)
.RE
.PP
Default: 's'
.PP
\fB\fC\-select\fR \fIstring\fP
.PP
Select first line that matches the given string
.PP
\fB\fC\-mesg\fR \fIstring\fP
.PP
Add a message line below the filter entry box. Supports Pango markup.
For more information on supported markup, see here
\[la]https://docs.gtk.org/Pango/pango_markup.html\[ra]
.PP
\fB\fC\-dump\fR
.PP
Dump the filtered list to stdout and quit.
This can be used to get the list as \fBrofi\fP would filter it.
Use together with \fB\fC\-filter\fR command.
.PP
\fB\fC\-input\fR \fIfile\fP
.PP
Reads from \fIfile\fP instead of stdin.
.PP
\fB\fC\-password\fR
.PP
Hide the input text. This should not be considered secure!
.PP
\fB\fC\-markup\-rows\fR
.PP
Tell \fBrofi\fP that DMenu input is Pango markup encoded, and should be rendered.
See here
\[la]https://developer.gnome.org/pygtk/stable/pango-markup-language.html\[ra] for details about Pango markup.
.PP
\fB\fC\-multi\-select\fR
.PP
Allow multiple lines to be selected. Adds a small selection indicator to the left of each entry.
.PP
\fB\fC\-sync\fR
.PP
Force \fBrofi\fP mode to first read all data from stdin before showing the selection window. This is original dmenu behavior.
.PP
Note: the default asynchronous mode will also be automatically disabled if used with conflicting options,
such as \fB\fC\-dump\fR, \fB\fC\-only\-match\fR or \fB\fC\-auto\-select\fR\&.
.PP
\fB\fC\-async\-pre\-read\fR \fInumber\fP
.PP
Reads the first \fInumber\fP entries blocking, then switches to async mode.
This makes it feel more 'snappy'.
.PP
\fIdefault\fP: 25
.PP
\fB\fC\-window\-title\fR \fItitle\fP
.PP
Set name used for the window title. Will be shown as Rofi \- \fItitle\fP
.PP
\fB\fC\-w\fR \fIwindowid\fP
.PP
Position \fBrofi\fP over the window with the given X11 window ID.
.PP
\fB\fC\-keep\-right\fR
.PP
Set ellipsize mode to start. So, the end of the string is visible.
.SH RETURN VALUE
.RS
.IP \(bu 2
\fB0\fP: Row has been selected accepted by user.
.IP \(bu 2
\fB1\fP: User cancelled the selection.
.IP \(bu 2
\fB10\-28\fP: Row accepted by custom keybinding.
.RE
.SH SEE ALSO
.PP
rofi(1), rofi\-sensible\-terminal(1), dmenu(1), rofi\-theme(5), rofi\-script(5), rofi\-theme\-selector(1)
.SH AUTHOR
.PP
Qball Cow
\[la]qball@gmpclient.org\[ra]
.PP
Rasmus Steinke
\[la]rasi@xssn.at\[ra]
.PP
Quentin Glidic
\[la]sardemff7+rofi@sardemff7.net\[ra]
.PP
Original code based on work by: Sean Pringle
\[la]sean.pringle@gmail.com\[ra]
.PP
For a full list of authors, check the AUTHORS file.

203
doc/rofi-dmenu.5.markdown Normal file
View file

@ -0,0 +1,203 @@
# ROFI-DMENU 5 rofi-dmenu
## NAME
**rofi dmenu mode** - Rofi dmenu emulation
## DESCRIPTION
To integrate **rofi** into scripts as simple selection dialogs,
**rofi** supports emulating **dmenu(1)** (A dynamic menu for X11).
The website for `dmenu` can be found [here](http://tools.suckless.org/dmenu/).
**rofi** does not aim to be 100% compatible with `dmenu`. There are simply too many flavors of `dmenu`.
The idea is that the basic usage command-line flags are obeyed, theme-related flags are not.
Besides, **rofi** offers some extended features (like multi-select, highlighting, message bar, extra key bindings).
## BASIC CONCEPT
In `dmenu` mode, **rofi** reads data from standard in, splits them into separate entries and displays them.
If the user selects an row, this is printed out to standard out, allow the script to process it further.
By default separation of rows is done on new lines, making it easy to pipe the output a one application into
**rofi** and the output of rofi into the next.
## USAGE
By launching **rofi** with the `-dmenu` flag it will go into dmenu emulation mode.
```bash
ls | rofi -dmenu
```
### DMENU DROP-IN REPLACEMENT
If `argv[0]` (calling command) is dmenu, **rofi** will start in dmenu mode.
This way, it can be used as a drop-in replacement for dmenu. Just copy or symlink **rofi** to dmenu in `$PATH`.
ln -s /usr/bin/rofi /usr/bin/dmenu
### DMENU VS SCRIPT MODE
Script mode is used to extend **rofi**, dmenu mode is used to extend a script.
The two do share much of the same input format. Please see the **rofi-script(5)** manpage for more information.
### DMENU SPECIFIC COMMANDLINE FLAGS
A lot of these options can also be modified by the script using special input. See the **rofi-script(5)** manpage
for more information about this syntax.
`-sep` *separator*
Separator for `dmenu`. Example: To show a list of 'a' to 'e' with '|' as a separator:
echo "a|b|c|d|e" | rofi -sep '|' -dmenu
`-p` *prompt*
Specify the prompt to show in `dmenu` mode. For example, select 'monkey', a,b,c,d, or e.
echo "a|b|c|d|e" | rofi -sep '|' -dmenu -p "monkey"
Default: *dmenu*
`-l` *number of lines to show*
Maximum number of lines the menu may show before scrolling.
rofi -dmenu -l 25
Default: *15*
`-i`
Makes `dmenu` searches case-insensitive
`-a` *X*
Active row, mark *X* as active. Where *X* 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:
* A single row: '5'
* A range of (last 3) rows: '-3:'
* 4 rows starting from row 7: '7:11' (or in legacy notation: '7-10')
* A set of rows: '2,0,-9'
* Or any combination: '5,-3:,7:11,2,0,-9'
`-u` *X*
Urgent row, mark *X* as urgent. See `-a` option for details.
`-only-match`
Only return a selected item, do not allow custom entry.
This mode always returns an entry. It will not return if no matching entry is
selected.
`-no-custom`
Only return a selected item, do not allow custom entry.
This mode returns directly when no entries given.
`-format` *format*
Allows the output of dmenu to be customized (N is the total number of input entries):
* 's' selected string
* 'i' index (0 - (N-1))
* 'd' index (1 - N)
* 'q' quote string
* 'p' Selected string stripped from Pango markup (Needs to be a valid string)
* 'f' filter string (user input)
* 'F' quoted filter string (user input)
Default: 's'
`-select` *string*
Select first line that matches the given string
`-mesg` *string*
Add a message line below the filter entry box. Supports Pango markup.
For more information on supported markup, see [here](https://docs.gtk.org/Pango/pango_markup.html)
`-dump`
Dump the filtered list to stdout and quit.
This can be used to get the list as **rofi** would filter it.
Use together with `-filter` command.
`-input` *file*
Reads from *file* instead of stdin.
`-password`
Hide the input text. This should not be considered secure!
`-markup-rows`
Tell **rofi** that DMenu input is Pango markup encoded, and should be rendered.
See [here](https://developer.gnome.org/pygtk/stable/pango-markup-language.html) for details about Pango markup.
`-multi-select`
Allow multiple lines to be selected. Adds a small selection indicator to the left of each entry.
`-sync`
Force **rofi** mode to first read all data from stdin before showing the selection window. This is original dmenu behavior.
Note: the default asynchronous mode will also be automatically disabled if used with conflicting options,
such as `-dump`, `-only-match` or `-auto-select`.
`-async-pre-read` *number*
Reads the first *number* entries blocking, then switches to async mode.
This makes it feel more 'snappy'.
*default*: 25
`-window-title` *title*
Set name used for the window title. Will be shown as Rofi - *title*
`-w` *windowid*
Position **rofi** over the window with the given X11 window ID.
`-keep-right`
Set ellipsize mode to start. So, the end of the string is visible.
## RETURN VALUE
* **0**: Row has been selected accepted by user.
* **1**: User cancelled the selection.
* **10-28**: Row accepted by custom keybinding.
## SEE ALSO
rofi(1), rofi-sensible-terminal(1), dmenu(1), rofi-theme(5), rofi-script(5), rofi-theme-selector(1)
## AUTHOR
Qball Cow <qball@gmpclient.org>
Rasmus Steinke <rasi@xssn.at>
Quentin Glidic <sardemff7+rofi@sardemff7.net>
Original code based on work by: Sean Pringle <sean.pringle@gmail.com>
For a full list of authors, check the AUTHORS file.

625
doc/rofi-keys.5 Normal file
View file

@ -0,0 +1,625 @@
.TH ROFI\-KEYS 5 rofi\-keys
.SH NAME
.PP
\fBrofi keys\fP \- Rofi Key and Mouse bindings
.SH DESCRIPTION
.PP
\fBrofi\fP supports overriding of any of it key and mouse binding.
.SH Setting binding
.PP
Bindings can be done on the commandline (\-{bindingname}):
.PP
.RS
.nf
rofi \-show run \-kb\-accept\-entry 'Control+Shift+space'
.fi
.RE
.PP
or via the configuration file:
.PP
.RS
.nf
configuration {
kb\-accept\-entry: "Control+Shift+space";
}
.fi
.RE
.PP
The key can be set by its name (see above) or its keycode:
.PP
.RS
.nf
configuration {
kb\-accept\-entry: "Control+Shift+[65]";
}
.fi
.RE
.PP
An easy way to look up keycode is xev(1).
.PP
Multiple keys can be specified for an action as a comma separated list:
.PP
.RS
.nf
configuration {
kb\-accept\-entry: "Control+Shift+space,Return";
}
.fi
.RE
.PP
By Default \fBrofi\fP reacts on pressing, to act on the release of all keys
prepend the binding with \fB\fC!\fR:
.PP
.RS
.nf
configuration {
kb\-accept\-entry: "!Control+Shift+space,Return";
}
.fi
.RE
.SH Keyboard Bindings
.SS \fBkb\-primary\-paste\fP:
.PP
Paste primary selection
.PP
\fBDefault\fP: Control+V,Shift+Insert
.SS \fBkb\-secondary\-paste\fP
.PP
Paste clipboard
.PP
\fBDefault\fP: Control+v,Insert
.SS \fBkb\-clear\-line\fP
.PP
Clear input line
.PP
\fBDefault\fP: Control+w
.SS \fBkb\-move\-front\fP
.PP
Beginning of line
.PP
\fBDefault\fP: Control+a
.SS \fBkb\-move\-end\fP
.PP
End of line
.PP
\fBDefault\fP: Control+e
.SS \fBkb\-move\-word\-back\fP
.PP
Move back one word
.PP
\fBDefault\fP: Alt+b,Control+Left
.SS \fBkb\-move\-word\-forward\fP
.PP
Move forward one word
.PP
\fBDefault\fP: Alt+f,Control+Right
.SS \fBkb\-move\-char\-back\fP
.PP
Move back one char
.PP
\fBDefault\fP: Left,Control+b
.SS \fBkb\-move\-char\-forward\fP
.PP
Move forward one char
.PP
\fBDefault\fP: Right,Control+f
.SS \fBkb\-remove\-word\-back\fP
.PP
Delete previous word
.PP
\fBDefault\fP: Control+Alt+h,Control+BackSpace
.SS \fBkb\-remove\-word\-forward\fP
.PP
Delete next word
.PP
\fBDefault\fP: Control+Alt+d
.SS \fBkb\-remove\-char\-forward\fP
.PP
Delete next char
.PP
\fBDefault\fP: Delete,Control+d
.SS \fBkb\-remove\-char\-back\fP
.PP
Delete previous char
.PP
\fBDefault\fP: BackSpace,Shift+BackSpace,Control+h
.SS \fBkb\-remove\-to\-eol\fP
.PP
Delete till the end of line
.PP
\fBDefault\fP: Control+k
.SS \fBkb\-remove\-to\-sol\fP
.PP
Delete till the start of line
.PP
\fBDefault\fP: Control+u
.SS \fBkb\-accept\-entry\fP
.PP
Accept entry
.PP
\fBDefault\fP: Control+j,Control+m,Return,KP\_Enter
.SS \fBkb\-accept\-custom\fP
.PP
Use entered text as command (in ssh/run modi)
.PP
\fBDefault\fP: Control+Return
.SS \fBkb\-accept\-custom\-alt\fP
.PP
Use entered text as command (in ssh/run modi)
.PP
\fBDefault\fP: Control+Shift+Return
.SS \fBkb\-accept\-alt\fP
.PP
Use alternate accept command.
.PP
\fBDefault\fP: Shift+Return
.SS \fBkb\-delete\-entry\fP
.PP
Delete entry from history
.PP
\fBDefault\fP: Shift+Delete
.SS \fBkb\-mode\-next\fP
.PP
Switch to the next mode.
.PP
\fBDefault\fP: Shift+Right,Control+Tab
.SS \fBkb\-mode\-previous\fP
.PP
Switch to the previous mode.
.PP
\fBDefault\fP: Shift+Left,Control+ISO\_Left\_Tab
.SS \fBkb\-mode\-complete\fP
.PP
Start completion for mode.
.PP
\fBDefault\fP: Control+l
.SS \fBkb\-row\-left\fP
.PP
Go to the previous column
.PP
\fBDefault\fP: Control+Page\_Up
.SS \fBkb\-row\-right\fP
.PP
Go to the next column
.PP
\fBDefault\fP: Control+Page\_Down
.SS \fBkb\-row\-up\fP
.PP
Select previous entry
.PP
\fBDefault\fP: Up,Control+p,ISO\_Left\_Tab
.SS \fBkb\-row\-down\fP
.PP
Select next entry
.PP
\fBDefault\fP: Down,Control+n
.SS \fBkb\-row\-tab\fP
.PP
Go to next row, if one left, accept it, if no left next mode.
.PP
\fBDefault\fP: Tab
.SS \fBkb\-page\-prev\fP
.PP
Go to the previous page
.PP
\fBDefault\fP: Page\_Up
.SS \fBkb\-page\-next\fP
.PP
Go to the next page
.PP
\fBDefault\fP: Page\_Down
.SS \fBkb\-row\-first\fP
.PP
Go to the first entry
.PP
\fBDefault\fP: Home,KP\_Home
.SS \fBkb\-row\-last\fP
.PP
Go to the last entry
.PP
\fBDefault\fP: End,KP\_End
.SS \fBkb\-row\-select\fP
.PP
Set selected item as input text
.PP
\fBDefault\fP: Control+space
.SS \fBkb\-screenshot\fP
.PP
Take a screenshot of the rofi window
.PP
\fBDefault\fP: Alt+S
.SS \fBkb\-ellipsize\fP
.PP
Toggle between ellipsize modes for displayed data
.PP
\fBDefault\fP: Alt+period
.SS \fBkb\-toggle\-case\-sensitivity\fP
.PP
Toggle case sensitivity
.PP
\fBDefault\fP: grave,dead\_grave
.SS \fBkb\-toggle\-sort\fP
.PP
Toggle sort
.PP
\fBDefault\fP: Alt+grave
.SS \fBkb\-cancel\fP
.PP
Quit rofi
.PP
\fBDefault\fP: Escape,Control+g,Control+bracketleft
.SS \fBkb\-custom\-1\fP
.PP
Custom keybinding 1
.PP
\fBDefault\fP: Alt+1
.SS \fBkb\-custom\-2\fP
.PP
Custom keybinding 2
.PP
\fBDefault\fP: Alt+2
.SS \fBkb\-custom\-3\fP
.PP
Custom keybinding 3
.PP
\fBDefault\fP: Alt+3
.SS \fBkb\-custom\-4\fP
.PP
Custom keybinding 4
.PP
\fBDefault\fP: Alt+4
.SS \fBkb\-custom\-5\fP
.PP
Custom Keybinding 5
.PP
\fBDefault\fP: Alt+5
.SS \fBkb\-custom\-6\fP
.PP
Custom keybinding 6
.PP
\fBDefault\fP: Alt+6
.SS \fBkb\-custom\-7\fP
.PP
Custom Keybinding 7
.PP
\fBDefault\fP: Alt+7
.SS \fBkb\-custom\-8\fP
.PP
Custom keybinding 8
.PP
\fBDefault\fP: Alt+8
.SS \fBkb\-custom\-9\fP
.PP
Custom keybinding 9
.PP
\fBDefault\fP: Alt+9
.SS \fBkb\-custom\-10\fP
.PP
Custom keybinding 10
.PP
\fBDefault\fP: Alt+0
.SS \fBkb\-custom\-11\fP
.PP
Custom keybinding 11
.PP
\fBDefault\fP: Alt+exclam
.SS \fBkb\-custom\-12\fP
.PP
Custom keybinding 12
.PP
\fBDefault\fP: Alt+at
.SS \fBkb\-custom\-13\fP
.PP
Custom keybinding 13
.PP
\fBDefault\fP: Alt+numbersign
.SS \fBkb\-custom\-14\fP
.PP
Custom keybinding 14
.PP
\fBDefault\fP: Alt+dollar
.SS \fBkb\-custom\-15\fP
.PP
Custom keybinding 15
.PP
\fBDefault\fP: Alt+percent
.SS \fBkb\-custom\-16\fP
.PP
Custom keybinding 16
.PP
\fBDefault\fP: Alt+dead\_circumflex
.SS \fBkb\-custom\-17\fP
.PP
Custom keybinding 17
.PP
\fBDefault\fP: Alt+ampersand
.SS \fBkb\-custom\-18\fP
.PP
Custom keybinding 18
.PP
\fBDefault\fP: Alt+asterisk
.SS \fBkb\-custom\-19\fP
.PP
Custom Keybinding 19
.PP
\fBDefault\fP: Alt+parenleft
.SS \fBkb\-select\-1\fP
.PP
Select row 1
.PP
\fBDefault\fP: Super+1
.SS \fBkb\-select\-2\fP
.PP
Select row 2
.PP
\fBDefault\fP: Super+2
.SS \fBkb\-select\-3\fP
.PP
Select row 3
.PP
\fBDefault\fP: Super+3
.SS \fBkb\-select\-4\fP
.PP
Select row 4
.PP
\fBDefault\fP: Super+4
.SS \fBkb\-select\-5\fP
.PP
Select row 5
.PP
\fBDefault\fP: Super+5
.SS \fBkb\-select\-6\fP
.PP
Select row 6
.PP
\fBDefault\fP: Super+6
.SS \fBkb\-select\-7\fP
.PP
Select row 7
.PP
\fBDefault\fP: Super+7
.SS \fBkb\-select\-8\fP
.PP
Select row 8
.PP
\fBDefault\fP: Super+8
.SS \fBkb\-select\-9\fP
.PP
Select row 9
.PP
\fBDefault\fP: Super+9
.SS \fBkb\-select\-10\fP
.PP
Select row 10
.PP
\fBDefault\fP: Super+0
.SH Mouse Bindings
.SS \fBml\-row\-left\fP
.PP
Go to the previous column
.PP
\fBDefault\fP: ScrollLeft
.SS \fBml\-row\-right\fP
.PP
Go to the next column
.PP
\fBDefault\fP: ScrollRight
.SS \fBml\-row\-up\fP
.PP
Select previous entry
.PP
\fBDefault\fP: ScrollUp
.SS \fBml\-row\-down\fP
.PP
Select next entry
.PP
\fBDefault\fP: ScrollDown
.SS \fBme\-select\-entry\fP
.PP
Select hovered row
.PP
\fBDefault\fP: MousePrimary
.SS \fBme\-accept\-entry\fP
.PP
Accept hovered row
.PP
\fBDefault\fP: MouseDPrimary
.SS \fBme\-accept\-custom\fP
.PP
Accept hovered row with custom action
.PP
\fBDefault\fP: Control+MouseDPrimary
.SH SEE ALSO
.PP
rofi(1), rofi\-sensible\-terminal(1), rofi\-theme(5), rofi\-script(5)
.SH AUTHOR
.PP
Qball Cow
\[la]qball@gmpclient.org\[ra]
.PP
Rasmus Steinke
\[la]rasi@xssn.at\[ra]
.PP
Quentin Glidic
\[la]sardemff7+rofi@sardemff7.net\[ra]
.PP
Original code based on work by: Sean Pringle
\[la]sean.pringle@gmail.com\[ra]
.PP
For a full list of authors, check the AUTHORS file.

446
doc/rofi-keys.5.markdown Normal file
View file

@ -0,0 +1,446 @@
# ROFI-KEYS 5 rofi-keys
## NAME
**rofi keys** - Rofi Key and Mouse bindings
## DESCRIPTION
**rofi** supports overriding of any of it key and mouse binding.
## Setting binding
Bindings can be done on the commandline (-{bindingname}):
```bash
rofi -show run -kb-accept-entry 'Control+Shift+space'
```
or via the configuration file:
```css
configuration {
kb-accept-entry: "Control+Shift+space";
}
```
The key can be set by its name (see above) or its keycode:
```css
configuration {
kb-accept-entry: "Control+Shift+[65]";
}
```
An easy way to look up keycode is xev(1).
Multiple keys can be specified for an action as a comma separated list:
```css
configuration {
kb-accept-entry: "Control+Shift+space,Return";
}
```
By Default **rofi** reacts on pressing, to act on the release of all keys
prepend the binding with `!`:
```css
configuration {
kb-accept-entry: "!Control+Shift+space,Return";
}
```
## Keyboard Bindings
### **kb-primary-paste**:
Paste primary selection
**Default**: Control+V,Shift+Insert
### **kb-secondary-paste**
Paste clipboard
**Default**: Control+v,Insert
### **kb-clear-line**
Clear input line
**Default**: Control+w
### **kb-move-front**
Beginning of line
**Default**: Control+a
### **kb-move-end**
End of line
**Default**: Control+e
### **kb-move-word-back**
Move back one word
**Default**: Alt+b,Control+Left
### **kb-move-word-forward**
Move forward one word
**Default**: Alt+f,Control+Right
### **kb-move-char-back**
Move back one char
**Default**: Left,Control+b
### **kb-move-char-forward**
Move forward one char
**Default**: Right,Control+f
### **kb-remove-word-back**
Delete previous word
**Default**: Control+Alt+h,Control+BackSpace
### **kb-remove-word-forward**
Delete next word
**Default**: Control+Alt+d
### **kb-remove-char-forward**
Delete next char
**Default**: Delete,Control+d
### **kb-remove-char-back**
Delete previous char
**Default**: BackSpace,Shift+BackSpace,Control+h
### **kb-remove-to-eol**
Delete till the end of line
**Default**: Control+k
### **kb-remove-to-sol**
Delete till the start of line
**Default**: Control+u
### **kb-accept-entry**
Accept entry
**Default**: Control+j,Control+m,Return,KP_Enter
### **kb-accept-custom**
Use entered text as command (in ssh/run modi)
**Default**: Control+Return
### **kb-accept-custom-alt**
Use entered text as command (in ssh/run modi)
**Default**: Control+Shift+Return
### **kb-accept-alt**
Use alternate accept command.
**Default**: Shift+Return
### **kb-delete-entry**
Delete entry from history
**Default**: Shift+Delete
### **kb-mode-next**
Switch to the next mode.
**Default**: Shift+Right,Control+Tab
### **kb-mode-previous**
Switch to the previous mode.
**Default**: Shift+Left,Control+ISO_Left_Tab
### **kb-mode-complete**
Start completion for mode.
**Default**: Control+l
### **kb-row-left**
Go to the previous column
**Default**: Control+Page_Up
### **kb-row-right**
Go to the next column
**Default**: Control+Page_Down
### **kb-row-up**
Select previous entry
**Default**: Up,Control+p,ISO_Left_Tab
### **kb-row-down**
Select next entry
**Default**: Down,Control+n
### **kb-row-tab**
Go to next row, if one left, accept it, if no left next mode.
**Default**: Tab
### **kb-page-prev**
Go to the previous page
**Default**: Page_Up
### **kb-page-next**
Go to the next page
**Default**: Page_Down
### **kb-row-first**
Go to the first entry
**Default**: Home,KP_Home
### **kb-row-last**
Go to the last entry
**Default**: End,KP_End
### **kb-row-select**
Set selected item as input text
**Default**: Control+space
### **kb-screenshot**
Take a screenshot of the rofi window
**Default**: Alt+S
### **kb-ellipsize**
Toggle between ellipsize modes for displayed data
**Default**: Alt+period
### **kb-toggle-case-sensitivity**
Toggle case sensitivity
**Default**: grave,dead_grave
### **kb-toggle-sort**
Toggle sort
**Default**: Alt+grave
### **kb-cancel**
Quit rofi
**Default**: Escape,Control+g,Control+bracketleft
### **kb-custom-1**
Custom keybinding 1
**Default**: Alt+1
### **kb-custom-2**
Custom keybinding 2
**Default**: Alt+2
### **kb-custom-3**
Custom keybinding 3
**Default**: Alt+3
### **kb-custom-4**
Custom keybinding 4
**Default**: Alt+4
### **kb-custom-5**
Custom Keybinding 5
**Default**: Alt+5
### **kb-custom-6**
Custom keybinding 6
**Default**: Alt+6
### **kb-custom-7**
Custom Keybinding 7
**Default**: Alt+7
### **kb-custom-8**
Custom keybinding 8
**Default**: Alt+8
### **kb-custom-9**
Custom keybinding 9
**Default**: Alt+9
### **kb-custom-10**
Custom keybinding 10
**Default**: Alt+0
### **kb-custom-11**
Custom keybinding 11
**Default**: Alt+exclam
### **kb-custom-12**
Custom keybinding 12
**Default**: Alt+at
### **kb-custom-13**
Custom keybinding 13
**Default**: Alt+numbersign
### **kb-custom-14**
Custom keybinding 14
**Default**: Alt+dollar
### **kb-custom-15**
Custom keybinding 15
**Default**: Alt+percent
### **kb-custom-16**
Custom keybinding 16
**Default**: Alt+dead_circumflex
### **kb-custom-17**
Custom keybinding 17
**Default**: Alt+ampersand
### **kb-custom-18**
Custom keybinding 18
**Default**: Alt+asterisk
### **kb-custom-19**
Custom Keybinding 19
**Default**: Alt+parenleft
### **kb-select-1**
Select row 1
**Default**: Super+1
### **kb-select-2**
Select row 2
**Default**: Super+2
### **kb-select-3**
Select row 3
**Default**: Super+3
### **kb-select-4**
Select row 4
**Default**: Super+4
### **kb-select-5**
Select row 5
**Default**: Super+5
### **kb-select-6**
Select row 6
**Default**: Super+6
### **kb-select-7**
Select row 7
**Default**: Super+7
### **kb-select-8**
Select row 8
**Default**: Super+8
### **kb-select-9**
Select row 9
**Default**: Super+9
### **kb-select-10**
Select row 10
**Default**: Super+0
## Mouse Bindings
### **ml-row-left**
Go to the previous column
**Default**: ScrollLeft
### **ml-row-right**
Go to the next column
**Default**: ScrollRight
### **ml-row-up**
Select previous entry
**Default**: ScrollUp
### **ml-row-down**
Select next entry
**Default**: ScrollDown
### **me-select-entry**
Select hovered row
**Default**: MousePrimary
### **me-accept-entry**
Accept hovered row
**Default**: MouseDPrimary
### **me-accept-custom**
Accept hovered row with custom action
**Default**: Control+MouseDPrimary
## SEE ALSO
rofi(1), rofi-sensible-terminal(1), rofi-theme(5), rofi-script(5)
## AUTHOR
Qball Cow <qball@gmpclient.org>
Rasmus Steinke <rasi@xssn.at>
Quentin Glidic <sardemff7+rofi@sardemff7.net>
Original code based on work by: Sean Pringle <sean.pringle@gmail.com>
For a full list of authors, check the AUTHORS file.

View file

@ -1,4 +1,3 @@
.nh
.TH ROFI\-SCRIPT 5 rofi\-script .TH ROFI\-SCRIPT 5 rofi\-script
.SH NAME .SH NAME
.PP .PP
@ -194,20 +193,20 @@ rofi(1), rofi\-sensible\-terminal(1), dmenu(1), rofi\-theme(5), rofi\-theme\-sel
.SH AUTHOR .SH AUTHOR
.PP .PP
Qball Cow qball@gmpclient.org Qball Cow
\[la]mailto:qball@gmpclient.org\[ra] \[la]qball@gmpclient.org\[ra]
.PP .PP
Rasmus Steinke rasi@xssn.at Rasmus Steinke
\[la]mailto:rasi@xssn.at\[ra] \[la]rasi@xssn.at\[ra]
.PP .PP
Quentin Glidic sardemff7+rofi@sardemff7.net Quentin Glidic
\[la]mailto:sardemff7+rofi@sardemff7.net\[ra] \[la]sardemff7+rofi@sardemff7.net\[ra]
.PP .PP
Original code based on work by: Sean Pringle sean.pringle@gmail.com Original code based on work by: Sean Pringle
\[la]mailto:sean.pringle@gmail.com\[ra] \[la]sean.pringle@gmail.com\[ra]
.PP .PP
For a full list of authors, check the AUTHORS file. For a full list of authors, check the AUTHORS file.

View file

@ -1,4 +1,3 @@
.nh
.TH rofi\-sensible\-terminal 1 rofi\-sensible\-terminal .TH rofi\-sensible\-terminal 1 rofi\-sensible\-terminal
.SH NAME .SH NAME
.PP .PP

View file

@ -1,4 +1,3 @@
.nh
.TH rofi\-theme\-selector 1 rofi\-theme\-selector .TH rofi\-theme\-selector 1 rofi\-theme\-selector
.SH NAME .SH NAME
.PP .PP
@ -31,8 +30,8 @@ $XDG\_DATA\_HOME/share/rofi/themes
.RE .RE
.PP .PP
${PREFIX} reflects the install location of rofi. In most cases this will be "/usr". ${PREFIX} reflects the install location of rofi. In most cases this will be "/usr".<br>
$XDG\_CONFIG\_HOME is normally unset. Default path is "$HOME/.config". $XDG\_CONFIG\_HOME is normally unset. Default path is "$HOME/.config".<br>
$XDG\_DATA\_HOME is normally unset. Default path is "$HOME/.local/share". $XDG\_DATA\_HOME is normally unset. Default path is "$HOME/.local/share".
.SH SEE ALSO .SH SEE ALSO
@ -41,5 +40,5 @@ rofi(1)
.SH AUTHORS .SH AUTHORS
.PP .PP
Qball Cow qball@gmpclient.org Qball Cow qball@gmpclient.org<br>
Rasmus Steinke rasi@xssn.at Rasmus Steinke rasi@xssn.at

View file

@ -1,4 +1,3 @@
.nh
.TH ROFI\-THEME 5 rofi\-theme .TH ROFI\-THEME 5 rofi\-theme
.SH NAME .SH NAME
.PP .PP
@ -134,7 +133,7 @@ abbreviation for \fBr\fPofi \fBa\fPdvanced \fBs\fPtyle \fBi\fPnformation.
.SH Basic Structure .SH Basic Structure
.PP .PP
Each element has a section with defined properties. Global properties can be defined in section \fB\fC* { }\fR\&. Each element has a section with defined properties. Global properties can be defined in section \fB\fC* { }\fR\&.
Sub\-\&section names begin with a hash symbol \fB\fC#\fR\&. Sub\-section names begin with a hash symbol \fB\fC#\fR\&.
.PP .PP
It is advised to define the \fIglobal properties section\fP on top of the file to It is advised to define the \fIglobal properties section\fP on top of the file to
@ -320,6 +319,8 @@ a cursor
.IP \(bu 2 .IP \(bu 2
a list of keywords a list of keywords
.IP \(bu 2 .IP \(bu 2
an array of values
.IP \(bu 2
an environment variable an environment variable
.IP \(bu 2 .IP \(bu 2
Inherit Inherit
@ -491,7 +492,11 @@ The different values are:
.IP \(bu 2 .IP \(bu 2
\fB\fC{PERCENTAGE}\fR can be between 0\-1.0, or 0%\-100% \fB\fC{PERCENTAGE}\fR can be between 0\-1.0, or 0%\-100%
.IP \(bu 2 .IP \(bu 2
\fB\fC{named\-color}\fR is one of the following colors:AliceBlue, AntiqueWhite, Aqua, Aquamarine, Azure, Beige, Bisque, Black, BlanchedAlmond, Blue, BlueViolet, Brown,
.PP
\fB\fC{named\-color}\fR is one of the following colors:
.PP
AliceBlue, AntiqueWhite, Aqua, Aquamarine, Azure, Beige, Bisque, Black, BlanchedAlmond, Blue, BlueViolet, Brown,
BurlyWood, CadetBlue, Chartreuse, Chocolate, Coral, CornflowerBlue, Cornsilk, Crimson, Cyan, DarkBlue, DarkCyan, BurlyWood, CadetBlue, Chartreuse, Chocolate, Coral, CornflowerBlue, Cornsilk, Crimson, Cyan, DarkBlue, DarkCyan,
DarkGoldenRod, DarkGray, DarkGrey, DarkGreen, DarkKhaki, DarkMagenta, DarkOliveGreen, DarkOrange, DarkOrchid, DarkRed, DarkGoldenRod, DarkGray, DarkGrey, DarkGreen, DarkKhaki, DarkMagenta, DarkOliveGreen, DarkOrange, DarkOrchid, DarkRed,
DarkSalmon, DarkSeaGreen, DarkSlateBlue, DarkSlateGray, DarkSlateGrey, DarkTurquoise, DarkViolet, DeepPink, DeepSkyBlue, DarkSalmon, DarkSeaGreen, DarkSlateBlue, DarkSlateGray, DarkSlateGrey, DarkTurquoise, DarkViolet, DeepPink, DeepSkyBlue,
@ -652,6 +657,12 @@ It supports the following operations:
\fB\fCmin\fR : Minimum of l or rvalue; \fB\fCmin\fR : Minimum of l or rvalue;
.IP \(bu 2 .IP \(bu 2
\fB\fCmax\fR : Maximum of l or rvalue; \fB\fCmax\fR : Maximum of l or rvalue;
.IP \(bu 2
\fB\fCfloor\fR : Round down lvalue to the next multiple of rvalue
.IP \(bu 2
\fB\fCceil\fR : Round up lvalue to the next multiple of rvalue
.IP \(bu 2
\fB\fCround\fR : Round lvalue to the next multiple of rvalue
.RE .RE
@ -723,7 +734,6 @@ style property.
.PP .PP
When no unit is specified, pixels are assumed. When no unit is specified, pixels are assumed.
.RE .RE
.SH Position .SH Position
@ -732,14 +742,22 @@ Indicate a place on the window/monitor.
.RS .RS
.IP \(bu 2 .IP \(bu 2
.PP
Format: \fB\fC(center|east|north|west|south|north east|north west|south west|south east)\fR Format: \fB\fC(center|east|north|west|south|north east|north west|south west|south east)\fR
\fB\fC .PP
.RS
.nf
north west | north | north east north west | north | north east
\-\-\-\-\-\-\-\-\-\-\-\-\-|\-\-\-\-\-\-\-\-\-\-\-\-\-|\-\-\-\-\-\-\-\-\-\-\-\- \-\-\-\-\-\-\-\-\-\-\-\-\-|\-\-\-\-\-\-\-\-\-\-\-\-\-|\-\-\-\-\-\-\-\-\-\-\-\-
west | center | east west | center | east
\-\-\-\-\-\-\-\-\-\-\-\-\-|\-\-\-\-\-\-\-\-\-\-\-\-\-|\-\-\-\-\-\-\-\-\-\-\-\- \-\-\-\-\-\-\-\-\-\-\-\-\-|\-\-\-\-\-\-\-\-\-\-\-\-\-|\-\-\-\-\-\-\-\-\-\-\-\-
south west | south | south east south west | south | south east
\fR
.fi
.RE
.RE .RE
@ -850,6 +868,16 @@ Format: \fB\fC[ keyword, keyword ]\fR
A list starts with a '[' and ends with a ']'. The entries in the list are comma\-separated. A list starts with a '[' and ends with a ']'. The entries in the list are comma\-separated.
The \fB\fCkeyword\fR in the list refers to an widget name. The \fB\fCkeyword\fR in the list refers to an widget name.
.SH List of values
.RS
.IP \(bu 2
Format: \fB\fC[ value, value, ... ]\fR
.RE
.PP
An list starts with a '[' and ends with a ']'. The entries in the list are comma\-separated.
.SH Environment variable .SH Environment variable
.RS .RS
.IP \(bu 2 .IP \(bu 2
@ -964,6 +992,7 @@ The current widgets available in \fBrofi\fP:
.RS .RS
.IP \(bu 2 .IP \(bu 2
\fB\fCwindow\fR \fB\fCwindow\fR
.RS .RS
.IP \(bu 2 .IP \(bu 2
\fB\fCoverlay\fR: the overlay widget. \fB\fCoverlay\fR: the overlay widget.
@ -971,6 +1000,7 @@ The current widgets available in \fBrofi\fP:
\fB\fCmainbox\fR: The mainbox box. \fB\fCmainbox\fR: The mainbox box.
.IP \(bu 2 .IP \(bu 2
\fB\fCinputbar\fR: The input bar box. \fB\fCinputbar\fR: The input bar box.
.RS .RS
.IP \(bu 2 .IP \(bu 2
\fB\fCbox\fR: the horizontal @box packing the widgets \fB\fCbox\fR: the horizontal @box packing the widgets
@ -986,14 +1016,15 @@ The current widgets available in \fBrofi\fP:
\fB\fCnum\-filtered\-rows\fR: Shows the total number of rows after filtering. \fB\fCnum\-filtered\-rows\fR: Shows the total number of rows after filtering.
.RE .RE
.IP \(bu 2 .IP \(bu 2
\fB\fClistview\fR: The listview. \fB\fClistview\fR: The listview.
.RS .RS
.IP \(bu 2 .IP \(bu 2
\fB\fCscrollbar\fR: the listview scrollbar \fB\fCscrollbar\fR: the listview scrollbar
.IP \(bu 2 .IP \(bu 2
\fB\fCelement\fR: a box in the listview holding the entries \fB\fCelement\fR: a box in the listview holding the entries
.RS .RS
.IP \(bu 2 .IP \(bu 2
\fB\fCelement\-icon\fR: the widget in the listview's entry showing the (optional) icon \fB\fCelement\-icon\fR: the widget in the listview's entry showing the (optional) icon
@ -1004,29 +1035,26 @@ The current widgets available in \fBrofi\fP:
.RE .RE
.RE .RE
.IP \(bu 2 .IP \(bu 2
\fB\fCmode\-switcher\fR: the main horizontal @box packing the buttons. \fB\fCmode\-switcher\fR: the main horizontal @box packing the buttons.
.RS .RS
.IP \(bu 2 .IP \(bu 2
\fB\fCbutton\fR: the buttons @textbox for each mode \fB\fCbutton\fR: the buttons @textbox for each mode
.RE .RE
.IP \(bu 2 .IP \(bu 2
\fB\fCmessage\fR: The container holding the textbox. \fB\fCmessage\fR: The container holding the textbox.
.RS .RS
.IP \(bu 2 .IP \(bu 2
\fB\fCtextbox\fR: the message textbox \fB\fCtextbox\fR: the message textbox
.RE .RE
.RE .RE
.RE .RE
.PP .PP
@ -1134,9 +1162,13 @@ Type of mouse cursor that is set when the mouse pointer is hovered over the widg
.SS window: .SS window:
.RS .RS
.IP \(bu 2 .IP \(bu 2
.PP
\fBfont\fP: string \fBfont\fP: string
The font used in the window The font used in the window
.IP \(bu 2 .IP \(bu 2
.PP
\fBtransparency\fP: string \fBtransparency\fP: string
Indicating if transparency should be used and what type: Indicating if transparency should be used and what type:
\fBreal\fP \- True transparency. Only works with a compositor. \fBreal\fP \- True transparency. Only works with a compositor.
@ -1144,20 +1176,32 @@ Indicating if transparency should be used and what type:
\fBscreenshot\fP \- Take a screenshot of the screen and use that. \fBscreenshot\fP \- Take a screenshot of the screen and use that.
\fBPath\fP to png file \- Use an image. \fBPath\fP to png file \- Use an image.
.IP \(bu 2 .IP \(bu 2
.PP
\fBlocation\fP: position \fBlocation\fP: position
The place of the anchor on the monitor The place of the anchor on the monitor
.IP \(bu 2 .IP \(bu 2
.PP
\fBanchor\fP: anchor \fBanchor\fP: anchor
The anchor position on the window The anchor position on the window
.IP \(bu 2 .IP \(bu 2
.PP
\fBfullscreen\fP: boolean \fBfullscreen\fP: boolean
Window is fullscreen. Window is fullscreen.
.IP \(bu 2 .IP \(bu 2
.PP
\fBwidth\fP: distance \fBwidth\fP: distance
The width of the window The width of the window
.IP \(bu 2 .IP \(bu 2
.PP
\fBx\-offset\fP: distance \fBx\-offset\fP: distance
.IP \(bu 2 .IP \(bu 2
.PP
\fBy\-offset\fP: distance \fBy\-offset\fP: distance
The offset of the window to the anchor point, allowing you to push the window left/right/up/down The offset of the window to the anchor point, allowing you to push the window left/right/up/down
@ -1219,6 +1263,11 @@ This option is only available on the \fB\fCelement\-text\fR widget.
\fBblink\fP: Enable/Disable blinking on an input textbox (Boolean). \fBblink\fP: Enable/Disable blinking on an input textbox (Boolean).
.IP \(bu 2 .IP \(bu 2
\fBmarkup\fP: Force markup on, beware that only valid pango markup strings are shown. \fBmarkup\fP: Force markup on, beware that only valid pango markup strings are shown.
.IP \(bu 2
\fBtab\-stops\fP: array of distances
Set the location of tab stops by their distance from the beginning of the line.
Each distance should be greater than the previous one.
The text appears to the right of the tab stop position (other alignments are not supported yet).
.RE .RE
@ -1655,15 +1704,15 @@ More dynamic spacing can be achieved by adding dummy widgets, for example to mak
.RS .RS
.nf .nf
|\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-|
| |\-\-\-\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-\-\-\-| | | |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| |
| | dummy | | child | | dummy | | | | dummy | | child | | dummy | |
| | expand: y | | | | expand: y | | | | expand: true; | | | | expand: true; | |
| | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | |
| |\-\-\-\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-\-\-\-| | | |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| |
|\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-|
.fi .fi
.RE .RE
@ -1713,6 +1762,18 @@ rofi \-theme\-str 'window { fullscreen:true;}' \-show run
.fi .fi
.RE .RE
.PP
Another syntax to modify theme properties is:
.PP
.RS
.nf
rofi \-theme+window+fullscreen true \-show run
.fi
.RE
.PP .PP
To print the current theme, run: To print the current theme, run:

View file

@ -216,6 +216,7 @@ The current theme format supports different types:
* an orientation * an orientation
* a cursor * a cursor
* a list of keywords * a list of keywords
* an array of values
* an environment variable * an environment variable
* Inherit * Inherit
@ -409,6 +410,9 @@ It supports the following operations:
* `%` : Multiply * `%` : Multiply
* `min` : Minimum of l or rvalue; * `min` : Minimum of l or rvalue;
* `max` : Maximum of l or rvalue; * `max` : Maximum of l or rvalue;
* `floor` : Round down lvalue to the next multiple of rvalue
* `ceil` : Round up lvalue to the next multiple of rvalue
* `round` : Round lvalue to the next multiple of rvalue
It uses the C precedence ordering. It uses the C precedence ordering.
@ -447,6 +451,7 @@ style property.
> When no unit is specified, pixels are assumed. > When no unit is specified, pixels are assumed.
## Position ## Position
Indicate a place on the window/monitor. Indicate a place on the window/monitor.
@ -530,6 +535,12 @@ Specify the type of mouse cursor that is set when the mouse pointer is over the
A list starts with a '[' and ends with a ']'. The entries in the list are comma-separated. A list starts with a '[' and ends with a ']'. The entries in the list are comma-separated.
The `keyword` in the list refers to an widget name. The `keyword` in the list refers to an widget name.
## List of values
* Format: `[ value, value, ... ]`
An list starts with a '[' and ends with a ']'. The entries in the list are comma-separated.
## Environment variable ## Environment variable
* Format: `${:alnum:}` * Format: `${:alnum:}`
@ -757,6 +768,10 @@ The following properties are currently supported:
* **placeholder-color**: Color of the placeholder text. * **placeholder-color**: Color of the placeholder text.
* **blink**: Enable/Disable blinking on an input textbox (Boolean). * **blink**: Enable/Disable blinking on an input textbox (Boolean).
* **markup**: Force markup on, beware that only valid pango markup strings are shown. * **markup**: Force markup on, beware that only valid pango markup strings are shown.
* **tab-stops**: array of distances
Set the location of tab stops by their distance from the beginning of the line.
Each distance should be greater than the previous one.
The text appears to the right of the tab stop position (other alignments are not supported yet).
### listview: ### listview:
* **columns**: integer * **columns**: integer
@ -1108,6 +1123,12 @@ To test minor changes, part of the theme can be passed on the command line, for
rofi -theme-str 'window { fullscreen:true;}' -show run rofi -theme-str 'window { fullscreen:true;}' -show run
``` ```
Another syntax to modify theme properties is:
```bash
rofi -theme+window+fullscreen true -show run
```
To print the current theme, run: To print the current theme, run:
``` ```

View file

@ -1,4 +1,3 @@
.nh
.TH ROFI 1 rofi .TH ROFI 1 rofi
.SH NAME .SH NAME
.PP .PP
@ -19,9 +18,9 @@ filter, tokenized search and more.
\fBrofi\fP\&'s main functionality is to assist in your workflow, allowing you to quickly switch \fBrofi\fP\&'s main functionality is to assist in your workflow, allowing you to quickly switch
between windows, start applications or log into a remote machine via \fB\fCssh\fR\&. between windows, start applications or log into a remote machine via \fB\fCssh\fR\&.
There are different \fImodi\fP for different types of actions. There are different \fImodi\fP for different types of actions.
\fBrofi\fP is a standalone application and should not be integrated into scripts.
.PP For integration into scripts it has a special mode that functions as a
\fBrofi\fP can also function as (drop\-in) replacement for \fBdmenu(1)\fP\&. (drop\-in) replacement for \fBdmenu(1)\fP\&. See emulating dmenu below.
.SS Running rofi .SS Running rofi
.PP .PP
@ -42,13 +41,7 @@ rofi \-show run
\fBrofi\fP can emulate \fBdmenu(1)\fP (a dynamic menu for X11) when launched with the \fB\fC\-dmenu\fR flag. \fBrofi\fP can emulate \fBdmenu(1)\fP (a dynamic menu for X11) when launched with the \fB\fC\-dmenu\fR flag.
.PP .PP
The website for \fB\fCdmenu\fR can be found here For more information see \fBrofi\-dmenu(5)\fP\&.
\[la]http://tools.suckless.org/dmenu/\[ra]\&.
.PP
\fBrofi\fP does not aim to be 100% compatible with \fB\fCdmenu\fR\&. There are simply too many flavors of \fB\fCdmenu\fR\&.
The idea is that the basic usage command\-\&line flags are obeyed, theme\-\&related flags are not.
Besides, \fBrofi\fP offers some extended features (like multi\-select, highlighting, message bar, extra key bindings).
.SS Display Error message .SS Display Error message
.PP .PP
@ -181,7 +174,11 @@ Specify the number of threads \fBrofi\fP should use:
.IP \(bu 2 .IP \(bu 2
1: Disable threading 1: Disable threading
.IP \(bu 2 .IP \(bu 2
2..n: Specify the maximum number of threads to use in the thread pool.Default: Autodetect
.PP
2..n: Specify the maximum number of threads to use in the thread pool.
.PP
Default: Autodetect
.RE .RE
@ -461,7 +458,11 @@ The different fields are:
.IP \(bu 2 .IP \(bu 2
\fBcomment\fP: the application comment \fBcomment\fP: the application comment
.IP \(bu 2 .IP \(bu 2
\fBall\fP: all the aboveDefault: \fIname,generic,exec,categories,keywords\fP
.PP
\fBall\fP: all the above
.PP
Default: \fIname,generic,exec,categories,keywords\fP
.RE .RE
@ -534,7 +535,11 @@ The different fields are:
.IP \(bu 2 .IP \(bu 2
\fBdesktop\fP: window's current desktop \fBdesktop\fP: window's current desktop
.IP \(bu 2 .IP \(bu 2
\fBall\fP: all the aboveDefault: \fIall\fP
.PP
\fBall\fP: all the above
.PP
Default: \fIall\fP
.RE .RE
@ -667,7 +672,11 @@ behavior.)
.IP \(bu 2 .IP \(bu 2
\fB\-4\fP: the monitor with the focused window. \fB\-4\fP: the monitor with the focused window.
.IP \(bu 2 .IP \(bu 2
\fB\-5\fP: the monitor that shows the mouse pointer.Default: \fI\-5\fP
.PP
\fB\-5\fP: the monitor that shows the mouse pointer.
.PP
Default: \fI\-5\fP
.RE .RE
@ -911,6 +920,35 @@ rofi \-show combi \-combi\-modi "window,run,ssh" \-modi combi
\fBNOTE\fP: The i3 window manager dislikes commas in the command when specifying an exec command. \fBNOTE\fP: The i3 window manager dislikes commas in the command when specifying an exec command.
For that case, \fB\fC#\fR can be used as a separator. For that case, \fB\fC#\fR can be used as a separator.
.PP
\fB\fC\-combi\-display\-format\fR
.PP
The format string for entries in the \fB\fCcombi\fR dialog:
.RS
.IP \(bu 2
\fBmode\fP: the mode display name
.IP \(bu 2
\fBtext\fP: the entry text
.RE
.PP
Pango markup can be used to formatting the output.
.PP
.RS
.nf
Default: {mode} {text}
.fi
.RE
.PP
Note: This setting is ignored if \fB\fCcombi\-hide\-mode\-prefix\fR is eanbled.
.SS History and Sorting .SS History and Sorting
.PP .PP
\fB\fC\-disable\-history\fR \fB\fC\-disable\-history\fR
@ -947,225 +985,13 @@ fzf sorting.
.PP .PP
Maximum number of entries to store in history. Defaults to 25. (WARNING: can cause slowdowns when set too high) Maximum number of entries to store in history. Defaults to 25. (WARNING: can cause slowdowns when set too high)
.SS Dmenu specific
.PP
\fB\fC\-sep\fR \fIseparator\fP
.PP
Separator for \fB\fCdmenu\fR\&. Example: To show a list of 'a' to 'e' with '|' as a separator:
.PP
.RS
.nf
echo "a|b|c|d|e" | rofi \-sep '|' \-dmenu
.fi
.RE
.PP
\fB\fC\-p\fR \fIprompt\fP
.PP
Specify the prompt to show in \fB\fCdmenu\fR mode. For example, select 'monkey', a,b,c,d, or e.
.PP
.RS
.nf
echo "a|b|c|d|e" | rofi \-sep '|' \-dmenu \-p "monkey"
.fi
.RE
.PP
Default: \fIdmenu\fP
.PP
\fB\fC\-l\fR \fInumber of lines to show\fP
.PP
Maximum number of lines the menu may show before scrolling.
.PP
.RS
.nf
rofi \-dmenu \-l 25
.fi
.RE
.PP
Default: \fI15\fP
.PP
\fB\fC\-i\fR
.PP
Makes \fB\fCdmenu\fR searches case\-insensitive
.PP
\fB\fC\-a\fR \fIX\fP
.PP
Active row, mark \fIX\fP as active. Where \fIX\fP 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:
.RS
.IP \(bu 2
A single row: '5'
.IP \(bu 2
A range of (last 3) rows: '\-3:'
.IP \(bu 2
4 rows starting from row 7: '7:11' (or in legacy notation: '7\-10')
.IP \(bu 2
A set of rows: '2,0,\-9'
.IP \(bu 2
Or any combination: '5,\-3:,7:11,2,0,\-9'
.RE
.PP
\fB\fC\-u\fR \fIX\fP
.PP
Urgent row, mark \fIX\fP as urgent. See \fB\fC\-a\fR option for details.
.PP
\fB\fC\-only\-match\fR
.PP
Only return a selected item, do not allow custom entry.
This mode always returns an entry. It will not return if no matching entry is
selected.
.PP
\fB\fC\-no\-custom\fR
.PP
Only return a selected item, do not allow custom entry.
This mode returns directly when no entries given.
.PP
\fB\fC\-format\fR \fIformat\fP
.PP
Allows the output of dmenu to be customized (N is the total number of input entries):
.RS
.IP \(bu 2
\&'s' selected string
.IP \(bu 2
\&'i' index (0 \-\& (N\-\&1))
.IP \(bu 2
\&'d' index (1 \-\& N)
.IP \(bu 2
\&'q' quote string
.IP \(bu 2
\&'p' Selected string stripped from Pango markup (Needs to be a valid string)
.IP \(bu 2
\&'f' filter string (user input)
.IP \(bu 2
\&'F' quoted filter string (user input)
.RE
.PP
Default: 's'
.PP
\fB\fC\-select\fR \fIstring\fP
.PP
Select first line that matches the given string
.PP
\fB\fC\-mesg\fR \fIstring\fP
.PP
Add a message line below the filter entry box. Supports Pango markup.
For more information on supported markup, see here
\[la]https://docs.gtk.org/Pango/pango_markup.html\[ra]
.PP
\fB\fC\-dump\fR
.PP
Dump the filtered list to stdout and quit.
This can be used to get the list as \fBrofi\fP would filter it.
Use together with \fB\fC\-filter\fR command.
.PP
\fB\fC\-input\fR \fIfile\fP
.PP
Reads from \fIfile\fP instead of stdin.
.PP
\fB\fC\-password\fR
.PP
Hide the input text. This should not be considered secure!
.PP
\fB\fC\-markup\-rows\fR
.PP
Tell \fBrofi\fP that DMenu input is Pango markup encoded, and should be rendered.
See here
\[la]https://developer.gnome.org/pygtk/stable/pango-markup-language.html\[ra] for details about Pango markup.
.PP
\fB\fC\-multi\-select\fR
.PP
Allow multiple lines to be selected. Adds a small selection indicator to the left of each entry.
.PP
\fB\fC\-sync\fR
.PP
Force \fBrofi\fP mode to first read all data from stdin before showing the selection window. This is original dmenu behavior.
.PP
Note: the default asynchronous mode will also be automatically disabled if used with conflicting options,
such as \fB\fC\-dump\fR, \fB\fC\-only\-match\fR or \fB\fC\-auto\-select\fR\&.
.PP
\fB\fC\-async\-pre\-read\fR \fInumber\fP
.PP
Reads the first \fInumber\fP entries blocking, then switches to async mode.
This makes it feel more 'snappy'.
.PP
\fIdefault\fP: 25
.PP
\fB\fC\-window\-title\fR \fItitle\fP
.PP
Set name used for the window title. Will be shown as Rofi \- \fItitle\fP
.PP
\fB\fC\-w\fR \fIwindowid\fP
.PP
Position \fBrofi\fP over the window with the given X11 window ID.
.PP
\fB\fC\-keep\-right\fR
.PP
Set ellipsize mode to start. So, the end of the string is visible.
.SS Message dialog .SS Message dialog
.PP .PP
\fB\fC\-e\fR \fImessage\fP \fB\fC\-e\fR \fImessage\fP
.PP .PP
Pops up a message dialog (used internally for showing errors) with \fImessage\fP\&. Pops up a message dialog (used internally for showing errors) with \fImessage\fP\&.
Message can be multi\-\&line. Message can be multi\-line.
.SS File browser settings .SS File browser settings
.PP .PP
@ -1220,6 +1046,12 @@ Command to open a Desktop Entry that is a Link.
.PP .PP
Make \fBrofi\fP create a pid file and check this on startup. The pid file prevents multiple \fBrofi\fP instances from running simultaneously. This is useful when running \fBrofi\fP from a key\-binding daemon. Make \fBrofi\fP create a pid file and check this on startup. The pid file prevents multiple \fBrofi\fP instances from running simultaneously. This is useful when running \fBrofi\fP from a key\-binding daemon.
.PP
\fB\fC\-replace\fR
.PP
If rofi is already running, based on pid file, try to kill that instance.
.PP .PP
\fB\fC\-display\-{mode}\fR \fIstring\fP \fB\fC\-display\-{mode}\fR \fIstring\fP
@ -1260,7 +1092,7 @@ To launch commands (for example, when using the ssh launcher), the user can ente
.IP \(bu 2 .IP \(bu 2
\fB\fC{host}\fR: the host to connect to \fB\fC{host}\fR: the host to connect to
.IP \(bu 2 .IP \(bu 2
\fB\fC{terminal}\fR: the configured terminal (see \-terminal\-emulator) \fB\fC{terminal}\fR: the configured terminal (see \-terminal)
.IP \(bu 2 .IP \(bu 2
\fB\fC{ssh\-client}\fR: the configured ssh client (see \-ssh\-client) \fB\fC{ssh\-client}\fR: the configured ssh client (see \-ssh\-client)
.IP \(bu 2 .IP \(bu 2
@ -1270,20 +1102,6 @@ To launch commands (for example, when using the ssh launcher), the user can ente
.RE .RE
.SH DMENU REPLACEMENT
.PP
If \fB\fCargv[0]\fR (calling command) is dmenu, \fBrofi\fP will start in dmenu mode.
This way, it can be used as a drop\-in replacement for dmenu. Just copy or symlink \fBrofi\fP to dmenu in \fB\fC$PATH\fR\&.
.PP
.RS
.nf
ln \-s /usr/bin/rofi /usr/bin/dmenu
.fi
.RE
.SH THEMING .SH THEMING
.PP .PP
Please see \fBrofi\-theme(5)\fP manpage for more information on theming. Please see \fBrofi\-theme(5)\fP manpage for more information on theming.
@ -1418,6 +1236,9 @@ configuration {
.fi .fi
.RE .RE
.PP
For a full list of bindings, see the \fBrofi\-keys(5)\fP manpage.
.SH Available Modi .SH Available Modi
.SS window .SS window
.PP .PP
@ -1540,6 +1361,21 @@ The indicator shows:
.fi .fi
.RE .RE
.SS Why do I see different icons for run,drun and window mode
.PP
Each of these modes uses different methods of resolving the icon:
.RS
.IP \(bu 2
Window: It first uses the icon that the application exposes via the X11
Server, if none is set it does a lookup of the window Class name in the icon theme.
.IP \(bu 2
drun: It uses the icon set in the desktop file.
.IP \(bu 2
run: It does a lookup using the executable name.
.RE
.SH EXAMPLES .SH EXAMPLES
.PP .PP
Some basic usage examples of \fBrofi\fP: Some basic usage examples of \fBrofi\fP:
@ -1779,26 +1615,26 @@ first.
.SH SEE ALSO .SH SEE ALSO
.PP .PP
\fBrofi\-sensible\-terminal(1)\fP, \fBdmenu(1)\fP, \fBrofi\-theme(5)\fP, \fBrofi\-script(5)\fP, \fBrofi\-theme\-selector(1)\fP \fBrofi\-sensible\-terminal(1)\fP, \fBdmenu(1)\fP, \fBrofi\-theme(5)\fP, \fBrofi\-script(5)\fP, \fBrofi\-keys(5)\fP,\fBrofi\-theme\-selector(1)\fP
.SH AUTHOR .SH AUTHOR
.RS .RS
.IP \(bu 2 .IP \(bu 2
Qball Cow qball@blame.services Qball Cow
\[la]mailto:qball@blame.services\[ra] \[la]qball@blame.services\[ra]
.IP \(bu 2 .IP \(bu 2
Rasmus Steinke rasi@xssn.at Rasmus Steinke
\[la]mailto:rasi@xssn.at\[ra] \[la]rasi@xssn.at\[ra]
.IP \(bu 2 .IP \(bu 2
Quentin Glidic sardemff7+rofi@sardemff7.net Quentin Glidic
\[la]mailto:sardemff7+rofi@sardemff7.net\[ra] \[la]sardemff7+rofi@sardemff7.net\[ra]
.RE .RE
.PP .PP
Original code based on work by: Sean Pringle Original code based on work by: Sean Pringle
\[la]https://github.com/seanpringle/simpleswitcher\[ra] sean.pringle@gmail.com \[la]https://github.com/seanpringle/simpleswitcher\[ra]
\[la]mailto:sean.pringle@gmail.com\[ra] \[la]sean.pringle@gmail.com\[ra]
.PP .PP
For a full list of authors, check the \fB\fCAUTHORS\fR file. For a full list of authors, check the \fB\fCAUTHORS\fR file.

View file

@ -21,8 +21,9 @@ filter, tokenized search and more.
**rofi**'s main functionality is to assist in your workflow, allowing you to quickly switch **rofi**'s main functionality is to assist in your workflow, allowing you to quickly switch
between windows, start applications or log into a remote machine via `ssh`. between windows, start applications or log into a remote machine via `ssh`.
There are different *modi* for different types of actions. There are different *modi* for different types of actions.
**rofi** is a standalone application and should not be integrated into scripts.
**rofi** can also function as (drop-in) replacement for **dmenu(1)**. For integration into scripts it has a special mode that functions as a
(drop-in) replacement for **dmenu(1)**. See emulating dmenu below.
### Running rofi ### Running rofi
@ -35,11 +36,7 @@ To show the `run` dialog:
**rofi** can emulate **dmenu(1)** (a dynamic menu for X11) when launched with the `-dmenu` flag. **rofi** can emulate **dmenu(1)** (a dynamic menu for X11) when launched with the `-dmenu` flag.
The website for `dmenu` can be found [here](http://tools.suckless.org/dmenu/). For more information see **rofi-dmenu(5)**.
**rofi** does not aim to be 100% compatible with `dmenu`. There are simply too many flavors of `dmenu`.
The idea is that the basic usage command-line flags are obeyed, theme-related flags are not.
Besides, **rofi** offers some extended features (like multi-select, highlighting, message bar, extra key bindings).
### Display Error message ### Display Error message
@ -547,6 +544,20 @@ To get one merge view, of `window`,`run`, and `ssh`:
**NOTE**: The i3 window manager dislikes commas in the command when specifying an exec command. **NOTE**: The i3 window manager dislikes commas in the command when specifying an exec command.
For that case, `#` can be used as a separator. For that case, `#` can be used as a separator.
`-combi-display-format`
The format string for entries in the `combi` dialog:
* **mode**: the mode display name
* **text**: the entry text
Pango markup can be used to formatting the output.
Default: {mode} {text}
Note: This setting is ignored if `combi-hide-mode-prefix` is eanbled.
### History and Sorting ### History and Sorting
`-disable-history` `-disable-history`
@ -571,132 +582,6 @@ There are 2 sorting methods:
Maximum number of entries to store in history. Defaults to 25. (WARNING: can cause slowdowns when set too high) Maximum number of entries to store in history. Defaults to 25. (WARNING: can cause slowdowns when set too high)
### Dmenu specific
`-sep` *separator*
Separator for `dmenu`. Example: To show a list of 'a' to 'e' with '|' as a separator:
echo "a|b|c|d|e" | rofi -sep '|' -dmenu
`-p` *prompt*
Specify the prompt to show in `dmenu` mode. For example, select 'monkey', a,b,c,d, or e.
echo "a|b|c|d|e" | rofi -sep '|' -dmenu -p "monkey"
Default: *dmenu*
`-l` *number of lines to show*
Maximum number of lines the menu may show before scrolling.
rofi -dmenu -l 25
Default: *15*
`-i`
Makes `dmenu` searches case-insensitive
`-a` *X*
Active row, mark *X* as active. Where *X* 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:
* A single row: '5'
* A range of (last 3) rows: '-3:'
* 4 rows starting from row 7: '7:11' (or in legacy notation: '7-10')
* A set of rows: '2,0,-9'
* Or any combination: '5,-3:,7:11,2,0,-9'
`-u` *X*
Urgent row, mark *X* as urgent. See `-a` option for details.
`-only-match`
Only return a selected item, do not allow custom entry.
This mode always returns an entry. It will not return if no matching entry is
selected.
`-no-custom`
Only return a selected item, do not allow custom entry.
This mode returns directly when no entries given.
`-format` *format*
Allows the output of dmenu to be customized (N is the total number of input entries):
* 's' selected string
* 'i' index (0 - (N-1))
* 'd' index (1 - N)
* 'q' quote string
* 'p' Selected string stripped from Pango markup (Needs to be a valid string)
* 'f' filter string (user input)
* 'F' quoted filter string (user input)
Default: 's'
`-select` *string*
Select first line that matches the given string
`-mesg` *string*
Add a message line below the filter entry box. Supports Pango markup.
For more information on supported markup, see [here](https://docs.gtk.org/Pango/pango_markup.html)
`-dump`
Dump the filtered list to stdout and quit.
This can be used to get the list as **rofi** would filter it.
Use together with `-filter` command.
`-input` *file*
Reads from *file* instead of stdin.
`-password`
Hide the input text. This should not be considered secure!
`-markup-rows`
Tell **rofi** that DMenu input is Pango markup encoded, and should be rendered.
See [here](https://developer.gnome.org/pygtk/stable/pango-markup-language.html) for details about Pango markup.
`-multi-select`
Allow multiple lines to be selected. Adds a small selection indicator to the left of each entry.
`-sync`
Force **rofi** mode to first read all data from stdin before showing the selection window. This is original dmenu behavior.
Note: the default asynchronous mode will also be automatically disabled if used with conflicting options,
such as `-dump`, `-only-match` or `-auto-select`.
`-async-pre-read` *number*
Reads the first *number* entries blocking, then switches to async mode.
This makes it feel more 'snappy'.
*default*: 25
`-window-title` *title*
Set name used for the window title. Will be shown as Rofi - *title*
`-w` *windowid*
Position **rofi** over the window with the given X11 window ID.
`-keep-right`
Set ellipsize mode to start. So, the end of the string is visible.
### Message dialog ### Message dialog
@ -746,6 +631,10 @@ Command to open a Desktop Entry that is a Link.
Make **rofi** create a pid file and check this on startup. The pid file prevents multiple **rofi** instances from running simultaneously. This is useful when running **rofi** from a key-binding daemon. Make **rofi** create a pid file and check this on startup. The pid file prevents multiple **rofi** instances from running simultaneously. This is useful when running **rofi** from a key-binding daemon.
`-replace`
If rofi is already running, based on pid file, try to kill that instance.
`-display-{mode}` *string* `-display-{mode}` *string*
Set the name to use for mode. This is used as prompt and in combi-browser. Set the name to use for mode. This is used as prompt and in combi-browser.
@ -773,17 +662,11 @@ Default: *enabled*
To launch commands (for example, when using the ssh launcher), the user can enter the used command-line. The following keys can be used that will be replaced at runtime: To launch commands (for example, when using the ssh launcher), the user can enter the used command-line. The following keys can be used that will be replaced at runtime:
* `{host}`: the host to connect to * `{host}`: the host to connect to
* `{terminal}`: the configured terminal (see -terminal-emulator) * `{terminal}`: the configured terminal (see -terminal)
* `{ssh-client}`: the configured ssh client (see -ssh-client) * `{ssh-client}`: the configured ssh client (see -ssh-client)
* `{cmd}`: the command to execute * `{cmd}`: the command to execute
* `{window}`: the window ID of the selected window (in `window-command`) * `{window}`: the window ID of the selected window (in `window-command`)
## DMENU REPLACEMENT
If `argv[0]` (calling command) is dmenu, **rofi** will start in dmenu mode.
This way, it can be used as a drop-in replacement for dmenu. Just copy or symlink **rofi** to dmenu in `$PATH`.
ln -s /usr/bin/rofi /usr/bin/dmenu
## THEMING ## THEMING
@ -867,6 +750,7 @@ configuration {
} }
``` ```
For a full list of bindings, see the **rofi-keys(5)** manpage.
## Available Modi ## Available Modi
@ -974,6 +858,15 @@ The indicator shows:
`+` Case insensitive and Sorting enabled `+` Case insensitive and Sorting enabled
`±` Sorting and Case sensitivity enabled" `±` Sorting and Case sensitivity enabled"
### Why do I see different icons for run,drun and window mode
Each of these modes uses different methods of resolving the icon:
* Window: It first uses the icon that the application exposes via the X11
Server, if none is set it does a lookup of the window Class name in the icon theme.
* drun: It uses the icon set in the desktop file.
* run: It does a lookup using the executable name.
## EXAMPLES ## EXAMPLES
Some basic usage examples of **rofi**: Some basic usage examples of **rofi**:
@ -1103,7 +996,7 @@ first.
## SEE ALSO ## SEE ALSO
**rofi-sensible-terminal(1)**, **dmenu(1)**, **rofi-theme(5)**, **rofi-script(5)**, **rofi-theme-selector(1)** **rofi-sensible-terminal(1)**, **dmenu(1)**, **rofi-theme(5)**, **rofi-script(5)**, **rofi-keys(5)**,**rofi-theme-selector(1)**
## AUTHOR ## AUTHOR

View file

@ -120,6 +120,8 @@ rofi.scroll-method: 0
! rofi.max-history-size: 25 ! rofi.max-history-size: 25
! "Hide the prefix mode prefix on the combi view." Set from: Default ! "Hide the prefix mode prefix on the combi view." Set from: Default
! rofi.combi-hide-mode-prefix: false ! rofi.combi-hide-mode-prefix: false
! "Combi format string. (Supports: mode, text)" Set from: Default
! rofi.combi-display-format: {mode} {text}
! "Set the character used to negate the matching. ('\0' to disable)" Set from: Default ! "Set the character used to negate the matching. ('\0' to disable)" Set from: Default
! rofi.matching-negate-char: - ! rofi.matching-negate-char: -
! "Directory where history and temporary files are stored." Set from: Default ! "Directory where history and temporary files are stored." Set from: Default

View file

@ -40,7 +40,7 @@
* *
* @returns TRUE if script was successful. * @returns TRUE if script was successful.
*/ */
int dmenu_switcher_dialog(void); int dmenu_mode_dialog(void);
/** /**
* Print dmenu mode commandline options to stdout, for use in help menu. * Print dmenu mode commandline options to stdout, for use in help menu.

View file

@ -45,7 +45,7 @@
* *
* @returns NULL when it fails, a newly allocated ScriptOptions when successful. * @returns NULL when it fails, a newly allocated ScriptOptions when successful.
*/ */
Mode *script_switcher_parse_setup(const char *str); Mode *script_mode_parse_setup(const char *str);
/** /**
* @param token The modi str to check * @param token The modi str to check
@ -54,6 +54,6 @@ Mode *script_switcher_parse_setup(const char *str);
* *
* @returns true when valid. * @returns true when valid.
*/ */
gboolean script_switcher_is_valid(const char *token); gboolean script_mode_is_valid(const char *token);
/**@}*/ /**@}*/
#endif // ROFI_DIALOG_SCRIPT_H #endif // ROFI_DIALOG_SCRIPT_H

View file

@ -149,10 +149,11 @@ int execute_generator(const char *cmd) __attribute__((nonnull));
/** /**
* @param pidfile The pidfile to create. * @param pidfile The pidfile to create.
* @param kill Try killing running instance.
* *
* returns file descriptor (or -1 when failed) * returns file descriptor (or -1 when failed)
*/ */
int create_pid_file(const char *pidfile); int create_pid_file(const char *pidfile, gboolean kill);
/** /**
* Remove pid file * Remove pid file
@ -228,15 +229,6 @@ char *rofi_force_utf8(const gchar *data, ssize_t length);
*/ */
char *rofi_latin_to_utf8_strdup(const char *input, gssize length); char *rofi_latin_to_utf8_strdup(const char *input, gssize length);
/**
* @param text the string to escape
*
* Escape XML markup from the string. text is freed.
*
* @return the escaped string
*/
gchar *rofi_escape_markup(gchar *text);
/** /**
* @param pattern The user input to match against. * @param pattern The user input to match against.
* @param plen Pattern length. * @param plen Pattern length.

View file

@ -103,6 +103,9 @@ typedef enum {
ROFI_DISTANCE_MODIFIER_GROUP, ROFI_DISTANCE_MODIFIER_GROUP,
ROFI_DISTANCE_MODIFIER_MIN, ROFI_DISTANCE_MODIFIER_MIN,
ROFI_DISTANCE_MODIFIER_MAX, ROFI_DISTANCE_MODIFIER_MAX,
ROFI_DISTANCE_MODIFIER_ROUND,
ROFI_DISTANCE_MODIFIER_FLOOR,
ROFI_DISTANCE_MODIFIER_CEIL,
} RofiDistanceModifier; } RofiDistanceModifier;
typedef struct RofiDistanceUnit { typedef struct RofiDistanceUnit {

View file

@ -162,6 +162,8 @@ typedef struct {
/** Maximum history length per mode. */ /** Maximum history length per mode. */
unsigned int max_history_size; unsigned int max_history_size;
gboolean combi_hide_mode_prefix; gboolean combi_hide_mode_prefix;
/** Combi format display */
char *combi_display_format;
char matching_negate_char; char matching_negate_char;

View file

@ -392,24 +392,6 @@ ThemeWidget *rofi_config_find_widget(const char *name, const char *state,
Property *rofi_theme_find_property(ThemeWidget *widget, PropertyType type, Property *rofi_theme_find_property(ThemeWidget *widget, PropertyType type,
const char *property, gboolean exact); const char *property, gboolean exact);
/**
* @param widget The widget to query
* @param property The property to query.
* @param defaults The default value.
*
* Obtain list of elements (strings) of the widget.
*
* @returns a GList holding the names in the list of this property for this
* widget.
*/
GList *rofi_theme_get_list(const widget *widget, const char *property,
const char *defaults);
/**
* Checks if a theme is set, or is empty.
* @returns TRUE when empty.
*/
gboolean rofi_theme_is_empty(void);
/** /**
* Reset the current theme. * Reset the current theme.
*/ */
@ -459,4 +441,23 @@ RofiDistance rofi_theme_property_copy_distance(RofiDistance const distance);
*/ */
int rofi_theme_rasi_validate(const char *filename); int rofi_theme_rasi_validate(const char *filename);
/**
*
* Free memory.
*/
void rofi_theme_free_parsed_files(void);
/**
* @param is_term Indicate if printed to terminal.
*
* Print the list of parsed config files.
*/
void rofi_theme_print_parsed_files(int is_term);
/**
* Returns a list of allocated RofiDistance objects that should be
* freed.
*/
GList *rofi_theme_get_list_distance(const widget *widget, const char *property);
GList *rofi_theme_get_list_strings(const widget *widget, const char *property);
#endif #endif

View file

@ -214,15 +214,6 @@ void listview_set_multi_select(listview *lv, gboolean enable);
*/ */
void listview_set_num_lines(listview *lv, unsigned int num_lines); void listview_set_num_lines(listview *lv, unsigned int num_lines);
/**
* @param lv Handler to the listview object.
*
* Get the maximum number of lines to display.
*
* @returns get the number of lines to display.
*/
unsigned int listview_get_num_lines(listview *lv);
/** /**
* @param lv Handler to the listview object. * @param lv Handler to the listview object.
* *

View file

@ -29,6 +29,28 @@
#define WIDGET_INTERNAL_H #define WIDGET_INTERNAL_H
#include "theme.h" #include "theme.h"
/** Macro for initializing the RofiDistance struct. */
#define WIDGET_DISTANCE_INIT \
(RofiDistance){ \
.base = { \
.distance = 0, \
.type = ROFI_PU_PX, \
.modtype = ROFI_DISTANCE_MODIFIER_NONE, \
.left = NULL, \
.right = NULL, \
}, \
.style = ROFI_HL_SOLID, \
}
/* Macro for initializing the RofiPadding struct. */
#define WIDGET_PADDING_INIT \
(RofiPadding){ \
.top = WIDGET_DISTANCE_INIT, \
.right = WIDGET_DISTANCE_INIT, \
.bottom = WIDGET_DISTANCE_INIT, \
.left = WIDGET_DISTANCE_INIT, \
}
/** /**
* Data structure holding the internal state of the Widget * Data structure holding the internal state of the Widget
*/ */

View file

@ -136,14 +136,6 @@ int widget_intersect(const widget *widget, int x, int y);
*/ */
void widget_move(widget *widget, short x, short y); void widget_move(widget *widget, short x, short y);
/**
* @param widget Handle to widget
*
* Get the type of the widget.
* @returns The type of the widget.
*/
WidgetType widget_type(widget *widget);
/** /**
* @param widget Handle to widget * @param widget Handle to widget
* @param type The widget type. * @param type The widget type.
@ -290,8 +282,8 @@ widget *widget_find_mouse_target(widget *wid, WidgetType type, gint x, gint y);
* *
* @returns Whether the action would be handled or not * @returns Whether the action would be handled or not
*/ */
WidgetTriggerActionResult widget_check_action(widget *wid, guint action, WidgetTriggerActionResult widget_check_action(widget *wid, guint action, gint x,
gint x, gint y); gint y);
/** /**
* @param wid The widget handle * @param wid The widget handle

View file

@ -161,7 +161,7 @@ static double rofi_theme_parse_convert_hex ( char high, char low)
ASC [\x00-\x7f] ASC [\x00-\x7f]
ASCN [\x00-\t\v-\x7f] ASCN [\x00-\t\v-\x7f]
ASCNP [\x00-\t\v-\x21\x23-\x7f] ASCNP [\x00-\t\v-\x21\x23-\x7f]
U [\x80-\xbf] U [\x80-\xbf]
U2 [\xc2-\xdf] U2 [\xc2-\xdf]
U3 [\xe0-\xef] U3 [\xe0-\xef]
@ -176,6 +176,7 @@ UANYNP {ASCNP}|{U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
WHITESPACE [[:blank:]] WHITESPACE [[:blank:]]
WSO [[:blank:]]* WSO [[:blank:]]*
WORD [[:alnum:]-]+ WORD [[:alnum:]-]+
WORD_ELEMENT [[:alpha:]][[:alnum:]-]*
WORD_ENV [[:alpha:]_][[:alnum:]_]* WORD_ENV [[:alpha:]_][[:alnum:]_]*
MEDIA_NAME [[:alpha:]-]+ MEDIA_NAME [[:alpha:]-]+
COLOR_NAME [[:alpha:]]+ COLOR_NAME [[:alpha:]]+
@ -202,6 +203,9 @@ MODIFIER_SUBTRACT -
MODIFIER_MULTIPLY \* MODIFIER_MULTIPLY \*
MODIFIER_MIN (min) MODIFIER_MIN (min)
MODIFIER_MAX (max) MODIFIER_MAX (max)
MODIFIER_ROUND (round)
MODIFIER_FLOOR (floor)
MODIFIER_CEIL (ceil)
/* Position */ /* Position */
CENTER (?i:center) CENTER (?i:center)
@ -293,7 +297,7 @@ CONFIGURATION (?i:configuration)
%x PROPERTIES_VAR %x PROPERTIES_VAR
%x PROPERTIES_ENV_VAR %x PROPERTIES_ENV_VAR
%x PROPERTIES_VAR_DEFAULT %x PROPERTIES_VAR_DEFAULT
%x PROPERTIES_LIST %x PROPERTIES_ARRAY
%x NAMESTR %x NAMESTR
%x SECTION %x SECTION
%x DEFAULTS %x DEFAULTS
@ -489,21 +493,22 @@ if ( queue == NULL ) {
/* Alias color to text-color */ /* Alias color to text-color */
<SECTION>"color" { yylval->sval = g_strdup("text-color"); return T_PROP_NAME;} <SECTION>"color" { yylval->sval = g_strdup("text-color"); return T_PROP_NAME;}
<SECTION>{WORD} { yylval->sval = g_strdup(yytext); return T_PROP_NAME;} <SECTION>{WORD} { yylval->sval = g_strdup(yytext); return T_PROP_NAME;}
<NAMESTR>{WORD} { yylval->sval = g_strdup(yytext); return T_NAME_ELEMENT;} <NAMESTR>{WORD_ELEMENT} { yylval->sval = g_strdup(yytext); return T_NAME_ELEMENT;}
/* After Namestr/Classstr we want to go to state str, then to { */ /* After Namestr/Classstr we want to go to state str, then to { */
<INITIAL,SECTION>{WHITESPACE}+ ; // ignore all whitespace <INITIAL,SECTION>{WHITESPACE}+ ; // ignore all whitespace
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,PROPERTIES_LIST,PROPERTIES_ENV_VAR,PROPERTIES_VAR,MEDIA_CONTENT>{WHITESPACE}+ ; // ignore all whitespace <PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,PROPERTIES_ARRAY,PROPERTIES_ENV_VAR,PROPERTIES_VAR,MEDIA_CONTENT>{WHITESPACE}+ ; // ignore all whitespace
<SECTION>":" { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(PROPERTIES); return T_PSEP; } <SECTION>":" { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(PROPERTIES); return T_PSEP; }
<PROPERTIES>";" { BEGIN(GPOINTER_TO_INT ( g_queue_pop_head ( queue ))); return T_PCLOSE;} <PROPERTIES>";" { BEGIN(GPOINTER_TO_INT ( g_queue_pop_head ( queue ))); return T_PCLOSE;}
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>(true|false) { yylval->bval= g_strcmp0(yytext, "true") == 0; return T_BOOLEAN;} <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>(true|false) { yylval->bval= g_strcmp0(yytext, "true") == 0; return T_BOOLEAN;}
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,MEDIA_CONTENT>{PNNUMBER}\.{NUMBER}+ { yylval->fval = g_ascii_strtod(yytext, NULL); return T_DOUBLE;} <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,MEDIA_CONTENT>{PNNUMBER}\.{NUMBER}+ { yylval->fval = g_ascii_strtod(yytext, NULL); return T_DOUBLE;}
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,MEDIA_CONTENT>{PNNUMBER} { yylval->ival = (int)g_ascii_strtoll(yytext, NULL, 10); return T_INT;} <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,MEDIA_CONTENT>{PNNUMBER} { yylval->ival = (int)g_ascii_strtoll(yytext, NULL, 10); return T_INT;}
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{STRING} { yytext[yyleng-1] = '\0'; yylval->sval = g_strcompress(&yytext[1]); return T_STRING;} <PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{STRING} { yytext[yyleng-1] = '\0'; yylval->sval = g_strcompress(&yytext[1]); return T_STRING;}
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CHAR} { yytext[yyleng-1] = '\0'; yylval->cval = g_strcompress(&yytext[1])[0]; return T_CHAR;} <PROPERTIES_ARRAY>{STRING_LIST} { yytext[yyleng-1] = '\0'; yylval->sval = g_strcompress(&yytext[1]); return T_STRING;}
<PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CHAR} { yytext[yyleng-1] = '\0'; yylval->cval = g_strcompress(&yytext[1])[0]; return T_CHAR;}
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>@{WORD} { <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>@{WORD} {
yylval->sval = g_strdup(yytext+1); yylval->sval = g_strdup(yytext+1);
return T_LINK; return T_LINK;
} }
@ -516,23 +521,26 @@ if ( queue == NULL ) {
return T_BOPEN; return T_BOPEN;
} }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{EM} { return T_UNIT_EM; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_ARRAY,PROPERTIES_VAR_DEFAULT>{EM} { return T_UNIT_EM; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CH} { return T_UNIT_CH; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_ARRAY,PROPERTIES_VAR_DEFAULT>{CH} { return T_UNIT_CH; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,MEDIA_CONTENT>{PX} { return T_UNIT_PX; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_ARRAY,PROPERTIES_VAR_DEFAULT,MEDIA_CONTENT>{PX} { return T_UNIT_PX; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,MEDIA_CONTENT>{MM} { return T_UNIT_MM; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_ARRAY,PROPERTIES_VAR_DEFAULT,MEDIA_CONTENT>{MM} { return T_UNIT_MM; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{PERCENT} { return T_PERCENT; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_ARRAY,PROPERTIES_VAR_DEFAULT>{PERCENT} { return T_PERCENT; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{LS_SOLID} { return T_SOLID; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_ARRAY,PROPERTIES_VAR_DEFAULT>{LS_SOLID} { return T_SOLID; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{LS_DASH} { return T_DASH; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_ARRAY,PROPERTIES_VAR_DEFAULT>{LS_DASH} { return T_DASH; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{INHERIT} { return T_INHERIT; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_ARRAY,PROPERTIES_VAR_DEFAULT>{INHERIT} { return T_INHERIT; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{MODIFIER_ADD} { return T_MODIFIER_ADD; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_ARRAY,PROPERTIES_VAR_DEFAULT>{MODIFIER_ADD} { return T_MODIFIER_ADD; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{MODIFIER_SUBTRACT} { return T_MODIFIER_SUBTRACT; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_ARRAY,PROPERTIES_VAR_DEFAULT>{MODIFIER_SUBTRACT} { return T_MODIFIER_SUBTRACT; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{MODIFIER_MULTIPLY} { return T_MODIFIER_MULTIPLY; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_ARRAY,PROPERTIES_VAR_DEFAULT>{MODIFIER_MULTIPLY} { return T_MODIFIER_MULTIPLY; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{MODIFIER_MIN} { return T_MODIFIER_MIN; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_ARRAY,PROPERTIES_VAR_DEFAULT>{MODIFIER_MIN} { return T_MODIFIER_MIN; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{MODIFIER_MAX} { return T_MODIFIER_MAX; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_ARRAY,PROPERTIES_VAR_DEFAULT>{MODIFIER_MAX} { return T_MODIFIER_MAX; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CALC} { return T_CALC; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_ARRAY,PROPERTIES_VAR_DEFAULT>{MODIFIER_ROUND} { return T_MODIFIER_ROUND; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_ARRAY,PROPERTIES_VAR_DEFAULT>{MODIFIER_FLOOR} { return T_MODIFIER_FLOOR; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_ARRAY,PROPERTIES_VAR_DEFAULT>{MODIFIER_CEIL} { return T_MODIFIER_CEIL; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_ARRAY,PROPERTIES_VAR_DEFAULT>{CALC} { return T_CALC; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ENV} { <PROPERTIES,PROPERTIES_ENV,PROPERTIES_ARRAY,PROPERTIES_VAR_DEFAULT>{ENV} {
yytext[yyleng-1] = '\0'; yytext[yyleng-1] = '\0';
const char *val = g_getenv(yytext+2); const char *val = g_getenv(yytext+2);
if ( val ) { if ( val ) {
@ -664,47 +672,47 @@ if ( queue == NULL ) {
} }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{S_T_PARENT_LEFT} { return T_PARENT_LEFT; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{S_T_PARENT_LEFT} { return T_PARENT_LEFT; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{S_T_PARENT_RIGHT} { return T_PARENT_RIGHT; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{S_T_PARENT_RIGHT} { return T_PARENT_RIGHT; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,PROPERTIES_LIST>{COMMA} { return T_COMMA; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{COMMA} { return T_COMMA; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{LIST_OPEN} { <PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{LIST_OPEN} {
g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) );
BEGIN(PROPERTIES_LIST); BEGIN(PROPERTIES_ARRAY);
return T_LIST_OPEN; return T_LIST_OPEN;
} }
<PROPERTIES_LIST>{LIST_CLOSE} { <PROPERTIES_ARRAY>{LIST_CLOSE} {
BEGIN(GPOINTER_TO_INT(g_queue_pop_head ( queue ))); BEGIN(GPOINTER_TO_INT(g_queue_pop_head ( queue )));
return T_LIST_CLOSE; return T_LIST_CLOSE;
} }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{FORWARD_SLASH} { return T_FORWARD_SLASH; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{FORWARD_SLASH} { return T_FORWARD_SLASH; }
/* Position */ /* Position */
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CENTER} { return T_POS_CENTER; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CENTER} { return T_POS_CENTER; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{EAST} { return T_POS_EAST; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{EAST} { return T_POS_EAST; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{WEST} { return T_POS_WEST; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{WEST} { return T_POS_WEST; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{SOUTH} { return T_POS_SOUTH; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{SOUTH} { return T_POS_SOUTH; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{NORTH} { return T_POS_NORTH; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{NORTH} { return T_POS_NORTH; }
/* Highlight style */ /* Highlight style */
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{NONE} { return T_NONE; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{NONE} { return T_NONE; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{BOLD} { return T_BOLD; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{BOLD} { return T_BOLD; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ITALIC} { return T_ITALIC; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ITALIC} { return T_ITALIC; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{UNDERLINE} { return T_UNDERLINE; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{UNDERLINE} { return T_UNDERLINE; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{STRIKETHROUGH} { return T_STRIKETHROUGH; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{STRIKETHROUGH} { return T_STRIKETHROUGH; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{SMALLCAPS} { return T_SMALLCAPS; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{SMALLCAPS} { return T_SMALLCAPS; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ANGLE_DEG} { return T_ANGLE_DEG; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ANGLE_DEG} { return T_ANGLE_DEG; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ANGLE_RAD} { return T_ANGLE_RAD; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ANGLE_RAD} { return T_ANGLE_RAD; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ANGLE_GRAD} { return T_ANGLE_GRAD; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ANGLE_GRAD} { return T_ANGLE_GRAD; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ANGLE_TURN} { return T_ANGLE_TURN; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ANGLE_TURN} { return T_ANGLE_TURN; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ORIENTATION_HORI} { return ORIENTATION_HORI; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ORIENTATION_HORI} { return ORIENTATION_HORI; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ORIENTATION_VERT} { return ORIENTATION_VERT; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{ORIENTATION_VERT} { return ORIENTATION_VERT; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CURSOR_DEF} { return CURSOR_DEF; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CURSOR_DEF} { return CURSOR_DEF; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CURSOR_PTR} { return CURSOR_PTR; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CURSOR_PTR} { return CURSOR_PTR; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CURSOR_TXT} { return CURSOR_TXT; } <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{CURSOR_TXT} { return CURSOR_TXT; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{COLOR_TRANSPARENT} { <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{COLOR_TRANSPARENT} {
return T_COLOR_TRANSPARENT; return T_COLOR_TRANSPARENT;
} }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{COLOR_NAME} { <PROPERTIES,PROPERTIES_ARRAY,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{COLOR_NAME} {
for ( unsigned int iter = 0; iter < num_CSSColors; iter++) { for ( unsigned int iter = 0; iter < num_CSSColors; iter++) {
if ( strcasecmp(yytext, CSSColors[iter].name )== 0 ) { if ( strcasecmp(yytext, CSSColors[iter].name )== 0 ) {
yylval->colorval.alpha = 1.0; yylval->colorval.alpha = 1.0;
@ -800,7 +808,7 @@ if ( queue == NULL ) {
* If we just encounter a word, we assume it is a Widget name. * If we just encounter a word, we assume it is a Widget name.
* This makes include,theme, configuration a reserved keyword. * This makes include,theme, configuration a reserved keyword.
*/ */
<INITIAL>{WORD} { <INITIAL>{WORD_ELEMENT} {
g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) );
BEGIN(NAMESTR); BEGIN(NAMESTR);
yylval->sval = g_strdup(yytext); yylval->sval = g_strdup(yytext);
@ -815,17 +823,12 @@ if ( queue == NULL ) {
fprintf(stderr,"section found: |%s|\n", yytext); fprintf(stderr,"section found: |%s|\n", yytext);
return T_ERROR_SECTION; return T_ERROR_SECTION;
} }
<PROPERTIES_LIST,PROPERTIES_VAR>{WORD} { <PROPERTIES_ARRAY,PROPERTIES_VAR>{WORD_ELEMENT} {
yylval->sval = g_strdup(yytext); yylval->sval = g_strdup(yytext);
return T_ELEMENT; return T_ELEMENT;
} }
<PROPERTIES_LIST>{STRING_LIST} {
yytext[yyleng-1] = '\0';
yylval->sval = g_strdup(yytext+1);
return T_ELEMENT;
}
<PROPERTIES_ENV_VAR,PROPERTIES_VAR,PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT,PROPERTIES_LIST>. { <PROPERTIES_ENV_VAR,PROPERTIES_VAR,PROPERTIES_ARRAY,PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>. {
yytext[yyleng-1] = '\0'; yytext[yyleng-1] = '\0';
return T_ERROR_PROPERTY; return T_ERROR_PROPERTY;
} }
@ -867,16 +870,14 @@ gboolean rofi_theme_parse_file ( const char *file )
yyin = NULL; yyin = NULL;
while ( (po = g_queue_pop_head ( file_queue ) )) { while ( (po = g_queue_pop_head ( file_queue ) )) {
if ( po ) { if ( po->type == PT_FILE ) {
if ( po->type == PT_FILE ) { fclose ( po->filein );
fclose ( po->filein ); }
} if ( po->type == PT_STRING_ALLOC ) {
if ( po->type == PT_STRING_ALLOC ) { g_free( po->malloc_str);
g_free( po->malloc_str); }
} g_free ( po->filename );
g_free ( po->filename ); g_free ( po );
g_free ( po );
}
} }
// Free up. // Free up.
g_queue_free ( file_queue ); g_queue_free ( file_queue );
@ -904,16 +905,14 @@ gboolean rofi_theme_parse_string ( const char *string )
yylex_destroy (); yylex_destroy ();
while ( (po = g_queue_pop_head ( file_queue ) )) { while ( (po = g_queue_pop_head ( file_queue ) )) {
if ( po ) { if ( po->type == PT_FILE ) {
if ( po->type == PT_FILE ) { fclose ( po->filein );
fclose ( po->filein ); }
} if ( po->type == PT_STRING_ALLOC ) {
if ( po->type == PT_STRING_ALLOC ) { g_free( po->malloc_str);
g_free( po->malloc_str); }
} g_free ( po->filename );
g_free ( po->filename ); g_free ( po );
g_free ( po );
}
} }
// Free up. // Free up.
g_queue_free ( file_queue ); g_queue_free ( file_queue );

View file

@ -231,6 +231,7 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b )
%token T_OPTIONAL_COMMA "Optional comma separator (',')" %token T_OPTIONAL_COMMA "Optional comma separator (',')"
%token T_FORWARD_SLASH "forward slash ('/')" %token T_FORWARD_SLASH "forward slash ('/')"
%token T_PERCENT "Percent sign ('%')" %token T_PERCENT "Percent sign ('%')"
%token T_LIST_OPEN "List open ('[')" %token T_LIST_OPEN "List open ('[')"
%token T_LIST_CLOSE "List close (']')" %token T_LIST_CLOSE "List close (']')"
@ -240,6 +241,9 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b )
%token T_MODIFIER_MAX "Max ('max')" %token T_MODIFIER_MAX "Max ('max')"
%token T_MODIFIER_MIN "Min ('min')" %token T_MODIFIER_MIN "Min ('min')"
%token T_MODIFIER_ROUND "Min ('round')"
%token T_MODIFIER_FLOOR "Min ('floor')"
%token T_MODIFIER_CEIL "Min ('ceil')"
%token T_CALC "calc" %token T_CALC "calc"
@ -649,8 +653,18 @@ t_property_element_list_optional
; ;
t_property_element_list t_property_element_list
: T_ELEMENT { $$ = g_list_append ( NULL, $1); } : t_property_element { $$ = g_list_append ( NULL, $1); }
| T_ELEMENT {
Property *p = rofi_theme_property_create ( P_STRING );
p->value.s = $1;
$$ = g_list_append ( NULL, p);
}
| t_property_element_list T_COMMA T_ELEMENT { | t_property_element_list T_COMMA T_ELEMENT {
Property *p = rofi_theme_property_create ( P_STRING );
p->value.s = $3;
$$ = g_list_append ( $1, p);
}
| t_property_element_list T_COMMA t_property_element {
$$ = g_list_append ( $1, $3 ); $$ = g_list_append ( $1, $3 );
} }
; ;
@ -801,6 +815,24 @@ t_property_distance_unit_math3
$$->right = $3; $$->right = $3;
$$->modtype = ROFI_DISTANCE_MODIFIER_MAX; $$->modtype = ROFI_DISTANCE_MODIFIER_MAX;
} }
| t_property_distance_unit_math3 T_MODIFIER_ROUND t_property_distance_unit_math2 {
$$ = g_slice_new0(RofiDistanceUnit);
$$->left = $1;
$$->right = $3;
$$->modtype = ROFI_DISTANCE_MODIFIER_ROUND;
}
| t_property_distance_unit_math3 T_MODIFIER_FLOOR t_property_distance_unit_math2 {
$$ = g_slice_new0(RofiDistanceUnit);
$$->left = $1;
$$->right = $3;
$$->modtype = ROFI_DISTANCE_MODIFIER_FLOOR;
}
| t_property_distance_unit_math3 T_MODIFIER_CEIL t_property_distance_unit_math2 {
$$ = g_slice_new0(RofiDistanceUnit);
$$->left = $1;
$$->right = $3;
$$->modtype = ROFI_DISTANCE_MODIFIER_CEIL;
}
| t_property_distance_unit_math2 { | t_property_distance_unit_math2 {
$$ = $1; $$ = $1;
}; };

View file

@ -1,5 +1,5 @@
project('rofi', 'c', project('rofi', 'c',
version: '1.7.2+wayland1-dev', version: '1.7.3+wayland1',
meson_version: '>=0.47.0', meson_version: '>=0.47.0',
license: [ 'MIT' ], license: [ 'MIT' ],
default_options: [ default_options: [
@ -297,6 +297,8 @@ install_man(
'doc/rofi-sensible-terminal.1', 'doc/rofi-sensible-terminal.1',
'doc/rofi-script.5', 'doc/rofi-script.5',
'doc/rofi-theme.5', 'doc/rofi-theme.5',
'doc/rofi-dmenu.5',
'doc/rofi-keys.5',
) )
install_data( install_data(

View file

@ -0,0 +1,35 @@
# 1.7.3: Sturtled!
A small intermediate release with a few fixes, mostly in documentation and two great additions by Jakub Jiruta:
* An option to customize the combi mode display format.
* To possibility to set tab stops on listview and entry boxes.
# Changelog
v1.7.3:
- [Help] Print out the parsed config/theme files in -help output.
- [Keybindings] Fix keybindings being modified by -theme-str
- [Doc] Add rofi-dmenu manpage.
- [XCB] Cache lookup of monitor.
- Add -replace option (#568)
- Fix memory leak.
- [1566] Add extra debug for resolving monitors.
- [Theme] Add round,floor,ceil function in @calc (#1569)
- [Doc] Explain icon lookup.
- [Combi] Add -combi-display-format (#1570) (thanks to Jakub)
- [Theme] Expand list type ([]) for more data types.
- [Theme] Add support for tab-stops on textbox. (#1571) (thanks to Jakub)
- [Theme] Testing direct access to widgets via cmdline option (-theme+widget+property value)
# Thanks
Big thanks to everybody reporting issues.
Special thanks goes to:
* Iggy
* Quentin Glidic
* Danny Colin
* Jakub Jiruta
Apologies if I mistyped or missed anybody.

View file

@ -35,6 +35,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "mode-private.h" #include "mode-private.h"
#include "widgets/textbox.h"
#include <dialogs/dialogs.h> #include <dialogs/dialogs.h>
#include <pango/pango.h> #include <pango/pango.h>
#include <theme.h> #include <theme.h>
@ -68,7 +69,7 @@ static void combi_mode_parse_switchers(Mode *sw) {
for (char *token = strtok_r(switcher_str, sep, &savept); token != NULL; for (char *token = strtok_r(switcher_str, sep, &savept); token != NULL;
token = strtok_r(NULL, sep, &savept)) { token = strtok_r(NULL, sep, &savept)) {
/* Check against recursion. */ /* Check against recursion. */
if ( g_strcmp0(token, sw->name) == 0 ){ if (g_strcmp0(token, sw->name) == 0) {
g_warning("You cannot add '%s' to the list of combined modi.", sw->name); g_warning("You cannot add '%s' to the list of combined modi.", sw->name);
continue; continue;
} }
@ -83,7 +84,7 @@ static void combi_mode_parse_switchers(Mode *sw) {
continue; continue;
} }
// If not build in, use custom switchers. // If not build in, use custom switchers.
mode = script_switcher_parse_setup(token); mode = script_mode_parse_setup(token);
if (mode != NULL) { if (mode != NULL) {
pd->switchers[pd->num_switchers].disable = FALSE; pd->switchers[pd->num_switchers].disable = FALSE;
pd->switchers[pd->num_switchers++].mode = mode; pd->switchers[pd->num_switchers++].mode = mode;
@ -225,8 +226,20 @@ static char *combi_mgrv(const Mode *sw, unsigned int selected_line, int *state,
selected_line - pd->starts[i], selected_line - pd->starts[i],
state, attr_list, TRUE); state, attr_list, TRUE);
const char *dname = mode_get_display_name(pd->switchers[i].mode); const char *dname = mode_get_display_name(pd->switchers[i].mode);
if (!config.combi_hide_mode_prefix) { if (!config.combi_hide_mode_prefix) {
retv = g_strdup_printf("%s %s", dname, str); if (!(*state & MARKUP)) {
char *tmp = str;
str = g_markup_escape_text(tmp, -1);
g_free(tmp);
*state |= MARKUP;
}
retv = helper_string_replace_if_exists(
config.combi_display_format,
"{mode}", dname,
"{text}", str,
NULL);
g_free(str); g_free(str);
if (attr_list != NULL) { if (attr_list != NULL) {

View file

@ -545,7 +545,7 @@ static void dmenu_print_results(DmenuModePrivateData *pd, const char *input) {
if (pd->selected_line != UINT32_MAX) { if (pd->selected_line != UINT32_MAX) {
cmd = cmd_list[pd->selected_line].entry; cmd = cmd_list[pd->selected_line].entry;
} }
if ( cmd ) { if (cmd) {
rofi_output_formatted_line(pd->format, cmd, pd->selected_line, input); rofi_output_formatted_line(pd->format, cmd, pd->selected_line, input);
} }
} }
@ -676,7 +676,7 @@ static void dmenu_finalize(RofiViewState *state) {
} }
} }
int dmenu_switcher_dialog(void) { int dmenu_mode_dialog(void) {
mode_init(&dmenu_mode); mode_init(&dmenu_mode);
MenuFlags menu_flags = MENU_NORMAL; MenuFlags menu_flags = MENU_NORMAL;
DmenuModePrivateData *pd = (DmenuModePrivateData *)dmenu_mode.private_data; DmenuModePrivateData *pd = (DmenuModePrivateData *)dmenu_mode.private_data;

View file

@ -28,8 +28,8 @@
/** The log domain of this dialog. */ /** The log domain of this dialog. */
#define G_LOG_DOMAIN "Dialogs.Script" #define G_LOG_DOMAIN "Dialogs.Script"
#include "config.h"
#include "dialogs/script.h" #include "dialogs/script.h"
#include "config.h"
#include "helper.h" #include "helper.h"
#include "rofi.h" #include "rofi.h"
#include <assert.h> #include <assert.h>
@ -202,20 +202,22 @@ static DmenuScriptEntry *execute_executor(Mode *sw, char *arg,
actual_size += 256; actual_size += 256;
retv = g_realloc(retv, (actual_size) * sizeof(DmenuScriptEntry)); retv = g_realloc(retv, (actual_size) * sizeof(DmenuScriptEntry));
} }
size_t buf_length = strlen(buffer) + 1; if (retv) {
retv[(*length)].entry = g_memdup(buffer, buf_length); size_t buf_length = strlen(buffer) + 1;
retv[(*length)].icon_name = NULL; retv[(*length)].entry = g_memdup(buffer, buf_length);
retv[(*length)].meta = NULL; retv[(*length)].icon_name = NULL;
retv[(*length)].info = NULL; retv[(*length)].meta = NULL;
retv[(*length)].icon_fetch_uid = 0; retv[(*length)].info = NULL;
retv[(*length)].nonselectable = FALSE; retv[(*length)].icon_fetch_uid = 0;
if (buf_length > 0 && (read_length > (ssize_t)buf_length)) { retv[(*length)].nonselectable = FALSE;
dmenuscript_parse_entry_extras(sw, &(retv[(*length)]), if (buf_length > 0 && (read_length > (ssize_t)buf_length)) {
buffer + buf_length, dmenuscript_parse_entry_extras(sw, &(retv[(*length)]),
read_length - buf_length); buffer + buf_length,
read_length - buf_length);
}
retv[(*length) + 1].entry = NULL;
(*length)++;
} }
retv[(*length) + 1].entry = NULL;
(*length)++;
} }
} }
if (buffer) { if (buffer) {
@ -420,7 +422,7 @@ script_get_icon(const Mode *sw, unsigned int selected_line, int height) {
} }
#include "mode-private.h" #include "mode-private.h"
Mode *script_switcher_parse_setup(const char *str) { Mode *script_mode_parse_setup(const char *str) {
Mode *sw = g_malloc0(sizeof(*sw)); Mode *sw = g_malloc0(sizeof(*sw));
char *endp = NULL; char *endp = NULL;
char *parse = g_strdup(str); char *parse = g_strdup(str);
@ -458,6 +460,6 @@ Mode *script_switcher_parse_setup(const char *str) {
return NULL; return NULL;
} }
gboolean script_switcher_is_valid(const char *token) { gboolean script_mode_is_valid(const char *token) {
return strchr(token, ':') != NULL; return strchr(token, ':') != NULL;
} }

View file

@ -535,7 +535,7 @@ int execute_generator(const char *cmd) {
return fd; return fd;
} }
int create_pid_file(const char *pidfile) { int create_pid_file(const char *pidfile, gboolean kill_running) {
if (pidfile == NULL) { if (pidfile == NULL) {
return -1; return -1;
} }
@ -558,6 +558,26 @@ int create_pid_file(const char *pidfile) {
if (retv != 0) { if (retv != 0) {
g_warning("Failed to set lock on pidfile: Rofi already running?"); g_warning("Failed to set lock on pidfile: Rofi already running?");
g_warning("Got error: %d %s", retv, g_strerror(errno)); g_warning("Got error: %d %s", retv, g_strerror(errno));
if (kill_running) {
char buffer[64] = {
0,
};
ssize_t l = read(fd, &buffer, 64);
if (l > 1) {
pid_t pid = g_ascii_strtoll(buffer, NULL, 0);
kill(pid, SIGTERM);
while (1) {
retv = flock(fd, LOCK_EX | LOCK_NB);
if (retv == 0) {
break;
}
g_usleep(100);
}
}
remove_pid_file(fd);
return create_pid_file(pidfile, FALSE);
}
remove_pid_file(fd); remove_pid_file(fd);
return -1; return -1;
} }
@ -680,23 +700,6 @@ int config_sanity_check(void) {
} }
#endif #endif
if (config.menu_font) {
PangoFontDescription *pfd =
pango_font_description_from_string(config.menu_font);
const char *fam = pango_font_description_get_family(pfd);
int size = pango_font_description_get_size(pfd);
if (fam == NULL || size == 0) {
g_string_append_printf(msg, "Pango failed to parse font: '%s'\n",
config.menu_font);
g_string_append_printf(msg,
"Got font family: <b>%s</b> at size <b>%d</b>\n",
fam ? fam : "{unknown}", size);
config.menu_font = NULL;
found_error = TRUE;
}
pango_font_description_free(pfd);
}
if (g_strcmp0(config.monitor, "-3") == 0) { if (g_strcmp0(config.monitor, "-3") == 0) {
// On -3, set to location 1. // On -3, set to location 1.
config.location = 1; config.location = 1;
@ -786,15 +789,6 @@ char *rofi_latin_to_utf8_strdup(const char *input, gssize length) {
NULL, &slength, NULL); NULL, &slength, NULL);
} }
gchar *rofi_escape_markup(gchar *text) {
if (text == NULL) {
return NULL;
}
gchar *ret = g_markup_escape_text(text, -1);
g_free(text);
return ret;
}
char *rofi_force_utf8(const gchar *data, ssize_t length) { char *rofi_force_utf8(const gchar *data, ssize_t length) {
if (data == NULL) { if (data == NULL) {
return NULL; return NULL;
@ -1273,10 +1267,10 @@ char *helper_string_replace_if_exists(char *string, ...) {
* @param h Hash table with set of {key}, value that will be replaced, * @param h Hash table with set of {key}, value that will be replaced,
* terminated by a NULL * terminated by a NULL
* *
* Items {key} are replaced by the value if '{key}' is passed as key/value pair, * Items {key} are replaced by the value if '{key}' is passed as key/value
* otherwise removed from string. If the {key} is in between [] all the text * pair, otherwise removed from string. If the {key} is in between [] all the
* between [] are removed if {key} is not found. Otherwise key is replaced and [ * text between [] are removed if {key} is not found. Otherwise key is
* & ] removed. * replaced and [ & ] removed.
* *
* This allows for optional replacement, f.e. '{ssh-client} [-t {title}] -e * This allows for optional replacement, f.e. '{ssh-client} [-t {title}] -e
* "{cmd}"' the '-t {title}' is only there if {title} is set. * "{cmd}"' the '-t {title}' is only there if {title} is set.

View file

@ -110,7 +110,7 @@ unsigned int num_available_modi = 0;
/** Number of activated modi in #modi array */ /** Number of activated modi in #modi array */
unsigned int num_modi = 0; unsigned int num_modi = 0;
/** Current selected mode */ /** Current selected mode */
unsigned int curr_switcher = 0; unsigned int curr_mode = 0;
/** Handle to NkBindings object for input devices. */ /** Handle to NkBindings object for input devices. */
NkBindings *bindings = NULL; NkBindings *bindings = NULL;
@ -132,13 +132,13 @@ unsigned int rofi_get_num_enabled_modi(void) { return num_modi; }
const Mode *rofi_get_mode(unsigned int index) { return modi[index]; } const Mode *rofi_get_mode(unsigned int index) { return modi[index]; }
/** /**
* @param name Name of the switcher to lookup. * @param name Name of the mode to lookup.
* *
* Find the index of the switcher with name. * Find the index of the mode with name.
* *
* @returns index of the switcher in modi, -1 if not found. * @returns index of the mode in modi, -1 if not found.
*/ */
static int switcher_get(const char *name) { static int mode_lookup(const char *name) {
for (unsigned int i = 0; i < num_modi; i++) { for (unsigned int i = 0; i < num_modi; i++) {
if (strcmp(mode_get_name(modi[i]), name) == 0) { if (strcmp(mode_get_name(modi[i]), name) == 0) {
return i; return i;
@ -162,7 +162,7 @@ static void teardown(int pfd) {
// Cleanup pid file. // Cleanup pid file.
remove_pid_file(pfd); remove_pid_file(pfd);
} }
static void run_switcher(ModeMode mode) { static void run_mode_index(ModeMode mode) {
// Otherwise check if requested mode is enabled. // Otherwise check if requested mode is enabled.
for (unsigned int i = 0; i < num_modi; i++) { for (unsigned int i = 0; i < num_modi; i++) {
if (!mode_init(modi[i])) { if (!mode_init(modi[i])) {
@ -179,7 +179,7 @@ static void run_switcher(ModeMode mode) {
if (rofi_view_get_active() != NULL) { if (rofi_view_get_active() != NULL) {
return; return;
} }
curr_switcher = mode; curr_mode = mode;
RofiViewState *state = RofiViewState *state =
rofi_view_create(modi[mode], config.filter, 0, process_result); rofi_view_create(modi[mode], config.filter, 0, process_result);
@ -217,7 +217,7 @@ void process_result(RofiViewState *state) {
} }
g_free(input); g_free(input);
ModeMode mode = curr_switcher; ModeMode mode = curr_mode;
// Find next enabled // Find next enabled
if (retv == NEXT_DIALOG) { if (retv == NEXT_DIALOG) {
mode = (mode + 1) % num_modi; mode = (mode + 1) % num_modi;
@ -241,7 +241,7 @@ void process_result(RofiViewState *state) {
* Load in the new mode. * Load in the new mode.
*/ */
rofi_view_switch_mode(state, modi[mode]); rofi_view_switch_mode(state, modi[mode]);
curr_switcher = mode; curr_mode = mode;
return; return;
} }
// On exit, free current view, and pop to one above. // On exit, free current view, and pop to one above.
@ -266,7 +266,7 @@ static void print_list_of_modi(int is_term) {
break; break;
} }
} }
printf(" * %s%s%s%s\n", active ? "+" : "", printf(" %s%s%s%s\n", active ? "+" : "",
is_term ? (active ? color_green : color_red) : "", is_term ? (active ? color_green : color_red) : "",
available_modi[i]->name, is_term ? color_reset : ""); available_modi[i]->name, is_term ? color_reset : "");
} }
@ -325,31 +325,31 @@ static void help(G_GNUC_UNUSED int argc, char **argv) {
printf("\n"); printf("\n");
printf("Compile time options:\n"); printf("Compile time options:\n");
#ifdef WINDOW_MODE #ifdef WINDOW_MODE
printf("\t* window %senabled%s\n", is_term ? color_green : "", printf("\t window %senabled%s\n", is_term ? color_green : "",
is_term ? color_reset : ""); is_term ? color_reset : "");
#else #else
printf("\t* window %sdisabled%s\n", is_term ? color_red : "", printf("\t window %sdisabled%s\n", is_term ? color_red : "",
is_term ? color_reset : ""); is_term ? color_reset : "");
#endif #endif
#ifdef ENABLE_DRUN #ifdef ENABLE_DRUN
printf("\t* drun %senabled%s\n", is_term ? color_green : "", printf("\t drun %senabled%s\n", is_term ? color_green : "",
is_term ? color_reset : ""); is_term ? color_reset : "");
#else #else
printf("\t* drun %sdisabled%s\n", is_term ? color_red : "", printf("\t drun %sdisabled%s\n", is_term ? color_red : "",
is_term ? color_reset : ""); is_term ? color_reset : "");
#endif #endif
#ifdef ENABLE_GCOV #ifdef ENABLE_GCOV
printf("\t* gcov %senabled%s\n", is_term ? color_green : "", printf("\t gcov %senabled%s\n", is_term ? color_green : "",
is_term ? color_reset : ""); is_term ? color_reset : "");
#else #else
printf("\t* gcov %sdisabled%s\n", is_term ? color_red : "", printf("\t gcov %sdisabled%s\n", is_term ? color_red : "",
is_term ? color_reset : ""); is_term ? color_reset : "");
#endif #endif
#ifdef ENABLE_ASAN #ifdef ENABLE_ASAN
printf("\t* asan %senabled%s\n", is_term ? color_green : "", printf("\t asan %senabled%s\n", is_term ? color_green : "",
is_term ? color_reset : ""); is_term ? color_reset : "");
#else #else
printf("\t* asan %sdisabled%s\n", is_term ? color_red : "", printf("\t asan %sdisabled%s\n", is_term ? color_red : "",
is_term ? color_reset : ""); is_term ? color_reset : "");
#endif #endif
printf("\n"); printf("\n");
@ -377,6 +377,7 @@ static void help(G_GNUC_UNUSED int argc, char **argv) {
printf(" Configuration file: %sDisabled%s\n", printf(" Configuration file: %sDisabled%s\n",
is_term ? color_bold : "", is_term ? color_reset : ""); is_term ? color_bold : "", is_term ? color_reset : "");
} }
rofi_theme_print_parsed_files(is_term);
} }
static void help_print_disabled_mode(const char *mode) { static void help_print_disabled_mode(const char *mode) {
@ -475,6 +476,7 @@ static void cleanup(void) {
rofi_collect_modi_destroy(); rofi_collect_modi_destroy();
rofi_icon_fetcher_destroy(); rofi_icon_fetcher_destroy();
rofi_theme_free_parsed_files();
if (rofi_configuration) { if (rofi_configuration) {
rofi_theme_free(rofi_configuration); rofi_theme_free(rofi_configuration);
rofi_configuration = NULL; rofi_configuration = NULL;
@ -612,11 +614,11 @@ static void rofi_collect_modi_destroy(void) {
} }
/** /**
* Parse the switcher string, into internal array of type Mode. * Parse the mode string, into internal array of type Mode.
* *
* String is split on separator ',' * String is split on separator ','
* First the three build-in modi are checked: window, run, ssh * First the three build-in modi are checked: window, run, ssh
* if that fails, a script-switcher is created. * if that fails, a script-mode is created.
*/ */
static int add_mode(const char *token) { static int add_mode(const char *token) {
unsigned int index = num_modi; unsigned int index = num_modi;
@ -627,9 +629,9 @@ static int add_mode(const char *token) {
if (mode) { if (mode) {
modi[num_modi] = mode; modi[num_modi] = mode;
num_modi++; num_modi++;
} else if (script_switcher_is_valid(token)) { } else if (script_mode_is_valid(token)) {
// If not build in, use custom modi. // If not build in, use custom modi.
Mode *sw = script_switcher_parse_setup(token); Mode *sw = script_mode_parse_setup(token);
if (sw != NULL) { if (sw != NULL) {
// Add to available list, so combi can find it. // Add to available list, so combi can find it.
rofi_collect_modi_add(sw); rofi_collect_modi_add(sw);
@ -644,16 +646,16 @@ static gboolean setup_modi(void) {
const char *const sep = ",#"; const char *const sep = ",#";
char *savept = NULL; char *savept = NULL;
// Make a copy, as strtok will modify it. // Make a copy, as strtok will modify it.
char *switcher_str = g_strdup(config.modi); char *mode_str = g_strdup(config.modi);
// Split token on ','. This modifies switcher_str. // Split token on ','. This modifies mode_str.
for (char *token = strtok_r(switcher_str, sep, &savept); token != NULL; for (char *token = strtok_r(mode_str, sep, &savept); token != NULL;
token = strtok_r(NULL, sep, &savept)) { token = strtok_r(NULL, sep, &savept)) {
if (add_mode(token) == -1) { if (add_mode(token) == -1) {
help_print_mode_not_found(token); help_print_mode_not_found(token);
} }
} }
// Free string that was modified by strtok_r // Free string that was modified by strtok_r
g_free(switcher_str); g_free(mode_str);
return FALSE; return FALSE;
} }
@ -715,7 +717,7 @@ static gboolean startup(G_GNUC_UNUSED gpointer data) {
if (dmenu_mode == TRUE) { if (dmenu_mode == TRUE) {
// force off sidebar mode: // force off sidebar mode:
config.sidebar_mode = FALSE; config.sidebar_mode = FALSE;
int retv = dmenu_switcher_dialog(); int retv = dmenu_mode_dialog();
if (retv) { if (retv) {
rofi_set_return_code(EXIT_SUCCESS); rofi_set_return_code(EXIT_SUCCESS);
// Directly exit. // Directly exit.
@ -730,7 +732,7 @@ static gboolean startup(G_GNUC_UNUSED gpointer data) {
g_main_loop_quit(main_loop); g_main_loop_quit(main_loop);
} }
} else if (find_arg_str("-show", &sname) == TRUE) { } else if (find_arg_str("-show", &sname) == TRUE) {
int index = switcher_get(sname); int index = mode_lookup(sname);
if (index < 0) { if (index < 0) {
// Add it to the list // Add it to the list
index = add_mode(sname); index = add_mode(sname);
@ -741,14 +743,14 @@ static gboolean startup(G_GNUC_UNUSED gpointer data) {
// Run it anyway if found. // Run it anyway if found.
} }
if (index >= 0) { if (index >= 0) {
run_switcher(index); run_mode_index(index);
} else { } else {
help_print_mode_not_found(sname); help_print_mode_not_found(sname);
show_error_dialog(); show_error_dialog();
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
} }
} else if (find_arg("-show") >= 0 && num_modi > 0) { } else if (find_arg("-show") >= 0 && num_modi > 0) {
run_switcher(0); run_mode_index(0);
} else { } else {
help_print_no_arguments(); help_print_no_arguments();
@ -983,8 +985,6 @@ int main(int argc, char *argv[]) {
} }
TICK_N("Load cmd config "); TICK_N("Load cmd config ");
parse_keys_abe(bindings);
// Get the path to the cache dir. // Get the path to the cache dir.
cache_dir = g_get_user_cache_dir(); cache_dir = g_get_user_cache_dir();
@ -1030,6 +1030,7 @@ int main(int argc, char *argv[]) {
g_free(theme_str); g_free(theme_str);
} }
parse_keys_abe(bindings);
if (find_arg("-dump-theme") >= 0) { if (find_arg("-dump-theme") >= 0) {
rofi_theme_print(rofi_theme); rofi_theme_print(rofi_theme);
cleanup(); cleanup();
@ -1068,8 +1069,12 @@ int main(int argc, char *argv[]) {
rofi_icon_fetcher_init(); rofi_icon_fetcher_init();
TICK_N("Icon fetcher initialize"); TICK_N("Icon fetcher initialize");
gboolean kill_running = FALSE;
if (find_arg("-replace") >= 0) {
kill_running = TRUE;
}
// Create pid file // Create pid file
int pfd = create_pid_file(pidfile); int pfd = create_pid_file(pidfile, kill_running);
TICK_N("Pid file created"); TICK_N("Pid file created");
if (pfd < 0) { if (pfd < 0) {
cleanup(); cleanup();

View file

@ -47,6 +47,23 @@
#include "widgets/textbox.h" #include "widgets/textbox.h"
#include <gio/gio.h> #include <gio/gio.h>
GList *parsed_config_files = NULL;
void rofi_theme_free_parsed_files(void) {
g_list_free_full(parsed_config_files, g_free);
parsed_config_files = NULL;
}
void rofi_theme_print_parsed_files(gboolean is_term) {
printf("\nParsed files:\n");
for (GList *iter = g_list_first(parsed_config_files); iter != NULL;
iter = g_list_next(iter)) {
printf("\t\u2022 %s%s%s\n", is_term ? color_bold : "",
(const char *)(iter->data), is_term ? color_reset : "");
}
printf("\n");
}
void yyerror(YYLTYPE *yylloc, const char *, const char *); void yyerror(YYLTYPE *yylloc, const char *, const char *);
static gboolean distance_compare(RofiDistance d, RofiDistance e) { static gboolean distance_compare(RofiDistance d, RofiDistance e) {
// TODO UPDATE // TODO UPDATE
@ -54,11 +71,6 @@ static gboolean distance_compare(RofiDistance d, RofiDistance e) {
d.style == e.style; d.style == e.style;
} }
static gpointer rofi_g_list_strdup(gconstpointer data,
G_GNUC_UNUSED gpointer user_data) {
return g_strdup(data);
}
ThemeWidget *rofi_theme_find_or_create_name(ThemeWidget *base, ThemeWidget *rofi_theme_find_or_create_name(ThemeWidget *base,
const char *name) { const char *name) {
for (unsigned int i = 0; i < base->num_widgets; i++) { for (unsigned int i = 0; i < base->num_widgets; i++) {
@ -118,8 +130,8 @@ Property *rofi_theme_property_copy(const Property *p) {
retv->value.s = g_strdup(p->value.s); retv->value.s = g_strdup(p->value.s);
break; break;
case P_LIST: case P_LIST:
retv->value.list = retv->value.list = g_list_copy_deep(
g_list_copy_deep(p->value.list, rofi_g_list_strdup, NULL); p->value.list, (GCopyFunc)rofi_theme_property_copy, NULL);
break; break;
case P_LINK: case P_LINK:
retv->value.link.name = g_strdup(p->value.link.name); retv->value.link.name = g_strdup(p->value.link.name);
@ -188,7 +200,7 @@ void rofi_theme_property_free(Property *p) {
if (p->type == P_STRING) { if (p->type == P_STRING) {
g_free(p->value.s); g_free(p->value.s);
} else if (p->type == P_LIST) { } else if (p->type == P_LIST) {
g_list_free_full(p->value.list, g_free); g_list_free_full(p->value.list, (GDestroyNotify)rofi_theme_property_free);
p->value.list = 0; p->value.list = 0;
} else if (p->type == P_LINK) { } else if (p->type == P_LINK) {
g_free(p->value.link.name); g_free(p->value.link.name);
@ -267,6 +279,12 @@ static void rofi_theme_print_distance_unit(RofiDistanceUnit *unit) {
fputs(" min ", stdout); fputs(" min ", stdout);
} else if (unit->modtype == ROFI_DISTANCE_MODIFIER_MAX) { } else if (unit->modtype == ROFI_DISTANCE_MODIFIER_MAX) {
fputs(" max ", stdout); fputs(" max ", stdout);
} else if (unit->modtype == ROFI_DISTANCE_MODIFIER_ROUND) {
fputs(" round ", stdout);
} else if (unit->modtype == ROFI_DISTANCE_MODIFIER_FLOOR) {
fputs(" floor ", stdout);
} else if (unit->modtype == ROFI_DISTANCE_MODIFIER_CEIL) {
fputs(" ceil ", stdout);
} }
if (unit->right) { if (unit->right) {
rofi_theme_print_distance_unit(unit->right); rofi_theme_print_distance_unit(unit->right);
@ -339,7 +357,7 @@ static void int_rofi_theme_print_property(Property *p) {
case P_LIST: case P_LIST:
printf("[ "); printf("[ ");
for (GList *iter = p->value.list; iter != NULL; iter = g_list_next(iter)) { for (GList *iter = p->value.list; iter != NULL; iter = g_list_next(iter)) {
printf("%s", (char *)(iter->data)); int_rofi_theme_print_property((Property *)iter->data);
if (iter->next != NULL) { if (iter->next != NULL) {
printf(","); printf(",");
} }
@ -1190,7 +1208,7 @@ RofiPadding rofi_theme_get_padding(const widget *widget, const char *property,
static GList *rofi_theme_get_list_inside(Property *p, const widget *widget, static GList *rofi_theme_get_list_inside(Property *p, const widget *widget,
const char *property, const char *property,
const char *defaults) { PropertyType child_type) {
if (p) { if (p) {
if (p->type == P_INHERIT) { if (p->type == P_INHERIT) {
if (widget->parent) { if (widget->parent) {
@ -1199,28 +1217,58 @@ static GList *rofi_theme_get_list_inside(Property *p, const widget *widget,
Property *pv = Property *pv =
rofi_theme_find_property(parent, P_LIST, property, FALSE); rofi_theme_find_property(parent, P_LIST, property, FALSE);
return rofi_theme_get_list_inside(pv, widget->parent, property, return rofi_theme_get_list_inside(pv, widget->parent, property,
defaults); child_type);
} }
} else if (p->type == P_LIST) { } else if (p->type == P_LIST) {
return g_list_copy_deep(p->value.list, rofi_g_list_strdup, NULL); return p->value.list;
} }
} }
char **r = defaults ? g_strsplit(defaults, ",", 0) : NULL;
if (r) {
GList *l = NULL;
for (int i = 0; r[i] != NULL; i++) {
l = g_list_append(l, r[i]);
}
g_free(r);
return l;
}
return NULL; return NULL;
} }
GList *rofi_theme_get_list(const widget *widget, const char *property, GList *rofi_theme_get_list_distance(const widget *widget,
const char *defaults) { const char *property) {
ThemeWidget *wid2 = rofi_theme_find_widget(widget->name, widget->state, TRUE); ThemeWidget *wid2 =
Property *p = rofi_theme_find_property(wid2, P_LIST, property, TRUE); rofi_theme_find_widget(widget->name, widget->state, FALSE);
return rofi_theme_get_list_inside(p, widget, property, defaults); Property *p = rofi_theme_find_property(wid2, P_LIST, property, FALSE);
GList *list = rofi_theme_get_list_inside(p, widget, property, P_PADDING);
GList *retv = NULL;
for (GList *iter = g_list_first(list); iter != NULL;
iter = g_list_next(iter)) {
Property *prop = (Property *)(iter->data);
if (prop->type == P_PADDING) {
RofiDistance *p = g_new0(RofiDistance, 1);
*p = prop->value.padding.left;
retv = g_list_append(retv, p);
} else if (prop->type == P_INTEGER) {
RofiDistance *p = g_new0(RofiDistance, 1);
RofiDistance d =
(RofiDistance){.base = {prop->value.i, ROFI_PU_PX,
ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL},
.style = ROFI_HL_SOLID};
*p = d;
retv = g_list_append(retv, p);
} else {
g_warning("Invalid type detected in list.");
}
}
return retv;
}
GList *rofi_theme_get_list_strings(const widget *widget, const char *property) {
ThemeWidget *wid2 =
rofi_theme_find_widget(widget->name, widget->state, FALSE);
Property *p = rofi_theme_find_property(wid2, P_LIST, property, FALSE);
GList *list = rofi_theme_get_list_inside(p, widget, property, P_STRING);
GList *retv = NULL;
for (GList *iter = g_list_first(list); iter != NULL;
iter = g_list_next(iter)) {
Property *prop = (Property *)(iter->data);
if (prop->type == P_STRING) {
retv = g_list_append(retv, g_strdup(prop->value.s));
} else {
g_warning("Invalid type detected in list.");
}
}
return retv;
} }
static RofiHighlightColorStyle static RofiHighlightColorStyle
@ -1248,9 +1296,9 @@ rofi_theme_get_highlight_inside(Property *p, widget *widget,
} else { } else {
ThemeWidget *wid = ThemeWidget *wid =
rofi_theme_find_widget(widget->name, widget->state, FALSE); rofi_theme_find_widget(widget->name, widget->state, FALSE);
Property *p = rofi_theme_find_property(wid, P_COLOR, property, FALSE); Property *p2 = rofi_theme_find_property(wid, P_COLOR, property, FALSE);
if (p != NULL) { if (p2 != NULL) {
return rofi_theme_get_highlight_inside(p, widget, property, th); return rofi_theme_get_highlight_inside(p2, widget, property, th);
} }
return th; return th;
} }
@ -1332,6 +1380,21 @@ static int distance_unit_get_pixel(RofiDistanceUnit *unit,
int b = distance_unit_get_pixel(unit->right, ori); int b = distance_unit_get_pixel(unit->right, ori);
return MAX(a, b); return MAX(a, b);
} }
case ROFI_DISTANCE_MODIFIER_ROUND: {
double a = (double)distance_unit_get_pixel(unit->left, ori);
double b = (double)distance_unit_get_pixel(unit->right, ori);
return (int)(round(a / b) * b);
}
case ROFI_DISTANCE_MODIFIER_CEIL: {
double a = (double)distance_unit_get_pixel(unit->left, ori);
double b = (double)distance_unit_get_pixel(unit->right, ori);
return (int)(ceil(a / b) * b);
}
case ROFI_DISTANCE_MODIFIER_FLOOR: {
double a = (double)distance_unit_get_pixel(unit->left, ori);
double b = (double)distance_unit_get_pixel(unit->right, ori);
return (int)(floor(a / b) * b);
}
default: default:
break; break;
} }
@ -1351,16 +1414,6 @@ void distance_get_linestyle(RofiDistance d, cairo_t *draw) {
} }
} }
gboolean rofi_theme_is_empty(void) {
if (rofi_theme == NULL) {
return TRUE;
}
if (rofi_theme->properties == NULL && rofi_theme->num_widgets == 0) {
return TRUE;
}
return FALSE;
}
char *rofi_theme_parse_prepare_file(const char *file, const char *parent_file) { char *rofi_theme_parse_prepare_file(const char *file, const char *parent_file) {
char *filename = rofi_expand_path(file); char *filename = rofi_expand_path(file);
// If no absolute path specified, expand it. // If no absolute path specified, expand it.
@ -1372,7 +1425,7 @@ char *rofi_theme_parse_prepare_file(const char *file, const char *parent_file) {
g_free(basedir); g_free(basedir);
} }
GFile *gf = g_file_new_for_path(filename); GFile *gf = g_file_new_for_path(filename);
g_free(filename); parsed_config_files = g_list_append(parsed_config_files, filename);
filename = g_file_get_path(gf); filename = g_file_get_path(gf);
g_object_unref(gf); g_object_unref(gf);

View file

@ -1017,12 +1017,12 @@ static WidgetTriggerActionResult textbox_button_trigger_action(
switch (action) { switch (action) {
case MOUSE_CLICK_DOWN: { case MOUSE_CLICK_DOWN: {
const char *type = rofi_theme_get_string(wid, "action", NULL); const char *type = rofi_theme_get_string(wid, "action", NULL);
if (type ) { if (type) {
if ( state->list_view) { if (state->list_view) {
(state->selected_line) = (state->selected_line) =
state->line_map[listview_get_selected(state->list_view)]; state->line_map[listview_get_selected(state->list_view)];
} else { } else {
(state->selected_line) = UINT32_MAX; (state->selected_line) = UINT32_MAX;
} }
guint id = key_binding_get_action_from_name(type); guint id = key_binding_get_action_from_name(type);
if (id != UINT32_MAX) { if (id != UINT32_MAX) {
@ -1261,11 +1261,22 @@ static void rofi_view_add_widget(RofiViewState *state, widget *parent_widget,
// g_error("The widget %s does not exists. Invalid layout.", name); // g_error("The widget %s does not exists. Invalid layout.", name);
} }
if (wid) { if (wid) {
GList *list = rofi_theme_get_list(wid, "children", defaults); GList *list = rofi_theme_get_list_strings(wid, "children");
for (const GList *iter = list; iter != NULL; iter = g_list_next(iter)) { if (list == NULL) {
rofi_view_add_widget(state, wid, (const char *)iter->data); if (defaults) {
char **a = g_strsplit(defaults, ",", 0);
for (int i = 0; a && a[i]; i++) {
rofi_view_add_widget(state, wid, a[i]);
}
g_strfreev(a);
}
} else {
for (const GList *iter = g_list_first(list); iter != NULL;
iter = g_list_next(iter)) {
rofi_view_add_widget(state, wid, (const char *)iter->data);
}
g_list_free_full(list, g_free);
} }
g_list_free_full(list, g_free);
} }
} }
@ -1305,12 +1316,16 @@ RofiViewState *rofi_view_create(Mode *sw, const char *input,
state->main_window = box_create(NULL, "window", ROFI_ORIENTATION_VERTICAL); state->main_window = box_create(NULL, "window", ROFI_ORIENTATION_VERTICAL);
// Get children. // Get children.
GList *list = GList *list =
rofi_theme_get_list(WIDGET(state->main_window), "children", "mainbox"); rofi_theme_get_list_strings(WIDGET(state->main_window), "children");
for (const GList *iter = list; iter != NULL; iter = g_list_next(iter)) { if (list == NULL) {
rofi_view_add_widget(state, WIDGET(state->main_window), rofi_view_add_widget(state, WIDGET(state->main_window), "mainbox");
(const char *)iter->data); } else {
for (const GList *iter = list; iter != NULL; iter = g_list_next(iter)) {
rofi_view_add_widget(state, WIDGET(state->main_window),
(const char *)iter->data);
}
g_list_free_full(list, g_free);
} }
g_list_free_full(list, g_free);
if (state->text && input) { if (state->text && input) {
textbox_text(state->text, input); textbox_text(state->text, input);

View file

@ -176,7 +176,9 @@ static void listview_add_widget(listview *lv, _listview_row *row, widget *wid,
} else { } else {
widget *wid2 = (widget *)box_create(wid, label, ROFI_ORIENTATION_VERTICAL); widget *wid2 = (widget *)box_create(wid, label, ROFI_ORIENTATION_VERTICAL);
box_add((box *)wid, WIDGET(wid2), TRUE); box_add((box *)wid, WIDGET(wid2), TRUE);
GList *list = rofi_theme_get_list(WIDGET(wid2), "children", ""); GList *list = rofi_theme_get_list_strings(
WIDGET(wid2),
"children"); // rofi_theme_get_list(WIDGET(wid2), "children", "");
for (GList *iter = g_list_first(list); iter != NULL; for (GList *iter = g_list_first(list); iter != NULL;
iter = g_list_next(iter)) { iter = g_list_next(iter)) {
listview_add_widget(lv, row, wid2, (const char *)iter->data); listview_add_widget(lv, row, wid2, (const char *)iter->data);
@ -188,11 +190,14 @@ static void listview_create_row(listview *lv, _listview_row *row) {
row->box = box_create(WIDGET(lv), "element", ROFI_ORIENTATION_HORIZONTAL); row->box = box_create(WIDGET(lv), "element", ROFI_ORIENTATION_HORIZONTAL);
widget_set_type(WIDGET(row->box), WIDGET_TYPE_LISTVIEW_ELEMENT); widget_set_type(WIDGET(row->box), WIDGET_TYPE_LISTVIEW_ELEMENT);
GList *list = NULL; GList *list = NULL;
if (config.show_icons) { list = rofi_theme_get_list_strings(WIDGET(row->box), "children");
list = rofi_theme_get_list(WIDGET(row->box), "children", if (list == NULL) {
"element-icon,element-text"); if (config.show_icons) {
} else { list = g_list_append(list, g_strdup("element-icon"));
list = rofi_theme_get_list(WIDGET(row->box), "children", "element-text"); list = g_list_append(list, g_strdup("element-text"));
} else {
list = g_list_append(list, g_strdup("element-text"));
}
} }
row->textbox = NULL; row->textbox = NULL;
@ -946,12 +951,6 @@ void listview_set_num_lines(listview *lv, unsigned int num_lines) {
} }
} }
unsigned int listview_get_num_lines(listview *lv) {
if (lv) {
return lv->menu_lines;
}
return 0;
}
void listview_set_max_lines(listview *lv, unsigned int max_lines) { void listview_set_max_lines(listview *lv, unsigned int max_lines) {
if (lv) { if (lv) {
lv->max_displayed_lines = max_lines; lv->max_displayed_lines = max_lines;

View file

@ -162,6 +162,31 @@ static void textbox_initialize_font(textbox *tb) {
} }
} }
static void textbox_tab_stops(textbox *tb) {
GList *dists = rofi_theme_get_list_distance(WIDGET(tb), "tab-stops");
if (dists != NULL) {
PangoTabArray *tabs = pango_tab_array_new(g_list_length(dists), TRUE);
int i = 0, ppx = 0;
for (const GList *iter = g_list_first(dists); iter != NULL;
iter = g_list_next(iter), i++) {
const RofiDistance *dist = iter->data;
int px = distance_get_pixel(*dist, ROFI_ORIENTATION_HORIZONTAL);
if (px <= ppx) {
continue;
}
pango_tab_array_set_tab(tabs, i, PANGO_TAB_LEFT, px);
ppx = px;
}
pango_layout_set_tabs(tb->layout, tabs);
pango_tab_array_free(tabs);
g_list_free_full(dists, g_free);
}
}
textbox *textbox_create(widget *parent, WidgetType type, const char *name, textbox *textbox_create(widget *parent, WidgetType type, const char *name,
TextboxFlags flags, TextBoxFontType tbft, TextboxFlags flags, TextBoxFontType tbft,
const char *text, double xalign, double yalign) { const char *text, double xalign, double yalign) {
@ -185,6 +210,7 @@ textbox *textbox_create(widget *parent, WidgetType type, const char *name,
textbox_font(tb, tbft); textbox_font(tb, tbft);
textbox_initialize_font(tb); textbox_initialize_font(tb);
textbox_tab_stops(tb);
if ((tb->flags & TB_WRAP) == TB_WRAP) { if ((tb->flags & TB_WRAP) == TB_WRAP) {
pango_layout_set_wrap(tb->layout, PANGO_WRAP_WORD_CHAR); pango_layout_set_wrap(tb->layout, PANGO_WRAP_WORD_CHAR);

View file

@ -31,30 +31,15 @@
#include <glib.h> #include <glib.h>
#include <math.h> #include <math.h>
/** Default padding. */
#define WIDGET_DEFAULT_PADDING 0
/** macro for initializing the padding struction. */
#define WIDGET_PADDING_INIT \
{ \
{WIDGET_DEFAULT_PADDING, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL, \
NULL}, \
ROFI_HL_SOLID \
}
void widget_init(widget *wid, widget *parent, WidgetType type, void widget_init(widget *wid, widget *parent, WidgetType type,
const char *name) { const char *name) {
wid->type = type; wid->type = type;
wid->parent = parent; wid->parent = parent;
wid->name = g_strdup(name); wid->name = g_strdup(name);
wid->def_padding = (RofiPadding){WIDGET_PADDING_INIT, WIDGET_PADDING_INIT, wid->def_padding = WIDGET_PADDING_INIT;
WIDGET_PADDING_INIT, WIDGET_PADDING_INIT}; wid->def_border = WIDGET_PADDING_INIT;
wid->def_border = (RofiPadding){WIDGET_PADDING_INIT, WIDGET_PADDING_INIT, wid->def_border_radius = WIDGET_PADDING_INIT;
WIDGET_PADDING_INIT, WIDGET_PADDING_INIT}; wid->def_margin = WIDGET_PADDING_INIT;
wid->def_border_radius =
(RofiPadding){WIDGET_PADDING_INIT, WIDGET_PADDING_INIT,
WIDGET_PADDING_INIT, WIDGET_PADDING_INIT};
wid->def_margin = (RofiPadding){WIDGET_PADDING_INIT, WIDGET_PADDING_INIT,
WIDGET_PADDING_INIT, WIDGET_PADDING_INIT};
wid->padding = rofi_theme_get_padding(wid, "padding", wid->def_padding); wid->padding = rofi_theme_get_padding(wid, "padding", wid->def_padding);
wid->border = rofi_theme_get_padding(wid, "border", wid->def_border); wid->border = rofi_theme_get_padding(wid, "border", wid->def_border);
@ -128,13 +113,6 @@ void widget_set_type(widget *widget, WidgetType type) {
widget->type = type; widget->type = type;
} }
WidgetType widget_type(widget *widget) {
if (widget == NULL) {
return WIDGET_TYPE_UNKNOWN;
}
return widget->type;
}
gboolean widget_enabled(widget *widget) { gboolean widget_enabled(widget *widget) {
if (widget == NULL) { if (widget == NULL) {
return FALSE; return FALSE;
@ -548,8 +526,8 @@ widget *widget_find_mouse_target(widget *wid, WidgetType type, gint x, gint y) {
return NULL; return NULL;
} }
WidgetTriggerActionResult widget_check_action(widget *wid, guint action, WidgetTriggerActionResult widget_check_action(widget *wid, guint action, gint x,
gint x, gint y) { gint y) {
if (wid == NULL) { if (wid == NULL) {
return FALSE; return FALSE;
} }

View file

@ -747,6 +747,10 @@ static int monitor_get_dimension(int monitor_id, workarea *mon) {
} }
// find the dimensions of the monitor displaying point x,y // find the dimensions of the monitor displaying point x,y
static void monitor_dimensions(int x, int y, workarea *mon) { static void monitor_dimensions(int x, int y, workarea *mon) {
if (mon == NULL) {
g_error("%s: mon == NULL", __FUNCTION__);
return;
}
memset(mon, 0, sizeof(workarea)); memset(mon, 0, sizeof(workarea));
mon->w = xcb->screen->width_in_pixels; mon->w = xcb->screen->width_in_pixels;
mon->h = xcb->screen->height_in_pixels; mon->h = xcb->screen->height_in_pixels;
@ -784,7 +788,12 @@ static int pointer_get(xcb_window_t root, int *x, int *y) {
return FALSE; return FALSE;
} }
static int monitor_active_from_winid(xcb_drawable_t id, workarea *mon) { static int monitor_active_from_winid(xcb_drawable_t id, workarea *mon) {
if (mon == NULL) {
g_error("%s: mon == NULL", __FUNCTION__);
return FALSE;
}
xcb_window_t root = xcb->screen->root; xcb_window_t root = xcb->screen->root;
xcb_get_geometry_cookie_t c = xcb_get_geometry(xcb->connection, id); xcb_get_geometry_cookie_t c = xcb_get_geometry(xcb->connection, id);
xcb_get_geometry_reply_t *r = xcb_get_geometry_reply_t *r =
@ -814,6 +823,10 @@ static int monitor_active_from_id_focused(int mon_id, workarea *mon) {
int retv = FALSE; int retv = FALSE;
xcb_window_t active_window; xcb_window_t active_window;
xcb_get_property_cookie_t awc; xcb_get_property_cookie_t awc;
if (mon == NULL) {
g_error("%s: mon == NULL", __FUNCTION__);
return retv;
}
awc = xcb_ewmh_get_active_window(&xcb->ewmh, xcb->screen_nbr); awc = xcb_ewmh_get_active_window(&xcb->ewmh, xcb->screen_nbr);
if (!xcb_ewmh_get_active_window_reply(&xcb->ewmh, awc, &active_window, if (!xcb_ewmh_get_active_window_reply(&xcb->ewmh, awc, &active_window,
NULL)) { NULL)) {
@ -862,7 +875,9 @@ static int monitor_active_from_id_focused(int mon_id, workarea *mon) {
} }
g_debug("mon pos: %d %d %d-%d", mon->x, mon->y, mon->w, mon->h); g_debug("mon pos: %d %d %d-%d", mon->x, mon->y, mon->w, mon->h);
} else if (mon_id == -4) { } else if (mon_id == -4) {
g_debug("Find monitor at location: %d %d", t->dst_x, t->dst_y);
monitor_dimensions(t->dst_x, t->dst_y, mon); monitor_dimensions(t->dst_x, t->dst_y, mon);
g_debug("Monitor found pos: %d %d %d-%d", mon->x, mon->y, mon->w, mon->h);
retv = TRUE; retv = TRUE;
} }
free(t); free(t);
@ -877,6 +892,11 @@ static int monitor_active_from_id_focused(int mon_id, workarea *mon) {
static int monitor_active_from_id(int mon_id, workarea *mon) { static int monitor_active_from_id(int mon_id, workarea *mon) {
xcb_window_t root = xcb->screen->root; xcb_window_t root = xcb->screen->root;
int x, y; int x, y;
if (mon == NULL) {
g_error("%s: mon == NULL", __FUNCTION__);
return FALSE;
}
g_debug("Monitor id: %d", mon_id);
// At mouse position. // At mouse position.
if (mon_id == -3) { if (mon_id == -3) {
if (pointer_get(root, &x, &y)) { if (pointer_get(root, &x, &y)) {
@ -888,19 +908,27 @@ static int monitor_active_from_id(int mon_id, workarea *mon) {
} }
// Focused monitor // Focused monitor
else if (mon_id == -1) { else if (mon_id == -1) {
g_debug("rofi on current monitor");
// Get the current desktop. // Get the current desktop.
unsigned int current_desktop = 0; unsigned int current_desktop = 0;
xcb_get_property_cookie_t gcdc; xcb_get_property_cookie_t gcdc;
gcdc = xcb_ewmh_get_current_desktop(&xcb->ewmh, xcb->screen_nbr); gcdc = xcb_ewmh_get_current_desktop(&xcb->ewmh, xcb->screen_nbr);
if (xcb_ewmh_get_current_desktop_reply(&xcb->ewmh, gcdc, &current_desktop, if (xcb_ewmh_get_current_desktop_reply(&xcb->ewmh, gcdc, &current_desktop,
NULL)) { NULL)) {
g_debug("Found current desktop: %u", current_desktop);
xcb_get_property_cookie_t c = xcb_get_property_cookie_t c =
xcb_ewmh_get_desktop_viewport(&xcb->ewmh, xcb->screen_nbr); xcb_ewmh_get_desktop_viewport(&xcb->ewmh, xcb->screen_nbr);
xcb_ewmh_get_desktop_viewport_reply_t vp; xcb_ewmh_get_desktop_viewport_reply_t vp;
if (xcb_ewmh_get_desktop_viewport_reply(&xcb->ewmh, c, &vp, NULL)) { if (xcb_ewmh_get_desktop_viewport_reply(&xcb->ewmh, c, &vp, NULL)) {
g_debug("Found %d number of desktops", vp.desktop_viewport_len);
if (current_desktop < vp.desktop_viewport_len) { if (current_desktop < vp.desktop_viewport_len) {
g_debug("Found viewport for desktop: %d %d",
vp.desktop_viewport[current_desktop].x,
vp.desktop_viewport[current_desktop].y);
monitor_dimensions(vp.desktop_viewport[current_desktop].x, monitor_dimensions(vp.desktop_viewport[current_desktop].x,
vp.desktop_viewport[current_desktop].y, mon); vp.desktop_viewport[current_desktop].y, mon);
g_debug("Found monitor @: %d %d %dx%d", mon->x, mon->y, mon->w,
mon->h);
xcb_ewmh_get_desktop_viewport_reply_wipe(&vp); xcb_ewmh_get_desktop_viewport_reply_wipe(&vp);
return TRUE; return TRUE;
} }
@ -937,20 +965,42 @@ static int monitor_active_from_id(int mon_id, workarea *mon) {
// determine which monitor holds the active window, or failing that the mouse // determine which monitor holds the active window, or failing that the mouse
// pointer // pointer
gboolean mon_set = FALSE;
workarea mon_cache = {
0,
};
int monitor_active(workarea *mon) { int monitor_active(workarea *mon) {
if (mon == NULL) {
g_error("%s: mon == NULL", __FUNCTION__);
return FALSE;
}
g_debug("Monitor active");
if (mon_set) {
if (mon) {
*mon = mon_cache;
return TRUE;
}
}
if (config.monitor != NULL) { if (config.monitor != NULL) {
g_debug("Monitor lookup by name : %s", config.monitor);
for (workarea *iter = xcb->monitors; iter; iter = iter->next) { for (workarea *iter = xcb->monitors; iter; iter = iter->next) {
if (g_strcmp0(config.monitor, iter->name) == 0) { if (g_strcmp0(config.monitor, iter->name) == 0) {
*mon = *iter; *mon = *iter;
mon_cache = *mon;
mon_set = TRUE;
return TRUE; return TRUE;
} }
} }
} }
g_debug("Monitor lookup by name failed: %s", config.monitor);
// Grab primary. // Grab primary.
if (g_strcmp0(config.monitor, "primary") == 0) { if (g_strcmp0(config.monitor, "primary") == 0) {
for (workarea *iter = xcb->monitors; iter; iter = iter->next) { for (workarea *iter = xcb->monitors; iter; iter = iter->next) {
if (iter->primary) { if (iter->primary) {
*mon = *iter; *mon = *iter;
mon_cache = *mon;
mon_set = TRUE;
return TRUE; return TRUE;
} }
} }
@ -960,6 +1010,8 @@ int monitor_active(workarea *mon) {
xcb_drawable_t win = g_ascii_strtoll(config.monitor + 4, &end, 0); xcb_drawable_t win = g_ascii_strtoll(config.monitor + 4, &end, 0);
if (end != config.monitor) { if (end != config.monitor) {
if (monitor_active_from_winid(win, mon)) { if (monitor_active_from_winid(win, mon)) {
mon_cache = *mon;
mon_set = TRUE;
return TRUE; return TRUE;
} }
} }
@ -971,16 +1023,23 @@ int monitor_active(workarea *mon) {
if (end != config.monitor) { if (end != config.monitor) {
if (mon_id >= 0) { if (mon_id >= 0) {
if (monitor_get_dimension(mon_id, mon)) { if (monitor_get_dimension(mon_id, mon)) {
mon_cache = *mon;
mon_set = TRUE;
return TRUE; return TRUE;
} }
g_warning("Failed to find selected monitor."); g_warning("Failed to find selected monitor.");
} else { } else {
return monitor_active_from_id(mon_id, mon); int val = monitor_active_from_id(mon_id, mon);
mon_cache = *mon;
mon_set = TRUE;
return val;
} }
} }
} }
// Fallback. // Fallback.
monitor_dimensions(0, 0, mon); monitor_dimensions(0, 0, mon);
mon_cache = *mon;
mon_set = TRUE;
return FALSE; return FALSE;
} }
@ -1186,6 +1245,7 @@ static void main_loop_x11_event_handler_view(xcb_generic_event_t *event) {
NK_BINDINGS_KEY_STATE_PRESS); NK_BINDINGS_KEY_STATE_PRESS);
if (text != NULL) { if (text != NULL) {
rofi_view_handle_text(state, text); rofi_view_handle_text(state, text);
g_free(text);
} }
break; break;
} }

View file

@ -350,7 +350,14 @@ static XrmOption xrmOptions[] = {
"combi-hide-mode-prefix", "combi-hide-mode-prefix",
{.snum = &config.combi_hide_mode_prefix}, {.snum = &config.combi_hide_mode_prefix},
NULL, NULL,
"Hide the prefix mode prefix on the combi view.", "Hide the prefix mode prefix on the combi view.**deprecated** use "
"combi-display-format",
CONFIG_DEFAULT},
{xrm_String,
"combi-display-format",
{.str = &config.combi_display_format},
NULL,
"Combi format string. (Supports: mode, text)",
CONFIG_DEFAULT}, CONFIG_DEFAULT},
{xrm_Char, {xrm_Char,
"matching-negate-char", "matching-negate-char",
@ -500,6 +507,25 @@ static void config_parse_cmd_option(XrmOption *option) {
g_free(key); g_free(key);
} }
static gboolean config_parser_form_rasi_format(GString *str, char **tokens,
int count, char *argv,
gboolean string) {
for (int j = 0; j < (count - 1); j++) {
g_string_append_printf(str, "%s { ", tokens[j]);
}
if (string) {
char *esc = g_strescape(argv, NULL);
g_string_append_printf(str, "%s: \"%s\";", tokens[count - 1], esc);
g_free(esc);
} else {
g_string_append_printf(str, "%s: %s;", tokens[count - 1], argv);
}
for (int j = 0; j < (count - 1); j++) {
g_string_append(str, " } ");
}
return TRUE;
}
void config_parse_cmd_options(void) { void config_parse_cmd_options(void) {
for (unsigned int i = 0; i < sizeof(xrmOptions) / sizeof(XrmOption); ++i) { for (unsigned int i = 0; i < sizeof(xrmOptions) / sizeof(XrmOption); ++i) {
XrmOption *op = &(xrmOptions[i]); XrmOption *op = &(xrmOptions[i]);
@ -516,41 +542,53 @@ void config_parse_cmd_options(void) {
extern char **stored_argv; extern char **stored_argv;
for (int in = 1; in < (stored_argc - 1); in++) { for (int in = 1; in < (stored_argc - 1); in++) {
if (stored_argv[in][0] == '-') { if (stored_argv[in][0] == '-') {
if (stored_argv[in + 1][0] == '-') {
continue;
}
/** TODO: This is a hack, and should be fixed in a nicer way. */ /** TODO: This is a hack, and should be fixed in a nicer way. */
char **tokens = g_strsplit(stored_argv[in], "-", 3); char **tokens = g_strsplit(stored_argv[in], "-", 3);
int count = 1; int count = 1;
for (int j = 1; tokens && tokens[j]; j++) { for (int j = 1; tokens && tokens[j]; j++) {
count++; count++;
} }
if (count > 2 && g_strcmp0(tokens[1], "no") != 0) { if (count >= 2) {
GString *str = g_string_new("configuration { "); if (g_str_has_prefix(tokens[1], "theme")) {
for (int j = 1; j < (count - 1); j++) { g_strfreev(tokens);
g_string_append_printf(str, "%s { ", tokens[j]); tokens = g_strsplit(stored_argv[in], "+", 0);
} count = g_strv_length(tokens);
g_string_append_printf(str, "%s: %s;", tokens[count - 1], if (count > 2) {
stored_argv[in + 1]); GString *str = g_string_new("");
for (int j = 0; j < (count - 1); j++) { config_parser_form_rasi_format(str, &(tokens[1]), count - 1,
g_string_append(str, " } "); stored_argv[in + 1], FALSE);
} if (rofi_theme_parse_string(str->str) == 1) {
if (rofi_theme_parse_string(str->str) == 1) { /** Failed to parse, try again as string. */
/** Failed to parse, try again as string. */ g_strfreev(tokens);
rofi_clear_error_messages(); g_string_free(str, TRUE);
g_string_assign(str, "configuration { "); return;
for (int j = 1; j < (count - 1); j++) { }
g_string_append_printf(str, "%s { ", tokens[j]); g_string_free(str, TRUE);
}
char *esc = g_strescape(stored_argv[in + 1], NULL);
g_string_append_printf(str, "%s: \"%s\";", tokens[count - 1], esc);
g_free(esc);
for (int j = 0; j < (count - 1); j++) {
g_string_append(str, " } ");
} }
} else if (g_strcmp0(tokens[1], "no") != 0) {
GString *str = g_string_new("configuration { ");
config_parser_form_rasi_format(str, &(tokens[1]), count - 1,
stored_argv[in + 1], FALSE);
g_string_append(str, "}");
g_debug("str: \"%s\"\n", str->str);
if (rofi_theme_parse_string(str->str) == 1) { if (rofi_theme_parse_string(str->str) == 1) {
/** Failed to parse, try again as string. */ /** Failed to parse, try again as string. */
rofi_clear_error_messages(); rofi_clear_error_messages();
g_string_assign(str, "configuration { ");
config_parser_form_rasi_format(str, &(tokens[1]), count - 1,
stored_argv[in + 1], TRUE);
g_string_append(str, "}");
g_debug("str: \"%s\"\n", str->str);
if (rofi_theme_parse_string(str->str) == 1) {
/** Failed to parse, try again as string. */
rofi_clear_error_messages();
}
} }
g_string_free(str, TRUE);
} }
g_string_free(str, TRUE);
in++; in++;
} }
g_strfreev(tokens); g_strfreev(tokens);
@ -571,10 +609,11 @@ static gboolean __config_parser_set_property(XrmOption *option,
if (p->type == P_LIST) { if (p->type == P_LIST) {
for (GList *iter = p->value.list; iter != NULL; for (GList *iter = p->value.list; iter != NULL;
iter = g_list_next(iter)) { iter = g_list_next(iter)) {
Property *p = (Property *)iter->data;
if (value == NULL) { if (value == NULL) {
value = g_strdup((char *)(iter->data)); value = g_strdup((char *)(p->value.s));
} else { } else {
char *nv = g_strjoin(",", value, (char *)(iter->data), NULL); char *nv = g_strjoin(",", value, (char *)(p->value.s), NULL);
g_free(value); g_free(value);
value = nv; value = nv;
} }
@ -666,7 +705,7 @@ gboolean config_parse_set_property(const Property *p, char **error) {
} }
} }
//*error = g_strdup_printf("Option: %s is not found.", p->name); //*error = g_strdup_printf("Option: %s is not found.", p->name);
g_warning("Option: %s is not found.", p->name); g_debug("Option: %s is not found.", p->name);
for (GList *iter = g_list_first(extra_parsed_options); iter != NULL; for (GList *iter = g_list_first(extra_parsed_options); iter != NULL;
iter = g_list_next(iter)) { iter = g_list_next(iter)) {

View file

@ -25,101 +25,78 @@
* *
*/ */
#include <assert.h>
#include <locale.h>
#include <glib.h>
#include <stdio.h>
#include <helper.h>
#include <string.h>
#include "display.h" #include "display.h"
#include "rofi-icon-fetcher.h"
#include "rofi.h" #include "rofi.h"
#include "settings.h" #include "settings.h"
#include "widgets/textbox.h" #include "widgets/textbox.h"
#include "rofi-icon-fetcher.h" #include <assert.h>
#include <glib.h>
#include <helper.h>
#include <locale.h>
#include <stdio.h>
#include <string.h>
static int test = 0; static int test = 0;
#define TASSERT( a ) { \ #define TASSERT(a) \
assert ( a ); \ { \
printf ( "Test %i passed (%s)\n", ++test, # a ); \ assert(a); \
} printf("Test %i passed (%s)\n", ++test, #a); \
}
#include "theme.h" #include "theme.h"
ThemeWidget *rofi_theme = NULL; ThemeWidget *rofi_theme = NULL;
uint32_t rofi_icon_fetcher_query ( const char *name, const int size ) uint32_t rofi_icon_fetcher_query(const char *name, const int size) { return 0; }
{ uint32_t rofi_icon_fetcher_query_advanced(const char *name, const int wsize,
return 0; const int hsize) {
}
uint32_t rofi_icon_fetcher_query_advanced ( const char *name, const int wsize, const int hsize )
{
return 0; return 0;
} }
cairo_surface_t * rofi_icon_fetcher_get ( const uint32_t uid ) cairo_surface_t *rofi_icon_fetcher_get(const uint32_t uid) { return NULL; }
{
return NULL;
}
void rofi_clear_error_messages ( void ) void rofi_clear_error_messages(void) {}
{
}
gboolean rofi_theme_parse_string ( const char *string ) gboolean rofi_theme_parse_string(const char *string) { return FALSE; }
{ double textbox_get_estimated_char_height(void) { return 12.0; }
return FALSE; void rofi_view_get_current_monitor(int *width, int *height) {
*width = 1920;
*height = 1080;
} }
double textbox_get_estimated_char_height ( void ) double textbox_get_estimated_ch(void) { return 9.0; }
{ void rofi_add_error_message(G_GNUC_UNUSED GString *msg) {}
return 12.0; int rofi_view_error_dialog(const char *msg, G_GNUC_UNUSED int markup) {
} fputs(msg, stderr);
void rofi_view_get_current_monitor ( int *width, int *height ) return TRUE;
{
*width = 1920;
*height = 1080;
}
double textbox_get_estimated_ch ( void )
{
return 9.0;
}
void rofi_add_error_message ( G_GNUC_UNUSED GString *msg )
{
}
int rofi_view_error_dialog ( const char *msg, G_GNUC_UNUSED int markup )
{
fputs ( msg, stderr );
return TRUE;
}
int monitor_active ( G_GNUC_UNUSED workarea *mon )
{
return 0;
} }
int monitor_active(G_GNUC_UNUSED workarea *mon) { return 0; }
void display_startup_notification ( G_GNUC_UNUSED RofiHelperExecuteContext *context, G_GNUC_UNUSED GSpawnChildSetupFunc *child_setup, G_GNUC_UNUSED gpointer *user_data ) void display_startup_notification(
{ G_GNUC_UNUSED RofiHelperExecuteContext *context,
} G_GNUC_UNUSED GSpawnChildSetupFunc *child_setup,
G_GNUC_UNUSED gpointer *user_data) {}
int main ( G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv ) int main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv) {
{ if (setlocale(LC_ALL, "") == NULL) {
if ( setlocale ( LC_ALL, "" ) == NULL ) { fprintf(stderr, "Failed to set locale.\n");
fprintf ( stderr, "Failed to set locale.\n" ); return EXIT_FAILURE;
return EXIT_FAILURE; }
} // Pid test.
// Pid test. // Tests basic functionality of writing it, locking, seeing if I can write
// Tests basic functionality of writing it, locking, seeing if I can write same again // same again And close/reopen it again.
// And close/reopen it again. {
{ const char *tmpd = g_get_tmp_dir();
const char *tmpd = g_get_tmp_dir (); char *path = g_build_filename(tmpd, "rofi-pid.pid", NULL);
char *path = g_build_filename (tmpd, "rofi-pid.pid", NULL); TASSERT(create_pid_file(NULL, FALSE) == -1);
TASSERT ( create_pid_file ( NULL ) == -1 ); int fd = create_pid_file(path, FALSE);
int fd = create_pid_file ( path ); TASSERT(fd >= 0);
TASSERT ( fd >= 0 ); int fd2 = create_pid_file(path, FALSE);
int fd2 = create_pid_file ( path ); TASSERT(fd2 < 0);
TASSERT ( fd2 < 0 );
remove_pid_file ( fd ); remove_pid_file(fd);
fd = create_pid_file ( path ); fd = create_pid_file(path, FALSE);
TASSERT ( fd >= 0 ); TASSERT(fd >= 0);
remove_pid_file ( fd ); remove_pid_file(fd);
free ( path ); free(path);
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -37,7 +37,7 @@ element,element-text,element-icon, button {
inputbar { inputbar {
margin: 0px 0px 0.5em 0em; margin: 0px 0px 0.5em 0em;
spacing: 0.2em; spacing: 0.4em;
children: [ button-iggy1, entry,overlay,case-indicator, button-iggy2]; children: [ button-iggy1, entry,overlay,case-indicator, button-iggy2];
} }
@ -45,6 +45,7 @@ button-iggy1, button-iggy2 {
expand: false; expand: false;
content: "🐢"; content: "🐢";
action: "kb-primary-paste"; action: "kb-primary-paste";
horizontal-align: 0.5;
} }
button-iggy2 { button-iggy2 {
action: "kb-screenshot"; action: "kb-screenshot";
@ -97,9 +98,11 @@ wrapper-mode-switcher {
} }
icon-ms-ic1 { icon-ms-ic1 {
filename: "go-previous"; filename: "go-previous";
action: "kb-mode-previous";
} }
icon-ms-ic2 { icon-ms-ic2 {
filename: "go-next"; filename: "go-next";
action: "kb-mode-next";
} }
icon-ms-ic1,icon-ms-ic2 { icon-ms-ic1,icon-ms-ic2 {
size: 16; size: 16;
@ -133,3 +136,7 @@ button selected.normal {
background-image: linear-gradient(to bottom, darkgreen, black/70%); background-image: linear-gradient(to bottom, darkgreen, black/70%);
} }
entry {
placeholder: "Iggy";
placeholder-color: darkgrey/30%;
}