mirror of
https://github.com/fltk/fltk.git
synced 2026-02-07 08:51:47 +08:00
All platforms use same code to remove context-dependent codepoints from text input.
This commit introduces function fl_utf8_remove_context_dependent() that removes from an UTF-8 string its context-dependent codepoints. Platforms macOS, Wayland and X11 call this function to process UTF-8 text received from a character palette as input to FLTK text. This makes sure FLTK text-editing widgets process textual input equally and consistently across platforms, especially emojis entered via a palette. Platform Windows creates a series of separate system events to input an emoji via the character palette. For this reason, function fl_utf8_remove_context_dependent() is not used by this platform which does internally the same filtering of context- dependent codepoints.
This commit is contained in:
@@ -67,6 +67,7 @@ extern "C" {
|
||||
// external functions
|
||||
extern void fl_fix_focus();
|
||||
extern int fl_send_system_handlers(void *e);
|
||||
extern int fl_utf8_remove_context_dependent(char *text, int len);
|
||||
|
||||
// forward definition of functions in this file
|
||||
// converting cr lf converter function
|
||||
@@ -2956,21 +2957,7 @@ static FLTextInputContext* fltextinputcontext_instance = nil;
|
||||
// insertText sent during handleEvent of a key without text cannot be processed in a single FL_KEYBOARD event.
|
||||
// Occurs with deadkey followed by non-text key. Occurs also with emoji palette.
|
||||
if (!in_key_event || !has_text_key) {
|
||||
if (fl_utf_nb_char((const uchar*)Fl::e_text, Fl::e_length) > 1) {
|
||||
// Some emojis are expressed by a series of Unicode points
|
||||
const char *p = Fl::e_text, *end = Fl::e_text + Fl::e_length;
|
||||
int len;
|
||||
while (p < end) { // loop over all unicode points of the series
|
||||
unsigned u = fl_utf8decode(p, end, &len); // extract one such unicode point
|
||||
if ((u >= 0xFE00 && u <= 0xFE0F) // variation selectors
|
||||
|| u == 0x200D // zero-width joiner
|
||||
|| (u >= 0x1F3FB && u <= 0x1F3FF) // EMOJI MODIFIERS FITZPATRICK TYPE
|
||||
) { // remove context-dependent unicode points
|
||||
memmove((void*)p, p + len, (end - (p+len)) + 1);
|
||||
Fl::e_length -= len; end -= len;
|
||||
} else p += len; // keep other unicode points
|
||||
}
|
||||
}
|
||||
Fl::e_length = fl_utf8_remove_context_dependent(Fl::e_text, Fl::e_length);
|
||||
Fl::handle(FL_KEYBOARD, target);
|
||||
Fl::e_length = 0;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// X specific code for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2025 by Bill Spitzak and others.
|
||||
// Copyright 1998-2026 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
@@ -101,6 +101,7 @@ extern Fl_Window *fl_xmousewin;
|
||||
|
||||
static void open_display_i(Display *d); // open display (internal)
|
||||
extern int fl_send_system_handlers(void *e);
|
||||
extern int fl_utf8_remove_context_dependent(char *text, int len);
|
||||
|
||||
#if FLTK_CONSOLIDATE_MOTION
|
||||
static Fl_Window *send_motion;
|
||||
@@ -1833,6 +1834,7 @@ int fl_handle(const XEvent& thisevent)
|
||||
Status status;
|
||||
len = XUtf8LookupString(Fl_X11_Screen_Driver::xim_ic, (XKeyPressedEvent *)&xevent.xkey,
|
||||
kp_buffer, kp_buffer_len, &keysym, &status);
|
||||
len = fl_utf8_remove_context_dependent(kp_buffer, len);
|
||||
|
||||
while (status == XBufferOverflow && kp_buffer_len < 50000) {
|
||||
kp_buffer_len = kp_buffer_len * 5 + 1;
|
||||
|
||||
@@ -53,6 +53,7 @@ extern "C" {
|
||||
bool fl_is_surface_from_GTK_titlebar (struct wl_surface *surface, struct libdecor_frame *frame,
|
||||
bool *using_GTK);
|
||||
}
|
||||
extern int fl_utf8_remove_context_dependent(char *text, int len);
|
||||
|
||||
// set this to 1 for keyboard debug output, 0 for no debug output
|
||||
#define DEBUG_KEYBOARD 0
|
||||
@@ -1017,6 +1018,7 @@ void text_input_commit_string(void *data, struct zwp_text_input_v3 *zwp_text_inp
|
||||
//printf("text_input_commit_string %s\n",text);
|
||||
free(pending_commit);
|
||||
pending_commit = text ? strdup(text) : NULL;
|
||||
fl_utf8_remove_context_dependent(pending_commit, strlen(pending_commit));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Author: Jean-Marc Lienher ( http://oksid.ch )
|
||||
// Copyright 2000-2010 by O'ksi'D.
|
||||
// Copyright 2016-2022 by Bill Spitzak and others.
|
||||
// Copyright 2016-2026 by Bill Spitzak and others.
|
||||
//
|
||||
// This library is free software. Distribution and use rights are outlined in
|
||||
// the file "COPYING" which should have been included with this file. If this
|
||||
@@ -1630,3 +1630,30 @@ unsigned fl_utf8from_mb(char* dst, unsigned dstlen, const char* src, unsigned sr
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifndef FL_DOXYGEN
|
||||
|
||||
/* This function removes from an UTF-8 string its context-dependent codepoints
|
||||
when there are any, and returns the length of the possibly shortened string.
|
||||
*/
|
||||
int fl_utf8_remove_context_dependent(char *text, int len) {
|
||||
if (len > 1 && fl_utf_nb_char((const uchar*)text, len) > 1) {
|
||||
// Some emojis are expressed by a series of Unicode points
|
||||
char *p = text, *end = text + len;
|
||||
while (p < end) { // loop over all unicode points of the series
|
||||
int l_point;
|
||||
unsigned u = fl_utf8decode(p, end, &l_point); // extract one such unicode point
|
||||
if ((u >= 0xFE00 && u <= 0xFE0F) // variation selectors
|
||||
|| u == 0x200D // zero-width joiner
|
||||
|| (u >= 0x1F3FB && u <= 0x1F3FF) // EMOJI MODIFIERS FITZPATRICK TYPE
|
||||
) { // remove context-dependent unicode points
|
||||
memmove((void*)p, p + l_point, (end - (p+l_point)) + 1);
|
||||
end -= l_point;
|
||||
len -= l_point;
|
||||
} else p += l_point; // keep other unicode points
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
#endif // ! FL_DOXYGEN
|
||||
|
||||
Reference in New Issue
Block a user