From 2c325b3f09eaad94d1ea07b999fcd5872be6b8f1 Mon Sep 17 00:00:00 2001 From: Dave Davenport Date: Sun, 13 Jun 2021 20:50:25 +0200 Subject: [PATCH] [Widget] Add initial support for background-image. * Supports url("path") and linear-gradient(start,stop). --- doc/rofi-script.5 | 17 ++++----- doc/rofi-sensible-terminal.1 | 1 - doc/rofi-theme-selector.1 | 7 ++-- doc/rofi-theme.5 | 71 +++++++++++++++++++++++++++++------- doc/rofi-theme.5.markdown | 14 ++++++- doc/rofi.1 | 45 +++++++++++++++-------- include/rofi-types.h | 27 ++++++++++++++ include/widgets/widget.h | 1 + lexer/theme-lexer.l | 7 ++++ lexer/theme-parser.y | 14 +++++++ source/theme.c | 54 ++++++++++++++++++++++++++- source/widgets/widget.c | 1 + 12 files changed, 215 insertions(+), 44 deletions(-) diff --git a/doc/rofi-script.5 b/doc/rofi-script.5 index 8f71d0c3..bc6b98bc 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 653dee3f..30d4a15d 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 e0f09c31..de076ff4 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 01aa5ac2..70d6148b 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 @@ -96,7 +95,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 @@ -260,6 +259,8 @@ a boolean value .IP \(bu 2 a color .IP \(bu 2 +image +.IP \(bu 2 text style .IP \(bu 2 line style @@ -383,6 +384,21 @@ dynamic: false; .fi .RE +.SH Image +.PP +\fBrofi\fP support a very limited set of image formats. + +.RS +.IP \(bu 2 +Format: url("path to image"); +.IP \(bu 2 +Format: linear\-gradient(start color,stop color); + +.RE + +.PP +Where the path is a string, and start/stop color is of type color. + .SH Color .PP \fBrofi\fP supports the color formats as specified in the CSS standard (1,2,3 and some of CSS 4) @@ -427,7 +443,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, @@ -659,7 +679,6 @@ style property. .PP When no unit is specified, pixels are assumed. - .RE .SH Position @@ -668,14 +687,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 @@ -847,6 +874,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. @@ -854,6 +882,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 @@ -869,14 +898,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 @@ -887,29 +917,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 @@ -1003,6 +1030,9 @@ Sets a radius on the corners of the borders. \fBbackground\-color\fP: color Background color .IP \(bu 2 +\fBbackground\-image\fP: image +Background image +.IP \(bu 2 \fBborder\-color\fP: color Color of the border .IP \(bu 2 @@ -1014,9 +1044,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. @@ -1024,20 +1058,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 @@ -1237,7 +1283,6 @@ The current layout of \fBrofi\fP is structured as follows: .PP ci is the case\-indicator - .RE .SS Error message structure diff --git a/doc/rofi-theme.5.markdown b/doc/rofi-theme.5.markdown index adcdf4c1..149c8cb4 100644 --- a/doc/rofi-theme.5.markdown +++ b/doc/rofi-theme.5.markdown @@ -181,6 +181,7 @@ The current theme format supports different types: * a fractional number * a boolean value * a color + * image * text style * line style * a distance @@ -249,6 +250,15 @@ For example: dynamic: false; ``` +## Image + +**rofi** support a very limited set of image formats. + +* Format: url("path to image"); +* Format: linear-gradient(start color,stop color); + +Where the path is a string, and start/stop color is of type color. + ## Color **rofi** supports the color formats as specified in the CSS standard (1,2,3 and some of CSS 4) @@ -622,6 +632,8 @@ The following properties are currently supported: Sets a radius on the corners of the borders. * **background-color**: color Background color +* **background-image**: image + Background image * **border-color**: color Color of the border * **cursor**: cursor @@ -1057,7 +1069,7 @@ If a filename is provided, it will try to resolve it in the following order: * `${XDG_CONFIG_HOME}/rofi/themes/` * `${XDG_CONFIG_HOME}/rofi/` * `${XDG_DATA_HOME}/rofi/themes/` - * `${INSTALL PREFIX}/share/rofi/themes/` + * `${INSTALL PREFIX}/share/rofi/themes/` A name is resolved as a filename by appending the `.rasi` extension. diff --git a/doc/rofi.1 b/doc/rofi.1 index af5f0856..f69b3d30 100644 --- a/doc/rofi.1 +++ b/doc/rofi.1 @@ -1,4 +1,3 @@ -.nh .TH ROFI 1 rofi .SH NAME .PP @@ -47,7 +46,7 @@ The website for \fB\fCdmenu\fR can be found here .PP \fBrofi\fP does not aim to be 100% compatible with \fB\fCdmenu\fR\&. There are simply too many different flavors of \fB\fCdmenu\fR\&. -The idea is that the basic usage command\-\&line flags are obeyed, theme\-\&related flags are not. +The idea is that the basic usage command\-line flags are obeyed, theme\-related flags are not. Besides, \fBrofi\fP offers some extended features (like multi\-select, highlighting, message bar, extra key bindings). .SS Display Error message @@ -181,7 +180,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 +464,11 @@ The different fields are: .IP \(bu 2 \fBcomment\fP: the application comment .IP \(bu 2 -\fBall\fP: all of the aboveDefault: \fIname,generic,exec,categories,keywords\fP + +.PP +\fBall\fP: all of the above +.PP +Default: \fIname,generic,exec,categories,keywords\fP .RE @@ -534,7 +541,11 @@ The different fields are: .IP \(bu 2 \fBdesktop\fP: window's current desktop .IP \(bu 2 -\fBall\fP: all of the aboveDefault: \fIall\fP + +.PP +\fBall\fP: all of the above +.PP +Default: \fIall\fP .RE @@ -667,7 +678,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 @@ -1148,7 +1163,7 @@ Set ellipsize mode to start. So end of 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 @@ -1662,21 +1677,21 @@ first. .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/include/rofi-types.h b/include/rofi-types.h index 9bf8869f..769b9290 100644 --- a/include/rofi-types.h +++ b/include/rofi-types.h @@ -2,6 +2,7 @@ #define INCLUDE_ROFI_TYPES_H #include +#include G_BEGIN_DECLS /** @@ -21,6 +22,8 @@ typedef enum P_BOOLEAN, /** Color */ P_COLOR, + /** Image */ + P_IMAGE, /** RofiPadding */ P_PADDING, /** Link to global setting */ @@ -167,6 +170,28 @@ typedef struct double alpha; } ThemeColor; +/** + * Theme Image + */ +typedef enum +{ + ROFI_IMAGE_URL, + ROFI_IMAGE_LINEAR_GRADIENT +} RofiImageType; +typedef struct +{ + RofiImageType type; + char *url; + /** Start color */ + ThemeColor start; + /** Stop color */ + ThemeColor stop; + + uint32_t surface_id; + uint32_t surface_size; + +} RofiImage; + /** * RofiPadding */ @@ -248,6 +273,8 @@ typedef union _PropertyValue } link; /** Highlight Style */ RofiHighlightColorStyle highlight; + /** Image */ + RofiImage image; /** List */ GList *list; } PropertyValue; diff --git a/include/widgets/widget.h b/include/widgets/widget.h index 06f57d96..e0cd7fb1 100644 --- a/include/widgets/widget.h +++ b/include/widgets/widget.h @@ -348,5 +348,6 @@ int widget_get_absolute_xpos ( widget *wid ); */ int widget_get_absolute_ypos ( widget *wid ); +void rofi_theme_get_image ( const widget *widget, const char *property, cairo_t *d ); /**@}*/ #endif // ROFI_WIDGET_H diff --git a/lexer/theme-lexer.l b/lexer/theme-lexer.l index 74d203b3..d0a05f8e 100644 --- a/lexer/theme-lexer.l +++ b/lexer/theme-lexer.l @@ -239,6 +239,10 @@ HWB (?i:hwb) CMYK (?i:cmyk) HSL (?i:hsl[a]?) +/* Image type */ +URL (?i:url?) +LINEAR_GRADIENT (?i:linear-gradient?) + COLOR_TRANSPARENT (?i:transparent) S_T_PARENT_LEFT \( @@ -544,6 +548,9 @@ if ( queue == NULL ){ argb:{HEX}{7} { return T_ERROR_ARGB_SPEC; } +{URL} { return T_URL; } +{LINEAR_GRADIENT} { return T_LINEAR_GRADIENT; } + /* Color schemes */ {RGBA} { return T_COL_RGBA; } {HSL} { return T_COL_HSL; } diff --git a/lexer/theme-parser.y b/lexer/theme-parser.y index 5e1f49c4..1b4fc24e 100644 --- a/lexer/theme-parser.y +++ b/lexer/theme-parser.y @@ -209,6 +209,9 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b) %token T_COL_HWB "hwb colorscheme" %token T_COL_CMYK "cmyk colorscheme" +%token T_URL "an URL" +%token T_LINEAR_GRADIENT "a linear gradient" + %token T_PARENT_LEFT "Parent left ('(')" %token T_PARENT_RIGHT "Parent right (')')" %token T_COMMA "comma separator (',')" @@ -528,6 +531,17 @@ t_property_element $$ = rofi_theme_property_create ( P_CURSOR ); $$->value.i = $1; } +| T_URL T_PARENT_LEFT T_STRING T_PARENT_RIGHT { + $$ = rofi_theme_property_create ( P_IMAGE ); + $$->value.image.type = ROFI_IMAGE_URL; + $$->value.image.url = $3; +} +| T_LINEAR_GRADIENT T_PARENT_LEFT t_property_color T_COMMA t_property_color T_PARENT_RIGHT { + $$ = rofi_theme_property_create ( P_IMAGE ); + $$->value.image.type = ROFI_IMAGE_LINEAR_GRADIENT; + $$->value.image.start = $3; + $$->value.image.stop = $5; +} ; /** List of elements */ diff --git a/source/theme.c b/source/theme.c index 63df760b..fe8a28d3 100644 --- a/source/theme.c +++ b/source/theme.c @@ -43,6 +43,7 @@ #include "view.h" #include "rofi.h" #include "rofi-types.h" +#include "rofi-icon-fetcher.h" void yyerror ( YYLTYPE *yylloc, const char *, const char * ); static gboolean distance_compare ( RofiDistance d, RofiDistance e ) @@ -135,6 +136,12 @@ Property* rofi_theme_property_copy ( const Property *p ) retv->value.padding.right = rofi_theme_property_copy_distance ( p->value.padding.right ); break; } + case P_IMAGE: + { + retv->value = p->value; + retv->value.image.url = g_strdup ( p->value.image.url ); + break; + } default: retv->value = p->value; } @@ -180,12 +187,17 @@ void rofi_theme_property_free ( Property *p ) rofi_theme_property_free ( p->value.link.def_value ); } } - if ( p->type == P_PADDING ) { + else if ( p->type == P_PADDING ) { rofi_theme_distance_property_free ( &( p->value.padding.top ) ); rofi_theme_distance_property_free ( &( p->value.padding.right ) ); rofi_theme_distance_property_free ( &( p->value.padding.bottom ) ); rofi_theme_distance_property_free ( &( p->value.padding.left ) ); } + else if ( p->type == P_IMAGE ) { + if ( p->value.image.url ) { + g_free( p->value.image.url ); + } + } g_slice_free ( Property, p ); } @@ -906,6 +918,46 @@ void rofi_theme_get_color ( const widget *widget, const char *property, cairo_t g_debug ( "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property ); } } +void rofi_theme_get_image ( const widget *widget, const char *property, cairo_t *d ) +{ + ThemeWidget *wid = rofi_theme_find_widget ( widget->name, widget->state, FALSE ); + Property *p = rofi_theme_find_property ( wid, P_IMAGE , property, FALSE ); + if ( p ) { + if ( p->type == P_INHERIT ) { + if ( widget->parent ) { + rofi_theme_get_image ( widget->parent, property, d ); + } + return; + } + if ( p->value.image.type == ROFI_IMAGE_URL ) { + uint32_t maxs = MAX(widget->h, widget->w); + if ( p->value.image.surface_id == 0 || p->value.image.surface_size != maxs ) { + p->value.image.surface_id = rofi_icon_fetcher_query ( p->value.image.url, maxs ); + p->value.image.surface_size = maxs; + } + cairo_surface_t *img = rofi_icon_fetcher_get ( p->value.image.surface_id ); + + if ( img != NULL ) { + cairo_surface_reference ( img ); + cairo_set_source_surface ( d, img, 0.0, 0.0 ); + cairo_surface_destroy ( img ); + } + } else if ( p->value.image.type == ROFI_IMAGE_LINEAR_GRADIENT ) { + cairo_pattern_t * pat = cairo_pattern_create_linear (0.0,0.0, widget->w, 0.0); + cairo_pattern_add_color_stop_rgba ( pat, 0.0, + p->value.image.start.red, p->value.image.start.green, + p->value.image.start.blue, p->value.image.start.alpha); + cairo_pattern_add_color_stop_rgba ( pat, 1.0, + p->value.image.stop.red, p->value.image.stop.green, + p->value.image.stop.blue, p->value.image.stop.alpha); + cairo_set_source ( d, pat ); + cairo_pattern_destroy ( pat ); + } + } + else { + g_debug ( "Theme entry: #%s %s property %s unset.", widget->name, widget->state ? widget->state : "", property ); + } +} RofiPadding rofi_theme_get_padding ( const widget *widget, const char *property, RofiPadding pad ) { ThemeWidget *wid = rofi_theme_find_widget ( widget->name, widget->state, FALSE ); diff --git a/source/widgets/widget.c b/source/widgets/widget.c index 76f21700..1d074db6 100644 --- a/source/widgets/widget.c +++ b/source/widgets/widget.c @@ -267,6 +267,7 @@ void widget_draw ( widget *widget, cairo_t *d ) cairo_set_source_rgba ( d, 1.0, 1.0, 1.0, 1.0 ); rofi_theme_get_color ( widget, "background-color", d ); + rofi_theme_get_image ( widget, "background-image", d ); cairo_fill_preserve ( d ); cairo_clip ( d );