diff --git a/Changelog b/Changelog index 554394a25..6a3e27145 100644 --- a/Changelog +++ b/Changelog @@ -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! - [Build] Fix building without window mode enabled. - [Config] Do not print out the 'theme' field in configuration on dump. diff --git a/Makefile.am b/Makefile.am index 90447dca1..13e1a9027 100644 --- a/Makefile.am +++ b/Makefile.am @@ -177,11 +177,15 @@ dist_man1_MANS=\ dist_man5_MANS=\ doc/rofi-theme.5\ + doc/rofi-keys.5\ + doc/rofi-dmenu.5\ doc/rofi-script.5 EXTRA_DIST += \ doc/rofi-theme.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-sensible-terminal.1.markdown \ doc/rofi.1.markdown\ @@ -245,11 +249,13 @@ EXTRA_DIST+=\ # 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-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-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-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 ## diff --git a/README.md b/README.md index 6d6eb77f7..fa370c5cf 100644 --- a/README.md +++ b/README.md @@ -188,7 +188,8 @@ Please see the [configuration guide](https://github.com/davatorium/rofi/blob/nex ## 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). @@ -233,3 +234,8 @@ for discussions. * [GitHub Discussions](https://github.com/davatorium/rofi/discussions) * IRC (#rofi on irc.libera.chat) * [Reddit](https://reddit.com/r/qtools/) + + +## Stargazers over time + +[![Stargazers over time](https://starchart.cc/davatorium/rofi.svg)](https://starchart.cc/davatorium/rofi) diff --git a/config/config.c b/config/config.c index 0da445dd6..c846cb32d 100644 --- a/config/config.c +++ b/config/config.c @@ -139,6 +139,7 @@ Settings config = { .plugin_path = PLUGIN_PATH, .max_history_size = 25, .combi_hide_mode_prefix = FALSE, + .combi_display_format = "{mode} {text}", .matching_negate_char = '-', diff --git a/configure.ac b/configure.ac index 590b28747..2ec8644fb 100644 --- a/configure.ac +++ b/configure.ac @@ -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_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_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([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([setjmp.h],, AC_MSG_ERROR("Could not find the setjmp.h header file")) diff --git a/doc/meson.build b/doc/meson.build index 435b15af8..97b1fd66d 100644 --- a/doc/meson.build +++ b/doc/meson.build @@ -5,6 +5,8 @@ if gomd2man.found() 'rofi.1.markdown', 'rofi-theme-selector.1.markdown', 'rofi-theme.5.markdown', + 'rofi-dmenu.5.markdown', + 'rofi-keys.5.markdown', 'rofi-script.5.markdown', 'rofi-sensible-terminal.1.markdown' )] diff --git a/doc/rofi-dmenu.5 b/doc/rofi-dmenu.5 new file mode 100644 index 000000000..297dc3f0e --- /dev/null +++ b/doc/rofi-dmenu.5 @@ -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. diff --git a/doc/rofi-dmenu.5.markdown b/doc/rofi-dmenu.5.markdown new file mode 100644 index 000000000..73ff22359 --- /dev/null +++ b/doc/rofi-dmenu.5.markdown @@ -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 + +Rasmus Steinke + +Quentin Glidic + + +Original code based on work by: Sean Pringle + +For a full list of authors, check the AUTHORS file. diff --git a/doc/rofi-keys.5 b/doc/rofi-keys.5 new file mode 100644 index 000000000..f335e39e7 --- /dev/null +++ b/doc/rofi-keys.5 @@ -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. diff --git a/doc/rofi-keys.5.markdown b/doc/rofi-keys.5.markdown new file mode 100644 index 000000000..6ea5c83b1 --- /dev/null +++ b/doc/rofi-keys.5.markdown @@ -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 + +Rasmus Steinke + +Quentin Glidic + + +Original code based on work by: Sean Pringle + +For a full list of authors, check the AUTHORS file. diff --git a/doc/rofi-script.5 b/doc/rofi-script.5 index f414c1a24..cc409edd5 100644 --- a/doc/rofi-script.5 +++ b/doc/rofi-script.5 @@ -1,4 +1,3 @@ -.nh .TH ROFI\-SCRIPT 5 rofi\-script .SH NAME .PP @@ -194,20 +193,20 @@ rofi(1), rofi\-sensible\-terminal(1), dmenu(1), rofi\-theme(5), rofi\-theme\-sel .SH AUTHOR .PP -Qball Cow qball@gmpclient.org -\[la]mailto:qball@gmpclient.org\[ra] +Qball Cow +\[la]qball@gmpclient.org\[ra] .PP -Rasmus Steinke rasi@xssn.at -\[la]mailto:rasi@xssn.at\[ra] +Rasmus Steinke +\[la]rasi@xssn.at\[ra] .PP -Quentin Glidic sardemff7+rofi@sardemff7.net -\[la]mailto:sardemff7+rofi@sardemff7.net\[ra] +Quentin Glidic +\[la]sardemff7+rofi@sardemff7.net\[ra] .PP -Original code based on work by: Sean Pringle sean.pringle@gmail.com -\[la]mailto:sean.pringle@gmail.com\[ra] +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. diff --git a/doc/rofi-sensible-terminal.1 b/doc/rofi-sensible-terminal.1 index 653dee3ff..30d4a15d7 100644 --- a/doc/rofi-sensible-terminal.1 +++ b/doc/rofi-sensible-terminal.1 @@ -1,4 +1,3 @@ -.nh .TH rofi\-sensible\-terminal 1 rofi\-sensible\-terminal .SH NAME .PP diff --git a/doc/rofi-theme-selector.1 b/doc/rofi-theme-selector.1 index e0f09c31e..de076ff4c 100644 --- a/doc/rofi-theme-selector.1 +++ b/doc/rofi-theme-selector.1 @@ -1,4 +1,3 @@ -.nh .TH rofi\-theme\-selector 1 rofi\-theme\-selector .SH NAME .PP @@ -31,8 +30,8 @@ $XDG\_DATA\_HOME/share/rofi/themes .RE .PP -${PREFIX} reflects the install location of rofi. In most cases this will be "/usr". -$XDG\_CONFIG\_HOME is normally unset. Default path is "$HOME/.config". +${PREFIX} reflects the install location of rofi. In most cases this will be "/usr".
+$XDG\_CONFIG\_HOME is normally unset. Default path is "$HOME/.config".
$XDG\_DATA\_HOME is normally unset. Default path is "$HOME/.local/share". .SH SEE ALSO @@ -41,5 +40,5 @@ rofi(1) .SH AUTHORS .PP -Qball Cow qball@gmpclient.org +Qball Cow qball@gmpclient.org
Rasmus Steinke rasi@xssn.at diff --git a/doc/rofi-theme.5 b/doc/rofi-theme.5 index d08d55db2..07be4cd72 100644 --- a/doc/rofi-theme.5 +++ b/doc/rofi-theme.5 @@ -1,4 +1,3 @@ -.nh .TH ROFI\-THEME 5 rofi\-theme .SH NAME .PP @@ -134,7 +133,7 @@ abbreviation for \fBr\fPofi \fBa\fPdvanced \fBs\fPtyle \fBi\fPnformation. .SH Basic Structure .PP Each element has a section with defined properties. Global properties can be defined in section \fB\fC* { }\fR\&. -Sub\-\§ion names begin with a hash symbol \fB\fC#\fR\&. +Sub\-section names begin with a hash symbol \fB\fC#\fR\&. .PP 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 a list of keywords .IP \(bu 2 +an array of values +.IP \(bu 2 an environment variable .IP \(bu 2 Inherit @@ -491,7 +492,11 @@ The different values are: .IP \(bu 2 \fB\fC{PERCENTAGE}\fR can be between 0\-1.0, or 0%\-100% .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, DarkGoldenRod, DarkGray, DarkGrey, DarkGreen, DarkKhaki, DarkMagenta, DarkOliveGreen, DarkOrange, DarkOrchid, DarkRed, 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; .IP \(bu 2 \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 @@ -723,7 +734,6 @@ style property. .PP When no unit is specified, pixels are assumed. - .RE .SH Position @@ -732,14 +742,22 @@ Indicate a place on the window/monitor. .RS .IP \(bu 2 + +.PP 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 \-\-\-\-\-\-\-\-\-\-\-\-\-|\-\-\-\-\-\-\-\-\-\-\-\-\-|\-\-\-\-\-\-\-\-\-\-\-\- west | center | east \-\-\-\-\-\-\-\-\-\-\-\-\-|\-\-\-\-\-\-\-\-\-\-\-\-\-|\-\-\-\-\-\-\-\-\-\-\-\- south west | south | south east -\fR + +.fi +.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. 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 .RS .IP \(bu 2 @@ -964,6 +992,7 @@ The current widgets available in \fBrofi\fP: .RS .IP \(bu 2 \fB\fCwindow\fR + .RS .IP \(bu 2 \fB\fCoverlay\fR: the overlay widget. @@ -971,6 +1000,7 @@ The current widgets available in \fBrofi\fP: \fB\fCmainbox\fR: The mainbox box. .IP \(bu 2 \fB\fCinputbar\fR: The input bar box. + .RS .IP \(bu 2 \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. .RE - .IP \(bu 2 \fB\fClistview\fR: The listview. + .RS .IP \(bu 2 \fB\fCscrollbar\fR: the listview scrollbar .IP \(bu 2 \fB\fCelement\fR: a box in the listview holding the entries + .RS .IP \(bu 2 \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 - .IP \(bu 2 \fB\fCmode\-switcher\fR: the main horizontal @box packing the buttons. + .RS .IP \(bu 2 \fB\fCbutton\fR: the buttons @textbox for each mode .RE - .IP \(bu 2 \fB\fCmessage\fR: The container holding the textbox. + .RS .IP \(bu 2 \fB\fCtextbox\fR: the message textbox .RE - .RE - .RE .PP @@ -1134,9 +1162,13 @@ Type of mouse cursor that is set when the mouse pointer is hovered over the widg .SS window: .RS .IP \(bu 2 + +.PP \fBfont\fP: string The font used in the window .IP \(bu 2 + +.PP \fBtransparency\fP: string Indicating if transparency should be used and what type: \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. \fBPath\fP to png file \- Use an image. .IP \(bu 2 + +.PP \fBlocation\fP: position The place of the anchor on the monitor .IP \(bu 2 + +.PP \fBanchor\fP: anchor The anchor position on the window .IP \(bu 2 + +.PP \fBfullscreen\fP: boolean Window is fullscreen. .IP \(bu 2 + +.PP \fBwidth\fP: distance The width of the window .IP \(bu 2 + +.PP \fBx\-offset\fP: distance .IP \(bu 2 + +.PP \fBy\-offset\fP: distance 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). .IP \(bu 2 \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 @@ -1655,15 +1704,15 @@ More dynamic spacing can be achieved by adding dummy widgets, for example to mak .RS .nf -|\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| -| |\-\-\-\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-\-\-\-| | -| | dummy | | child | | dummy | | -| | expand: y | | | | expand: y | | -| | | | | | | | -| | | | | | | | -| | | | | | | | -| |\-\-\-\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-\-\-\-| | -|\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| +|\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| +| |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| | +| | dummy | | child | | dummy | | +| | expand: true; | | | | expand: true; | | +| | | | | | | | +| | | | | | | | +| | | | | | | | +| |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-| |\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| | +|\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-| .fi .RE @@ -1713,6 +1762,18 @@ rofi \-theme\-str 'window { fullscreen:true;}' \-show run .fi .RE +.PP +Another syntax to modify theme properties is: + +.PP +.RS + +.nf +rofi \-theme+window+fullscreen true \-show run + +.fi +.RE + .PP To print the current theme, run: diff --git a/doc/rofi-theme.5.markdown b/doc/rofi-theme.5.markdown index f18224497..11b0d4246 100644 --- a/doc/rofi-theme.5.markdown +++ b/doc/rofi-theme.5.markdown @@ -216,6 +216,7 @@ The current theme format supports different types: * an orientation * a cursor * a list of keywords + * an array of values * an environment variable * Inherit @@ -409,6 +410,9 @@ It supports the following operations: * `%` : Multiply * `min` : Minimum 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. @@ -447,6 +451,7 @@ style property. > When no unit is specified, pixels are assumed. + ## Position 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. 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 * Format: `${:alnum:}` @@ -757,6 +768,10 @@ The following properties are currently supported: * **placeholder-color**: Color of the placeholder text. * **blink**: Enable/Disable blinking on an input textbox (Boolean). * **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: * **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 ``` +Another syntax to modify theme properties is: + +```bash +rofi -theme+window+fullscreen true -show run +``` + To print the current theme, run: ``` diff --git a/doc/rofi.1 b/doc/rofi.1 index 05d6a2baf..97612d093 100644 --- a/doc/rofi.1 +++ b/doc/rofi.1 @@ -1,4 +1,3 @@ -.nh .TH ROFI 1 rofi .SH NAME .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 between windows, start applications or log into a remote machine via \fB\fCssh\fR\&. There are different \fImodi\fP for different types of actions. - -.PP -\fBrofi\fP can also function as (drop\-in) replacement for \fBdmenu(1)\fP\&. +\fBrofi\fP is a standalone application and should not be integrated into scripts. +For integration into scripts it has a special mode that functions as a +(drop\-in) replacement for \fBdmenu(1)\fP\&. See emulating dmenu below. .SS Running rofi .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. .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). +For more information see \fBrofi\-dmenu(5)\fP\&. .SS Display Error message .PP @@ -181,7 +174,11 @@ Specify the number of threads \fBrofi\fP should use: .IP \(bu 2 1: Disable threading .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 @@ -461,7 +458,11 @@ The different fields are: .IP \(bu 2 \fBcomment\fP: the application comment .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 @@ -534,7 +535,11 @@ The different fields are: .IP \(bu 2 \fBdesktop\fP: window's current desktop .IP \(bu 2 -\fBall\fP: all the aboveDefault: \fIall\fP + +.PP +\fBall\fP: all the above +.PP +Default: \fIall\fP .RE @@ -667,7 +672,11 @@ behavior.) .IP \(bu 2 \fB\-4\fP: the monitor with the focused window. .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 @@ -911,253 +920,70 @@ 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. For that case, \fB\fC#\fR can be used as a separator. -.SS History and Sorting -.PP -\fB\fC\-disable\-history\fR -\fB\fC\-no\-disable\-history\fR (re\-enable history) - .PP -Disable history +\fB\fC\-combi\-display\-format\fR .PP -\fB\fC\-sort\fR to enable -\fB\fC\-no\-sort\fR to disable - -.PP -Enable, disable sorting. -This setting can be changed at runtime (see \fB\fC\-kb\-toggle\-sort\fR). - -.PP -\fB\fC\-sorting\-method\fR 'method' to specify the sorting method. - -.PP -There are 2 sorting methods: +The format string for entries in the \fB\fCcombi\fR dialog: .RS .IP \(bu 2 -levenshtein (Default) +\fBmode\fP: the mode display name .IP \(bu 2 -fzf sorting. +\fBtext\fP: the entry text .RE .PP -\fB\fC\-max\-history\-size\fR \fInumber\fP - -.PP -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. +Pango markup can be used to formatting the output. .PP .RS .nf -rofi \-dmenu \-l 25 +Default: {mode} {text} .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. +Note: This setting is ignored if \fB\fCcombi\-hide\-mode\-prefix\fR is eanbled. +.SS History and Sorting .PP -\fB\fC\-only\-match\fR +\fB\fC\-disable\-history\fR +\fB\fC\-no\-disable\-history\fR (re\-enable history) .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. +Disable history .PP -\fB\fC\-no\-custom\fR +\fB\fC\-sort\fR to enable +\fB\fC\-no\-sort\fR to disable .PP -Only return a selected item, do not allow custom entry. -This mode returns directly when no entries given. +Enable, disable sorting. +This setting can be changed at runtime (see \fB\fC\-kb\-toggle\-sort\fR). .PP -\fB\fC\-format\fR \fIformat\fP +\fB\fC\-sorting\-method\fR 'method' to specify the sorting method. .PP -Allows the output of dmenu to be customized (N is the total number of input entries): +There are 2 sorting methods: .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) +levenshtein (Default) .IP \(bu 2 -\&'F' quoted filter string (user input) +fzf sorting. .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 +\fB\fC\-max\-history\-size\fR \fInumber\fP .PP -Set ellipsize mode to start. So, the end of the string is visible. +Maximum number of entries to store in history. Defaults to 25. (WARNING: can cause slowdowns when set too high) .SS Message dialog .PP @@ -1165,7 +991,7 @@ Set ellipsize mode to start. So, the end of the string is visible. .PP 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 .PP @@ -1220,6 +1046,12 @@ Command to open a Desktop Entry that is a Link. .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. +.PP +\fB\fC\-replace\fR + +.PP +If rofi is already running, based on pid file, try to kill that instance. + .PP \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 \fB\fC{host}\fR: the host to connect to .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 \fB\fC{ssh\-client}\fR: the configured ssh client (see \-ssh\-client) .IP \(bu 2 @@ -1270,20 +1102,6 @@ To launch commands (for example, when using the ssh launcher), the user can ente .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 .PP Please see \fBrofi\-theme(5)\fP manpage for more information on theming. @@ -1418,6 +1236,9 @@ configuration { .fi .RE +.PP +For a full list of bindings, see the \fBrofi\-keys(5)\fP manpage. + .SH Available Modi .SS window .PP @@ -1540,6 +1361,21 @@ The indicator shows: .fi .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 .PP Some basic usage examples of \fBrofi\fP: @@ -1779,26 +1615,26 @@ first. .SH SEE ALSO .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 .RS .IP \(bu 2 -Qball Cow qball@blame.services -\[la]mailto:qball@blame.services\[ra] +Qball Cow +\[la]qball@blame.services\[ra] .IP \(bu 2 -Rasmus Steinke rasi@xssn.at -\[la]mailto:rasi@xssn.at\[ra] +Rasmus Steinke +\[la]rasi@xssn.at\[ra] .IP \(bu 2 -Quentin Glidic sardemff7+rofi@sardemff7.net -\[la]mailto:sardemff7+rofi@sardemff7.net\[ra] +Quentin Glidic +\[la]sardemff7+rofi@sardemff7.net\[ra] .RE .PP Original code based on work by: Sean Pringle -\[la]https://github.com/seanpringle/simpleswitcher\[ra] sean.pringle@gmail.com -\[la]mailto:sean.pringle@gmail.com\[ra] +\[la]https://github.com/seanpringle/simpleswitcher\[ra] +\[la]sean.pringle@gmail.com\[ra] .PP For a full list of authors, check the \fB\fCAUTHORS\fR file. diff --git a/doc/rofi.1.markdown b/doc/rofi.1.markdown index 48e5ff5fd..bfb8c673e 100644 --- a/doc/rofi.1.markdown +++ b/doc/rofi.1.markdown @@ -21,8 +21,9 @@ filter, tokenized search and more. **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`. There are different *modi* for different types of actions. - -**rofi** can also function as (drop-in) replacement for **dmenu(1)**. +**rofi** is a standalone application and should not be integrated into scripts. +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 @@ -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. -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). +For more information see **rofi-dmenu(5)**. ### 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. 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 `-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) -### 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 @@ -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. +`-replace` + +If rofi is already running, based on pid file, try to kill that instance. + `-display-{mode}` *string* 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: * `{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) * `{cmd}`: the command to execute * `{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 @@ -867,6 +750,7 @@ configuration { } ``` +For a full list of bindings, see the **rofi-keys(5)** manpage. ## Available Modi @@ -974,6 +858,15 @@ The indicator shows: `+` Case insensitive and Sorting 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 Some basic usage examples of **rofi**: @@ -1103,7 +996,7 @@ first. ## 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 diff --git a/doc/test_xr.txt b/doc/test_xr.txt index b5308dc00..7884be844 100644 --- a/doc/test_xr.txt +++ b/doc/test_xr.txt @@ -120,6 +120,8 @@ rofi.scroll-method: 0 ! rofi.max-history-size: 25 ! "Hide the prefix mode prefix on the combi view." Set from: Default ! 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 ! rofi.matching-negate-char: - ! "Directory where history and temporary files are stored." Set from: Default diff --git a/include/dialogs/dmenu.h b/include/dialogs/dmenu.h index c816fe2c9..2b030e17f 100644 --- a/include/dialogs/dmenu.h +++ b/include/dialogs/dmenu.h @@ -40,7 +40,7 @@ * * @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. diff --git a/include/dialogs/script.h b/include/dialogs/script.h index 403866be8..f0418c8f7 100644 --- a/include/dialogs/script.h +++ b/include/dialogs/script.h @@ -45,7 +45,7 @@ * * @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 @@ -54,6 +54,6 @@ Mode *script_switcher_parse_setup(const char *str); * * @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 diff --git a/include/helper.h b/include/helper.h index 6de3c74c0..12ed0f70e 100644 --- a/include/helper.h +++ b/include/helper.h @@ -149,10 +149,11 @@ int execute_generator(const char *cmd) __attribute__((nonnull)); /** * @param pidfile The pidfile to create. + * @param kill Try killing running instance. * * 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 @@ -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); -/** - * @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 plen Pattern length. diff --git a/include/rofi-types.h b/include/rofi-types.h index 49ea42c6f..48de8f781 100644 --- a/include/rofi-types.h +++ b/include/rofi-types.h @@ -103,6 +103,9 @@ typedef enum { ROFI_DISTANCE_MODIFIER_GROUP, ROFI_DISTANCE_MODIFIER_MIN, ROFI_DISTANCE_MODIFIER_MAX, + ROFI_DISTANCE_MODIFIER_ROUND, + ROFI_DISTANCE_MODIFIER_FLOOR, + ROFI_DISTANCE_MODIFIER_CEIL, } RofiDistanceModifier; typedef struct RofiDistanceUnit { diff --git a/include/settings.h b/include/settings.h index d3b5f3a2a..3e15a1ea6 100644 --- a/include/settings.h +++ b/include/settings.h @@ -162,6 +162,8 @@ typedef struct { /** Maximum history length per mode. */ unsigned int max_history_size; gboolean combi_hide_mode_prefix; + /** Combi format display */ + char *combi_display_format; char matching_negate_char; diff --git a/include/theme.h b/include/theme.h index 729a8264a..d8d7a6e6d 100644 --- a/include/theme.h +++ b/include/theme.h @@ -392,24 +392,6 @@ ThemeWidget *rofi_config_find_widget(const char *name, const char *state, Property *rofi_theme_find_property(ThemeWidget *widget, PropertyType type, 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. */ @@ -459,4 +441,23 @@ RofiDistance rofi_theme_property_copy_distance(RofiDistance const distance); */ 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 diff --git a/include/widgets/listview.h b/include/widgets/listview.h index 9b551f2bb..f7ebec665 100644 --- a/include/widgets/listview.h +++ b/include/widgets/listview.h @@ -214,15 +214,6 @@ void listview_set_multi_select(listview *lv, gboolean enable); */ 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. * diff --git a/include/widgets/widget-internal.h b/include/widgets/widget-internal.h index 91c3a8d97..f7b7c25ff 100644 --- a/include/widgets/widget-internal.h +++ b/include/widgets/widget-internal.h @@ -29,6 +29,28 @@ #define WIDGET_INTERNAL_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 */ diff --git a/include/widgets/widget.h b/include/widgets/widget.h index d8ba7c151..bc2db6291 100644 --- a/include/widgets/widget.h +++ b/include/widgets/widget.h @@ -136,14 +136,6 @@ int widget_intersect(const widget *widget, int x, int 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 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 */ -WidgetTriggerActionResult widget_check_action(widget *wid, guint action, - gint x, gint y); +WidgetTriggerActionResult widget_check_action(widget *wid, guint action, gint x, + gint y); /** * @param wid The widget handle diff --git a/lexer/theme-lexer.l b/lexer/theme-lexer.l index e9b8e99f6..de2eeb673 100644 --- a/lexer/theme-lexer.l +++ b/lexer/theme-lexer.l @@ -161,7 +161,7 @@ static double rofi_theme_parse_convert_hex ( char high, char low) ASC [\x00-\x7f] ASCN [\x00-\t\v-\x7f] -ASCNP [\x00-\t\v-\x21\x23-\x7f] +ASCNP [\x00-\t\v-\x21\x23-\x7f] U [\x80-\xbf] U2 [\xc2-\xdf] U3 [\xe0-\xef] @@ -176,6 +176,7 @@ UANYNP {ASCNP}|{U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} WHITESPACE [[:blank:]] WSO [[:blank:]]* WORD [[:alnum:]-]+ +WORD_ELEMENT [[:alpha:]][[:alnum:]-]* WORD_ENV [[:alpha:]_][[:alnum:]_]* MEDIA_NAME [[:alpha:]-]+ COLOR_NAME [[:alpha:]]+ @@ -202,6 +203,9 @@ MODIFIER_SUBTRACT - MODIFIER_MULTIPLY \* MODIFIER_MIN (min) MODIFIER_MAX (max) +MODIFIER_ROUND (round) +MODIFIER_FLOOR (floor) +MODIFIER_CEIL (ceil) /* Position */ CENTER (?i:center) @@ -293,7 +297,7 @@ CONFIGURATION (?i:configuration) %x PROPERTIES_VAR %x PROPERTIES_ENV_VAR %x PROPERTIES_VAR_DEFAULT -%x PROPERTIES_LIST +%x PROPERTIES_ARRAY %x NAMESTR %x SECTION %x DEFAULTS @@ -489,21 +493,22 @@ if ( queue == NULL ) { /* Alias color to text-color */
"color" { yylval->sval = g_strdup("text-color"); return T_PROP_NAME;}
{WORD} { yylval->sval = g_strdup(yytext); return T_PROP_NAME;} -{WORD} { yylval->sval = g_strdup(yytext); return T_NAME_ELEMENT;} +{WORD_ELEMENT} { yylval->sval = g_strdup(yytext); return T_NAME_ELEMENT;} /* After Namestr/Classstr we want to go to state str, then to { */ {WHITESPACE}+ ; // ignore all whitespace -{WHITESPACE}+ ; // ignore all whitespace +{WHITESPACE}+ ; // ignore all whitespace
":" { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(PROPERTIES); return T_PSEP; } ";" { BEGIN(GPOINTER_TO_INT ( g_queue_pop_head ( queue ))); return T_PCLOSE;} -(true|false) { yylval->bval= g_strcmp0(yytext, "true") == 0; return T_BOOLEAN;} -{PNNUMBER}\.{NUMBER}+ { yylval->fval = g_ascii_strtod(yytext, NULL); return T_DOUBLE;} -{PNNUMBER} { yylval->ival = (int)g_ascii_strtoll(yytext, NULL, 10); return T_INT;} -{STRING} { yytext[yyleng-1] = '\0'; yylval->sval = g_strcompress(&yytext[1]); return T_STRING;} -{CHAR} { yytext[yyleng-1] = '\0'; yylval->cval = g_strcompress(&yytext[1])[0]; return T_CHAR;} - -@{WORD} { +(true|false) { yylval->bval= g_strcmp0(yytext, "true") == 0; return T_BOOLEAN;} +{PNNUMBER}\.{NUMBER}+ { yylval->fval = g_ascii_strtod(yytext, NULL); return T_DOUBLE;} +{PNNUMBER} { yylval->ival = (int)g_ascii_strtoll(yytext, NULL, 10); return T_INT;} +{STRING} { yytext[yyleng-1] = '\0'; yylval->sval = g_strcompress(&yytext[1]); return T_STRING;} +{STRING_LIST} { yytext[yyleng-1] = '\0'; yylval->sval = g_strcompress(&yytext[1]); return T_STRING;} +{CHAR} { yytext[yyleng-1] = '\0'; yylval->cval = g_strcompress(&yytext[1])[0]; return T_CHAR;} + +@{WORD} { yylval->sval = g_strdup(yytext+1); return T_LINK; } @@ -516,23 +521,26 @@ if ( queue == NULL ) { return T_BOPEN; } -{EM} { return T_UNIT_EM; } -{CH} { return T_UNIT_CH; } -{PX} { return T_UNIT_PX; } -{MM} { return T_UNIT_MM; } -{PERCENT} { return T_PERCENT; } -{LS_SOLID} { return T_SOLID; } -{LS_DASH} { return T_DASH; } - -{INHERIT} { return T_INHERIT; } -{MODIFIER_ADD} { return T_MODIFIER_ADD; } -{MODIFIER_SUBTRACT} { return T_MODIFIER_SUBTRACT; } -{MODIFIER_MULTIPLY} { return T_MODIFIER_MULTIPLY; } -{MODIFIER_MIN} { return T_MODIFIER_MIN; } -{MODIFIER_MAX} { return T_MODIFIER_MAX; } -{CALC} { return T_CALC; } - -{ENV} { +{EM} { return T_UNIT_EM; } +{CH} { return T_UNIT_CH; } +{PX} { return T_UNIT_PX; } +{MM} { return T_UNIT_MM; } +{PERCENT} { return T_PERCENT; } +{LS_SOLID} { return T_SOLID; } +{LS_DASH} { return T_DASH; } + +{INHERIT} { return T_INHERIT; } +{MODIFIER_ADD} { return T_MODIFIER_ADD; } +{MODIFIER_SUBTRACT} { return T_MODIFIER_SUBTRACT; } +{MODIFIER_MULTIPLY} { return T_MODIFIER_MULTIPLY; } +{MODIFIER_MIN} { return T_MODIFIER_MIN; } +{MODIFIER_MAX} { return T_MODIFIER_MAX; } +{MODIFIER_ROUND} { return T_MODIFIER_ROUND; } +{MODIFIER_FLOOR} { return T_MODIFIER_FLOOR; } +{MODIFIER_CEIL} { return T_MODIFIER_CEIL; } +{CALC} { return T_CALC; } + +{ENV} { yytext[yyleng-1] = '\0'; const char *val = g_getenv(yytext+2); if ( val ) { @@ -664,47 +672,47 @@ if ( queue == NULL ) { } {S_T_PARENT_LEFT} { return T_PARENT_LEFT; } {S_T_PARENT_RIGHT} { return T_PARENT_RIGHT; } -{COMMA} { return T_COMMA; } +{COMMA} { return T_COMMA; } {LIST_OPEN} { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); - BEGIN(PROPERTIES_LIST); + BEGIN(PROPERTIES_ARRAY); return T_LIST_OPEN; } -{LIST_CLOSE} { +{LIST_CLOSE} { BEGIN(GPOINTER_TO_INT(g_queue_pop_head ( queue ))); return T_LIST_CLOSE; } -{FORWARD_SLASH} { return T_FORWARD_SLASH; } +{FORWARD_SLASH} { return T_FORWARD_SLASH; } /* Position */ -{CENTER} { return T_POS_CENTER; } -{EAST} { return T_POS_EAST; } -{WEST} { return T_POS_WEST; } -{SOUTH} { return T_POS_SOUTH; } -{NORTH} { return T_POS_NORTH; } +{CENTER} { return T_POS_CENTER; } +{EAST} { return T_POS_EAST; } +{WEST} { return T_POS_WEST; } +{SOUTH} { return T_POS_SOUTH; } +{NORTH} { return T_POS_NORTH; } /* Highlight style */ -{NONE} { return T_NONE; } -{BOLD} { return T_BOLD; } -{ITALIC} { return T_ITALIC; } -{UNDERLINE} { return T_UNDERLINE; } -{STRIKETHROUGH} { return T_STRIKETHROUGH; } -{SMALLCAPS} { return T_SMALLCAPS; } - -{ANGLE_DEG} { return T_ANGLE_DEG; } -{ANGLE_RAD} { return T_ANGLE_RAD; } -{ANGLE_GRAD} { return T_ANGLE_GRAD; } -{ANGLE_TURN} { return T_ANGLE_TURN; } - -{ORIENTATION_HORI} { return ORIENTATION_HORI; } -{ORIENTATION_VERT} { return ORIENTATION_VERT; } - -{CURSOR_DEF} { return CURSOR_DEF; } -{CURSOR_PTR} { return CURSOR_PTR; } -{CURSOR_TXT} { return CURSOR_TXT; } - -{COLOR_TRANSPARENT} { +{NONE} { return T_NONE; } +{BOLD} { return T_BOLD; } +{ITALIC} { return T_ITALIC; } +{UNDERLINE} { return T_UNDERLINE; } +{STRIKETHROUGH} { return T_STRIKETHROUGH; } +{SMALLCAPS} { return T_SMALLCAPS; } + +{ANGLE_DEG} { return T_ANGLE_DEG; } +{ANGLE_RAD} { return T_ANGLE_RAD; } +{ANGLE_GRAD} { return T_ANGLE_GRAD; } +{ANGLE_TURN} { return T_ANGLE_TURN; } + +{ORIENTATION_HORI} { return ORIENTATION_HORI; } +{ORIENTATION_VERT} { return ORIENTATION_VERT; } + +{CURSOR_DEF} { return CURSOR_DEF; } +{CURSOR_PTR} { return CURSOR_PTR; } +{CURSOR_TXT} { return CURSOR_TXT; } + +{COLOR_TRANSPARENT} { return T_COLOR_TRANSPARENT; } -{COLOR_NAME} { +{COLOR_NAME} { for ( unsigned int iter = 0; iter < num_CSSColors; iter++) { if ( strcasecmp(yytext, CSSColors[iter].name )== 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. * This makes include,theme, configuration a reserved keyword. */ -{WORD} { +{WORD_ELEMENT} { g_queue_push_head ( queue, GINT_TO_POINTER (YY_START) ); BEGIN(NAMESTR); yylval->sval = g_strdup(yytext); @@ -815,17 +823,12 @@ if ( queue == NULL ) { fprintf(stderr,"section found: |%s|\n", yytext); return T_ERROR_SECTION; } -{WORD} { +{WORD_ELEMENT} { yylval->sval = g_strdup(yytext); return T_ELEMENT; } -{STRING_LIST} { - yytext[yyleng-1] = '\0'; - yylval->sval = g_strdup(yytext+1); - return T_ELEMENT; -} -. { +. { yytext[yyleng-1] = '\0'; return T_ERROR_PROPERTY; } @@ -867,16 +870,14 @@ gboolean rofi_theme_parse_file ( const char *file ) yyin = NULL; while ( (po = g_queue_pop_head ( file_queue ) )) { - if ( po ) { - if ( po->type == PT_FILE ) { - fclose ( po->filein ); - } - if ( po->type == PT_STRING_ALLOC ) { - g_free( po->malloc_str); - } - g_free ( po->filename ); - g_free ( po ); - } + if ( po->type == PT_FILE ) { + fclose ( po->filein ); + } + if ( po->type == PT_STRING_ALLOC ) { + g_free( po->malloc_str); + } + g_free ( po->filename ); + g_free ( po ); } // Free up. g_queue_free ( file_queue ); @@ -904,16 +905,14 @@ gboolean rofi_theme_parse_string ( const char *string ) yylex_destroy (); while ( (po = g_queue_pop_head ( file_queue ) )) { - if ( po ) { - if ( po->type == PT_FILE ) { - fclose ( po->filein ); - } - if ( po->type == PT_STRING_ALLOC ) { - g_free( po->malloc_str); - } - g_free ( po->filename ); - g_free ( po ); - } + if ( po->type == PT_FILE ) { + fclose ( po->filein ); + } + if ( po->type == PT_STRING_ALLOC ) { + g_free( po->malloc_str); + } + g_free ( po->filename ); + g_free ( po ); } // Free up. g_queue_free ( file_queue ); diff --git a/lexer/theme-parser.y b/lexer/theme-parser.y index d149f05b1..c33aeee94 100644 --- a/lexer/theme-parser.y +++ b/lexer/theme-parser.y @@ -231,6 +231,7 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b ) %token T_OPTIONAL_COMMA "Optional comma separator (',')" %token T_FORWARD_SLASH "forward slash ('/')" %token T_PERCENT "Percent sign ('%')" + %token T_LIST_OPEN "List open ('[')" %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_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" @@ -649,8 +653,18 @@ t_property_element_list_optional ; 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 { + 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 ); } ; @@ -801,6 +815,24 @@ t_property_distance_unit_math3 $$->right = $3; $$->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 { $$ = $1; }; diff --git a/meson.build b/meson.build index 663b1fe8a..0e81cb072 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('rofi', 'c', - version: '1.7.2+wayland1-dev', + version: '1.7.3+wayland1', meson_version: '>=0.47.0', license: [ 'MIT' ], default_options: [ @@ -297,6 +297,8 @@ install_man( 'doc/rofi-sensible-terminal.1', 'doc/rofi-script.5', 'doc/rofi-theme.5', + 'doc/rofi-dmenu.5', + 'doc/rofi-keys.5', ) install_data( diff --git a/releasenotes/1.7.3/release-1.7.3.markdown b/releasenotes/1.7.3/release-1.7.3.markdown new file mode 100644 index 000000000..762fbca2b --- /dev/null +++ b/releasenotes/1.7.3/release-1.7.3.markdown @@ -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. diff --git a/source/dialogs/combi.c b/source/dialogs/combi.c index 354a23f6f..b0c448d7f 100644 --- a/source/dialogs/combi.c +++ b/source/dialogs/combi.c @@ -35,6 +35,7 @@ #include #include "mode-private.h" +#include "widgets/textbox.h" #include #include #include @@ -68,7 +69,7 @@ static void combi_mode_parse_switchers(Mode *sw) { for (char *token = strtok_r(switcher_str, sep, &savept); token != NULL; token = strtok_r(NULL, sep, &savept)) { /* 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); continue; } @@ -83,7 +84,7 @@ static void combi_mode_parse_switchers(Mode *sw) { continue; } // If not build in, use custom switchers. - mode = script_switcher_parse_setup(token); + mode = script_mode_parse_setup(token); if (mode != NULL) { pd->switchers[pd->num_switchers].disable = FALSE; 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], state, attr_list, TRUE); const char *dname = mode_get_display_name(pd->switchers[i].mode); + 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); if (attr_list != NULL) { diff --git a/source/dialogs/dmenu.c b/source/dialogs/dmenu.c index ee1b7ab7f..ebfb810b7 100644 --- a/source/dialogs/dmenu.c +++ b/source/dialogs/dmenu.c @@ -545,7 +545,7 @@ static void dmenu_print_results(DmenuModePrivateData *pd, const char *input) { if (pd->selected_line != UINT32_MAX) { cmd = cmd_list[pd->selected_line].entry; } - if ( cmd ) { + if (cmd) { 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); MenuFlags menu_flags = MENU_NORMAL; DmenuModePrivateData *pd = (DmenuModePrivateData *)dmenu_mode.private_data; diff --git a/source/dialogs/script.c b/source/dialogs/script.c index b7751f53a..67997757e 100644 --- a/source/dialogs/script.c +++ b/source/dialogs/script.c @@ -28,8 +28,8 @@ /** The log domain of this dialog. */ #define G_LOG_DOMAIN "Dialogs.Script" -#include "config.h" #include "dialogs/script.h" +#include "config.h" #include "helper.h" #include "rofi.h" #include @@ -202,20 +202,22 @@ static DmenuScriptEntry *execute_executor(Mode *sw, char *arg, actual_size += 256; retv = g_realloc(retv, (actual_size) * sizeof(DmenuScriptEntry)); } - size_t buf_length = strlen(buffer) + 1; - retv[(*length)].entry = g_memdup(buffer, buf_length); - retv[(*length)].icon_name = NULL; - retv[(*length)].meta = NULL; - retv[(*length)].info = NULL; - retv[(*length)].icon_fetch_uid = 0; - retv[(*length)].nonselectable = FALSE; - if (buf_length > 0 && (read_length > (ssize_t)buf_length)) { - dmenuscript_parse_entry_extras(sw, &(retv[(*length)]), - buffer + buf_length, - read_length - buf_length); + if (retv) { + size_t buf_length = strlen(buffer) + 1; + retv[(*length)].entry = g_memdup(buffer, buf_length); + retv[(*length)].icon_name = NULL; + retv[(*length)].meta = NULL; + retv[(*length)].info = NULL; + retv[(*length)].icon_fetch_uid = 0; + retv[(*length)].nonselectable = FALSE; + if (buf_length > 0 && (read_length > (ssize_t)buf_length)) { + dmenuscript_parse_entry_extras(sw, &(retv[(*length)]), + buffer + buf_length, + read_length - buf_length); + } + retv[(*length) + 1].entry = NULL; + (*length)++; } - retv[(*length) + 1].entry = NULL; - (*length)++; } } if (buffer) { @@ -420,7 +422,7 @@ script_get_icon(const Mode *sw, unsigned int selected_line, int height) { } #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)); char *endp = NULL; char *parse = g_strdup(str); @@ -458,6 +460,6 @@ Mode *script_switcher_parse_setup(const char *str) { return NULL; } -gboolean script_switcher_is_valid(const char *token) { +gboolean script_mode_is_valid(const char *token) { return strchr(token, ':') != NULL; } diff --git a/source/helper.c b/source/helper.c index d66c1106b..559fdbd87 100644 --- a/source/helper.c +++ b/source/helper.c @@ -535,7 +535,7 @@ int execute_generator(const char *cmd) { return fd; } -int create_pid_file(const char *pidfile) { +int create_pid_file(const char *pidfile, gboolean kill_running) { if (pidfile == NULL) { return -1; } @@ -558,6 +558,26 @@ int create_pid_file(const char *pidfile) { if (retv != 0) { g_warning("Failed to set lock on pidfile: Rofi already running?"); 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); return -1; } @@ -680,23 +700,6 @@ int config_sanity_check(void) { } #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: %s at size %d\n", - fam ? fam : "{unknown}", size); - config.menu_font = NULL; - found_error = TRUE; - } - pango_font_description_free(pfd); - } - if (g_strcmp0(config.monitor, "-3") == 0) { // On -3, set to location 1. config.location = 1; @@ -786,15 +789,6 @@ char *rofi_latin_to_utf8_strdup(const char *input, gssize length) { 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) { if (data == 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, * terminated by a NULL * - * Items {key} are replaced by the value if '{key}' is passed as key/value pair, - * otherwise removed from string. If the {key} is in between [] all the text - * between [] are removed if {key} is not found. Otherwise key is replaced and [ - * & ] removed. + * Items {key} are replaced by the value if '{key}' is passed as key/value + * pair, otherwise removed from string. If the {key} is in between [] all the + * text between [] are removed if {key} is not found. Otherwise key is + * replaced and [ & ] removed. * * This allows for optional replacement, f.e. '{ssh-client} [-t {title}] -e * "{cmd}"' the '-t {title}' is only there if {title} is set. diff --git a/source/rofi.c b/source/rofi.c index f6d1bd346..21aeb8838 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -110,7 +110,7 @@ unsigned int num_available_modi = 0; /** Number of activated modi in #modi array */ unsigned int num_modi = 0; /** Current selected mode */ -unsigned int curr_switcher = 0; +unsigned int curr_mode = 0; /** Handle to NkBindings object for input devices. */ 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]; } /** - * @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++) { if (strcmp(mode_get_name(modi[i]), name) == 0) { return i; @@ -162,7 +162,7 @@ static void teardown(int pfd) { // Cleanup pid file. remove_pid_file(pfd); } -static void run_switcher(ModeMode mode) { +static void run_mode_index(ModeMode mode) { // Otherwise check if requested mode is enabled. for (unsigned int i = 0; i < num_modi; i++) { if (!mode_init(modi[i])) { @@ -179,7 +179,7 @@ static void run_switcher(ModeMode mode) { if (rofi_view_get_active() != NULL) { return; } - curr_switcher = mode; + curr_mode = mode; RofiViewState *state = rofi_view_create(modi[mode], config.filter, 0, process_result); @@ -217,7 +217,7 @@ void process_result(RofiViewState *state) { } g_free(input); - ModeMode mode = curr_switcher; + ModeMode mode = curr_mode; // Find next enabled if (retv == NEXT_DIALOG) { mode = (mode + 1) % num_modi; @@ -241,7 +241,7 @@ void process_result(RofiViewState *state) { * Load in the new mode. */ rofi_view_switch_mode(state, modi[mode]); - curr_switcher = mode; + curr_mode = mode; return; } // On exit, free current view, and pop to one above. @@ -266,7 +266,7 @@ static void print_list_of_modi(int is_term) { break; } } - printf(" * %s%s%s%s\n", active ? "+" : "", + printf(" • %s%s%s%s\n", active ? "+" : "", is_term ? (active ? color_green : color_red) : "", 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("Compile time options:\n"); #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 : ""); #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 : ""); #endif #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 : ""); #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 : ""); #endif #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 : ""); #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 : ""); #endif #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 : ""); #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 : ""); #endif printf("\n"); @@ -377,6 +377,7 @@ static void help(G_GNUC_UNUSED int argc, char **argv) { printf(" Configuration file: %sDisabled%s\n", is_term ? color_bold : "", is_term ? color_reset : ""); } + rofi_theme_print_parsed_files(is_term); } static void help_print_disabled_mode(const char *mode) { @@ -475,6 +476,7 @@ static void cleanup(void) { rofi_collect_modi_destroy(); rofi_icon_fetcher_destroy(); + rofi_theme_free_parsed_files(); if (rofi_configuration) { rofi_theme_free(rofi_configuration); 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 ',' * 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) { unsigned int index = num_modi; @@ -627,9 +629,9 @@ static int add_mode(const char *token) { if (mode) { modi[num_modi] = mode; num_modi++; - } else if (script_switcher_is_valid(token)) { + } else if (script_mode_is_valid(token)) { // If not build in, use custom modi. - Mode *sw = script_switcher_parse_setup(token); + Mode *sw = script_mode_parse_setup(token); if (sw != NULL) { // Add to available list, so combi can find it. rofi_collect_modi_add(sw); @@ -644,16 +646,16 @@ static gboolean setup_modi(void) { const char *const sep = ",#"; char *savept = NULL; // Make a copy, as strtok will modify it. - char *switcher_str = g_strdup(config.modi); - // Split token on ','. This modifies switcher_str. - for (char *token = strtok_r(switcher_str, sep, &savept); token != NULL; + char *mode_str = g_strdup(config.modi); + // Split token on ','. This modifies mode_str. + for (char *token = strtok_r(mode_str, sep, &savept); token != NULL; token = strtok_r(NULL, sep, &savept)) { if (add_mode(token) == -1) { help_print_mode_not_found(token); } } // Free string that was modified by strtok_r - g_free(switcher_str); + g_free(mode_str); return FALSE; } @@ -715,7 +717,7 @@ static gboolean startup(G_GNUC_UNUSED gpointer data) { if (dmenu_mode == TRUE) { // force off sidebar mode: config.sidebar_mode = FALSE; - int retv = dmenu_switcher_dialog(); + int retv = dmenu_mode_dialog(); if (retv) { rofi_set_return_code(EXIT_SUCCESS); // Directly exit. @@ -730,7 +732,7 @@ static gboolean startup(G_GNUC_UNUSED gpointer data) { g_main_loop_quit(main_loop); } } else if (find_arg_str("-show", &sname) == TRUE) { - int index = switcher_get(sname); + int index = mode_lookup(sname); if (index < 0) { // Add it to the list index = add_mode(sname); @@ -741,14 +743,14 @@ static gboolean startup(G_GNUC_UNUSED gpointer data) { // Run it anyway if found. } if (index >= 0) { - run_switcher(index); + run_mode_index(index); } else { help_print_mode_not_found(sname); show_error_dialog(); return G_SOURCE_REMOVE; } } else if (find_arg("-show") >= 0 && num_modi > 0) { - run_switcher(0); + run_mode_index(0); } else { help_print_no_arguments(); @@ -983,8 +985,6 @@ int main(int argc, char *argv[]) { } TICK_N("Load cmd config "); - parse_keys_abe(bindings); - // Get the path to the cache dir. cache_dir = g_get_user_cache_dir(); @@ -1030,6 +1030,7 @@ int main(int argc, char *argv[]) { g_free(theme_str); } + parse_keys_abe(bindings); if (find_arg("-dump-theme") >= 0) { rofi_theme_print(rofi_theme); cleanup(); @@ -1068,8 +1069,12 @@ int main(int argc, char *argv[]) { rofi_icon_fetcher_init(); TICK_N("Icon fetcher initialize"); + gboolean kill_running = FALSE; + if (find_arg("-replace") >= 0) { + kill_running = TRUE; + } // Create pid file - int pfd = create_pid_file(pidfile); + int pfd = create_pid_file(pidfile, kill_running); TICK_N("Pid file created"); if (pfd < 0) { cleanup(); diff --git a/source/theme.c b/source/theme.c index f3c4e83fc..8ad99fa49 100644 --- a/source/theme.c +++ b/source/theme.c @@ -47,6 +47,23 @@ #include "widgets/textbox.h" #include +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 *); static gboolean distance_compare(RofiDistance d, RofiDistance e) { // TODO UPDATE @@ -54,11 +71,6 @@ static gboolean distance_compare(RofiDistance d, RofiDistance e) { 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, const char *name) { 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); break; case P_LIST: - retv->value.list = - g_list_copy_deep(p->value.list, rofi_g_list_strdup, NULL); + retv->value.list = g_list_copy_deep( + p->value.list, (GCopyFunc)rofi_theme_property_copy, NULL); break; case P_LINK: 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) { g_free(p->value.s); } 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; } else if (p->type == P_LINK) { g_free(p->value.link.name); @@ -267,6 +279,12 @@ static void rofi_theme_print_distance_unit(RofiDistanceUnit *unit) { fputs(" min ", stdout); } else if (unit->modtype == ROFI_DISTANCE_MODIFIER_MAX) { 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) { rofi_theme_print_distance_unit(unit->right); @@ -339,7 +357,7 @@ static void int_rofi_theme_print_property(Property *p) { case P_LIST: printf("[ "); 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) { 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, const char *property, - const char *defaults) { + PropertyType child_type) { if (p) { if (p->type == P_INHERIT) { if (widget->parent) { @@ -1199,28 +1217,58 @@ static GList *rofi_theme_get_list_inside(Property *p, const widget *widget, Property *pv = rofi_theme_find_property(parent, P_LIST, property, FALSE); return rofi_theme_get_list_inside(pv, widget->parent, property, - defaults); + child_type); } } 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]); + return NULL; +} +GList *rofi_theme_get_list_distance(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_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."); } - g_free(r); - return l; } - return NULL; + return retv; } -GList *rofi_theme_get_list(const widget *widget, const char *property, - const char *defaults) { - ThemeWidget *wid2 = rofi_theme_find_widget(widget->name, widget->state, TRUE); - Property *p = rofi_theme_find_property(wid2, P_LIST, property, TRUE); - return rofi_theme_get_list_inside(p, widget, property, defaults); +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 @@ -1248,9 +1296,9 @@ rofi_theme_get_highlight_inside(Property *p, widget *widget, } else { ThemeWidget *wid = rofi_theme_find_widget(widget->name, widget->state, FALSE); - Property *p = rofi_theme_find_property(wid, P_COLOR, property, FALSE); - if (p != NULL) { - return rofi_theme_get_highlight_inside(p, widget, property, th); + Property *p2 = rofi_theme_find_property(wid, P_COLOR, property, FALSE); + if (p2 != NULL) { + return rofi_theme_get_highlight_inside(p2, widget, property, th); } return th; } @@ -1332,6 +1380,21 @@ static int distance_unit_get_pixel(RofiDistanceUnit *unit, int b = distance_unit_get_pixel(unit->right, ori); 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: 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 *filename = rofi_expand_path(file); // 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); } 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); g_object_unref(gf); diff --git a/source/view.c b/source/view.c index ce6c8bac1..45d8fc8ea 100644 --- a/source/view.c +++ b/source/view.c @@ -1017,12 +1017,12 @@ static WidgetTriggerActionResult textbox_button_trigger_action( switch (action) { case MOUSE_CLICK_DOWN: { const char *type = rofi_theme_get_string(wid, "action", NULL); - if (type ) { - if ( state->list_view) { + if (type) { + if (state->list_view) { (state->selected_line) = - state->line_map[listview_get_selected(state->list_view)]; + state->line_map[listview_get_selected(state->list_view)]; } else { - (state->selected_line) = UINT32_MAX; + (state->selected_line) = UINT32_MAX; } guint id = key_binding_get_action_from_name(type); 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); } if (wid) { - GList *list = rofi_theme_get_list(wid, "children", defaults); - for (const GList *iter = list; iter != NULL; iter = g_list_next(iter)) { - rofi_view_add_widget(state, wid, (const char *)iter->data); + GList *list = rofi_theme_get_list_strings(wid, "children"); + if (list == NULL) { + 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); // Get children. GList *list = - rofi_theme_get_list(WIDGET(state->main_window), "children", "mainbox"); - 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); + rofi_theme_get_list_strings(WIDGET(state->main_window), "children"); + if (list == NULL) { + rofi_view_add_widget(state, WIDGET(state->main_window), "mainbox"); + } 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) { textbox_text(state->text, input); diff --git a/source/widgets/listview.c b/source/widgets/listview.c index c43c508e2..b01c7123f 100644 --- a/source/widgets/listview.c +++ b/source/widgets/listview.c @@ -176,7 +176,9 @@ static void listview_add_widget(listview *lv, _listview_row *row, widget *wid, } else { widget *wid2 = (widget *)box_create(wid, label, ROFI_ORIENTATION_VERTICAL); 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; iter = g_list_next(iter)) { 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); widget_set_type(WIDGET(row->box), WIDGET_TYPE_LISTVIEW_ELEMENT); GList *list = NULL; - if (config.show_icons) { - list = rofi_theme_get_list(WIDGET(row->box), "children", - "element-icon,element-text"); - } else { - list = rofi_theme_get_list(WIDGET(row->box), "children", "element-text"); + list = rofi_theme_get_list_strings(WIDGET(row->box), "children"); + if (list == NULL) { + if (config.show_icons) { + list = g_list_append(list, g_strdup("element-icon")); + list = g_list_append(list, g_strdup("element-text")); + } else { + list = g_list_append(list, g_strdup("element-text")); + } } 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) { if (lv) { lv->max_displayed_lines = max_lines; diff --git a/source/widgets/textbox.c b/source/widgets/textbox.c index c404f912d..1f7e155f9 100644 --- a/source/widgets/textbox.c +++ b/source/widgets/textbox.c @@ -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, TextboxFlags flags, TextBoxFontType tbft, 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_initialize_font(tb); + textbox_tab_stops(tb); if ((tb->flags & TB_WRAP) == TB_WRAP) { pango_layout_set_wrap(tb->layout, PANGO_WRAP_WORD_CHAR); diff --git a/source/widgets/widget.c b/source/widgets/widget.c index 3eb5debd3..4316dc43c 100644 --- a/source/widgets/widget.c +++ b/source/widgets/widget.c @@ -31,30 +31,15 @@ #include #include -/** 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, const char *name) { wid->type = type; wid->parent = parent; wid->name = g_strdup(name); - wid->def_padding = (RofiPadding){WIDGET_PADDING_INIT, WIDGET_PADDING_INIT, - WIDGET_PADDING_INIT, WIDGET_PADDING_INIT}; - wid->def_border = (RofiPadding){WIDGET_PADDING_INIT, WIDGET_PADDING_INIT, - WIDGET_PADDING_INIT, 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->def_padding = WIDGET_PADDING_INIT; + wid->def_border = WIDGET_PADDING_INIT; + wid->def_border_radius = WIDGET_PADDING_INIT; + wid->def_margin = WIDGET_PADDING_INIT; wid->padding = rofi_theme_get_padding(wid, "padding", wid->def_padding); 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; } -WidgetType widget_type(widget *widget) { - if (widget == NULL) { - return WIDGET_TYPE_UNKNOWN; - } - return widget->type; -} - gboolean widget_enabled(widget *widget) { if (widget == NULL) { return FALSE; @@ -548,8 +526,8 @@ widget *widget_find_mouse_target(widget *wid, WidgetType type, gint x, gint y) { return NULL; } -WidgetTriggerActionResult widget_check_action(widget *wid, guint action, - gint x, gint y) { +WidgetTriggerActionResult widget_check_action(widget *wid, guint action, gint x, + gint y) { if (wid == NULL) { return FALSE; } diff --git a/source/xcb.c b/source/xcb.c index 89d049a03..0637cd31d 100644 --- a/source/xcb.c +++ b/source/xcb.c @@ -747,6 +747,10 @@ static int monitor_get_dimension(int monitor_id, workarea *mon) { } // find the dimensions of the monitor displaying point x,y 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)); mon->w = xcb->screen->width_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; } + 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_get_geometry_cookie_t c = xcb_get_geometry(xcb->connection, id); 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; xcb_window_t active_window; 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); if (!xcb_ewmh_get_active_window_reply(&xcb->ewmh, awc, &active_window, 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); } 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); + g_debug("Monitor found pos: %d %d %d-%d", mon->x, mon->y, mon->w, mon->h); retv = TRUE; } 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) { xcb_window_t root = xcb->screen->root; int x, y; + if (mon == NULL) { + g_error("%s: mon == NULL", __FUNCTION__); + return FALSE; + } + g_debug("Monitor id: %d", mon_id); // At mouse position. if (mon_id == -3) { if (pointer_get(root, &x, &y)) { @@ -888,19 +908,27 @@ static int monitor_active_from_id(int mon_id, workarea *mon) { } // Focused monitor else if (mon_id == -1) { + g_debug("rofi on current monitor"); // Get the current desktop. unsigned int current_desktop = 0; xcb_get_property_cookie_t gcdc; gcdc = xcb_ewmh_get_current_desktop(&xcb->ewmh, xcb->screen_nbr); if (xcb_ewmh_get_current_desktop_reply(&xcb->ewmh, gcdc, ¤t_desktop, NULL)) { + g_debug("Found current desktop: %u", current_desktop); xcb_get_property_cookie_t c = xcb_ewmh_get_desktop_viewport(&xcb->ewmh, xcb->screen_nbr); xcb_ewmh_get_desktop_viewport_reply_t vp; 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) { + 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, 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); 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 // pointer + +gboolean mon_set = FALSE; +workarea mon_cache = { + 0, +}; 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) { + g_debug("Monitor lookup by name : %s", config.monitor); for (workarea *iter = xcb->monitors; iter; iter = iter->next) { if (g_strcmp0(config.monitor, iter->name) == 0) { *mon = *iter; + mon_cache = *mon; + mon_set = TRUE; return TRUE; } } } + g_debug("Monitor lookup by name failed: %s", config.monitor); // Grab primary. if (g_strcmp0(config.monitor, "primary") == 0) { for (workarea *iter = xcb->monitors; iter; iter = iter->next) { if (iter->primary) { *mon = *iter; + mon_cache = *mon; + mon_set = TRUE; return TRUE; } } @@ -960,6 +1010,8 @@ int monitor_active(workarea *mon) { xcb_drawable_t win = g_ascii_strtoll(config.monitor + 4, &end, 0); if (end != config.monitor) { if (monitor_active_from_winid(win, mon)) { + mon_cache = *mon; + mon_set = TRUE; return TRUE; } } @@ -971,16 +1023,23 @@ int monitor_active(workarea *mon) { if (end != config.monitor) { if (mon_id >= 0) { if (monitor_get_dimension(mon_id, mon)) { + mon_cache = *mon; + mon_set = TRUE; return TRUE; } g_warning("Failed to find selected monitor."); } 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. monitor_dimensions(0, 0, mon); + mon_cache = *mon; + mon_set = TRUE; return FALSE; } @@ -1186,6 +1245,7 @@ static void main_loop_x11_event_handler_view(xcb_generic_event_t *event) { NK_BINDINGS_KEY_STATE_PRESS); if (text != NULL) { rofi_view_handle_text(state, text); + g_free(text); } break; } diff --git a/source/xrmoptions.c b/source/xrmoptions.c index 5dc33b906..6d855cf40 100644 --- a/source/xrmoptions.c +++ b/source/xrmoptions.c @@ -350,7 +350,14 @@ static XrmOption xrmOptions[] = { "combi-hide-mode-prefix", {.snum = &config.combi_hide_mode_prefix}, 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}, {xrm_Char, "matching-negate-char", @@ -500,6 +507,25 @@ static void config_parse_cmd_option(XrmOption *option) { 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) { for (unsigned int i = 0; i < sizeof(xrmOptions) / sizeof(XrmOption); ++i) { XrmOption *op = &(xrmOptions[i]); @@ -516,41 +542,53 @@ void config_parse_cmd_options(void) { extern char **stored_argv; for (int in = 1; in < (stored_argc - 1); in++) { 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. */ char **tokens = g_strsplit(stored_argv[in], "-", 3); int count = 1; for (int j = 1; tokens && tokens[j]; j++) { count++; } - if (count > 2 && g_strcmp0(tokens[1], "no") != 0) { - GString *str = g_string_new("configuration { "); - for (int j = 1; j < (count - 1); j++) { - g_string_append_printf(str, "%s { ", tokens[j]); - } - g_string_append_printf(str, "%s: %s;", tokens[count - 1], - stored_argv[in + 1]); - for (int j = 0; j < (count - 1); j++) { - g_string_append(str, " } "); - } - if (rofi_theme_parse_string(str->str) == 1) { - /** Failed to parse, try again as string. */ - rofi_clear_error_messages(); - g_string_assign(str, "configuration { "); - for (int j = 1; j < (count - 1); j++) { - g_string_append_printf(str, "%s { ", tokens[j]); - } - 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, " } "); + if (count >= 2) { + if (g_str_has_prefix(tokens[1], "theme")) { + g_strfreev(tokens); + tokens = g_strsplit(stored_argv[in], "+", 0); + count = g_strv_length(tokens); + if (count > 2) { + GString *str = g_string_new(""); + config_parser_form_rasi_format(str, &(tokens[1]), count - 1, + stored_argv[in + 1], FALSE); + if (rofi_theme_parse_string(str->str) == 1) { + /** Failed to parse, try again as string. */ + g_strfreev(tokens); + g_string_free(str, TRUE); + return; + } + g_string_free(str, TRUE); } + } 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) { /** Failed to parse, try again as string. */ 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++; } g_strfreev(tokens); @@ -571,10 +609,11 @@ static gboolean __config_parser_set_property(XrmOption *option, if (p->type == P_LIST) { for (GList *iter = p->value.list; iter != NULL; iter = g_list_next(iter)) { + Property *p = (Property *)iter->data; if (value == NULL) { - value = g_strdup((char *)(iter->data)); + value = g_strdup((char *)(p->value.s)); } else { - char *nv = g_strjoin(",", value, (char *)(iter->data), NULL); + char *nv = g_strjoin(",", value, (char *)(p->value.s), NULL); g_free(value); 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); - 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; iter = g_list_next(iter)) { diff --git a/test/helper-pidfile.c b/test/helper-pidfile.c index 8558ab72a..b5738c341 100644 --- a/test/helper-pidfile.c +++ b/test/helper-pidfile.c @@ -25,101 +25,78 @@ * */ -#include -#include -#include -#include -#include -#include #include "display.h" +#include "rofi-icon-fetcher.h" #include "rofi.h" #include "settings.h" #include "widgets/textbox.h" -#include "rofi-icon-fetcher.h" +#include +#include +#include +#include +#include +#include -static int test = 0; +static int test = 0; -#define TASSERT( a ) { \ - assert ( a ); \ - printf ( "Test %i passed (%s)\n", ++test, # a ); \ -} +#define TASSERT(a) \ + { \ + assert(a); \ + printf("Test %i passed (%s)\n", ++test, #a); \ + } #include "theme.h" ThemeWidget *rofi_theme = NULL; -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, const int hsize ) -{ +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, + const int hsize) { return 0; } -cairo_surface_t * rofi_icon_fetcher_get ( const uint32_t uid ) -{ - return NULL; -} +cairo_surface_t *rofi_icon_fetcher_get(const uint32_t uid) { return NULL; } -void rofi_clear_error_messages ( void ) -{ -} +void rofi_clear_error_messages(void) {} -gboolean rofi_theme_parse_string ( const char *string ) -{ - return FALSE; +gboolean rofi_theme_parse_string(const char *string) { return FALSE; } +double textbox_get_estimated_char_height(void) { return 12.0; } +void rofi_view_get_current_monitor(int *width, int *height) { + *width = 1920; + *height = 1080; } -double textbox_get_estimated_char_height ( void ) -{ - return 12.0; -} -void rofi_view_get_current_monitor ( int *width, int *height ) -{ -*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; +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; } -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 ) -{ - if ( setlocale ( LC_ALL, "" ) == NULL ) { - fprintf ( stderr, "Failed to set locale.\n" ); - return EXIT_FAILURE; - } - // Pid test. - // Tests basic functionality of writing it, locking, seeing if I can write same again - // And close/reopen it again. - { - const char *tmpd = g_get_tmp_dir (); - char *path = g_build_filename (tmpd, "rofi-pid.pid", NULL); - TASSERT ( create_pid_file ( NULL ) == -1 ); - int fd = create_pid_file ( path ); - TASSERT ( fd >= 0 ); - int fd2 = create_pid_file ( path ); - TASSERT ( fd2 < 0 ); +int main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv) { + if (setlocale(LC_ALL, "") == NULL) { + fprintf(stderr, "Failed to set locale.\n"); + return EXIT_FAILURE; + } + // Pid test. + // Tests basic functionality of writing it, locking, seeing if I can write + // same again And close/reopen it again. + { + const char *tmpd = g_get_tmp_dir(); + char *path = g_build_filename(tmpd, "rofi-pid.pid", NULL); + TASSERT(create_pid_file(NULL, FALSE) == -1); + int fd = create_pid_file(path, FALSE); + TASSERT(fd >= 0); + int fd2 = create_pid_file(path, FALSE); + TASSERT(fd2 < 0); - remove_pid_file ( fd ); - fd = create_pid_file ( path ); - TASSERT ( fd >= 0 ); - remove_pid_file ( fd ); - free ( path ); - } + remove_pid_file(fd); + fd = create_pid_file(path, FALSE); + TASSERT(fd >= 0); + remove_pid_file(fd); + free(path); + } } diff --git a/test/theme-parser-test.c b/test/theme-parser-test.c index ccae1bb97..29f2301fb 100644 --- a/test/theme-parser-test.c +++ b/test/theme-parser-test.c @@ -25,87 +25,68 @@ * */ -#include -#include -#include -#include -#include -#include +#include "css-colors.h" +#include "display.h" +#include "rofi-icon-fetcher.h" #include "rofi.h" #include "settings.h" -#include "display.h" #include "theme.h" -#include "css-colors.h" -#include "widgets/widget-internal.h" #include "widgets/textbox.h" -#include "rofi-icon-fetcher.h" - +#include "widgets/widget-internal.h" +#include +#include +#include +#include +#include +#include #include #define REAL_COMPARE_DELTA 0.001 - -uint32_t rofi_icon_fetcher_query ( const char *name, const int size ) -{ - return 0; -} -void rofi_clear_error_messages ( void ) {} -uint32_t rofi_icon_fetcher_query_advanced ( const char *name, const int wsize, const int hsize ) -{ - return 0; +uint32_t rofi_icon_fetcher_query(const char *name, const int size) { return 0; } +void rofi_clear_error_messages(void) {} +uint32_t rofi_icon_fetcher_query_advanced(const char *name, const int wsize, + const int hsize) { + return 0; } -cairo_surface_t * rofi_icon_fetcher_get ( const uint32_t uid ) -{ - return NULL; -} +cairo_surface_t *rofi_icon_fetcher_get(const uint32_t uid) { return NULL; } -int rofi_view_error_dialog ( const char *msg, G_GNUC_UNUSED int markup ) -{ - fputs ( msg, stderr ); - return TRUE; +int rofi_view_error_dialog(const char *msg, G_GNUC_UNUSED int markup) { + fputs(msg, stderr); + return TRUE; } -void rofi_view_get_current_monitor ( int *width, int *height ) -{ - if ( width ) { - *width = 1920; - } - if ( height ) { - *height = 1080; - } -} -double textbox_get_estimated_char_height ( void ) -{ - return 16.0; +void rofi_view_get_current_monitor(int *width, int *height) { + if (width) { + *width = 1920; + } + if (height) { + *height = 1080; + } } +double textbox_get_estimated_char_height(void) { return 16.0; } -double textbox_get_estimated_ch ( void ) -{ - return 8.0; -} +double textbox_get_estimated_ch(void) { return 8.0; } -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) {} #ifndef _ck_assert_ptr_null /* Pointer against NULL comparison macros with improved output * compared to ck_assert(). */ /* OP may only be == or != */ -#define _ck_assert_ptr_null(X, OP) do { \ - const void* _ck_x = (X); \ - ck_assert_msg(_ck_x OP NULL, \ - "Assertion '%s' failed: %s == %#x", \ - #X" "#OP" NULL", \ - #X, _ck_x); \ -} while (0) +#define _ck_assert_ptr_null(X, OP) \ + do { \ + const void *_ck_x = (X); \ + ck_assert_msg(_ck_x OP NULL, "Assertion '%s' failed: %s == %#x", \ + #X " " #OP " NULL", #X, _ck_x); \ + } while (0) #define ck_assert_ptr_null(X) _ck_assert_ptr_null(X, ==) #define ck_assert_ptr_nonnull(X) _ck_assert_ptr_null(X, !=) @@ -113,1355 +94,1416 @@ void display_startup_notification ( G_GNUC_UNUSED RofiHelperExecuteContext *cont gboolean error = FALSE; GString *error_msg = NULL; -void rofi_add_error_message ( GString *msg ) -{ - ck_assert_ptr_null ( error_msg ); - error_msg = msg; - error = TRUE; -} - -static void theme_parser_setup ( void ) -{ - error = 0; -} -static void theme_parser_teardown ( void ) -{ - ck_assert_ptr_null ( error_msg ); - ck_assert_int_eq ( error, 0); - rofi_theme_free ( rofi_theme ); - rofi_theme = NULL; -} - -START_TEST (test_core_empty_string ) -{ - rofi_theme_parse_string ( ""); - ck_assert_ptr_nonnull ( rofi_theme ); - //ck_assert_ptr_null ( rofi_theme->widgets ); - ck_assert_ptr_null ( rofi_theme->properties ); - ck_assert_ptr_null ( rofi_theme->parent ); - ck_assert_str_eq ( rofi_theme->name, "Root" ); +void rofi_add_error_message(GString *msg) { + ck_assert_ptr_null(error_msg); + error_msg = msg; + error = TRUE; +} + +static void theme_parser_setup(void) { error = 0; } +static void theme_parser_teardown(void) { + ck_assert_ptr_null(error_msg); + ck_assert_int_eq(error, 0); + rofi_theme_free(rofi_theme); + rofi_theme = NULL; +} + +START_TEST(test_core_empty_string) { + rofi_theme_parse_string(""); + ck_assert_ptr_nonnull(rofi_theme); + // ck_assert_ptr_null ( rofi_theme->widgets ); + ck_assert_ptr_null(rofi_theme->properties); + ck_assert_ptr_null(rofi_theme->parent); + ck_assert_str_eq(rofi_theme->name, "Root"); } END_TEST -START_TEST (test_core_empty_global_section ) -{ - rofi_theme_parse_string ( " * {}"); - ck_assert_ptr_nonnull ( rofi_theme ); - //ck_assert_ptr_null ( rofi_theme->widgets ); - ck_assert_ptr_null ( rofi_theme->properties ); - ck_assert_ptr_null ( rofi_theme->parent ); - ck_assert_str_eq ( rofi_theme->name, "Root" ); +START_TEST(test_core_empty_global_section) { + rofi_theme_parse_string(" * {}"); + ck_assert_ptr_nonnull(rofi_theme); + // ck_assert_ptr_null ( rofi_theme->widgets ); + ck_assert_ptr_null(rofi_theme->properties); + ck_assert_ptr_null(rofi_theme->parent); + ck_assert_str_eq(rofi_theme->name, "Root"); } END_TEST -START_TEST (test_core_empty_section ) -{ - rofi_theme_parse_string ( " #test {}"); - ck_assert_ptr_nonnull ( rofi_theme ); - ck_assert_ptr_nonnull ( rofi_theme->widgets ); - ck_assert_ptr_null ( rofi_theme->properties ); - ck_assert_ptr_null ( rofi_theme->parent ); - ck_assert_str_eq ( rofi_theme->name, "Root" ); - //ck_assert_str_eq ( rofi_theme->widgets[3]->name, "test" ); - //ck_assert_ptr_null ( rofi_theme->widgets[3]->properties ); - //ck_assert_ptr_eq ( rofi_theme->widgets[3]->parent, rofi_theme ); +START_TEST(test_core_empty_section) { + rofi_theme_parse_string(" #test {}"); + ck_assert_ptr_nonnull(rofi_theme); + ck_assert_ptr_nonnull(rofi_theme->widgets); + ck_assert_ptr_null(rofi_theme->properties); + ck_assert_ptr_null(rofi_theme->parent); + ck_assert_str_eq(rofi_theme->name, "Root"); + // ck_assert_str_eq ( rofi_theme->widgets[3]->name, "test" ); + // ck_assert_ptr_null ( rofi_theme->widgets[3]->properties ); + // ck_assert_ptr_eq ( rofi_theme->widgets[3]->parent, rofi_theme ); } END_TEST -START_TEST (test_core_error_root ) -{ - rofi_theme_parse_string ( "Blaat"); - ck_assert_int_eq ( error, 1 ); - ck_assert_ptr_null ( rofi_theme ); - //ck_assert_ptr_null ( rofi_theme->widgets ); - //ck_assert_ptr_null ( rofi_theme->properties ); - //ck_assert_ptr_null ( rofi_theme->parent ); - const char *error_str = "Error while parsing theme: Blaat\n"\ -" Parser error: syntax error, unexpected end of file, expecting "bracket open ('{')" or "Selector separator (',')"\n"\ -" Location: line 1 column 6 to line 1 column 6\n"; - ck_assert_str_eq ( error_msg->str, error_str ); - - - g_string_free ( error_msg, TRUE ); - error_msg = NULL; - error = 0; +START_TEST(test_core_error_root) { + rofi_theme_parse_string("Blaat"); + ck_assert_int_eq(error, 1); + ck_assert_ptr_null(rofi_theme); + // ck_assert_ptr_null ( rofi_theme->widgets ); + // ck_assert_ptr_null ( rofi_theme->properties ); + // ck_assert_ptr_null ( rofi_theme->parent ); + const char *error_str = + "Error while parsing theme: Blaat\n" + " Parser error: syntax error, " + "unexpected end of file, expecting "bracket open " + "('{')" or "Selector separator " + "(',')"\n" + " Location: line 1 column 6 to line 1 column 6\n"; + ck_assert_str_eq(error_msg->str, error_str); + + g_string_free(error_msg, TRUE); + error_msg = NULL; + error = 0; } END_TEST -START_TEST ( test_core_comments ) -{ - rofi_theme_parse_string ( "// Random comments // /*test */"); - rofi_theme_parse_string ( "/* test /* aap */ */"); - rofi_theme_parse_string ( "// Random comments\n// /*test */"); - rofi_theme_parse_string ( "/* test \n*\n* /* aap */ */"); - ck_assert_ptr_nonnull ( rofi_theme ); - //ck_assert_ptr_null ( rofi_theme->widgets ); - ck_assert_ptr_null ( rofi_theme->properties ); - ck_assert_ptr_null ( rofi_theme->parent ); - ck_assert_str_eq ( rofi_theme->name, "Root" ); - - // Test comment on last lines - rofi_theme_parse_string ( "// c++ style" ); - rofi_theme_parse_string ( "/* c style" ); +START_TEST(test_core_comments) { + rofi_theme_parse_string("// Random comments // /*test */"); + rofi_theme_parse_string("/* test /* aap */ */"); + rofi_theme_parse_string("// Random comments\n// /*test */"); + rofi_theme_parse_string("/* test \n*\n* /* aap */ */"); + ck_assert_ptr_nonnull(rofi_theme); + // ck_assert_ptr_null ( rofi_theme->widgets ); + ck_assert_ptr_null(rofi_theme->properties); + ck_assert_ptr_null(rofi_theme->parent); + ck_assert_str_eq(rofi_theme->name, "Root"); + + // Test comment on last lines + rofi_theme_parse_string("// c++ style"); + rofi_theme_parse_string("/* c style"); } END_TEST -START_TEST ( test_core_newline ) -{ - rofi_theme_parse_string ( "\r\n\n\r\n\n/*\r\n*/"); - ck_assert_ptr_nonnull ( rofi_theme ); - //ck_assert_ptr_null ( rofi_theme->widgets ); - ck_assert_ptr_null ( rofi_theme->properties ); - ck_assert_ptr_null ( rofi_theme->parent ); - ck_assert_str_eq ( rofi_theme->name, "Root" ); +START_TEST(test_core_newline) { + rofi_theme_parse_string("\r\n\n\r\n\n/*\r\n*/"); + ck_assert_ptr_nonnull(rofi_theme); + // ck_assert_ptr_null ( rofi_theme->widgets ); + ck_assert_ptr_null(rofi_theme->properties); + ck_assert_ptr_null(rofi_theme->parent); + ck_assert_str_eq(rofi_theme->name, "Root"); } END_TEST -START_TEST(test_properties_boolean) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - /** Boolean property */ - rofi_theme_parse_string ( "*{ test: true; test2:/* inline */false; }"); - ck_assert_ptr_nonnull ( rofi_theme ); - //ck_assert_ptr_null ( rofi_theme->widgets ); - ck_assert_ptr_nonnull ( rofi_theme->properties ); - ck_assert_ptr_null ( rofi_theme->parent ); - ck_assert_int_eq( rofi_theme_get_boolean ( &wid, "test", FALSE), TRUE ); - ck_assert_int_eq( rofi_theme_get_boolean ( &wid, "test2", TRUE), FALSE ); +START_TEST(test_properties_boolean) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + /** Boolean property */ + rofi_theme_parse_string("*{ test: true; test2:/* inline */false; }"); + ck_assert_ptr_nonnull(rofi_theme); + // ck_assert_ptr_null ( rofi_theme->widgets ); + ck_assert_ptr_nonnull(rofi_theme->properties); + ck_assert_ptr_null(rofi_theme->parent); + ck_assert_int_eq(rofi_theme_get_boolean(&wid, "test", FALSE), TRUE); + ck_assert_int_eq(rofi_theme_get_boolean(&wid, "test2", TRUE), FALSE); } END_TEST -START_TEST(test_properties_boolean_reference) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { test: true; test2:/* inline */false;} *{ a:@test; b:@test2;}"); - ck_assert_ptr_nonnull ( rofi_theme ); - ck_assert_int_eq ( rofi_theme_get_boolean ( &wid, "test", FALSE),TRUE ); - ck_assert_int_eq ( rofi_theme_get_boolean ( &wid, "b", TRUE),FALSE ); - ck_assert_int_eq ( rofi_theme_get_boolean ( &wid, "a", FALSE),TRUE ); - ck_assert_int_eq ( rofi_theme_get_boolean ( &wid, "test2", TRUE),FALSE ); +START_TEST(test_properties_boolean_reference) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string( + "* { test: true; test2:/* inline */false;} *{ a:@test; b:@test2;}"); + ck_assert_ptr_nonnull(rofi_theme); + ck_assert_int_eq(rofi_theme_get_boolean(&wid, "test", FALSE), TRUE); + ck_assert_int_eq(rofi_theme_get_boolean(&wid, "b", TRUE), FALSE); + ck_assert_int_eq(rofi_theme_get_boolean(&wid, "a", FALSE), TRUE); + ck_assert_int_eq(rofi_theme_get_boolean(&wid, "test2", TRUE), FALSE); } END_TEST -START_TEST ( test_properties_distance_em) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { test: 10em;}"); - ck_assert_ptr_nonnull ( rofi_theme ); - RofiDistance d = (RofiDistance){ {1, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE,NULL, NULL }, ROFI_HL_SOLID}; - RofiPadding pi = (RofiPadding){d,d,d,d}; - RofiPadding p = rofi_theme_get_padding ( &wid, "test", pi); - ck_assert_int_eq ( p.left.base.distance , 10 ); - ck_assert_int_eq( p.left.base.type , ROFI_PU_EM ); - ck_assert_int_eq( p.left.style, ROFI_HL_SOLID); - +START_TEST(test_properties_distance_em) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { test: 10em;}"); + ck_assert_ptr_nonnull(rofi_theme); + RofiDistance d = (RofiDistance){ + {1, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL}, ROFI_HL_SOLID}; + RofiPadding pi = (RofiPadding){d, d, d, d}; + RofiPadding p = rofi_theme_get_padding(&wid, "test", pi); + ck_assert_int_eq(p.left.base.distance, 10); + ck_assert_int_eq(p.left.base.type, ROFI_PU_EM); + ck_assert_int_eq(p.left.style, ROFI_HL_SOLID); } END_TEST -START_TEST ( test_properties_distance_em_linestyle) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { sol: 1.3em solid; dash: 1.5em dash;}"); - ck_assert_ptr_nonnull ( rofi_theme ); - RofiDistance d = (RofiDistance){ {1, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE,NULL, NULL }, ROFI_HL_SOLID}; - RofiPadding pi = (RofiPadding){d,d,d,d}; - RofiPadding p = rofi_theme_get_padding ( &wid, "sol", pi); - ck_assert_double_eq_tol ( p.left.base.distance , 1.3 , REAL_COMPARE_DELTA ); - ck_assert_int_eq( p.left.base.type , ROFI_PU_EM ); - ck_assert_int_eq( p.left.style, ROFI_HL_SOLID); - - p = rofi_theme_get_padding ( &wid, "dash", pi); - ck_assert_double_eq_tol ( p.left.base.distance , 1.5 , REAL_COMPARE_DELTA ); - ck_assert_int_eq( p.left.base.type , ROFI_PU_EM ); - ck_assert_int_eq( p.left.style, ROFI_HL_DASH); +START_TEST(test_properties_distance_em_linestyle) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { sol: 1.3em solid; dash: 1.5em dash;}"); + ck_assert_ptr_nonnull(rofi_theme); + RofiDistance d = (RofiDistance){ + {1, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL}, ROFI_HL_SOLID}; + RofiPadding pi = (RofiPadding){d, d, d, d}; + RofiPadding p = rofi_theme_get_padding(&wid, "sol", pi); + ck_assert_double_eq_tol(p.left.base.distance, 1.3, REAL_COMPARE_DELTA); + ck_assert_int_eq(p.left.base.type, ROFI_PU_EM); + ck_assert_int_eq(p.left.style, ROFI_HL_SOLID); + + p = rofi_theme_get_padding(&wid, "dash", pi); + ck_assert_double_eq_tol(p.left.base.distance, 1.5, REAL_COMPARE_DELTA); + ck_assert_int_eq(p.left.base.type, ROFI_PU_EM); + ck_assert_int_eq(p.left.style, ROFI_HL_DASH); } END_TEST -START_TEST ( test_properties_distance_px) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { test: 10px;}"); - ck_assert_ptr_nonnull ( rofi_theme ); - RofiDistance d = (RofiDistance){ {1, ROFI_PU_EM, ROFI_DISTANCE_MODIFIER_NONE,NULL, NULL }, ROFI_HL_DASH}; - RofiPadding pi = (RofiPadding){d,d,d,d}; - RofiPadding p = rofi_theme_get_padding ( &wid, "test", pi); - ck_assert_double_eq_tol ( p.left.base.distance , 10.0 , REAL_COMPARE_DELTA ); - ck_assert_int_eq( p.left.base.type , ROFI_PU_PX ); - ck_assert_int_eq( p.left.style, ROFI_HL_SOLID); +START_TEST(test_properties_distance_px) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { test: 10px;}"); + ck_assert_ptr_nonnull(rofi_theme); + RofiDistance d = (RofiDistance){ + {1, ROFI_PU_EM, ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL}, ROFI_HL_DASH}; + RofiPadding pi = (RofiPadding){d, d, d, d}; + RofiPadding p = rofi_theme_get_padding(&wid, "test", pi); + ck_assert_double_eq_tol(p.left.base.distance, 10.0, REAL_COMPARE_DELTA); + ck_assert_int_eq(p.left.base.type, ROFI_PU_PX); + ck_assert_int_eq(p.left.style, ROFI_HL_SOLID); } END_TEST -START_TEST ( test_properties_distance_px_linestyle) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { sol: 10px solid; dash: 14px dash;}"); - ck_assert_ptr_nonnull ( rofi_theme ); - RofiDistance d = (RofiDistance){ {1, ROFI_PU_EM, ROFI_DISTANCE_MODIFIER_NONE,NULL, NULL }, ROFI_HL_DASH}; - RofiPadding pi = (RofiPadding){d,d,d,d}; - RofiPadding p = rofi_theme_get_padding ( &wid, "sol", pi); - ck_assert_double_eq_tol ( p.left.base.distance , 10.0 , REAL_COMPARE_DELTA ); - ck_assert_int_eq( p.left.base.type , ROFI_PU_PX ); - ck_assert_int_eq( p.left.style, ROFI_HL_SOLID); - p = rofi_theme_get_padding ( &wid, "dash", pi); - ck_assert_double_eq_tol ( p.left.base.distance , 14.0 , REAL_COMPARE_DELTA ); - ck_assert_int_eq( p.left.base.type , ROFI_PU_PX ); - ck_assert_int_eq( p.left.style, ROFI_HL_DASH); +START_TEST(test_properties_distance_px_linestyle) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { sol: 10px solid; dash: 14px dash;}"); + ck_assert_ptr_nonnull(rofi_theme); + RofiDistance d = (RofiDistance){ + {1, ROFI_PU_EM, ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL}, ROFI_HL_DASH}; + RofiPadding pi = (RofiPadding){d, d, d, d}; + RofiPadding p = rofi_theme_get_padding(&wid, "sol", pi); + ck_assert_double_eq_tol(p.left.base.distance, 10.0, REAL_COMPARE_DELTA); + ck_assert_int_eq(p.left.base.type, ROFI_PU_PX); + ck_assert_int_eq(p.left.style, ROFI_HL_SOLID); + p = rofi_theme_get_padding(&wid, "dash", pi); + ck_assert_double_eq_tol(p.left.base.distance, 14.0, REAL_COMPARE_DELTA); + ck_assert_int_eq(p.left.base.type, ROFI_PU_PX); + ck_assert_int_eq(p.left.style, ROFI_HL_DASH); } END_TEST -START_TEST ( test_properties_distance_percent) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { test: 10%;}"); - ck_assert_ptr_nonnull ( rofi_theme ); - RofiDistance d = (RofiDistance){ {1, ROFI_PU_EM, ROFI_DISTANCE_MODIFIER_NONE,NULL, NULL }, ROFI_HL_DASH}; - RofiPadding pi = (RofiPadding){d,d,d,d}; - RofiPadding p = rofi_theme_get_padding ( &wid, "test", pi); - ck_assert_double_eq_tol ( p.left.base.distance , 10.0 , REAL_COMPARE_DELTA ); - ck_assert_int_eq( p.left.base.type , ROFI_PU_PERCENT); - ck_assert_int_eq( p.left.style, ROFI_HL_SOLID); +START_TEST(test_properties_distance_percent) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { test: 10%;}"); + ck_assert_ptr_nonnull(rofi_theme); + RofiDistance d = (RofiDistance){ + {1, ROFI_PU_EM, ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL}, ROFI_HL_DASH}; + RofiPadding pi = (RofiPadding){d, d, d, d}; + RofiPadding p = rofi_theme_get_padding(&wid, "test", pi); + ck_assert_double_eq_tol(p.left.base.distance, 10.0, REAL_COMPARE_DELTA); + ck_assert_int_eq(p.left.base.type, ROFI_PU_PERCENT); + ck_assert_int_eq(p.left.style, ROFI_HL_SOLID); } END_TEST -START_TEST ( test_properties_distance_percent_linestyle) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { sol: 10% solid; dash: 10% dash;}"); - ck_assert_ptr_nonnull ( rofi_theme ); - RofiDistance d = (RofiDistance){ {1, ROFI_PU_EM, ROFI_DISTANCE_MODIFIER_NONE,NULL, NULL }, ROFI_HL_DASH}; - RofiPadding pi = (RofiPadding){d,d,d,d}; - RofiPadding p = rofi_theme_get_padding ( &wid, "sol", pi); - ck_assert_double_eq_tol ( p.left.base.distance , 10.0 , REAL_COMPARE_DELTA ); - ck_assert_int_eq( p.left.base.type , ROFI_PU_PERCENT); - ck_assert_int_eq( p.left.style, ROFI_HL_SOLID); - p = rofi_theme_get_padding ( &wid, "dash", pi); - ck_assert_double_eq_tol ( p.left.base.distance , 10 , REAL_COMPARE_DELTA ); - ck_assert_int_eq( p.left.base.type , ROFI_PU_PERCENT); - ck_assert_int_eq( p.left.style, ROFI_HL_DASH); +START_TEST(test_properties_distance_percent_linestyle) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { sol: 10% solid; dash: 10% dash;}"); + ck_assert_ptr_nonnull(rofi_theme); + RofiDistance d = (RofiDistance){ + {1, ROFI_PU_EM, ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL}, ROFI_HL_DASH}; + RofiPadding pi = (RofiPadding){d, d, d, d}; + RofiPadding p = rofi_theme_get_padding(&wid, "sol", pi); + ck_assert_double_eq_tol(p.left.base.distance, 10.0, REAL_COMPARE_DELTA); + ck_assert_int_eq(p.left.base.type, ROFI_PU_PERCENT); + ck_assert_int_eq(p.left.style, ROFI_HL_SOLID); + p = rofi_theme_get_padding(&wid, "dash", pi); + ck_assert_double_eq_tol(p.left.base.distance, 10, REAL_COMPARE_DELTA); + ck_assert_int_eq(p.left.base.type, ROFI_PU_PERCENT); + ck_assert_int_eq(p.left.style, ROFI_HL_DASH); } END_TEST -START_TEST ( test_properties_position) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { center: center; east: east; west: west; south: south; north:north;}" ); - ck_assert_int_eq ( rofi_theme_get_position ( &wid, "center", WL_SOUTH) , WL_CENTER ); - ck_assert_int_eq ( rofi_theme_get_position ( &wid, "south", WL_EAST) , WL_SOUTH); - ck_assert_int_eq ( rofi_theme_get_position ( &wid, "east", WL_WEST) , WL_EAST); - ck_assert_int_eq ( rofi_theme_get_position ( &wid, "west", WL_NORTH) , WL_WEST); - ck_assert_int_eq ( rofi_theme_get_position ( &wid, "north", WL_CENTER) , WL_NORTH); - - rofi_theme_parse_string ( "* { southwest: southwest; southeast: southeast; northwest: northwest; northeast:northeast;}" ); - ck_assert_int_eq ( rofi_theme_get_position ( &wid, "southwest", WL_EAST) , WL_SOUTH_WEST); - ck_assert_int_eq ( rofi_theme_get_position ( &wid, "southeast", WL_WEST) , WL_SOUTH_EAST); - ck_assert_int_eq ( rofi_theme_get_position ( &wid, "northwest", WL_NORTH) , WL_NORTH_WEST); - ck_assert_int_eq ( rofi_theme_get_position ( &wid, "northeast", WL_CENTER) , WL_NORTH_EAST); - rofi_theme_parse_string ( "* { southwest: south west; southeast: south east; northwest: north west; northeast:north east;}" ); - ck_assert_int_eq ( rofi_theme_get_position ( &wid, "southwest", WL_EAST) , WL_SOUTH_WEST); - ck_assert_int_eq ( rofi_theme_get_position ( &wid, "southeast", WL_WEST) , WL_SOUTH_EAST); - ck_assert_int_eq ( rofi_theme_get_position ( &wid, "northwest", WL_NORTH) , WL_NORTH_WEST); - ck_assert_int_eq ( rofi_theme_get_position ( &wid, "northeast", WL_CENTER) , WL_NORTH_EAST); - rofi_theme_parse_string ( "* { westsouth: westsouth; eastsouth: eastsouth; westnorth: westnorth; eastnorth:eastnorth;}" ); - ck_assert_int_eq ( rofi_theme_get_position ( &wid, "westsouth", WL_EAST) , WL_SOUTH_WEST); - ck_assert_int_eq ( rofi_theme_get_position ( &wid, "eastsouth", WL_WEST) , WL_SOUTH_EAST); - ck_assert_int_eq ( rofi_theme_get_position ( &wid, "westnorth", WL_NORTH) , WL_NORTH_WEST); - ck_assert_int_eq ( rofi_theme_get_position ( &wid, "eastnorth", WL_CENTER) , WL_NORTH_EAST); - rofi_theme_parse_string ( "* { westsouth: west south; eastsouth: east south; westnorth: west north; eastnorth:east north;}" ); - ck_assert_int_eq ( rofi_theme_get_position ( &wid, "westsouth", WL_EAST) , WL_SOUTH_WEST); - ck_assert_int_eq ( rofi_theme_get_position ( &wid, "eastsouth", WL_WEST) , WL_SOUTH_EAST); - ck_assert_int_eq ( rofi_theme_get_position ( &wid, "westnorth", WL_NORTH) , WL_NORTH_WEST); - ck_assert_int_eq ( rofi_theme_get_position ( &wid, "eastnorth", WL_CENTER) , WL_NORTH_EAST); - rofi_theme_parse_string ( "* { westeast: west east;}" ); - // Should return error. - // TODO: check error message. - g_string_free ( error_msg, TRUE); - error_msg = NULL; - error = 0; +START_TEST(test_properties_position) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { center: center; east: east; west: west; south: " + "south; north:north;}"); + ck_assert_int_eq(rofi_theme_get_position(&wid, "center", WL_SOUTH), + WL_CENTER); + ck_assert_int_eq(rofi_theme_get_position(&wid, "south", WL_EAST), WL_SOUTH); + ck_assert_int_eq(rofi_theme_get_position(&wid, "east", WL_WEST), WL_EAST); + ck_assert_int_eq(rofi_theme_get_position(&wid, "west", WL_NORTH), WL_WEST); + ck_assert_int_eq(rofi_theme_get_position(&wid, "north", WL_CENTER), WL_NORTH); + + rofi_theme_parse_string("* { southwest: southwest; southeast: southeast; " + "northwest: northwest; northeast:northeast;}"); + ck_assert_int_eq(rofi_theme_get_position(&wid, "southwest", WL_EAST), + WL_SOUTH_WEST); + ck_assert_int_eq(rofi_theme_get_position(&wid, "southeast", WL_WEST), + WL_SOUTH_EAST); + ck_assert_int_eq(rofi_theme_get_position(&wid, "northwest", WL_NORTH), + WL_NORTH_WEST); + ck_assert_int_eq(rofi_theme_get_position(&wid, "northeast", WL_CENTER), + WL_NORTH_EAST); + rofi_theme_parse_string("* { southwest: south west; southeast: south east; " + "northwest: north west; northeast:north east;}"); + ck_assert_int_eq(rofi_theme_get_position(&wid, "southwest", WL_EAST), + WL_SOUTH_WEST); + ck_assert_int_eq(rofi_theme_get_position(&wid, "southeast", WL_WEST), + WL_SOUTH_EAST); + ck_assert_int_eq(rofi_theme_get_position(&wid, "northwest", WL_NORTH), + WL_NORTH_WEST); + ck_assert_int_eq(rofi_theme_get_position(&wid, "northeast", WL_CENTER), + WL_NORTH_EAST); + rofi_theme_parse_string("* { westsouth: westsouth; eastsouth: eastsouth; " + "westnorth: westnorth; eastnorth:eastnorth;}"); + ck_assert_int_eq(rofi_theme_get_position(&wid, "westsouth", WL_EAST), + WL_SOUTH_WEST); + ck_assert_int_eq(rofi_theme_get_position(&wid, "eastsouth", WL_WEST), + WL_SOUTH_EAST); + ck_assert_int_eq(rofi_theme_get_position(&wid, "westnorth", WL_NORTH), + WL_NORTH_WEST); + ck_assert_int_eq(rofi_theme_get_position(&wid, "eastnorth", WL_CENTER), + WL_NORTH_EAST); + rofi_theme_parse_string("* { westsouth: west south; eastsouth: east south; " + "westnorth: west north; eastnorth:east north;}"); + ck_assert_int_eq(rofi_theme_get_position(&wid, "westsouth", WL_EAST), + WL_SOUTH_WEST); + ck_assert_int_eq(rofi_theme_get_position(&wid, "eastsouth", WL_WEST), + WL_SOUTH_EAST); + ck_assert_int_eq(rofi_theme_get_position(&wid, "westnorth", WL_NORTH), + WL_NORTH_WEST); + ck_assert_int_eq(rofi_theme_get_position(&wid, "eastnorth", WL_CENTER), + WL_NORTH_EAST); + rofi_theme_parse_string("* { westeast: west east;}"); + // Should return error. + // TODO: check error message. + g_string_free(error_msg, TRUE); + error_msg = NULL; + error = 0; } END_TEST -START_TEST ( test_properties_style) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { none: none; bold: bold; underline: underline; italic: italic; st: italic strikethrough;}"); - RofiHighlightColorStyle th = { ROFI_HL_BOLD, {0.0,0.0,0.0,0.0}}; - th = rofi_theme_get_highlight ( &wid, "none", th); - ck_assert_int_eq ( th.style , ROFI_HL_NONE ); - th = rofi_theme_get_highlight ( &wid, "underline", th); - ck_assert_int_eq ( th.style , ROFI_HL_UNDERLINE); - th = rofi_theme_get_highlight ( &wid, "italic", th); - ck_assert_int_eq ( th.style , ROFI_HL_ITALIC); - th = rofi_theme_get_highlight ( &wid, "bold", th); - ck_assert_int_eq ( th.style , ROFI_HL_BOLD); - th = rofi_theme_get_highlight ( &wid, "st", th); - ck_assert_int_eq ( th.style , ROFI_HL_ITALIC|ROFI_HL_STRIKETHROUGH); +START_TEST(test_properties_style) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { none: none; bold: bold; underline: underline; " + "italic: italic; st: italic strikethrough;}"); + RofiHighlightColorStyle th = {ROFI_HL_BOLD, {0.0, 0.0, 0.0, 0.0}}; + th = rofi_theme_get_highlight(&wid, "none", th); + ck_assert_int_eq(th.style, ROFI_HL_NONE); + th = rofi_theme_get_highlight(&wid, "underline", th); + ck_assert_int_eq(th.style, ROFI_HL_UNDERLINE); + th = rofi_theme_get_highlight(&wid, "italic", th); + ck_assert_int_eq(th.style, ROFI_HL_ITALIC); + th = rofi_theme_get_highlight(&wid, "bold", th); + ck_assert_int_eq(th.style, ROFI_HL_BOLD); + th = rofi_theme_get_highlight(&wid, "st", th); + ck_assert_int_eq(th.style, ROFI_HL_ITALIC | ROFI_HL_STRIKETHROUGH); } END_TEST -START_TEST ( test_properties_style2 ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - - rofi_theme_parse_string ( "* { boldu: bold underline ; boldi: bold italic; underlinei: underline italic; italicu: italic underline;}"); - RofiHighlightColorStyle th = { ROFI_HL_BOLD, {0.0,0.0,0.0,0.0}}; - th = rofi_theme_get_highlight ( &wid, "boldu", th); - ck_assert_int_eq ( th.style , (ROFI_HL_UNDERLINE|ROFI_HL_BOLD)); - th = rofi_theme_get_highlight ( &wid, "boldi", th); - ck_assert_int_eq ( th.style , (ROFI_HL_ITALIC|ROFI_HL_BOLD)); - th = rofi_theme_get_highlight ( &wid, "underlinei", th); - ck_assert_int_eq ( th.style , (ROFI_HL_ITALIC|ROFI_HL_UNDERLINE)); - th = rofi_theme_get_highlight ( &wid, "italicu", th); - ck_assert_int_eq ( th.style , (ROFI_HL_ITALIC|ROFI_HL_UNDERLINE)); +START_TEST(test_properties_style2) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + + rofi_theme_parse_string( + "* { boldu: bold underline ; boldi: bold italic; underlinei: underline " + "italic; italicu: italic underline;}"); + RofiHighlightColorStyle th = {ROFI_HL_BOLD, {0.0, 0.0, 0.0, 0.0}}; + th = rofi_theme_get_highlight(&wid, "boldu", th); + ck_assert_int_eq(th.style, (ROFI_HL_UNDERLINE | ROFI_HL_BOLD)); + th = rofi_theme_get_highlight(&wid, "boldi", th); + ck_assert_int_eq(th.style, (ROFI_HL_ITALIC | ROFI_HL_BOLD)); + th = rofi_theme_get_highlight(&wid, "underlinei", th); + ck_assert_int_eq(th.style, (ROFI_HL_ITALIC | ROFI_HL_UNDERLINE)); + th = rofi_theme_get_highlight(&wid, "italicu", th); + ck_assert_int_eq(th.style, (ROFI_HL_ITALIC | ROFI_HL_UNDERLINE)); } END_TEST -START_TEST ( test_properties_style_color ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { comb: bold #123; }"); - RofiHighlightColorStyle th = { ROFI_HL_BOLD, {0.0,0.0,0.0,0.0}}; - th = rofi_theme_get_highlight ( &wid, "comb", th); - ck_assert_int_eq ( th.style , (ROFI_HL_BOLD|ROFI_HL_COLOR)); - ck_assert_double_eq_tol ( th.color.red , (1/15.0), REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( th.color.green , (2/15.0), REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( th.color.blue , (3/15.0), REAL_COMPARE_DELTA ); +START_TEST(test_properties_style_color) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { comb: bold #123; }"); + RofiHighlightColorStyle th = {ROFI_HL_BOLD, {0.0, 0.0, 0.0, 0.0}}; + th = rofi_theme_get_highlight(&wid, "comb", th); + ck_assert_int_eq(th.style, (ROFI_HL_BOLD | ROFI_HL_COLOR)); + ck_assert_double_eq_tol(th.color.red, (1 / 15.0), REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(th.color.green, (2 / 15.0), REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(th.color.blue, (3 / 15.0), REAL_COMPARE_DELTA); } END_TEST -START_TEST ( test_properties_color_h3 ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { red: #F00; green: #0F0; blue: #00F; }"); - ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE ); - Property *p = rofi_theme_find_property ( twid, P_COLOR, "red", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.red , 1 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , REAL_COMPARE_DELTA ); - p = rofi_theme_find_property ( twid, P_COLOR, "green", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.red , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 1 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , REAL_COMPARE_DELTA ); - p = rofi_theme_find_property ( twid, P_COLOR, "blue", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.red , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 1 , REAL_COMPARE_DELTA ); +START_TEST(test_properties_color_h3) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { red: #F00; green: #0F0; blue: #00F; }"); + ThemeWidget *twid = rofi_theme_find_widget(wid.name, wid.state, FALSE); + Property *p = rofi_theme_find_property(twid, P_COLOR, "red", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.red, 1, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 0, REAL_COMPARE_DELTA); + p = rofi_theme_find_property(twid, P_COLOR, "green", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.red, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 1, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 0, REAL_COMPARE_DELTA); + p = rofi_theme_find_property(twid, P_COLOR, "blue", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.red, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 1, REAL_COMPARE_DELTA); } END_TEST -START_TEST ( test_properties_color_h6 ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { red: #FF0000; green: #00FF00; blue: #0000FF; }"); - ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE ); - Property *p = rofi_theme_find_property ( twid, P_COLOR, "red", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.red , 1 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , REAL_COMPARE_DELTA ); - p = rofi_theme_find_property ( twid, P_COLOR, "green", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.red , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 1 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , REAL_COMPARE_DELTA ); - p = rofi_theme_find_property ( twid, P_COLOR, "blue", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.red , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 1 , REAL_COMPARE_DELTA ); +START_TEST(test_properties_color_h6) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { red: #FF0000; green: #00FF00; blue: #0000FF; }"); + ThemeWidget *twid = rofi_theme_find_widget(wid.name, wid.state, FALSE); + Property *p = rofi_theme_find_property(twid, P_COLOR, "red", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.red, 1, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 0, REAL_COMPARE_DELTA); + p = rofi_theme_find_property(twid, P_COLOR, "green", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.red, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 1, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 0, REAL_COMPARE_DELTA); + p = rofi_theme_find_property(twid, P_COLOR, "blue", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.red, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 1, REAL_COMPARE_DELTA); } END_TEST -START_TEST ( test_properties_color_h4 ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { red: #F003; green: #0F02; blue: #00F1; }"); - ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE ); - Property *p = rofi_theme_find_property ( twid, P_COLOR, "red", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.2 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 1 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , REAL_COMPARE_DELTA ); - p = rofi_theme_find_property ( twid, P_COLOR, "green", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 1/7.5 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 1 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , REAL_COMPARE_DELTA ); - p = rofi_theme_find_property ( twid, P_COLOR, "blue", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 1/15.0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 1 , REAL_COMPARE_DELTA ); +START_TEST(test_properties_color_h4) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { red: #F003; green: #0F02; blue: #00F1; }"); + ThemeWidget *twid = rofi_theme_find_widget(wid.name, wid.state, FALSE); + Property *p = rofi_theme_find_property(twid, P_COLOR, "red", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.2, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 1, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 0, REAL_COMPARE_DELTA); + p = rofi_theme_find_property(twid, P_COLOR, "green", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 1 / 7.5, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 1, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 0, REAL_COMPARE_DELTA); + p = rofi_theme_find_property(twid, P_COLOR, "blue", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 1 / 15.0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 1, REAL_COMPARE_DELTA); } END_TEST -START_TEST ( test_properties_color_h8 ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { red: #FF000033; green: #00FF0022; blue: #0000FF11; }"); - ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE ); - Property *p = rofi_theme_find_property ( twid, P_COLOR, "red", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.2 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 1 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , REAL_COMPARE_DELTA ); - p = rofi_theme_find_property ( twid, P_COLOR, "green", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 1/7.5 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 1 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , REAL_COMPARE_DELTA ); - p = rofi_theme_find_property ( twid, P_COLOR, "blue", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 1/15.0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 1 , REAL_COMPARE_DELTA ); +START_TEST(test_properties_color_h8) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string( + "* { red: #FF000033; green: #00FF0022; blue: #0000FF11; }"); + ThemeWidget *twid = rofi_theme_find_widget(wid.name, wid.state, FALSE); + Property *p = rofi_theme_find_property(twid, P_COLOR, "red", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.2, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 1, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 0, REAL_COMPARE_DELTA); + p = rofi_theme_find_property(twid, P_COLOR, "green", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 1 / 7.5, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 1, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 0, REAL_COMPARE_DELTA); + p = rofi_theme_find_property(twid, P_COLOR, "blue", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 1 / 15.0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 1, REAL_COMPARE_DELTA); } END_TEST -START_TEST ( test_properties_color_rgb ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { red: rgb(100%,0%,0%); green: rgb(0%,100%,0%); blue: rgb(0%,0%,100%); }"); - ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE ); - Property *p = rofi_theme_find_property ( twid, P_COLOR, "red", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.red , 1 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , REAL_COMPARE_DELTA ); - p = rofi_theme_find_property ( twid, P_COLOR, "green", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.red , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 1 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , REAL_COMPARE_DELTA ); - p = rofi_theme_find_property ( twid, P_COLOR, "blue", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.red , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 1 , REAL_COMPARE_DELTA ); +START_TEST(test_properties_color_rgb) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { red: rgb(100%,0%,0%); green: rgb(0%,100%,0%); " + "blue: rgb(0%,0%,100%); }"); + ThemeWidget *twid = rofi_theme_find_widget(wid.name, wid.state, FALSE); + Property *p = rofi_theme_find_property(twid, P_COLOR, "red", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.red, 1, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 0, REAL_COMPARE_DELTA); + p = rofi_theme_find_property(twid, P_COLOR, "green", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.red, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 1, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 0, REAL_COMPARE_DELTA); + p = rofi_theme_find_property(twid, P_COLOR, "blue", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.red, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 1, REAL_COMPARE_DELTA); } END_TEST -START_TEST ( test_properties_color_rgba_p ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { red: rgba(100%,0%,0%,0.3); green: rgba(0%,100%,0%,0.2); blue: rgba(0%,0%,100%,0.7); }"); - ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE ); - Property *p = rofi_theme_find_property ( twid, P_COLOR, "red", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.3 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 1 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , REAL_COMPARE_DELTA ); - p = rofi_theme_find_property ( twid, P_COLOR, "green", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.2 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 1 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , REAL_COMPARE_DELTA ); - p = rofi_theme_find_property ( twid, P_COLOR, "blue", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.7 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 1 , REAL_COMPARE_DELTA ); +START_TEST(test_properties_color_rgba_p) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string( + "* { red: rgba(100%,0%,0%,0.3); green: rgba(0%,100%,0%,0.2); blue: " + "rgba(0%,0%,100%,0.7); }"); + ThemeWidget *twid = rofi_theme_find_widget(wid.name, wid.state, FALSE); + Property *p = rofi_theme_find_property(twid, P_COLOR, "red", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.3, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 1, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 0, REAL_COMPARE_DELTA); + p = rofi_theme_find_property(twid, P_COLOR, "green", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.2, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 1, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 0, REAL_COMPARE_DELTA); + p = rofi_theme_find_property(twid, P_COLOR, "blue", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.7, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 1, REAL_COMPARE_DELTA); } END_TEST -START_TEST ( test_properties_color_rgba_percent_p ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { red: rgba(100%,0%,0%,30%); green: rgba(0%,100%,0%,20%); blue: rgba(0% 0% 100%/70.0%); }"); - ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE ); - Property *p = rofi_theme_find_property ( twid, P_COLOR, "red", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.3 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 1 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , REAL_COMPARE_DELTA ); - p = rofi_theme_find_property ( twid, P_COLOR, "green", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.2 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 1 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , REAL_COMPARE_DELTA ); - p = rofi_theme_find_property ( twid, P_COLOR, "blue", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.7 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 1 , REAL_COMPARE_DELTA ); +START_TEST(test_properties_color_rgba_percent_p) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string( + "* { red: rgba(100%,0%,0%,30%); green: rgba(0%,100%,0%,20%); blue: " + "rgba(0% 0% 100%/70.0%); }"); + ThemeWidget *twid = rofi_theme_find_widget(wid.name, wid.state, FALSE); + Property *p = rofi_theme_find_property(twid, P_COLOR, "red", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.3, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 1, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 0, REAL_COMPARE_DELTA); + p = rofi_theme_find_property(twid, P_COLOR, "green", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.2, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 1, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 0, REAL_COMPARE_DELTA); + p = rofi_theme_find_property(twid, P_COLOR, "blue", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.7, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 1, REAL_COMPARE_DELTA); } END_TEST -START_TEST ( test_properties_color_rgb_p ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { red: rgb(255,0,0); green: rgb(0,255,0); blue: rgb(0,0,255); }"); - ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE ); - Property *p = rofi_theme_find_property ( twid, P_COLOR, "red", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.red , 1 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , REAL_COMPARE_DELTA ); - p = rofi_theme_find_property ( twid, P_COLOR, "green", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.red , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 1 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , REAL_COMPARE_DELTA ); - p = rofi_theme_find_property ( twid, P_COLOR, "blue", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.red , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 1 , REAL_COMPARE_DELTA ); +START_TEST(test_properties_color_rgb_p) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string( + "* { red: rgb(255,0,0); green: rgb(0,255,0); blue: rgb(0,0,255); }"); + ThemeWidget *twid = rofi_theme_find_widget(wid.name, wid.state, FALSE); + Property *p = rofi_theme_find_property(twid, P_COLOR, "red", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.red, 1, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 0, REAL_COMPARE_DELTA); + p = rofi_theme_find_property(twid, P_COLOR, "green", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.red, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 1, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 0, REAL_COMPARE_DELTA); + p = rofi_theme_find_property(twid, P_COLOR, "blue", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.red, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 1, REAL_COMPARE_DELTA); } END_TEST -START_TEST ( test_properties_color_rgba ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { red: rgba(255,0,0,0.3); green: rgba(0,255,0,0.2); blue: rgba(0 0 255 /0.7); }"); - ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE ); - ck_assert_ptr_nonnull ( twid ); - Property *p = rofi_theme_find_property ( twid, P_COLOR, "red", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.3 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 1 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , REAL_COMPARE_DELTA ); - p = rofi_theme_find_property ( twid, P_COLOR, "green", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.2 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 1 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , REAL_COMPARE_DELTA ); - p = rofi_theme_find_property ( twid, P_COLOR, "blue", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.7 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 1 , REAL_COMPARE_DELTA ); +START_TEST(test_properties_color_rgba) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { red: rgba(255,0,0,0.3); green: " + "rgba(0,255,0,0.2); blue: rgba(0 0 255 /0.7); }"); + ThemeWidget *twid = rofi_theme_find_widget(wid.name, wid.state, FALSE); + ck_assert_ptr_nonnull(twid); + Property *p = rofi_theme_find_property(twid, P_COLOR, "red", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.3, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 1, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 0, REAL_COMPARE_DELTA); + p = rofi_theme_find_property(twid, P_COLOR, "green", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.2, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 1, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 0, REAL_COMPARE_DELTA); + p = rofi_theme_find_property(twid, P_COLOR, "blue", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.7, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 1, REAL_COMPARE_DELTA); } END_TEST -START_TEST ( test_properties_color_rgba_percent ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { red: rgba(255,0,0,30%); green: rgba(0,255,0,20%); blue: rgba(0,0,255,70.0%); }"); - ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE ); - Property *p = rofi_theme_find_property ( twid, P_COLOR, "red", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.3 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 1 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , REAL_COMPARE_DELTA ); - p = rofi_theme_find_property ( twid, P_COLOR, "green", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.2 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 1 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , REAL_COMPARE_DELTA ); - p = rofi_theme_find_property ( twid, P_COLOR, "blue", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.7 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 1 , REAL_COMPARE_DELTA ); +START_TEST(test_properties_color_rgba_percent) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { red: rgba(255,0,0,30%); green: " + "rgba(0,255,0,20%); blue: rgba(0,0,255,70.0%); }"); + ThemeWidget *twid = rofi_theme_find_widget(wid.name, wid.state, FALSE); + Property *p = rofi_theme_find_property(twid, P_COLOR, "red", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.3, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 1, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 0, REAL_COMPARE_DELTA); + p = rofi_theme_find_property(twid, P_COLOR, "green", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.2, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 1, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 0, REAL_COMPARE_DELTA); + p = rofi_theme_find_property(twid, P_COLOR, "blue", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.7, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 1, REAL_COMPARE_DELTA); } END_TEST -START_TEST ( test_properties_color_argb ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { red: argb:33FF0000; green: argb:2200FF00; blue: argb:110000FF; }"); - ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE ); - Property *p = rofi_theme_find_property ( twid, P_COLOR, "red", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.2 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 1 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , REAL_COMPARE_DELTA ); - p = rofi_theme_find_property ( twid, P_COLOR, "green", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 1/7.5 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 1 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , REAL_COMPARE_DELTA ); - p = rofi_theme_find_property ( twid, P_COLOR, "blue", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 1/15.0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.green , 0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.blue , 1 , REAL_COMPARE_DELTA ); +START_TEST(test_properties_color_argb) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string( + "* { red: argb:33FF0000; green: argb:2200FF00; blue: argb:110000FF; }"); + ThemeWidget *twid = rofi_theme_find_widget(wid.name, wid.state, FALSE); + Property *p = rofi_theme_find_property(twid, P_COLOR, "red", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.2, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 1, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 0, REAL_COMPARE_DELTA); + p = rofi_theme_find_property(twid, P_COLOR, "green", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 1 / 7.5, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 1, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 0, REAL_COMPARE_DELTA); + p = rofi_theme_find_property(twid, P_COLOR, "blue", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 1 / 15.0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.green, 0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.blue, 1, REAL_COMPARE_DELTA); } END_TEST -START_TEST ( test_properties_color_hsl ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { test1: hsl(127,40%,66.66666%); test2: hsl(0, 100%, 50%); testa: hsl(127,40%, 66.66666%, 30%);}"); - ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE ); - - Property *p = rofi_theme_find_property ( twid, P_COLOR, "test1", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 1.0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0x88/255.0 , 0.004); - ck_assert_double_eq_tol ( p->value.color.green, 0xcd/255.0, 0.004 ); - ck_assert_double_eq_tol ( p->value.color.blue , 0x90/255.0 , 0.004); - p = rofi_theme_find_property ( twid, P_COLOR, "test2", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 1.0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 1 , 0.004); - ck_assert_double_eq_tol ( p->value.color.green , 0, 0.004 ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , 0.004); - p = rofi_theme_find_property ( twid, P_COLOR, "testa", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.3 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0x88/255.0 ,0.004); - ck_assert_double_eq_tol ( p->value.color.green ,0xcd/255.0, 0.004 ); - ck_assert_double_eq_tol ( p->value.color.blue , 0x90/255.0 ,0.004); +START_TEST(test_properties_color_hsl) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { test1: hsl(127,40%,66.66666%); test2: hsl(0, " + "100%, 50%); testa: hsl(127,40%, 66.66666%, 30%);}"); + ThemeWidget *twid = rofi_theme_find_widget(wid.name, wid.state, FALSE); + + Property *p = rofi_theme_find_property(twid, P_COLOR, "test1", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 1.0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0x88 / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.green, 0xcd / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.blue, 0x90 / 255.0, 0.004); + p = rofi_theme_find_property(twid, P_COLOR, "test2", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 1.0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 1, 0.004); + ck_assert_double_eq_tol(p->value.color.green, 0, 0.004); + ck_assert_double_eq_tol(p->value.color.blue, 0, 0.004); + p = rofi_theme_find_property(twid, P_COLOR, "testa", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.3, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0x88 / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.green, 0xcd / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.blue, 0x90 / 255.0, 0.004); } END_TEST -START_TEST ( test_properties_color_hsla ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { test1: hsla(127,40%,66.66666%, 40%); test2: hsla(0, 100%, 50%,55%); }"); - ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE ); - - Property *p = rofi_theme_find_property ( twid, P_COLOR, "test1", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.4 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0x88/255.0 , 0.004); - ck_assert_double_eq_tol ( p->value.color.green , 0xcd/255.0, 0.004 ); - ck_assert_double_eq_tol ( p->value.color.blue , 0x90/255.0 , 0.004); - p = rofi_theme_find_property ( twid, P_COLOR, "test2", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.55 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 1 , 0.004); - ck_assert_double_eq_tol ( p->value.color.green , 0, 0.004 ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , 0.004); +START_TEST(test_properties_color_hsla) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { test1: hsla(127,40%,66.66666%, 40%); test2: " + "hsla(0, 100%, 50%,55%); }"); + ThemeWidget *twid = rofi_theme_find_widget(wid.name, wid.state, FALSE); + + Property *p = rofi_theme_find_property(twid, P_COLOR, "test1", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.4, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0x88 / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.green, 0xcd / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.blue, 0x90 / 255.0, 0.004); + p = rofi_theme_find_property(twid, P_COLOR, "test2", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.55, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 1, 0.004); + ck_assert_double_eq_tol(p->value.color.green, 0, 0.004); + ck_assert_double_eq_tol(p->value.color.blue, 0, 0.004); } END_TEST -START_TEST ( test_properties_color_hsl_ws ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { test1: hsl(127 40% 66.66666%); test2: hsl(0 100% 50%); testa: hsl(127 40% 66.66666% / 30%);}"); - ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE ); - - Property *p = rofi_theme_find_property ( twid, P_COLOR, "test1", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 1.0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0x88/255.0 , 0.004); - ck_assert_double_eq_tol ( p->value.color.green, 0xcd/255.0, 0.004 ); - ck_assert_double_eq_tol ( p->value.color.blue , 0x90/255.0 , 0.004); - p = rofi_theme_find_property ( twid, P_COLOR, "test2", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 1.0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 1 , 0.004); - ck_assert_double_eq_tol ( p->value.color.green , 0, 0.004 ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , 0.004); - p = rofi_theme_find_property ( twid, P_COLOR, "testa", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.3 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0x88/255.0 ,0.004); - ck_assert_double_eq_tol ( p->value.color.green ,0xcd/255.0, 0.004 ); - ck_assert_double_eq_tol ( p->value.color.blue , 0x90/255.0 ,0.004); +START_TEST(test_properties_color_hsl_ws) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string( + "* { test1: hsl(127 40% 66.66666%); test2: hsl(0 100% 50%); testa: " + "hsl(127 40% 66.66666% / 30%);}"); + ThemeWidget *twid = rofi_theme_find_widget(wid.name, wid.state, FALSE); + + Property *p = rofi_theme_find_property(twid, P_COLOR, "test1", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 1.0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0x88 / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.green, 0xcd / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.blue, 0x90 / 255.0, 0.004); + p = rofi_theme_find_property(twid, P_COLOR, "test2", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 1.0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 1, 0.004); + ck_assert_double_eq_tol(p->value.color.green, 0, 0.004); + ck_assert_double_eq_tol(p->value.color.blue, 0, 0.004); + p = rofi_theme_find_property(twid, P_COLOR, "testa", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.3, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0x88 / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.green, 0xcd / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.blue, 0x90 / 255.0, 0.004); } END_TEST -START_TEST ( test_properties_color_hsla_ws ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { test1: hsla(127 40% 66.66666% / 0.3); test2: hsla(0 100% 50%/ 55%); }"); - ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE ); - - Property *p = rofi_theme_find_property ( twid, P_COLOR, "test1", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.3 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0x88/255.0 , 0.004); - ck_assert_double_eq_tol ( p->value.color.green , 0xcd/255.0, 0.004 ); - ck_assert_double_eq_tol ( p->value.color.blue , 0x90/255.0 , 0.004); - p = rofi_theme_find_property ( twid, P_COLOR, "test2", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.55 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 1 , 0.004); - ck_assert_double_eq_tol ( p->value.color.green , 0, 0.004 ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , 0.004); +START_TEST(test_properties_color_hsla_ws) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { test1: hsla(127 40% 66.66666% / 0.3); test2: " + "hsla(0 100% 50%/ 55%); }"); + ThemeWidget *twid = rofi_theme_find_widget(wid.name, wid.state, FALSE); + + Property *p = rofi_theme_find_property(twid, P_COLOR, "test1", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.3, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0x88 / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.green, 0xcd / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.blue, 0x90 / 255.0, 0.004); + p = rofi_theme_find_property(twid, P_COLOR, "test2", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.55, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 1, 0.004); + ck_assert_double_eq_tol(p->value.color.green, 0, 0.004); + ck_assert_double_eq_tol(p->value.color.blue, 0, 0.004); } END_TEST -START_TEST ( test_properties_color_hwb ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { test1: hwb(190,65%,0%); test2: hwb(265, 31%, 29%); testa: hwb(265, 31%, 29%, 40%); }"); - ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE ); - - Property *p = rofi_theme_find_property ( twid, P_COLOR, "test2", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 1.0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0x7a/255.0 , 0.004); - ck_assert_double_eq_tol ( p->value.color.green , 0x4f/255.0, 0.004 ); - ck_assert_double_eq_tol ( p->value.color.blue , 0xb5/255.0 , 0.004); - p = rofi_theme_find_property ( twid, P_COLOR, "test1", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 1.0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 166/255.0, 0.004); - ck_assert_double_eq_tol ( p->value.color.green ,240/255.0, 0.004 ); - ck_assert_double_eq_tol ( p->value.color.blue , 255/255.0 , 0.004); - p = rofi_theme_find_property ( twid, P_COLOR, "testa", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.4 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0x7a/255.0 , 0.004); - ck_assert_double_eq_tol ( p->value.color.green , 0x4f/255.0, 0.004 ); - ck_assert_double_eq_tol ( p->value.color.blue , 0xb5/255.0 , 0.004); +START_TEST(test_properties_color_hwb) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { test1: hwb(190,65%,0%); test2: hwb(265, 31%, " + "29%); testa: hwb(265, 31%, 29%, 40%); }"); + ThemeWidget *twid = rofi_theme_find_widget(wid.name, wid.state, FALSE); + + Property *p = rofi_theme_find_property(twid, P_COLOR, "test2", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 1.0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0x7a / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.green, 0x4f / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.blue, 0xb5 / 255.0, 0.004); + p = rofi_theme_find_property(twid, P_COLOR, "test1", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 1.0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 166 / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.green, 240 / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.blue, 255 / 255.0, 0.004); + p = rofi_theme_find_property(twid, P_COLOR, "testa", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.4, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0x7a / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.green, 0x4f / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.blue, 0xb5 / 255.0, 0.004); } END_TEST -START_TEST ( test_properties_color_hwb_ws ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { test1: hwb(190 deg 65 %0%); test2: hwb(295 grad 31% 29%);testa: hwb(0.736 turn 31% 29% / 40%); rada: hwb(0.2 rad 30% 30%/40%); }"); - ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE ); - - Property *p = rofi_theme_find_property ( twid, P_COLOR, "test2", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 1.0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0x7a/255.0 , 0.004); - ck_assert_double_eq_tol ( p->value.color.green , 0x4f/255.0, 0.004 ); - ck_assert_double_eq_tol ( p->value.color.blue , 0xb5/255.0 , 0.004); - p = rofi_theme_find_property ( twid, P_COLOR, "test1", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 1.0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 166/255.0, 0.004); - ck_assert_double_eq_tol ( p->value.color.green ,240/255.0, 0.004 ); - ck_assert_double_eq_tol ( p->value.color.blue , 255/255.0 , 0.004); - p = rofi_theme_find_property ( twid, P_COLOR, "testa", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.4 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0x7a/255.0 , 0.004); - ck_assert_double_eq_tol ( p->value.color.green , 0x4f/255.0, 0.004 ); - ck_assert_double_eq_tol ( p->value.color.blue , 0xb5/255.0 , 0.004); - p = rofi_theme_find_property ( twid, P_COLOR, "rada", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.4 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0.7 , 0.004); - ck_assert_double_eq_tol ( p->value.color.green , 0.376, 0.004 ); - ck_assert_double_eq_tol ( p->value.color.blue , 0.3 , 0.004); +START_TEST(test_properties_color_hwb_ws) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string( + "* { test1: hwb(190 deg 65 %0%); test2: hwb(295 grad 31% 29%);testa: " + "hwb(0.736 turn 31% 29% / 40%); rada: hwb(0.2 rad 30% 30%/40%); }"); + ThemeWidget *twid = rofi_theme_find_widget(wid.name, wid.state, FALSE); + + Property *p = rofi_theme_find_property(twid, P_COLOR, "test2", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 1.0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0x7a / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.green, 0x4f / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.blue, 0xb5 / 255.0, 0.004); + p = rofi_theme_find_property(twid, P_COLOR, "test1", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 1.0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 166 / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.green, 240 / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.blue, 255 / 255.0, 0.004); + p = rofi_theme_find_property(twid, P_COLOR, "testa", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.4, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0x7a / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.green, 0x4f / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.blue, 0xb5 / 255.0, 0.004); + p = rofi_theme_find_property(twid, P_COLOR, "rada", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.4, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0.7, 0.004); + ck_assert_double_eq_tol(p->value.color.green, 0.376, 0.004); + ck_assert_double_eq_tol(p->value.color.blue, 0.3, 0.004); } END_TEST -START_TEST ( test_properties_color_cmyk ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { test1: cmyk ( 41%, 0%, 100%, 0%); test2: cmyk ( 0, 1.0, 1.0, 0);}"); - ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE ); - - Property *p = rofi_theme_find_property ( twid, P_COLOR, "test1", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 1.0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0x96/255.0 , 0.004); - ck_assert_double_eq_tol ( p->value.color.green , 1.0, 0.004 ); - ck_assert_double_eq_tol ( p->value.color.blue , 0.0 , 0.004); - p = rofi_theme_find_property ( twid, P_COLOR, "test2", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 1.0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 1 , 0.004); - ck_assert_double_eq_tol ( p->value.color.green , 0, 0.004 ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , 0.004); +START_TEST(test_properties_color_cmyk) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string( + "* { test1: cmyk ( 41%, 0%, 100%, 0%); test2: cmyk ( 0, 1.0, 1.0, 0);}"); + ThemeWidget *twid = rofi_theme_find_widget(wid.name, wid.state, FALSE); + + Property *p = rofi_theme_find_property(twid, P_COLOR, "test1", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 1.0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0x96 / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.green, 1.0, 0.004); + ck_assert_double_eq_tol(p->value.color.blue, 0.0, 0.004); + p = rofi_theme_find_property(twid, P_COLOR, "test2", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 1.0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 1, 0.004); + ck_assert_double_eq_tol(p->value.color.green, 0, 0.004); + ck_assert_double_eq_tol(p->value.color.blue, 0, 0.004); } END_TEST -START_TEST ( test_properties_color_cmyk_ws ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { test1: cmyk ( 41% 0% 100% 0%); test2: cmyk ( 0 1.0 1.0 0);}"); - ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE ); - - Property *p = rofi_theme_find_property ( twid, P_COLOR, "test1", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 1.0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0x96/255.0 , 0.004); - ck_assert_double_eq_tol ( p->value.color.green , 1.0, 0.004 ); - ck_assert_double_eq_tol ( p->value.color.blue , 0.0 , 0.004); - p = rofi_theme_find_property ( twid, P_COLOR, "test2", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 1.0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 1 , 0.004); - ck_assert_double_eq_tol ( p->value.color.green , 0, 0.004 ); - ck_assert_double_eq_tol ( p->value.color.blue , 0 , 0.004); +START_TEST(test_properties_color_cmyk_ws) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string( + "* { test1: cmyk ( 41% 0% 100% 0%); test2: cmyk ( 0 1.0 1.0 0);}"); + ThemeWidget *twid = rofi_theme_find_widget(wid.name, wid.state, FALSE); + + Property *p = rofi_theme_find_property(twid, P_COLOR, "test1", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 1.0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0x96 / 255.0, 0.004); + ck_assert_double_eq_tol(p->value.color.green, 1.0, 0.004); + ck_assert_double_eq_tol(p->value.color.blue, 0.0, 0.004); + p = rofi_theme_find_property(twid, P_COLOR, "test2", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 1.0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 1, 0.004); + ck_assert_double_eq_tol(p->value.color.green, 0, 0.004); + ck_assert_double_eq_tol(p->value.color.blue, 0, 0.004); } END_TEST -START_TEST ( test_properties_color_names ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - for ( unsigned int iter = 0; iter < num_CSSColors; iter++ ) { - char * str = g_strdup_printf("* { color: %s;}", CSSColors[iter].name); - rofi_theme_parse_string(str); - ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE ); - Property *p = rofi_theme_find_property ( twid, P_COLOR, "text-color", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 1.0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , CSSColors[iter].r/255.0, 0.004); - ck_assert_double_eq_tol ( p->value.color.green, CSSColors[iter].g/255.0, 0.004 ); - ck_assert_double_eq_tol ( p->value.color.blue , CSSColors[iter].b/255.0, 0.004); - - g_free ( str ); - } - { - rofi_theme_parse_string("* {color: transparent;}"); - ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE ); - Property *p = rofi_theme_find_property ( twid, P_COLOR, "text-color", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , 0.0 , REAL_COMPARE_DELTA ); - ck_assert_double_eq_tol ( p->value.color.red , 0.0, 0.004); - ck_assert_double_eq_tol ( p->value.color.green, 0.0, 0.004 ); - ck_assert_double_eq_tol ( p->value.color.blue , 0.0, 0.004); - } +START_TEST(test_properties_color_names) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + for (unsigned int iter = 0; iter < num_CSSColors; iter++) { + char *str = g_strdup_printf("* { color: %s;}", CSSColors[iter].name); + rofi_theme_parse_string(str); + ThemeWidget *twid = rofi_theme_find_widget(wid.name, wid.state, FALSE); + Property *p = rofi_theme_find_property(twid, P_COLOR, "text-color", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 1.0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, CSSColors[iter].r / 255.0, + 0.004); + ck_assert_double_eq_tol(p->value.color.green, CSSColors[iter].g / 255.0, + 0.004); + ck_assert_double_eq_tol(p->value.color.blue, CSSColors[iter].b / 255.0, + 0.004); + + g_free(str); + } + { + rofi_theme_parse_string("* {color: transparent;}"); + ThemeWidget *twid = rofi_theme_find_widget(wid.name, wid.state, FALSE); + Property *p = rofi_theme_find_property(twid, P_COLOR, "text-color", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, 0.0, REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, 0.0, 0.004); + ck_assert_double_eq_tol(p->value.color.green, 0.0, 0.004); + ck_assert_double_eq_tol(p->value.color.blue, 0.0, 0.004); + } } END_TEST -START_TEST ( test_properties_color_names_alpha ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - for ( unsigned int iter = 0; iter < num_CSSColors; iter++ ) { - char * str = g_strdup_printf("* { color: %s / %d %%;}", CSSColors[iter].name, iter%101); - rofi_theme_parse_string(str); - ThemeWidget *twid = rofi_theme_find_widget ( wid.name, wid.state, FALSE ); - Property *p = rofi_theme_find_property ( twid, P_COLOR, "text-color", FALSE ); - ck_assert_ptr_nonnull ( p ); - ck_assert_double_eq_tol ( p->value.color.alpha , (iter%101)/100.0, REAL_COMPARE_DELTA); - ck_assert_double_eq_tol ( p->value.color.red , CSSColors[iter].r/255.0, 0.004); - ck_assert_double_eq_tol ( p->value.color.green, CSSColors[iter].g/255.0, 0.004 ); - ck_assert_double_eq_tol ( p->value.color.blue , CSSColors[iter].b/255.0, 0.004); - - g_free ( str ); - } +START_TEST(test_properties_color_names_alpha) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + for (unsigned int iter = 0; iter < num_CSSColors; iter++) { + char *str = g_strdup_printf("* { color: %s / %d %%;}", CSSColors[iter].name, + iter % 101); + rofi_theme_parse_string(str); + ThemeWidget *twid = rofi_theme_find_widget(wid.name, wid.state, FALSE); + Property *p = rofi_theme_find_property(twid, P_COLOR, "text-color", FALSE); + ck_assert_ptr_nonnull(p); + ck_assert_double_eq_tol(p->value.color.alpha, (iter % 101) / 100.0, + REAL_COMPARE_DELTA); + ck_assert_double_eq_tol(p->value.color.red, CSSColors[iter].r / 255.0, + 0.004); + ck_assert_double_eq_tol(p->value.color.green, CSSColors[iter].g / 255.0, + 0.004); + ck_assert_double_eq_tol(p->value.color.blue, CSSColors[iter].b / 255.0, + 0.004); + + g_free(str); + } } END_TEST -START_TEST ( test_properties_padding_2 ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { test: 10px 20px;}"); - RofiDistance d = (RofiDistance){ {1, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE,NULL, NULL }, ROFI_HL_SOLID}; - RofiPadding pi = (RofiPadding){d,d,d,d}; - RofiPadding p = rofi_theme_get_padding ( &wid, "test", pi); - ck_assert_double_eq_tol ( p.left.base.distance , 20, REAL_COMPARE_DELTA ); - ck_assert_int_eq ( p.left.base.type , ROFI_PU_PX ); - ck_assert_double_eq_tol ( p.right.base.distance , 20, REAL_COMPARE_DELTA ); - ck_assert_int_eq ( p.right.base.type , ROFI_PU_PX ); - ck_assert_double_eq_tol ( p.top.base.distance , 10, REAL_COMPARE_DELTA); - ck_assert_int_eq ( p.top.base.type , ROFI_PU_PX ); - ck_assert_double_eq_tol ( p.bottom.base.distance , 10, REAL_COMPARE_DELTA ); - ck_assert_int_eq ( p.bottom.base.type , ROFI_PU_PX ); - +START_TEST(test_properties_padding_2) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { test: 10px 20px;}"); + RofiDistance d = (RofiDistance){ + {1, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL}, ROFI_HL_SOLID}; + RofiPadding pi = (RofiPadding){d, d, d, d}; + RofiPadding p = rofi_theme_get_padding(&wid, "test", pi); + ck_assert_double_eq_tol(p.left.base.distance, 20, REAL_COMPARE_DELTA); + ck_assert_int_eq(p.left.base.type, ROFI_PU_PX); + ck_assert_double_eq_tol(p.right.base.distance, 20, REAL_COMPARE_DELTA); + ck_assert_int_eq(p.right.base.type, ROFI_PU_PX); + ck_assert_double_eq_tol(p.top.base.distance, 10, REAL_COMPARE_DELTA); + ck_assert_int_eq(p.top.base.type, ROFI_PU_PX); + ck_assert_double_eq_tol(p.bottom.base.distance, 10, REAL_COMPARE_DELTA); + ck_assert_int_eq(p.bottom.base.type, ROFI_PU_PX); } END_TEST -START_TEST ( test_properties_padding_3 ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { test: 10px 30px 20px;}"); - RofiDistance d = (RofiDistance){ {1, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE,NULL, NULL }, ROFI_HL_SOLID}; - RofiPadding pi = (RofiPadding){d,d,d,d}; - RofiPadding p = rofi_theme_get_padding ( &wid, "test", pi); - ck_assert_double_eq_tol ( p.left.base.distance , 30, REAL_COMPARE_DELTA); - ck_assert_int_eq ( p.left.base.type , ROFI_PU_PX ); - ck_assert_double_eq_tol ( p.right.base.distance , 30, REAL_COMPARE_DELTA ); - ck_assert_int_eq ( p.right.base.type , ROFI_PU_PX ); - ck_assert_double_eq_tol ( p.top.base.distance , 10, REAL_COMPARE_DELTA ); - ck_assert_int_eq ( p.top.base.type , ROFI_PU_PX ); - ck_assert_double_eq_tol ( p.bottom.base.distance , 20, REAL_COMPARE_DELTA ); - ck_assert_int_eq ( p.bottom.base.type , ROFI_PU_PX ); - +START_TEST(test_properties_padding_3) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { test: 10px 30px 20px;}"); + RofiDistance d = (RofiDistance){ + {1, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL}, ROFI_HL_SOLID}; + RofiPadding pi = (RofiPadding){d, d, d, d}; + RofiPadding p = rofi_theme_get_padding(&wid, "test", pi); + ck_assert_double_eq_tol(p.left.base.distance, 30, REAL_COMPARE_DELTA); + ck_assert_int_eq(p.left.base.type, ROFI_PU_PX); + ck_assert_double_eq_tol(p.right.base.distance, 30, REAL_COMPARE_DELTA); + ck_assert_int_eq(p.right.base.type, ROFI_PU_PX); + ck_assert_double_eq_tol(p.top.base.distance, 10, REAL_COMPARE_DELTA); + ck_assert_int_eq(p.top.base.type, ROFI_PU_PX); + ck_assert_double_eq_tol(p.bottom.base.distance, 20, REAL_COMPARE_DELTA); + ck_assert_int_eq(p.bottom.base.type, ROFI_PU_PX); } END_TEST -START_TEST ( test_properties_padding_4 ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { test: 10px 30px 20px 40px;}"); - RofiDistance d = (RofiDistance){ {1, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE,NULL, NULL }, ROFI_HL_SOLID}; - RofiPadding pi = (RofiPadding){d,d,d,d}; - RofiPadding p = rofi_theme_get_padding ( &wid, "test", pi); - ck_assert_double_eq_tol ( p.left.base.distance , 40 , REAL_COMPARE_DELTA ); - ck_assert_int_eq ( p.left.base.type , ROFI_PU_PX ); - ck_assert_double_eq_tol ( p.right.base.distance , 30 , REAL_COMPARE_DELTA ); - ck_assert_int_eq ( p.right.base.type , ROFI_PU_PX ); - ck_assert_double_eq_tol ( p.top.base.distance , 10 , REAL_COMPARE_DELTA ); - ck_assert_int_eq ( p.top.base.type , ROFI_PU_PX ); - ck_assert_double_eq_tol ( p.bottom.base.distance , 20 , REAL_COMPARE_DELTA ); - ck_assert_int_eq ( p.bottom.base.type , ROFI_PU_PX ); - +START_TEST(test_properties_padding_4) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { test: 10px 30px 20px 40px;}"); + RofiDistance d = (RofiDistance){ + {1, ROFI_PU_PX, ROFI_DISTANCE_MODIFIER_NONE, NULL, NULL}, ROFI_HL_SOLID}; + RofiPadding pi = (RofiPadding){d, d, d, d}; + RofiPadding p = rofi_theme_get_padding(&wid, "test", pi); + ck_assert_double_eq_tol(p.left.base.distance, 40, REAL_COMPARE_DELTA); + ck_assert_int_eq(p.left.base.type, ROFI_PU_PX); + ck_assert_double_eq_tol(p.right.base.distance, 30, REAL_COMPARE_DELTA); + ck_assert_int_eq(p.right.base.type, ROFI_PU_PX); + ck_assert_double_eq_tol(p.top.base.distance, 10, REAL_COMPARE_DELTA); + ck_assert_int_eq(p.top.base.type, ROFI_PU_PX); + ck_assert_double_eq_tol(p.bottom.base.distance, 20, REAL_COMPARE_DELTA); + ck_assert_int_eq(p.bottom.base.type, ROFI_PU_PX); } END_TEST -START_TEST ( test_properties_string_escape ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { font: \"aap\" noot\" mies \";\ntest: \"'123.432'\"; }"); +START_TEST(test_properties_string_escape) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string( + "* { font: \"aap\" noot\" mies \";\ntest: \"'123.432'\"; }"); - const char *str= rofi_theme_get_string ( &wid, "font", NULL ); - ck_assert_ptr_nonnull ( str ); - ck_assert_int_eq ( g_utf8_collate ( str, "aap\" noot\" mies " ) , 0 ); - const char *str2= rofi_theme_get_string ( &wid, "test", NULL ); - ck_assert_ptr_nonnull ( str2 ); - ck_assert_int_eq ( g_utf8_collate ( str2, "'123.432'" ) , 0 ); + const char *str = rofi_theme_get_string(&wid, "font", NULL); + ck_assert_ptr_nonnull(str); + ck_assert_int_eq(g_utf8_collate(str, "aap\" noot\" mies "), 0); + const char *str2 = rofi_theme_get_string(&wid, "test", NULL); + ck_assert_ptr_nonnull(str2); + ck_assert_int_eq(g_utf8_collate(str2, "'123.432'"), 0); } END_TEST -START_TEST ( test_properties_string ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { font: \"blaat€\"; test: 123.432; }"); +START_TEST(test_properties_string) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { font: \"blaat€\"; test: 123.432; }"); - const char *str= rofi_theme_get_string ( &wid, "font", NULL ); - ck_assert_ptr_nonnull ( str ); - ck_assert_int_eq ( g_utf8_collate ( str, "blaat€" ) , 0 ); + const char *str = rofi_theme_get_string(&wid, "font", NULL); + ck_assert_ptr_nonnull(str); + ck_assert_int_eq(g_utf8_collate(str, "blaat€"), 0); } END_TEST -START_TEST ( test_properties_double) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { test: 123.432; }"); - ck_assert_double_eq_tol ( rofi_theme_get_double ( &wid, "test", 0.0) , 123.432 , REAL_COMPARE_DELTA ); +START_TEST(test_properties_double) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { test: 123.432; }"); + ck_assert_double_eq_tol(rofi_theme_get_double(&wid, "test", 0.0), 123.432, + REAL_COMPARE_DELTA); } END_TEST -START_TEST ( test_properties_integer) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { yoffset: 4; }"); - ck_assert_int_eq ( rofi_theme_get_integer ( &wid, "yoffset", 0) , 4); +START_TEST(test_properties_integer) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { yoffset: 4; }"); + ck_assert_int_eq(rofi_theme_get_integer(&wid, "yoffset", 0), 4); } END_TEST -START_TEST ( test_properties_orientation ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { vert: vertical; hori: horizontal; }"); - ck_assert_int_eq ( rofi_theme_get_orientation( &wid, "vert", ROFI_ORIENTATION_HORIZONTAL) , ROFI_ORIENTATION_VERTICAL); - ck_assert_int_eq ( rofi_theme_get_orientation( &wid, "hori", ROFI_ORIENTATION_VERTICAL) , ROFI_ORIENTATION_HORIZONTAL); - // default propagation - ck_assert_int_eq ( rofi_theme_get_orientation( &wid, "notfo", ROFI_ORIENTATION_HORIZONTAL) , ROFI_ORIENTATION_HORIZONTAL); - ck_assert_int_eq ( rofi_theme_get_orientation( &wid, "notfo", ROFI_ORIENTATION_VERTICAL) , ROFI_ORIENTATION_VERTICAL); - +START_TEST(test_properties_orientation) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { vert: vertical; hori: horizontal; }"); + ck_assert_int_eq( + rofi_theme_get_orientation(&wid, "vert", ROFI_ORIENTATION_HORIZONTAL), + ROFI_ORIENTATION_VERTICAL); + ck_assert_int_eq( + rofi_theme_get_orientation(&wid, "hori", ROFI_ORIENTATION_VERTICAL), + ROFI_ORIENTATION_HORIZONTAL); + // default propagation + ck_assert_int_eq( + rofi_theme_get_orientation(&wid, "notfo", ROFI_ORIENTATION_HORIZONTAL), + ROFI_ORIENTATION_HORIZONTAL); + ck_assert_int_eq( + rofi_theme_get_orientation(&wid, "notfo", ROFI_ORIENTATION_VERTICAL), + ROFI_ORIENTATION_VERTICAL); } END_TEST -START_TEST ( test_properties_orientation_case ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { vert: Vertical; hori: HoriZonTal;}"); - ck_assert_int_eq ( rofi_theme_get_orientation( &wid, "vert", ROFI_ORIENTATION_HORIZONTAL) , ROFI_ORIENTATION_VERTICAL); - ck_assert_int_eq ( rofi_theme_get_orientation( &wid, "hori", ROFI_ORIENTATION_VERTICAL) , ROFI_ORIENTATION_HORIZONTAL); - +START_TEST(test_properties_orientation_case) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { vert: Vertical; hori: HoriZonTal;}"); + ck_assert_int_eq( + rofi_theme_get_orientation(&wid, "vert", ROFI_ORIENTATION_HORIZONTAL), + ROFI_ORIENTATION_VERTICAL); + ck_assert_int_eq( + rofi_theme_get_orientation(&wid, "hori", ROFI_ORIENTATION_VERTICAL), + ROFI_ORIENTATION_HORIZONTAL); } END_TEST -START_TEST ( test_properties_cursor ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { def: default; ptr: pointer; txt: text; }"); - ck_assert_int_eq ( rofi_theme_get_cursor_type( &wid, "def", ROFI_CURSOR_TEXT), ROFI_CURSOR_DEFAULT); - ck_assert_int_eq ( rofi_theme_get_cursor_type( &wid, "ptr", ROFI_CURSOR_DEFAULT), ROFI_CURSOR_POINTER); - ck_assert_int_eq ( rofi_theme_get_cursor_type( &wid, "txt", ROFI_CURSOR_DEFAULT), ROFI_CURSOR_TEXT); +START_TEST(test_properties_cursor) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { def: default; ptr: pointer; txt: text; }"); + ck_assert_int_eq(rofi_theme_get_cursor_type(&wid, "def", ROFI_CURSOR_TEXT), + ROFI_CURSOR_DEFAULT); + ck_assert_int_eq(rofi_theme_get_cursor_type(&wid, "ptr", ROFI_CURSOR_DEFAULT), + ROFI_CURSOR_POINTER); + ck_assert_int_eq(rofi_theme_get_cursor_type(&wid, "txt", ROFI_CURSOR_DEFAULT), + ROFI_CURSOR_TEXT); } END_TEST -START_TEST ( test_properties_cursor_case ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "* { def: dEfault; ptr: POINter; txt: tExt; }"); - ck_assert_int_eq ( rofi_theme_get_cursor_type( &wid, "def", ROFI_CURSOR_TEXT), ROFI_CURSOR_DEFAULT); - ck_assert_int_eq ( rofi_theme_get_cursor_type( &wid, "ptr", ROFI_CURSOR_DEFAULT), ROFI_CURSOR_POINTER); - ck_assert_int_eq ( rofi_theme_get_cursor_type( &wid, "txt", ROFI_CURSOR_DEFAULT), ROFI_CURSOR_TEXT); +START_TEST(test_properties_cursor_case) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string("* { def: dEfault; ptr: POINter; txt: tExt; }"); + ck_assert_int_eq(rofi_theme_get_cursor_type(&wid, "def", ROFI_CURSOR_TEXT), + ROFI_CURSOR_DEFAULT); + ck_assert_int_eq(rofi_theme_get_cursor_type(&wid, "ptr", ROFI_CURSOR_DEFAULT), + ROFI_CURSOR_POINTER); + ck_assert_int_eq(rofi_theme_get_cursor_type(&wid, "txt", ROFI_CURSOR_DEFAULT), + ROFI_CURSOR_TEXT); } END_TEST -START_TEST ( test_properties_list ) -{ - widget wid; - wid.name = "blaat"; - wid.state = NULL; - rofi_theme_parse_string ( "#blaat { liste: []; list1: [ one ]; list2: [ one, two ];}"); - GList *list = rofi_theme_get_list ( &wid, "liste", NULL ); - ck_assert_ptr_null ( list ); - list = rofi_theme_get_list ( &wid, "list1", NULL ); - ck_assert_ptr_nonnull ( list ); - ck_assert_str_eq ( (char *)list->data, "one" ); - g_list_free_full ( list, (GDestroyNotify)g_free); - list = rofi_theme_get_list ( &wid, "list2", NULL ); - ck_assert_ptr_nonnull ( list ); - ck_assert_int_eq ( g_list_length ( list ), 2 ); - ck_assert_str_eq ( (char *)list->data, "one" ); - ck_assert_str_eq ( (char *)list->next->data, "two" ); - g_list_free_full ( list, (GDestroyNotify)g_free); - - list = rofi_theme_get_list ( &wid, "blaat", "aap,noot,mies"); - ck_assert_ptr_nonnull ( list ); - ck_assert_int_eq ( g_list_length ( list ), 3 ); - ck_assert_str_eq ( (char *)list->data, "aap" ); - ck_assert_str_eq ( (char *)list->next->data, "noot" ); - ck_assert_str_eq ( (char *)list->next->next->data, "mies" ); - g_list_free_full ( list, (GDestroyNotify)g_free); +START_TEST(test_properties_list) { + widget wid; + wid.name = "blaat"; + wid.state = NULL; + rofi_theme_parse_string( + "#blaat { liste: []; list1: [ one ]; list2: [ one, two ];}"); + GList *list = rofi_theme_get_list_strings(&wid, "liste"); + ck_assert_ptr_null(list); + list = rofi_theme_get_list_strings(&wid, "list1"); + ck_assert_ptr_nonnull(list); + ck_assert_str_eq((char *)list->data, "one"); + g_list_free_full(list, (GDestroyNotify)g_free); + + list = rofi_theme_get_list_strings(&wid, "list2"); + ck_assert_ptr_nonnull(list); + ck_assert_int_eq(g_list_length(list), 2); + list = g_list_first(list); + ck_assert_str_eq((char *)list->data, "one"); + ck_assert_str_eq((char *)list->next->data, "two"); + g_list_free_full(list, (GDestroyNotify)g_free); } END_TEST - -START_TEST ( test_configuration ) -{ - rofi_theme_parse_string ( "configuration { font: \"blaat€\"; yoffset: 4; }"); - ck_assert_int_eq ( g_utf8_collate ( config.menu_font, "blaat€" ) , 0 ); - ck_assert_int_eq ( config.y_offset , 4 ); +START_TEST(test_configuration) { + rofi_theme_parse_string("configuration { font: \"blaat€\"; yoffset: 4; }"); + ck_assert_int_eq(g_utf8_collate(config.menu_font, "blaat€"), 0); + ck_assert_int_eq(config.y_offset, 4); } END_TEST -START_TEST ( test_parse_file_empty ) -{ - rofi_theme_parse_file ("/dev/null"); - ck_assert_ptr_nonnull ( rofi_theme ); - //ck_assert_ptr_null ( rofi_theme->widgets ); - ck_assert_ptr_null ( rofi_theme->properties ); - ck_assert_ptr_null ( rofi_theme->parent ); - ck_assert_str_eq ( rofi_theme->name, "Root" ); +START_TEST(test_parse_file_empty) { + rofi_theme_parse_file("/dev/null"); + ck_assert_ptr_nonnull(rofi_theme); + // ck_assert_ptr_null ( rofi_theme->widgets ); + ck_assert_ptr_null(rofi_theme->properties); + ck_assert_ptr_null(rofi_theme->parent); + ck_assert_str_eq(rofi_theme->name, "Root"); } END_TEST -START_TEST ( test_parse_file_not_existing) -{ - rofi_theme_parse_file ("/not-existing-file.rasi"); - ck_assert_ptr_null ( rofi_theme ); - ck_assert_int_eq ( error, 1); - ck_assert_str_eq ( error_msg->str, "Failed to open theme: /not-existing-file.rasi\nError: No such file or directory"); - - g_string_free ( error_msg, TRUE); - error_msg = NULL; - error = 0; +START_TEST(test_parse_file_not_existing) { + rofi_theme_parse_file("/not-existing-file.rasi"); + ck_assert_ptr_null(rofi_theme); + ck_assert_int_eq(error, 1); + ck_assert_str_eq( + error_msg->str, + "Failed to open theme: /not-existing-file.rasi\nError: No such " + "file or directory"); + + g_string_free(error_msg, TRUE); + error_msg = NULL; + error = 0; } END_TEST -START_TEST ( test_import_empty) -{ - rofi_theme_parse_string("@import \"/dev/null\""); - ck_assert_ptr_nonnull ( rofi_theme ); - //ck_assert_ptr_null ( rofi_theme->widgets ); - ck_assert_ptr_null ( rofi_theme->properties ); - ck_assert_ptr_null ( rofi_theme->parent ); - ck_assert_str_eq ( rofi_theme->name, "Root" ); +START_TEST(test_import_empty) { + rofi_theme_parse_string("@import \"/dev/null\""); + ck_assert_ptr_nonnull(rofi_theme); + // ck_assert_ptr_null ( rofi_theme->widgets ); + ck_assert_ptr_null(rofi_theme->properties); + ck_assert_ptr_null(rofi_theme->parent); + ck_assert_str_eq(rofi_theme->name, "Root"); } END_TEST -START_TEST ( test_core_properties_error ) -{ - rofi_theme_parse_string ( " * { test: cmky(a,e,3); }"); - const char *errstr = "Error while parsing theme: * { test: cmky(a,e,3); }\n"\ - " Parser error: syntax error, unexpected invalid property value\n"\ - " Location: line 1 column 11 to line 1 column 23\n"; - ck_assert_int_eq ( error, 1); - ck_assert_str_eq ( error_msg->str, errstr ); - g_string_free ( error_msg, TRUE); - error_msg = NULL; - error = 0; - - const char *errstr2 = "Error while parsing theme: \n"\ - " Parser error: Value out of range: \n"\ - " Value: X = 500.00;\n"\ - " Range: 0.00 <= X <= 360.00.\n"\ - " Location: line 0 column 15 to line 0 column 18\n"; - rofi_theme_parse_string ( " * { test: hsl(500, 100% 10% ); }"); - ck_assert_int_eq ( error, 1); - ck_assert_str_eq ( error_msg->str, errstr2 ); - g_string_free ( error_msg, TRUE); - error_msg = NULL; - error = 0; +START_TEST(test_core_properties_error) { + rofi_theme_parse_string(" * { test: cmky(a,e,3); }"); + const char *errstr = + "Error while parsing theme: * { test: cmky(a,e,3); " + "}\n" + " Parser error: syntax error, " + "unexpected invalid property value\n" + " Location: line 1 column 11 to line 1 column 23\n"; + ck_assert_int_eq(error, 1); + ck_assert_str_eq(error_msg->str, errstr); + g_string_free(error_msg, TRUE); + error_msg = NULL; + error = 0; + + const char *errstr2 = + "Error while parsing theme: \n" + " Parser error: Value out of " + "range: \n" + " Value: X = 500.00;\n" + " Range: 0.00 <= X <= 360.00.\n" + " Location: line 0 column 15 to line 0 column 18\n"; + rofi_theme_parse_string(" * { test: hsl(500, 100% 10% ); }"); + ck_assert_int_eq(error, 1); + ck_assert_str_eq(error_msg->str, errstr2); + g_string_free(error_msg, TRUE); + error_msg = NULL; + error = 0; } END_TEST -START_TEST ( test_import_error ) -{ - rofi_theme_parse_string("@import \"/non-existing-file.rasi\""); +START_TEST(test_import_error) { + rofi_theme_parse_string("@import \"/non-existing-file.rasi\""); - const char *errstr = - "Failed to open theme: /non-existing-file.rasi\n"\ - "Error: No such file or directory"; - ck_assert_int_eq ( error, 1); - ck_assert_str_eq ( error_msg->str, errstr ); - g_string_free ( error_msg, TRUE); - error_msg = NULL; - error = 0; + const char *errstr = "Failed to open theme: /non-existing-file.rasi\n" + "Error: No such file or directory"; + ck_assert_int_eq(error, 1); + ck_assert_str_eq(error_msg->str, errstr); + g_string_free(error_msg, TRUE); + error_msg = NULL; + error = 0; } END_TEST +START_TEST(test_prepare_array) { + widget wid; + wid.name = "element-text"; + wid.state = "normal.normal"; + rofi_theme_parse_string("element-text { tabs: [ 10, 20px, 30px, 40px ];}"); + ck_assert_ptr_nonnull(rofi_theme); + // ck_assert_ptr_null ( rofi_theme->widgets ); + ck_assert_ptr_null(rofi_theme->properties); + ck_assert_ptr_null(rofi_theme->parent); + ck_assert_str_eq(rofi_theme->name, "Root"); + GList *l = rofi_theme_get_list_distance(&wid, "tabs"); + + ck_assert_int_eq(g_list_length(l), 4); + + int i = 10; + for (GList *iter = g_list_first(l); iter != NULL; iter = g_list_next(iter)) { + RofiDistance *d = (RofiDistance *)iter->data; + ck_assert_int_eq(d->base.distance, i); + i += 10; + } + + g_list_free_full(l, g_free); +} +END_TEST + +START_TEST(test_prepare_path) { + char *current_dir = g_get_current_dir(); + ck_assert_ptr_nonnull(current_dir); + char *f = rofi_theme_parse_prepare_file("../", NULL); + ck_assert_ptr_nonnull(f); + ck_assert_int_eq(*f, '/'); + ck_assert_str_ne(f, current_dir); + ck_assert(g_str_has_prefix(current_dir, f) == TRUE); + g_free(f); + + f = rofi_theme_parse_prepare_file("../", "/tmp/"); + ck_assert_ptr_nonnull(f); + ck_assert_str_eq(f, "/"); + g_free(f); + + f = rofi_theme_parse_prepare_file("/tmp/test.rasi", "/random/"); + ck_assert_ptr_nonnull(f); + ck_assert_str_eq(f, "/tmp/test.rasi"); + g_free(f); -START_TEST ( test_prepare_path ) -{ - char *current_dir = g_get_current_dir (); - ck_assert_ptr_nonnull ( current_dir ); - char *f = rofi_theme_parse_prepare_file ( "../", NULL ); - ck_assert_ptr_nonnull ( f ); - ck_assert_int_eq ( *f, '/'); - ck_assert_str_ne ( f, current_dir); - ck_assert ( g_str_has_prefix( current_dir, f ) == TRUE ); - g_free(f); - - f = rofi_theme_parse_prepare_file ( "../", "/tmp/" ); - ck_assert_ptr_nonnull ( f ); - ck_assert_str_eq ( f, "/"); - g_free ( f ); - - f = rofi_theme_parse_prepare_file ( "/tmp/test.rasi" , "/random/"); - ck_assert_ptr_nonnull ( f ); - ck_assert_str_eq ( f, "/tmp/test.rasi" ); - g_free ( f ); - - g_free ( current_dir ); + g_free(current_dir); } END_TEST -START_TEST(test_properties_types_names) -{ - ck_assert_str_eq ( PropertyTypeName[P_INTEGER], "Integer"); - ck_assert_str_eq ( PropertyTypeName[P_DOUBLE], "Double"); - ck_assert_str_eq ( PropertyTypeName[P_STRING], "String"); - ck_assert_str_eq ( PropertyTypeName[P_BOOLEAN], "Boolean"); - ck_assert_str_eq ( PropertyTypeName[P_COLOR], "Color"); - ck_assert_str_eq ( PropertyTypeName[P_PADDING], "Padding"); - ck_assert_str_eq ( PropertyTypeName[P_LINK], "Reference"); - ck_assert_str_eq ( PropertyTypeName[P_POSITION], "Position"); - ck_assert_str_eq ( PropertyTypeName[P_HIGHLIGHT], "Highlight"); - ck_assert_str_eq ( PropertyTypeName[P_LIST], "List"); - ck_assert_str_eq ( PropertyTypeName[P_ORIENTATION], "Orientation"); +START_TEST(test_properties_types_names) { + ck_assert_str_eq(PropertyTypeName[P_INTEGER], "Integer"); + ck_assert_str_eq(PropertyTypeName[P_DOUBLE], "Double"); + ck_assert_str_eq(PropertyTypeName[P_STRING], "String"); + ck_assert_str_eq(PropertyTypeName[P_BOOLEAN], "Boolean"); + ck_assert_str_eq(PropertyTypeName[P_COLOR], "Color"); + ck_assert_str_eq(PropertyTypeName[P_PADDING], "Padding"); + ck_assert_str_eq(PropertyTypeName[P_LINK], "Reference"); + ck_assert_str_eq(PropertyTypeName[P_POSITION], "Position"); + ck_assert_str_eq(PropertyTypeName[P_HIGHLIGHT], "Highlight"); + ck_assert_str_eq(PropertyTypeName[P_LIST], "List"); + ck_assert_str_eq(PropertyTypeName[P_ORIENTATION], "Orientation"); } END_TEST -static Suite * theme_parser_suite (void) -{ - Suite *s; - - s = suite_create("Theme"); - - /* Core test case */ - { - TCase *tc_core = tcase_create("Core"); - tcase_add_checked_fixture(tc_core, theme_parser_setup, theme_parser_teardown); - tcase_add_test(tc_core, test_properties_types_names); - tcase_add_test(tc_core, test_core_empty_string); - tcase_add_test(tc_core, test_core_empty_global_section); - tcase_add_test(tc_core, test_core_empty_section); - tcase_add_test(tc_core, test_core_error_root ); - tcase_add_test(tc_core, test_core_comments ); - tcase_add_test(tc_core, test_core_newline ); - tcase_add_test(tc_core, test_core_properties_error ); - suite_add_tcase(s, tc_core); - } - { - TCase *tc_prop_bool = tcase_create("PropertiesBoolean"); - tcase_add_checked_fixture(tc_prop_bool , theme_parser_setup, theme_parser_teardown); - tcase_add_test ( tc_prop_bool, test_properties_boolean); - tcase_add_test ( tc_prop_bool, test_properties_boolean_reference); - suite_add_tcase(s, tc_prop_bool ); - } - { - TCase *tc_prop_distance = tcase_create("PropertiesDistance"); - tcase_add_checked_fixture(tc_prop_distance , theme_parser_setup, theme_parser_teardown); - tcase_add_test ( tc_prop_distance, test_properties_distance_em ); - tcase_add_test ( tc_prop_distance, test_properties_distance_px ); - tcase_add_test ( tc_prop_distance, test_properties_distance_percent ); - tcase_add_test ( tc_prop_distance, test_properties_distance_em_linestyle ); - tcase_add_test ( tc_prop_distance, test_properties_distance_px_linestyle ); - tcase_add_test ( tc_prop_distance, test_properties_distance_percent_linestyle ); - suite_add_tcase(s, tc_prop_distance ); - } - { - TCase *tc_prop_position = tcase_create("PropertiesPosition"); - tcase_add_checked_fixture(tc_prop_position, theme_parser_setup, theme_parser_teardown); - tcase_add_test ( tc_prop_position, test_properties_position); - suite_add_tcase(s, tc_prop_position ); - } - { - TCase *tc_prop_style = tcase_create("PropertiesStyle"); - tcase_add_checked_fixture(tc_prop_style, theme_parser_setup, theme_parser_teardown); - tcase_add_test ( tc_prop_style, test_properties_style); - tcase_add_test ( tc_prop_style, test_properties_style2); - tcase_add_test ( tc_prop_style, test_properties_style_color); - suite_add_tcase(s, tc_prop_style ); - } - { - TCase *tc_prop_color = tcase_create("PropertiesColor"); - tcase_add_checked_fixture(tc_prop_color, theme_parser_setup, theme_parser_teardown); - tcase_add_test ( tc_prop_color, test_properties_color_h3); - tcase_add_test ( tc_prop_color, test_properties_color_h4); - tcase_add_test ( tc_prop_color, test_properties_color_h6); - tcase_add_test ( tc_prop_color, test_properties_color_h8); - tcase_add_test ( tc_prop_color, test_properties_color_rgb); - tcase_add_test ( tc_prop_color, test_properties_color_rgba); - tcase_add_test ( tc_prop_color, test_properties_color_rgba_percent); - tcase_add_test ( tc_prop_color, test_properties_color_rgb_p); - tcase_add_test ( tc_prop_color, test_properties_color_rgba_p); - tcase_add_test ( tc_prop_color, test_properties_color_rgba_percent_p); - tcase_add_test ( tc_prop_color, test_properties_color_argb); - tcase_add_test ( tc_prop_color, test_properties_color_hsl); - tcase_add_test ( tc_prop_color, test_properties_color_hsla); - tcase_add_test ( tc_prop_color, test_properties_color_hsl_ws); - tcase_add_test ( tc_prop_color, test_properties_color_hsla_ws); - tcase_add_test ( tc_prop_color, test_properties_color_hwb); - tcase_add_test ( tc_prop_color, test_properties_color_hwb_ws); - tcase_add_test ( tc_prop_color, test_properties_color_cmyk); - tcase_add_test ( tc_prop_color, test_properties_color_cmyk_ws); - tcase_add_test ( tc_prop_color, test_properties_color_names); - tcase_add_test ( tc_prop_color, test_properties_color_names_alpha); - suite_add_tcase(s, tc_prop_color ); - } - { - TCase *tc_prop_padding = tcase_create("PropertiesPadding"); - tcase_add_checked_fixture(tc_prop_padding, theme_parser_setup, theme_parser_teardown); - tcase_add_test ( tc_prop_padding, test_properties_padding_2); - tcase_add_test ( tc_prop_padding, test_properties_padding_3); - tcase_add_test ( tc_prop_padding, test_properties_padding_4); - suite_add_tcase(s, tc_prop_padding ); - } - { - TCase *tc_prop_string = tcase_create("PropertiesString"); - tcase_add_checked_fixture(tc_prop_string, theme_parser_setup, theme_parser_teardown); - tcase_add_test ( tc_prop_string, test_properties_string); - tcase_add_test ( tc_prop_string, test_properties_string_escape); - suite_add_tcase(s, tc_prop_string ); - } - - { - TCase *tc_prop_double = tcase_create("PropertiesDouble"); - tcase_add_checked_fixture(tc_prop_double, theme_parser_setup, theme_parser_teardown); - tcase_add_test ( tc_prop_double, test_properties_double); - suite_add_tcase(s, tc_prop_double ); - } - { - TCase *tc_prop_integer = tcase_create("PropertiesInteger"); - tcase_add_checked_fixture(tc_prop_integer, theme_parser_setup, theme_parser_teardown); - tcase_add_test ( tc_prop_integer, test_properties_integer); - suite_add_tcase(s, tc_prop_integer ); - } - { - TCase *tc_prop_orientation = tcase_create("Propertiesorientation"); - tcase_add_checked_fixture(tc_prop_orientation, theme_parser_setup, theme_parser_teardown); - tcase_add_test ( tc_prop_orientation, test_properties_orientation); - tcase_add_test ( tc_prop_orientation, test_properties_orientation_case ); - suite_add_tcase(s, tc_prop_orientation ); - } - { - TCase *tc_prop_cursor = tcase_create("Propertiescursor"); - tcase_add_checked_fixture(tc_prop_cursor, theme_parser_setup, theme_parser_teardown); - tcase_add_test ( tc_prop_cursor, test_properties_cursor); - tcase_add_test ( tc_prop_cursor, test_properties_cursor_case ); - suite_add_tcase(s, tc_prop_cursor ); - } - { - TCase *tc_prop_list = tcase_create("Propertieslist"); - tcase_add_checked_fixture(tc_prop_list, theme_parser_setup, theme_parser_teardown); - tcase_add_test ( tc_prop_list, test_properties_list); - suite_add_tcase(s, tc_prop_list ); - } - { - TCase *tc_prop_configuration = tcase_create("Configuration"); - tcase_add_checked_fixture(tc_prop_configuration, theme_parser_setup, theme_parser_teardown); - tcase_add_test ( tc_prop_configuration, test_configuration); - suite_add_tcase(s, tc_prop_configuration ); - } - { - TCase *tc_prop_parse_file = tcase_create("ParseFile"); - tcase_add_checked_fixture(tc_prop_parse_file, theme_parser_setup, theme_parser_teardown); - tcase_add_test ( tc_prop_parse_file, test_parse_file_empty); - tcase_add_test ( tc_prop_parse_file, test_parse_file_not_existing); - suite_add_tcase(s, tc_prop_parse_file ); - } - { - TCase *tc_prop_import = tcase_create("Import"); - tcase_add_checked_fixture(tc_prop_import, theme_parser_setup, theme_parser_teardown); - tcase_add_test ( tc_prop_import, test_import_empty); - tcase_add_test ( tc_prop_import, test_import_error); - suite_add_tcase(s, tc_prop_import ); - } - { - TCase *tc_prepare_path = tcase_create("prepare_path"); - tcase_add_test ( tc_prepare_path, test_prepare_path); - suite_add_tcase(s, tc_prepare_path ); - } - return s; -} - -int main ( int argc, char **argv ) -{ - cmd_set_arguments ( argc, argv ); - - if ( setlocale ( LC_ALL, "C" ) == NULL ) { - fprintf ( stderr, "Failed to set locale.\n" ); - return EXIT_FAILURE; - } - - Suite *s; - SRunner *sr; - - s = theme_parser_suite(); - sr = srunner_create(s); - - srunner_run_all(sr, CK_NORMAL); - int number_failed = srunner_ntests_failed(sr); - srunner_free(sr); - - return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +static Suite *theme_parser_suite(void) { + Suite *s; + + s = suite_create("Theme"); + + /* Core test case */ + { + TCase *tc_core = tcase_create("Core"); + tcase_add_checked_fixture(tc_core, theme_parser_setup, + theme_parser_teardown); + tcase_add_test(tc_core, test_properties_types_names); + tcase_add_test(tc_core, test_core_empty_string); + tcase_add_test(tc_core, test_core_empty_global_section); + tcase_add_test(tc_core, test_core_empty_section); + tcase_add_test(tc_core, test_core_error_root); + tcase_add_test(tc_core, test_core_comments); + tcase_add_test(tc_core, test_core_newline); + tcase_add_test(tc_core, test_core_properties_error); + suite_add_tcase(s, tc_core); + } + { + TCase *tc_prop_bool = tcase_create("PropertiesBoolean"); + tcase_add_checked_fixture(tc_prop_bool, theme_parser_setup, + theme_parser_teardown); + tcase_add_test(tc_prop_bool, test_properties_boolean); + tcase_add_test(tc_prop_bool, test_properties_boolean_reference); + suite_add_tcase(s, tc_prop_bool); + } + { + TCase *tc_prop_distance = tcase_create("PropertiesDistance"); + tcase_add_checked_fixture(tc_prop_distance, theme_parser_setup, + theme_parser_teardown); + tcase_add_test(tc_prop_distance, test_properties_distance_em); + tcase_add_test(tc_prop_distance, test_properties_distance_px); + tcase_add_test(tc_prop_distance, test_properties_distance_percent); + tcase_add_test(tc_prop_distance, test_properties_distance_em_linestyle); + tcase_add_test(tc_prop_distance, test_properties_distance_px_linestyle); + tcase_add_test(tc_prop_distance, + test_properties_distance_percent_linestyle); + suite_add_tcase(s, tc_prop_distance); + } + { + TCase *tc_prop_position = tcase_create("PropertiesPosition"); + tcase_add_checked_fixture(tc_prop_position, theme_parser_setup, + theme_parser_teardown); + tcase_add_test(tc_prop_position, test_properties_position); + suite_add_tcase(s, tc_prop_position); + } + { + TCase *tc_prop_style = tcase_create("PropertiesStyle"); + tcase_add_checked_fixture(tc_prop_style, theme_parser_setup, + theme_parser_teardown); + tcase_add_test(tc_prop_style, test_properties_style); + tcase_add_test(tc_prop_style, test_properties_style2); + tcase_add_test(tc_prop_style, test_properties_style_color); + suite_add_tcase(s, tc_prop_style); + } + { + TCase *tc_prop_color = tcase_create("PropertiesColor"); + tcase_add_checked_fixture(tc_prop_color, theme_parser_setup, + theme_parser_teardown); + tcase_add_test(tc_prop_color, test_properties_color_h3); + tcase_add_test(tc_prop_color, test_properties_color_h4); + tcase_add_test(tc_prop_color, test_properties_color_h6); + tcase_add_test(tc_prop_color, test_properties_color_h8); + tcase_add_test(tc_prop_color, test_properties_color_rgb); + tcase_add_test(tc_prop_color, test_properties_color_rgba); + tcase_add_test(tc_prop_color, test_properties_color_rgba_percent); + tcase_add_test(tc_prop_color, test_properties_color_rgb_p); + tcase_add_test(tc_prop_color, test_properties_color_rgba_p); + tcase_add_test(tc_prop_color, test_properties_color_rgba_percent_p); + tcase_add_test(tc_prop_color, test_properties_color_argb); + tcase_add_test(tc_prop_color, test_properties_color_hsl); + tcase_add_test(tc_prop_color, test_properties_color_hsla); + tcase_add_test(tc_prop_color, test_properties_color_hsl_ws); + tcase_add_test(tc_prop_color, test_properties_color_hsla_ws); + tcase_add_test(tc_prop_color, test_properties_color_hwb); + tcase_add_test(tc_prop_color, test_properties_color_hwb_ws); + tcase_add_test(tc_prop_color, test_properties_color_cmyk); + tcase_add_test(tc_prop_color, test_properties_color_cmyk_ws); + tcase_add_test(tc_prop_color, test_properties_color_names); + tcase_add_test(tc_prop_color, test_properties_color_names_alpha); + suite_add_tcase(s, tc_prop_color); + } + { + TCase *tc_prop_padding = tcase_create("PropertiesPadding"); + tcase_add_checked_fixture(tc_prop_padding, theme_parser_setup, + theme_parser_teardown); + tcase_add_test(tc_prop_padding, test_properties_padding_2); + tcase_add_test(tc_prop_padding, test_properties_padding_3); + tcase_add_test(tc_prop_padding, test_properties_padding_4); + suite_add_tcase(s, tc_prop_padding); + } + { + TCase *tc_prop_string = tcase_create("PropertiesString"); + tcase_add_checked_fixture(tc_prop_string, theme_parser_setup, + theme_parser_teardown); + tcase_add_test(tc_prop_string, test_properties_string); + tcase_add_test(tc_prop_string, test_properties_string_escape); + suite_add_tcase(s, tc_prop_string); + } + + { + TCase *tc_prop_double = tcase_create("PropertiesDouble"); + tcase_add_checked_fixture(tc_prop_double, theme_parser_setup, + theme_parser_teardown); + tcase_add_test(tc_prop_double, test_properties_double); + suite_add_tcase(s, tc_prop_double); + } + { + TCase *tc_prop_integer = tcase_create("PropertiesInteger"); + tcase_add_checked_fixture(tc_prop_integer, theme_parser_setup, + theme_parser_teardown); + tcase_add_test(tc_prop_integer, test_properties_integer); + suite_add_tcase(s, tc_prop_integer); + } + { + TCase *tc_prop_orientation = tcase_create("Propertiesorientation"); + tcase_add_checked_fixture(tc_prop_orientation, theme_parser_setup, + theme_parser_teardown); + tcase_add_test(tc_prop_orientation, test_properties_orientation); + tcase_add_test(tc_prop_orientation, test_properties_orientation_case); + suite_add_tcase(s, tc_prop_orientation); + } + { + TCase *tc_prop_cursor = tcase_create("Propertiescursor"); + tcase_add_checked_fixture(tc_prop_cursor, theme_parser_setup, + theme_parser_teardown); + tcase_add_test(tc_prop_cursor, test_properties_cursor); + tcase_add_test(tc_prop_cursor, test_properties_cursor_case); + suite_add_tcase(s, tc_prop_cursor); + } + { + TCase *tc_prop_configuration = tcase_create("Configuration"); + tcase_add_checked_fixture(tc_prop_configuration, theme_parser_setup, + theme_parser_teardown); + tcase_add_test(tc_prop_configuration, test_configuration); + suite_add_tcase(s, tc_prop_configuration); + } + { + TCase *tc_prop_list = tcase_create("Propertieslist"); + tcase_add_checked_fixture(tc_prop_list, theme_parser_setup, + theme_parser_teardown); + tcase_add_test(tc_prop_list, test_properties_list); + suite_add_tcase(s, tc_prop_list); + } + { + TCase *tc_prop_parse_file = tcase_create("ParseFile"); + tcase_add_checked_fixture(tc_prop_parse_file, theme_parser_setup, + theme_parser_teardown); + tcase_add_test(tc_prop_parse_file, test_parse_file_empty); + tcase_add_test(tc_prop_parse_file, test_parse_file_not_existing); + suite_add_tcase(s, tc_prop_parse_file); + } + { + TCase *tc_prop_import = tcase_create("Import"); + tcase_add_checked_fixture(tc_prop_import, theme_parser_setup, + theme_parser_teardown); + tcase_add_test(tc_prop_import, test_import_empty); + tcase_add_test(tc_prop_import, test_import_error); + suite_add_tcase(s, tc_prop_import); + } + { + TCase *tc_prepare_path = tcase_create("prepare_path"); + tcase_add_test(tc_prepare_path, test_prepare_path); + suite_add_tcase(s, tc_prepare_path); + } + { + TCase *tc_prepare_array = tcase_create("array"); + tcase_add_test(tc_prepare_array, test_prepare_array); + suite_add_tcase(s, tc_prepare_array); + } + return s; +} + +int main(int argc, char **argv) { + cmd_set_arguments(argc, argv); + + if (setlocale(LC_ALL, "C") == NULL) { + fprintf(stderr, "Failed to set locale.\n"); + return EXIT_FAILURE; + } + + Suite *s; + SRunner *sr; + + s = theme_parser_suite(); + sr = srunner_create(s); + + srunner_run_all(sr, CK_NORMAL); + int number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/themes/iggy.rasi b/themes/iggy.rasi index a6a0bebfe..c9bed581a 100644 --- a/themes/iggy.rasi +++ b/themes/iggy.rasi @@ -37,7 +37,7 @@ element,element-text,element-icon, button { inputbar { margin: 0px 0px 0.5em 0em; - spacing: 0.2em; + spacing: 0.4em; children: [ button-iggy1, entry,overlay,case-indicator, button-iggy2]; } @@ -45,6 +45,7 @@ button-iggy1, button-iggy2 { expand: false; content: "🐢"; action: "kb-primary-paste"; + horizontal-align: 0.5; } button-iggy2 { action: "kb-screenshot"; @@ -97,9 +98,11 @@ wrapper-mode-switcher { } icon-ms-ic1 { filename: "go-previous"; + action: "kb-mode-previous"; } icon-ms-ic2 { filename: "go-next"; + action: "kb-mode-next"; } icon-ms-ic1,icon-ms-ic2 { size: 16; @@ -133,3 +136,7 @@ button selected.normal { background-image: linear-gradient(to bottom, darkgreen, black/70%); } +entry { + placeholder: "Iggy"; + placeholder-color: darkgrey/30%; + }