Terminal.Gui: Most Glyphs not showing on macOS - E.g. Menu Glyphs and Character Map
It’s possible to scroll top and see the old screen. It’s a weird and ugly situation. Its happens with the Terminal and even ITerm2.

About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 39
Commits related to this issue
- #41 and #949. Unit test to compare the difference between System.Rune and System.Text.Rune. — committed to BDisp/Terminal.Gui by BDisp 4 years ago
- #41 and #949. Unit test to compare the difference between System.Rune and System.Text.Rune. — committed to BDisp/Terminal.Gui by BDisp 4 years ago
- Merge pull request #975 from BDisp/rune-versions #41 and #949. Unit test to compare the difference between System.Rune and System.Text.Rune. — committed to gui-cs/Terminal.Gui by tig 4 years ago
- Merge pull request #1122 from tig/fix_949_mac_glyphs made LC_ALL OS dependent. Fixes #949 — committed to gui-cs/Terminal.Gui by tig 3 years ago
Also, for good measure, we should change setlocale to return an
IntPtr, and not anint, in case we ever find a system that uses different calling conventions - it is just good hygiene.Hello,
@mklement0 found the culprit, the issue is that the
LC_ALLdefinition is wrong for Mac. It should be 0, according to locale.h:I do not know what the value is on Linux, but if it is not zero, then we will need to check the OS and use 0 on Mac, and 6 o Linux.
Hello,
The posters are right, this is a problem with ncurses, not really an issue with the terminal.
What might be happening is that ncurses is being initialized implicitly by some code before setlocale is invoked.
Perhaps an additional dependency, or some invocation to the library is taking place that loads and initializes ncurses before we call setlocale. One quick way of testing this theory would be to call
setlocalemanually in Main():Before anything else - also, not sure if we are now using global constructors (the ones that run on assembly load), that could also be initializing curses before we have a chance to.
I had some misconceptions:
It is indeed only the terminal emulator’s character-encoding setting that matters for display, for all programs.
Typically, terminal emulators are configured to reflect the locale + character encoding in the
LANGenvironment variable (which can be overridden via either category-specific individualLC_*environment variables or for all categories withLC_ALL), e.g.en_US.UTF-8.Locale-aware programs do respect these environment variables, so you can do the following to print the current date in French, for instance (using Bash syntax):
LC_ALL=fr_FR date-> French-style dateAnd while programs even respect the character-encoding part of the value, this won’t work for display in the terminal, because the terminal isn’t aware of the requested ad hoc character-encoding change; e.g., on macOS the following correctly translates single byte
0xe8, representing lowercaseèin ISO-8859-1 encoding, to single byte0xc8, its uppercaseÈequivalent (on Linux, utilitytrisn’t locale-aware); however, unless the terminal too is set to ISO-8859-1, the result will print as the replacement character:printf '\xe8' | LC_ALL=fr_FR.ISO8859-1 tr '[:lower:]' '[:upper:]' | od -t x1->c8; without| od -t x1, in a UTF-8 terminal window, you’d see�or?, depending on the terminal.Returning to the ncurses library:
On macOS, there’s only one binary,
/usr/lib/libncurses.dylib, which contains both the narrow and wide-character functions.The version that ships with macOS 10.15.7 is quite old (
ncurses5.4-config --version):5.7.20081102vs.6.2.20200212, the current version.From
man ncurses(emphasis added):The mystery is that Terminal.Gui does call
setlocale(LC_ALL, ""), yet ncurses on macOS seemingly always uses its built-in default, ISO-8859-1.One thing worth looking into: Is the
setlocale(LC_ALL, "")call truly effective on macOS?@ mklement0 thank you very much for your commitment. Your research is of enormous value. I hope you can come up with the solution to this because I’m already burning the fuses 😃
Thanks, @BDisp, but the logic of
LC_ALLis not a matter of bit patterns - asman setlocaleon macOS states:That is, the
LC_*categories are not flags to be bit-ORed - they are distinct values, withLC_ALLby convention overriding all others.Re macOS: The
setlocalemethod is misdefined as returningint, according to themanpage it ischar *, so if you define it asIntPtrand convert it to a string withMarshal.PtrToStringAuto(), it shows that the locale is seemingly correctly picked up from the environment.As an aside:
Window.initscr()is reentered viamain_window = new Window (methods.initscr ());- is that expected?The strange thing is that I eventually did get the glyphs to render correctly, namely by setting
LC_CTYPE(define it as0) instead ofLC_ALL, to target the character-encoding category explicitly - even thoughLC_ALLshould set all categories.Similarly strangely, querying the effective
LC_ALLcategory (by passingnullinstead of"") yields the correct value even when onlyLC_CTYPEwas set. Do the other locale categories matter and should they be set explicitly as well?See https://github.com/migueldeicaza/gui.cs/issues/41
I’ve already been down this path…
ncurses isn’t sending UTF-8 to the terminal (it is sending ISO-8859-1, always), so we need to figure out why.
By the way, given that Terminal.Gui can only ever work as expected with UTF-8, the right thing to do would be to refuse startup if the terminal window’s character encoding is found to be something other than UTF-8.
I confirm that it works.
iTerm2-Menlo:
iTerm2-Monaco:
Terminal-Menlo:
Terminal-monaco:
What I posted is a PowerShell command, so it only makes sense to run it from inside PowerShell (
iexis the built-in alias for theInvoke-Expressioncmdlet; the command also uses thegcalias for theGet-Contentcmdlet).How did you try to install PowerShell? The package downloadable from https://github.com/PowerShell/PowerShell#get-powershell should work.
If you have Homebrew installed, you can also try:
Thanks. Yes the
setlocale (LC_ALL, "")is called. It may not be influential on the macOS.Hey @mklement0 - you seem like you know what you are doing on a Mac. Can you help us with this?
I don’t have time to dive into this today or tomorrow. But it seems there’s some silly configuration related bug in ConsoleDriver/CursesDriver when running on Mac based on this.