all repos — fluxbox @ 5fc00dee32de8d31b7220c338810e86043eb87ae

custom fork of the fluxbox windowmanager

Improve utf-8 support

Operate on inverse iscntrl check which allows us to avoid wide character
conversions.
Thomas Lübking thomas.luebking@gmail.com
commit

5fc00dee32de8d31b7220c338810e86043eb87ae

parent

5869f391c1fa39a9a9826ee16e11e15c4f10200a

1 files changed, 41 insertions(+), 44 deletions(-)

jump to
M src/FbTk/TextBox.ccsrc/FbTk/TextBox.cc

@@ -60,6 +60,8 @@ m_end_pos(0),

m_select_pos(std::string::npos), m_xic(0) { + if (App::instance()->inputModule()) + m_xic = XCreateIC(App::instance()->inputModule(), XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, window(), NULL); FbTk::EventManager::instance()->add(*this, *this); }

@@ -74,12 +76,15 @@ m_start_pos(0),

m_end_pos(0), m_select_pos(std::string::npos), m_xic(0) { - + if (App::instance()->inputModule()) + m_xic = XCreateIC(App::instance()->inputModule(), XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, window(), NULL); FbTk::EventManager::instance()->add(*this, *this); } TextBox::~TextBox() { - + if (m_xic) + XFree(m_xic); + m_xic = 0; } void TextBox::setText(const FbTk::BiDiString &text) {

@@ -290,11 +295,17 @@ event.state = KeyUtil::instance().cleanMods(event.state);

KeySym ks; char keychar[20]; - int count = 1; - if (m_xic) - count = Xutf8LookupString(m_xic, &event, keychar, 20, &ks, 0); - else + if (m_xic) { + Status status; + int count = Xutf8LookupString(m_xic, &event, keychar, sizeof(keychar), &ks, &status); + if (status == XBufferOverflow) + return; + keychar[count] = '\0'; + } + else { XLookupString(&event, keychar, 1, &ks, 0); + keychar[1] = '\0'; + } // a modifier key by itself doesn't do anything if (IsModifierKey(ks)) return;

@@ -366,7 +377,7 @@ m_text.setLogical(t);

adjustPos(); } break; - case 'a': + case XK_a: selectAll(); break; }

@@ -394,56 +405,45 @@ break;

case XK_Delete: deleteForward(); break; +#define SET_SINGLE_BYTE(_B_) keychar[0] = _B_; keychar[1] = '\0' case XK_KP_Insert: - keychar[0] = '0'; + SET_SINGLE_BYTE('0'); break; case XK_KP_End: - keychar[0] = '1'; + SET_SINGLE_BYTE('1'); break; case XK_KP_Down: - keychar[0] = '2'; + SET_SINGLE_BYTE('2'); break; case XK_KP_Page_Down: - keychar[0] = '3'; + SET_SINGLE_BYTE('3'); break; case XK_KP_Left: - keychar[0] = '4'; + SET_SINGLE_BYTE('4'); break; case XK_KP_Begin: - keychar[0] = '5'; + SET_SINGLE_BYTE('5'); break; case XK_KP_Right: - keychar[0] = '6'; + SET_SINGLE_BYTE('6'); break; case XK_KP_Home: - keychar[0] = '7'; + SET_SINGLE_BYTE('7'); break; case XK_KP_Up: - keychar[0] = '8'; + SET_SINGLE_BYTE('8'); break; case XK_KP_Page_Up: - keychar[0] = '9'; + SET_SINGLE_BYTE('9'); break; case XK_KP_Delete: - keychar[0] = ','; + SET_SINGLE_BYTE(','); break; +#undef SET_SINGLE_BYTE } } - if (count > 1 && count < 20) { - wchar_t wc; - count = mbrtowc(&wc, keychar, count, 0); - if (count > 0 && iswprint(wc)) { - keychar[count] = '\0'; - std::string val; - val += (char*)keychar; - insertText(val); - m_select_pos = std::string::npos; - } - } - if (isprint(keychar[0])) { - std::string val; - val += keychar[0]; - insertText(val); + if ((m_xic && !std::iscntrl(*keychar)) || std::isprint(*keychar)) { + insertText(std::string(keychar)); m_select_pos = std::string::npos; } if ((event.state & ShiftMask) != ShiftMask)

@@ -454,17 +454,10 @@

void TextBox::handleEvent(XEvent &event) { if (event.type == KeymapNotify) { XRefreshKeyboardMapping(&event.xmapping); - } else if (event.type == FocusIn) { - if (!m_xic && App::instance()->inputModule()) - m_xic = XCreateIC(App::instance()->inputModule(), XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, window(), NULL); - if (m_xic) - XSetICFocus(m_xic); - } else if (event.type == FocusIn) { - if (m_xic) { - XUnsetICFocus(m_xic); - XFree(m_xic); - m_xic = 0; - } + } else if (event.type == FocusIn && m_xic) { + XSetICFocus(m_xic); + } else if (event.type == FocusOut && m_xic) { + XUnsetICFocus(m_xic); } }

@@ -590,6 +583,10 @@ return (c & indicator) == indicator;

}; StringRange range = {pos, pos}; + + if (!m_xic) + return range; + FbString t = text(); if (pos < 0 || pos >= t.size() || t.at(pos) > 0) // invalid pos or ASCII