diff --git a/config/config.def.c b/config/config.def.c index b14eac5c..7938561f 100644 --- a/config/config.def.c +++ b/config/config.def.c @@ -35,39 +35,46 @@ Settings config = { /** Set the default window opacity. */ /** This option only works when running a composite manager. */ /** -o */ - .window_opacity = 100, + .window_opacity = 100, /** Border width around the window. */ - .menu_bw = 1, + .menu_bw = 1, /** The width of the switcher. (0100 in % > 100 in pixels) */ - .menu_width = 50, + .menu_width = 50, /** Maximum number of options to show. */ - .menu_lines = 15, + .menu_lines = 15, /** Number of columns */ - .menu_columns = 1, + .menu_columns = 1, /** Font */ .menu_font = "mono 12", - /** Foreground color */ - .menu_fg = "#222222", - /** Text color used for urgent windows */ - .menu_fg_urgent = "#ff2222", - /** Text color used for active window */ - .menu_fg_active = "#2222ff", + /** Background color */ - .menu_bg = "#f2f1f0", - .menu_bg_urgent = "#f2f1f0", - .menu_bg_active = "#f2f1f0", + .menu_bg = NULL, + /** Border color. */ + .menu_bc = NULL, + /** Row colors */ + .color_normal = "#F2F1F0,#222222,#F2F1F0,#222222,#F1F1F0", + .color_urgent = "#F2F1F0,#FF2222,#F2F1F0,#FF2222,#F2F1F0", + .color_active = "#F2F1F0,#2222FF,#F2F1F0,#2222FF,#F2F1F0", + .color_window = "#F2F1F0,#000000", + + /** Foreground color */ + .menu_fg = NULL, + /** Text color used for urgent windows */ + .menu_fg_urgent = NULL, + /** Text color used for active window */ + .menu_fg_active = NULL, + .menu_bg_urgent = NULL, + .menu_bg_active = NULL, /** Background color alternate row */ .menu_bg_alt = NULL, /** Foreground color (selected) */ - .menu_hlfg = "#ffffff", - .menu_hlfg_urgent = "#ffffff", - .menu_hlfg_active = "#ffffff", + .menu_hlfg = NULL, + .menu_hlfg_urgent = NULL, + .menu_hlfg_active = NULL, /** Background color (selected) */ - .menu_hlbg = "#005577", - .menu_hlbg_urgent = "#005577", - .menu_hlbg_active = "#005577", - /** Border color. */ - .menu_bc = "black", + .menu_hlbg = NULL, + .menu_hlbg_urgent = NULL, + .menu_hlbg_active = NULL, /** Terminal to use. (for ssh and open in terminal) */ .terminal_emulator = "x-terminal-emulator", .ssh_client = "ssh", @@ -92,11 +99,11 @@ Settings config = { */ .location = WL_CENTER, /** Padding between elements */ - .padding = 5, + .padding = 5, /** Y offset */ - .y_offset = 0, + .y_offset = 0, /** X offset */ - .x_offset = 0, + .x_offset = 0, /** Always should config.menu_lines lines, even if less lines are available */ .fixed_num_lines = FALSE, /** Do not use history */ @@ -108,11 +115,11 @@ Settings config = { /** Separator to use for dmenu mode */ .separator = '\n', /** Height of an element in #chars */ - .element_height = 1, + .element_height = 1, /** Sidebar mode, show the switchers */ .sidebar_mode = FALSE, /** Lazy mode setting */ - .lazy_filter_limit = 5000, + .lazy_filter_limit = 5000, /** auto select */ .auto_select = FALSE, /** Parse /etc/hosts file in ssh view. */ diff --git a/include/rofi.h b/include/rofi.h index 7b756a30..b3f46ff6 100644 --- a/include/rofi.h +++ b/include/rofi.h @@ -152,6 +152,12 @@ typedef struct _Settings unsigned int menu_columns; /** Font string (pango format) */ char * menu_font; + + /** New row colors */ + char * color_normal; + char * color_active; + char * color_urgent; + char * color_window; /** Foreground color */ char * menu_fg; char * menu_fg_urgent; diff --git a/include/textbox.h b/include/textbox.h index 3ae8b118..1fd2dc33 100644 --- a/include/textbox.h +++ b/include/textbox.h @@ -35,18 +35,17 @@ typedef enum typedef enum { // Render font normally - NORMAL = 1, + NORMAL = 0, + URGENT = 1, + ACTIVE = 2, + // Alternating row. - ALT = 2, + ALT = 4, // Render font highlighted (inverted colors.) - HIGHLIGHT = 4, + HIGHLIGHT = 8, - STATE_MASK = ( NORMAL | ALT | HIGHLIGHT ), - - ACTIVE = 8, - URGENT = 16, - - FMOD_MASK = ( ACTIVE | URGENT ) + FMOD_MASK = ( ALT | HIGHLIGHT ), + STATE_MASK = ~( ALT | HIGHLIGHT ) } TextBoxFontType; textbox* textbox_create ( Window parent, @@ -146,20 +145,12 @@ void textbox_hide ( textbox *tb ); /** * @param visual Information about the visual to target * @param colormap The colormap to set the colors for. - * @param bg The background color. - * @param bg_alt The background color for alternating row. - * @param fg The foreground color. - * @param hlbg The background color for a highlighted entry. - * @param hlfg The foreground color for a highlighted entry. * * Setup the cached fonts. This is required to do * before any of the textbox_ functions is called. * Clean with textbox_cleanup() */ -void textbox_setup ( XVisualInfo *visual, Colormap colormap, - const char *bg, const char *bg_alt, const char *fg, - const char *hlbg, const char *hlfg - ); +void textbox_setup ( XVisualInfo *visual, Colormap colormap ); /** * Cleanup the allocated colors and fonts by textbox_setup(). diff --git a/include/x11-helper.h b/include/x11-helper.h index 3df9f8fb..249bedbb 100644 --- a/include/x11-helper.h +++ b/include/x11-helper.h @@ -133,4 +133,7 @@ void create_visual_and_colormap ( Display *display ); * Allocate a pixel value for an X named color */ unsigned int color_get ( Display *display, const char *const name ); + +unsigned int color_background ( Display *display ); +unsigned int color_border ( Display *display ); #endif diff --git a/source/rofi.c b/source/rofi.c index 82082130..a7bec183 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -254,8 +254,8 @@ static Window create_window ( Display *display ) { XSetWindowAttributes attr; attr.colormap = map; - attr.border_pixel = color_get ( display, config.menu_bc ); - attr.background_pixel = color_get ( display, config.menu_bg ); + attr.border_pixel = color_border ( display ); + attr.background_pixel = color_background ( display ); Window box = XCreateWindow ( display, DefaultRootWindow ( display ), 0, 0, 200, 100, config.menu_bw, vinfo.depth, InputOutput, @@ -264,7 +264,7 @@ static Window create_window ( Display *display ) gc = XCreateGC ( display, box, 0, 0 ); XSetLineAttributes ( display, gc, 2, LineOnOffDash, CapButt, JoinMiter ); - XSetForeground ( display, gc, color_get ( display, config.menu_bc ) ); + XSetForeground ( display, gc, color_border ( display ) ); // make it an unmanaged window window_set_atom_prop ( display, box, netatoms[_NET_WM_STATE], &netatoms[_NET_WM_STATE_ABOVE], 1 ); XSetWindowAttributes sattr; @@ -962,11 +962,11 @@ MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prom monitor_active ( display, &mon ); // we need this at this point so we can get height. - state.case_indicator = textbox_create ( main_window, &vinfo, map, TB_AUTOHEIGHT | TB_AUTOWIDTH, + state.line_height = textbox_get_estimated_char_height (); + state.case_indicator = textbox_create ( main_window, &vinfo, map, TB_AUTOWIDTH, ( config.padding ), ( config.padding ), - 0, 0, + 0, state.line_height, NORMAL, "*" ); - state.line_height = textbox_get_estimated_char_height (); // Height of a row. if ( config.menu_lines == 0 ) { // Autosize it. @@ -1000,7 +1000,7 @@ MenuReturn menu ( char **lines, unsigned int num_lines, char **input, char *prom // Move indicator to end. textbox_move ( state.case_indicator, config.padding + textbox_get_width ( state.prompt_tb ) + entrybox_width, - 0 ); + config.padding ); textbox_show ( state.text ); textbox_show ( state.prompt_tb ); @@ -1385,10 +1385,7 @@ static int run_dmenu () // Request truecolor visual. create_visual_and_colormap ( display ); - textbox_setup ( &vinfo, map, - config.menu_bg, config.menu_bg_alt, config.menu_fg, - config.menu_hlbg, - config.menu_hlfg ); + textbox_setup ( &vinfo, map ); char *input = NULL; // Dmenu modi has a return state. @@ -1428,10 +1425,7 @@ static void run_switcher ( int do_fork, SwitcherMode mode ) // Because of the above fork, we want to do this here. // Make sure this is isolated to its own thread. - textbox_setup ( &vinfo, map, - config.menu_bg, config.menu_bg_alt, config.menu_fg, - config.menu_hlbg, - config.menu_hlfg ); + textbox_setup ( &vinfo, map ); // Otherwise check if requested mode is enabled. char *input = NULL; for ( unsigned int i = 0; i < num_switchers; i++ ) { @@ -1666,10 +1660,7 @@ static void show_error_message ( const char *msg ) // Request truecolor visual. create_visual_and_colormap ( display ); - textbox_setup ( &vinfo, map, - config.menu_bg, config.menu_bg_alt, config.menu_fg, - config.menu_hlbg, - config.menu_hlfg ); + textbox_setup ( &vinfo, map ); error_dialog ( msg ); textbox_cleanup ( ); if ( map != None ) { diff --git a/source/textbox.c b/source/textbox.c index 6a30480f..9cba3449 100644 --- a/source/textbox.c +++ b/source/textbox.c @@ -47,26 +47,26 @@ extern Display *display; * Font + font color cache. * Avoid re-loading font on every change on every textbox. */ -// -XftColor color_fg; -XftColor color_bg; -XftColor color_fg_urgent; -XftColor color_fg_active; -XftColor color_bg_urgent; -XftColor color_bg_active; -// -XftColor color_hlfg; -XftColor color_hlbg; -XftColor color_hlfg_urgent; -XftColor color_hlfg_active; -XftColor color_hlbg_urgent; -XftColor color_hlbg_active; -XftColor color_bg_alt; -XVisualInfo *visual_info; -Colormap target_colormap; +XVisualInfo *visual_info; +Colormap target_colormap; + + +typedef struct _RowColor +{ + XftColor fg; + XftColor bg; + XftColor bgalt; + XftColor hlfg; + XftColor hlbg; +} RowColor; + +#define num_states 3 +RowColor colors[num_states]; + PangoContext *p_context = NULL; + // Xft text box, optionally editable textbox* textbox_create ( Window parent, XVisualInfo *vinfo, @@ -92,13 +92,13 @@ textbox* textbox_create ( Window parent, switch ( tbft ) { case HIGHLIGHT: - cp = color_hlbg.pixel; + cp = colors[NORMAL].hlbg.pixel; break; case ALT: - cp = color_bg_alt.pixel; + cp = colors[NORMAL].bgalt.pixel; break; default: - cp = color_bg.pixel; + cp = colors[NORMAL].bg.pixel; break; } @@ -137,44 +137,22 @@ textbox* textbox_create ( Window parent, // set an Xft font by name void textbox_font ( textbox *tb, TextBoxFontType tbft ) { - switch ( ( tbft & STATE_MASK ) ) + RowColor *color = &( colors[tbft & STATE_MASK] ); + switch ( ( tbft & FMOD_MASK ) ) { case HIGHLIGHT: - tb->color_bg = color_hlbg; - tb->color_fg = color_hlfg; + tb->color_bg = color->hlbg; + tb->color_fg = color->hlfg; break; case ALT: - tb->color_bg = color_bg_alt; - tb->color_fg = color_fg; + tb->color_bg = color->bgalt; + tb->color_fg = color->fg; break; - case NORMAL: default: - tb->color_bg = color_bg; - tb->color_fg = color_fg; + tb->color_bg = color->bg; + tb->color_fg = color->fg; break; } - if ( ( tbft & FMOD_MASK ) ) { - if ( ( tbft & ACTIVE ) ) { - if ( tbft & HIGHLIGHT ) { - tb->color_fg = color_hlfg_active; - tb->color_bg = color_hlbg_active; - } - else { - tb->color_fg = color_fg_active; - tb->color_bg = color_bg_active; - } - } - else if ( ( tbft & URGENT ) ) { - if ( tbft & HIGHLIGHT ) { - tb->color_fg = color_hlfg_urgent; - tb->color_bg = color_hlbg_urgent; - } - else { - tb->color_fg = color_fg_urgent; - tb->color_bg = color_bg_urgent; - } - } - } tb->tbft = tbft; } @@ -627,6 +605,9 @@ int textbox_keypress ( textbox *tb, XEvent *ev ) static void parse_color ( Visual *visual, Colormap colormap, const char *bg, XftColor *color ) { + if ( bg == NULL ) { + return; + } if ( strncmp ( bg, "argb:", 5 ) == 0 ) { XRenderColor col; unsigned int val = strtoul ( &bg[5], NULL, 16 ); @@ -640,52 +621,95 @@ static void parse_color ( Visual *visual, Colormap colormap, XftColorAllocName ( display, visual, colormap, bg, color ); } } - -void textbox_setup ( XVisualInfo *visual, Colormap colormap, - const char *bg, const char *bg_alt, const char *fg, - const char *hlbg, const char *hlfg - ) +#if 1 +static void textbox_parse_string ( XVisualInfo *visual, Colormap colormap, const char *str, RowColor *color ) +{ + if ( str == NULL ) { + return; + } + char *cstr = g_strdup ( str ); + char *endp; + char *token; + int index = 0; + for ( token = strtok_r ( cstr, ",", &endp ); token != NULL; token = strtok_r ( NULL, ",", &endp ) ) { + switch ( index ) + { + case 0: + parse_color ( visual->visual, colormap, token, &( color->bg ) ); + break; + case 1: + parse_color ( visual->visual, colormap, token, &( color->fg ) ); + break; + case 2: + parse_color ( visual->visual, colormap, token, &( color->bgalt ) ); + break; + case 3: + parse_color ( visual->visual, colormap, token, &( color->hlbg ) ); + break; + case 4: + parse_color ( visual->visual, colormap, token, &( color->hlfg ) ); + break; + } + index++; + } + g_free ( cstr ); +} +#endif +void textbox_setup ( XVisualInfo *visual, Colormap colormap ) { visual_info = visual; target_colormap = colormap; - parse_color ( visual_info->visual, target_colormap, bg, &color_bg ); - parse_color ( visual_info->visual, target_colormap, fg, &color_fg ); + textbox_parse_string ( visual_info->visual, target_colormap, + config.color_normal, &( colors[NORMAL] ) ); + textbox_parse_string ( visual_info->visual, target_colormap, + config.color_urgent, &( colors[URGENT] ) ); + textbox_parse_string ( visual_info->visual, target_colormap, + config.color_active, &( colors[ACTIVE] ) ); +#if 1 + parse_color ( visual_info->visual, target_colormap, config.menu_bg, &( colors[NORMAL].bg ) ); + parse_color ( visual_info->visual, target_colormap, config.menu_fg, &( colors[NORMAL].fg ) ); + parse_color ( visual_info->visual, target_colormap, config.menu_bg_alt, &( colors[NORMAL].bgalt ) ); + parse_color ( visual_info->visual, target_colormap, config.menu_hlfg, &( colors[NORMAL].hlfg ) ); + parse_color ( visual_info->visual, target_colormap, config.menu_hlbg, &( colors[NORMAL].hlbg ) ); - parse_color ( visual_info->visual, target_colormap, bg_alt, &color_bg_alt ); - parse_color ( visual_info->visual, target_colormap, hlfg, &color_hlfg ); - parse_color ( visual_info->visual, target_colormap, hlbg, &color_hlbg ); - - parse_color ( visual_info->visual, target_colormap, config.menu_fg_active, &color_fg_active ); - parse_color ( visual_info->visual, target_colormap, config.menu_fg_urgent, &color_fg_urgent ); - parse_color ( visual_info->visual, target_colormap, config.menu_bg_active, &color_bg_active ); - parse_color ( visual_info->visual, target_colormap, config.menu_bg_urgent, &color_bg_urgent ); - parse_color ( visual_info->visual, target_colormap, config.menu_hlbg_active, &color_hlbg_active ); - parse_color ( visual_info->visual, target_colormap, config.menu_hlbg_urgent, &color_hlbg_urgent ); - parse_color ( visual_info->visual, target_colormap, config.menu_hlfg_active, &color_hlfg_active ); - parse_color ( visual_info->visual, target_colormap, config.menu_hlfg_urgent, &color_hlfg_urgent ); + parse_color ( visual_info->visual, target_colormap, config.menu_bg_urgent, &( colors[URGENT].bg ) ); + parse_color ( visual_info->visual, target_colormap, config.menu_fg_urgent, &( colors[URGENT].fg ) ); + parse_color ( visual_info->visual, target_colormap, config.menu_bg_alt, &( colors[URGENT].bgalt ) ); + parse_color ( visual_info->visual, target_colormap, config.menu_hlfg_urgent, &( colors[URGENT].hlfg ) ); + parse_color ( visual_info->visual, target_colormap, config.menu_hlbg_urgent, &( colors[URGENT].hlbg ) ); + parse_color ( visual_info->visual, target_colormap, config.menu_bg_active, &( colors[ACTIVE].bg ) ); + parse_color ( visual_info->visual, target_colormap, config.menu_fg_active, &( colors[ACTIVE].fg ) ); + parse_color ( visual_info->visual, target_colormap, config.menu_bg_alt, &( colors[ACTIVE].bgalt ) ); + parse_color ( visual_info->visual, target_colormap, config.menu_hlfg_active, &( colors[ACTIVE].hlfg ) ); + parse_color ( visual_info->visual, target_colormap, config.menu_hlbg_active, &( colors[ACTIVE].hlbg ) ); +#endif PangoFontMap *font_map = pango_xft_get_font_map ( display, DefaultScreen ( display ) ); p_context = pango_font_map_create_context ( font_map ); } +static void textbox_clean_rowcolor ( RowColor * color ) +{ + XftColorFree ( display, visual_info->visual, target_colormap, + &( color->fg ) ); + XftColorFree ( display, visual_info->visual, target_colormap, + &( color->bg ) ); + XftColorFree ( display, visual_info->visual, target_colormap, + &( color->bgalt ) ); + XftColorFree ( display, visual_info->visual, target_colormap, + &( color->hlfg ) ); + XftColorFree ( display, visual_info->visual, target_colormap, + &( color->hlbg ) ); +} void textbox_cleanup ( void ) { if ( p_context ) { - XftColorFree ( display, visual_info->visual, target_colormap, &color_fg ); - XftColorFree ( display, visual_info->visual, target_colormap, &color_fg_urgent ); - XftColorFree ( display, visual_info->visual, target_colormap, &color_fg_active ); - XftColorFree ( display, visual_info->visual, target_colormap, &color_bg ); - XftColorFree ( display, visual_info->visual, target_colormap, &color_bg_urgent ); - XftColorFree ( display, visual_info->visual, target_colormap, &color_bg_active ); - XftColorFree ( display, visual_info->visual, target_colormap, &color_bg_alt ); - XftColorFree ( display, visual_info->visual, target_colormap, &color_hlfg ); - XftColorFree ( display, visual_info->visual, target_colormap, &color_hlbg ); - XftColorFree ( display, visual_info->visual, target_colormap, &color_hlbg_active ); - XftColorFree ( display, visual_info->visual, target_colormap, &color_hlbg_urgent ); - XftColorFree ( display, visual_info->visual, target_colormap, &color_hlfg_active ); - XftColorFree ( display, visual_info->visual, target_colormap, &color_hlfg_urgent ); + for ( unsigned int st = 0; st < num_states; st++ ) { + textbox_clean_rowcolor ( &colors[st] ); + } + g_object_unref ( p_context ); p_context = NULL; visual_info = NULL; diff --git a/source/x11-helper.c b/source/x11-helper.c index 6ad19af5..7c4435ed 100644 --- a/source/x11-helper.c +++ b/source/x11-helper.c @@ -43,6 +43,7 @@ #include #include +#include #define OVERLAP( a, b, c, d ) ( ( ( a ) == ( c ) && ( b ) == ( d ) ) || MIN ( ( a ) + ( b ), ( c ) + ( d ) ) - MAX ( ( a ), ( c ) ) > 0 ) #define INTERSECT( x, y, w, h, x1, y1, w1, h1 ) ( OVERLAP ( ( x ), ( w ), ( x1 ), ( w1 ) ) && OVERLAP ( ( y ), ( h ), ( y1 ), ( h1 ) ) ) #include "x11-helper.h" @@ -424,7 +425,6 @@ void create_visual_and_colormap ( Display *display ) map = DefaultColormap ( display, screen ); } } - unsigned int color_get ( Display *display, const char *const name ) { XColor color = { 0, 0, 0, 0, 0, 0 }; @@ -444,3 +444,33 @@ unsigned int color_get ( Display *display, const char *const name ) return XAllocNamedColor ( display, map, name, &color, &color ) ? color.pixel : None; } } + +unsigned int color_background ( Display *display ) +{ + if ( config.menu_bg ) { + return color_get ( display, config.menu_bg ); + } + unsigned int retv = 0; + + gchar **vals = g_strsplit ( config.color_window, ",", 2 ); + if ( vals != NULL && vals[0] != NULL ) { + retv = color_get ( display, vals[0] ); + } + g_strfreev ( vals ); + return retv; +} + +unsigned int color_border ( Display *display ) +{ + if ( config.menu_bc ) { + return color_get ( display, config.menu_bc ); + } + unsigned int retv = 0; + + gchar **vals = g_strsplit ( config.color_window, ",", 2 ); + if ( vals != NULL && vals[0] != NULL && vals[1] != NULL ) { + retv = color_get ( display, vals[1] ); + } + g_strfreev ( vals ); + return retv; +} diff --git a/source/xrmoptions.c b/source/xrmoptions.c index edb0e68b..41bd86ff 100644 --- a/source/xrmoptions.c +++ b/source/xrmoptions.c @@ -64,8 +64,15 @@ static XrmOption xrmOptions[] = { { xrm_String, "font", { .str = &config.menu_font }, NULL }, /* Foreground color */ - { xrm_String, "foreground", { .str = &config.menu_fg }, NULL }, +/* { xrm_String, "foreground", { .str = &config.menu_fg }, NULL },*/ { xrm_String, "fg", { .str = &config.menu_fg }, NULL }, +/* { xrm_String, "background", { .str = &config.menu_bg }, NULL },*/ + { xrm_String, "bg", { .str = &config.menu_bg }, NULL }, + + { xrm_String, "color-normal", { .str = &config.color_normal }, NULL }, + { xrm_String, "color-urgent", { .str = &config.color_urgent }, NULL }, + { xrm_String, "color-active", { .str = &config.color_active }, NULL }, + { xrm_String, "color-window", { .str = &config.color_window }, NULL }, { xrm_String, "fg-active", { .str = &config.menu_fg_active }, NULL }, { xrm_String, "fg-urgent", { .str = &config.menu_fg_urgent }, NULL }, @@ -77,8 +84,6 @@ static XrmOption xrmOptions[] = { { xrm_String, "hlbg-active", { .str = &config.menu_hlbg_active }, NULL }, { xrm_String, "hlbg-urgent", { .str = &config.menu_hlbg_urgent }, NULL }, - { xrm_String, "background", { .str = &config.menu_bg }, NULL }, - { xrm_String, "bg", { .str = &config.menu_bg }, NULL }, { xrm_String, "background-alternate", { .str = &config.menu_bg_alt }, NULL }, { xrm_String, "bgalt", { .str = &config.menu_bg_alt }, NULL }, diff --git a/test/textbox-test.c b/test/textbox-test.c index fdab21ec..5ca3fd47 100644 --- a/test/textbox-test.c +++ b/test/textbox-test.c @@ -73,8 +73,7 @@ int main ( G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv ) TASSERT( mw != None ); // Set alternate row to normal row. config.menu_bg_alt = config.menu_bg; - textbox_setup ( &vinfo, map, config.menu_bg, config.menu_bg_alt, config.menu_fg, - config.menu_hlbg, config.menu_hlfg ); + textbox_setup ( &vinfo, map ); textbox *box = textbox_create(mw , &vinfo, map, TB_EDITABLE|TB_AUTOWIDTH|TB_AUTOHEIGHT, 0,0, -1, -1, NORMAL, "test"); TASSERT( box != NULL );