Hi,
Here are some updates to merging colors logic.
First, there's a bug I've introduced during a rewrite: attributes
should always be merged, not only when indicator background or
foreground is set.
Here is the correct version:
diff --git a/color.c b/color.c
index 8f3c3ba7..cee39905 100644
--- a/color.c
+++ b/color.c
@@ -258,10 +258,11 @@ int mutt_merge_colors (int source_pair, int overlay_pair)
merged_fg = overlay->fg < 0 ? source->fg : overlay->fg;
merged_bg = overlay->bg < 0 ? source->bg : overlay->bg;
merged_pair = mutt_alloc_color (merged_fg, merged_bg, 0);
- merged_pair |= (source_pair & ATTR_MASK) | (overlay_pair & ATTR_MASK);
}
}
+ merged_pair |= (source_pair & ATTR_MASK) | (overlay_pair & ATTR_MASK);
+
return merged_pair;
}
Second, I've discovered another place that requires merging of colors:
print_enriched_string function. It is called by main menu drawing
routines and contains its own conditional coloring of a tree
component. As is, everything in there gets overwritten by the
indicator. Furthermore, do_color parameter specifically disables any
coloring in order for indicator highlight to overwrite everything
else.
We need to merge three colors here:
1) index color;
2) tree color, that is drawn within menu using its own color;
3) indicator color, that, if active, is drawn over both of them.
Combining these colors is implemented in that order.
Third, after some testing, I think it doesn't make sense to merge
colors when $arrow_cursor is on. This part is reverted to the original
behavior.
Here is an updated patch for menu.c restoring original highlighting
when $arrow_cursor is on, adding color merging for the tree component,
and refactoring print_enriched_string usage to be consistent
throughout the file:
diff --git a/menu.c b/menu.c
index 2da07c25..369ac238 100644
--- a/menu.c
+++ b/menu.c
@@ -35,12 +35,24 @@ static size_t MenuStackCount = 0;
static size_t MenuStackLen = 0;
static MUTTMENU **MenuStack = NULL;
-static void print_enriched_string (int attr, unsigned char *s, int do_color)
+static void print_enriched_string (int base_color, unsigned char *s, int
do_color, int is_current)
{
wchar_t wc;
size_t k;
size_t n = mutt_strlen ((char *)s);
mbstate_t mbstate;
+ int tree_color = ColorDefs[MT_COLOR_TREE];
+
+ if (option (OPTCURSOROVERLAY))
+ {
+ do_color = 1;
+ tree_color = mutt_merge_colors (base_color, tree_color);
+ if (is_current)
+ {
+ tree_color = mutt_merge_colors (tree_color,
ColorDefs[MT_COLOR_INDICATOR]);
+ base_color = mutt_merge_colors (base_color,
ColorDefs[MT_COLOR_INDICATOR]);
+ }
+ }
memset (&mbstate, 0, sizeof (mbstate));
while (*s)
@@ -48,7 +60,7 @@ static void print_enriched_string (int attr, unsigned char
*s, int do_color)
if (*s < MUTT_TREE_MAX)
{
if (do_color)
- SETCOLOR (MT_COLOR_TREE);
+ ATTRSET (tree_color);
while (*s && *s < MUTT_TREE_MAX)
{
switch (*s)
@@ -165,7 +177,8 @@ static void print_enriched_string (int attr, unsigned char
*s, int do_color)
}
s++, n--;
}
- if (do_color) ATTRSET(attr);
+ if (do_color)
+ ATTRSET(base_color);
}
else if ((k = mbrtowc (&wc, (char *)s, n, &mbstate)) > 0)
{
@@ -251,7 +264,6 @@ void menu_redraw_index (MUTTMENU *menu)
{
char buf[LONG_STRING];
int i;
- int do_color;
int attr;
for (i = menu->top; i < menu->top + menu->pagelen; i++)
@@ -265,24 +277,31 @@ void menu_redraw_index (MUTTMENU *menu)
ATTRSET(attr);
mutt_window_move (menu->indexwin, i - menu->top + menu->offset, 0);
- do_color = 1;
if (i == menu->current)
{
- mutt_attrset_cursor (attr, ColorDefs[MT_COLOR_INDICATOR]);
if (option(OPTARROWCURSOR))
{
+ SETCOLOR(MT_COLOR_INDICATOR);
addstr ("->");
ATTRSET(attr);
addch (' ');
+ print_enriched_string (attr, (unsigned char *) buf, 1, 0);
}
else
- do_color = 0;
+ {
+ mutt_attrset_cursor (attr, ColorDefs[MT_COLOR_INDICATOR]);
+ print_enriched_string (attr, (unsigned char *) buf, 0, 1);
+ }
+ }
+ else
+ {
+ if (option(OPTARROWCURSOR))
+ {
+ addstr(" ");
+ }
+ print_enriched_string (attr, (unsigned char *) buf, 1, 0);
}
- else if (option(OPTARROWCURSOR))
- addstr(" ");
-
- print_enriched_string (attr, (unsigned char *) buf, do_color);
}
else
{
@@ -325,11 +344,11 @@ void menu_redraw_motion (MUTTMENU *menu)
menu_make_entry (buf, sizeof (buf), menu, menu->oldcurrent);
menu_pad_string (menu, buf, sizeof (buf));
mutt_window_move (menu->indexwin, menu->oldcurrent + menu->offset -
menu->top, 3);
- print_enriched_string (old_color, (unsigned char *) buf, 1);
+ print_enriched_string (old_color, (unsigned char *) buf, 1, 0);
}
/* now draw it in the new location */
- mutt_attrset_cursor (cur_color, ColorDefs[MT_COLOR_INDICATOR]);
+ SETCOLOR(MT_COLOR_INDICATOR);
mutt_window_mvaddstr (menu->indexwin, menu->current + menu->offset -
menu->top, 0, "->");
}
else
@@ -337,14 +356,14 @@ void menu_redraw_motion (MUTTMENU *menu)
/* erase the current indicator */
menu_make_entry (buf, sizeof (buf), menu, menu->oldcurrent);
menu_pad_string (menu, buf, sizeof (buf));
- print_enriched_string (old_color, (unsigned char *) buf, 1);
+ print_enriched_string (old_color, (unsigned char *) buf, 1, 0);
/* now draw the new one to reflect the change */
menu_make_entry (buf, sizeof (buf), menu, menu->current);
menu_pad_string (menu, buf, sizeof (buf));
mutt_attrset_cursor (cur_color, ColorDefs[MT_COLOR_INDICATOR]);
mutt_window_move (menu->indexwin, menu->current + menu->offset -
menu->top, 0);
- print_enriched_string (cur_color, (unsigned char *) buf, 0);
+ print_enriched_string (cur_color, (unsigned char *) buf, 0, 1);
}
menu->redraw &= REDRAW_STATUS;
NORMAL_COLOR;
@@ -359,17 +378,21 @@ void menu_redraw_current (MUTTMENU *menu)
menu_make_entry (buf, sizeof (buf), menu, menu->current);
menu_pad_string (menu, buf, sizeof (buf));
- mutt_attrset_cursor (attr, ColorDefs[MT_COLOR_INDICATOR]);
if (option (OPTARROWCURSOR))
{
+ SETCOLOR(MT_COLOR_INDICATOR);
addstr ("->");
ATTRSET(attr);
addch (' ');
menu_pad_string (menu, buf, sizeof (buf));
- print_enriched_string (attr, (unsigned char *) buf, 1);
+ print_enriched_string (attr, (unsigned char *) buf, 1, 0);
}
else
- print_enriched_string (attr, (unsigned char *) buf, 0);
+ {
+ mutt_attrset_cursor (attr, ColorDefs[MT_COLOR_INDICATOR]);
+ print_enriched_string (attr, (unsigned char *) buf, 0, 1);
+ }
+
menu->redraw &= REDRAW_STATUS;
NORMAL_COLOR;
}