summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>2026-01-14 16:16:25 +0100
committerManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>2026-01-14 16:16:25 +0100
commit81c965f8e29c7b9fb68e9914d4223ab5fe293d1f (patch)
tree73c3e9c3f753274800c86259e01d3aebdbb2a911 /src
parentd38b699432ab9c69a9e1a257cc4544db8ba1217e (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.
Diffstat (limited to 'src')
-rw-r--r--src/Fl_win32.cxx28
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