Ok, I've been able to isolate the bug that sets the xfce4-term with
ncurses's default COLOR_WHITE/COLOR_BLACK foreground/background colors
after running a program using (colored) ncurses. This small example is
enough to trigger the incorrect behaviour:

    #include <curses.h>

    int main(int argc, char **argv)
    {
        initscr();
        if ( argc > 1 )
        {
            start_color();
            if ( argc > 2 )
                use_default_colors();
        }

        /*refresh();*/ /* this doesn't affect */
        endwin();
        /*refresh();*/ /* uncomment to fix */
        endwin();

        printw("This is a test\n");
        getch();

        endwin();

        return 0;
    }

Note: the number of arguments is used as a quickest way to change the
behaviour of the program in this way:

  ./test-ncurses         # doesn't invoke start_color()
  ./test-ncurses foo     # invokes start_color() but not use_default_colors()
  ./test-ncurses foo bar # invokes start_color() and use_default_colors()

The error is caused by the two consecutive endwin() function calls, but
only if start_color() has been previously called AND
use_default_colors() hasn't. So the bug is only reproducible using the
second of the 3 cases above (./test-ncurses foo). The other two cases
are provided only to prove the difference in behaviour.

One way to solve the problem is to ensure that use_default_colors() is
called after start_color(). Another way is to avoid any consecutive
calls to endwin() by introducing a wrefresh() call between them. In that
regard, the bug can also be fixed in the example above by uncommenting
the second call to refresh() (the one between both endwins).

This behaviour happens specifically in mutt because it doesn't
usually[1] call use_default_colors(), and because it calls endwin() a
lot[2]. The mutt developers have written a mutt_endwin() function,
supposedly to ensure that refresh() is always called before endwin(),
but there are still some locations in the code from where endwin() is
directly called, and unfortunately one of them[3] is the source of this
bug.

I'm explaining all of this because, from my current point of view, the
error is rather on the side of mutt than ncurses (and therefore it
should be fixed in mutt), but others may disagree. Perhaps Mr. Dickey
could bring some light on this, and about the expected behavior of the
endwind() function.


 [1]: for some reason use_default_colors() is not called just after
      start_color(), but delayed until the color settings have been read
      from the configuration files. The function is not even called
      except if one of the defined colors the "default" special value.
      Considering the default configuration doesn't use this "default"
      color, it's easy to see why mutt usually ends up not calling
      use_default_colors().

 [2]: mainly to execute external command line programs such as gpg or
      ispell

 [3]: http://sources.debian.net/src/mutt/1.6.0-1/init.c/#L3251

-- 
                       Saludos de Javier <jcant...@escomposlinux.org>


Attachment: signature.asc
Description: PGP signature

Reply via email to