diff options
| author | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2026-01-14 16:16:25 +0100 |
|---|---|---|
| committer | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2026-01-14 16:16:25 +0100 |
| commit | 81c965f8e29c7b9fb68e9914d4223ab5fe293d1f (patch) | |
| tree | 73c3e9c3f753274800c86259e01d3aebdbb2a911 | |
| parent | d38b699432ab9c69a9e1a257cc4544db8ba1217e (diff) | |
Partial fix for the Windows platform of the emoji issue (#1360)
This fixes input of emojis to Fl_Input and Fl_Text_editor widgets under Windows with the emoji palette.
Most emojis have a Unicode point > 0xFFFF and therefore are encoded as a surrogate pair
by Windows which uses UTF-16. Thus, Windows sends 2 consecutive WM_CHAR messages to the
window and gives one member of the pair each time. After the second WM_CHAR message arrived
FLTK is able to enter the emoji in its text. Windows may also send "variation selectors" and
zero-width Unicode points when dealing with emojis. FLTK just skips them.
Windows also translates some Unicode emojis into 1 emoji + 1 other Unicode point: for example
"woman pilot" produces "pilot emoji" + "woman" unicode point. FLTK now handles
this gracefuly.
This fix also prefixes the windows class names with "FLTK-" under Windows to prevent
collisions with Windows-reserved class names. That fix is necessary for the emoji palette
to be usable in some scenarios. That fix is still under debate and may evolve in latter commits.
| -rw-r--r-- | src/Fl_win32.cxx | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx index da1db6455..c3770024d 100644 --- a/src/Fl_win32.cxx +++ b/src/Fl_win32.cxx @@ -1561,7 +1561,25 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar static char buffer[1024]; if (uMsg == WM_CHAR || uMsg == WM_SYSCHAR) { wchar_t u = (wchar_t)wParam; - Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1); + // Windows emoji palette triggered with Windows + dot sends 2 or more WM_CHAR messages: + // the 2 components of a surrogate pair, or variation selectors, or zero-width stuff, + // or extra Unicode points. + if (u >= 0xD800 && u <= 0xDFFF) { // handle the 2 components of a surrogate pair + static wchar_t surrogate_pair[2]; + if (IS_HIGH_SURROGATE(u)) { + surrogate_pair[0] = u; // memorize the 1st member of the pair + Fl::e_length = 0; + return 0; // and wait for next WM_CHAR message that will give the 2nd member + } else { + surrogate_pair[1] = u; // memorize the 2nd member of the pair + Fl::e_length = fl_utf8fromwc(buffer, 1024, surrogate_pair, 2); // transform to UTF-8 + } + } else if ((u >= 0xFE00 && u <= 0xFE0F) || (u >= 0x200B && u <= 0x200D)) { + Fl::e_length = 0; // skip variation selectors and zero-width Unicode points + return 0; + } else { + Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1); // process regular Unicode point + } buffer[Fl::e_length] = 0; } else if (Fl::e_keysym >= FL_KP && Fl::e_keysym <= FL_KP_Last) { if (state & FL_NUM_LOCK) { @@ -2167,6 +2185,14 @@ void Fl_WinAPI_Window_Driver::makeWindow() { if (!first_class_name) { first_class_name = class_name; } +// Prefix user-set window class name by "FLTK", unless it's already here, +// to avoid collision with system-defined window class names (example "edit") + if (strncmp(class_name, "FLTK", 4)) { + static char new_class_name[100]; + snprintf(new_class_name, sizeof(new_class_name), "FLTK-%s", class_name); + class_name = new_class_name; + } + //fprintf(stderr,"makeWindow: class_name=%s\n",class_name);fflush(stderr); wchar_t class_namew[100]; // (limited) buffer for Windows class name |
