Skip to content

Commit 9ee6a0b

Browse files
committed
Fix Issue #66
1 parent fbf6cfc commit 9ee6a0b

File tree

3 files changed

+136
-8
lines changed

3 files changed

+136
-8
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ find_package(PkgConfig REQUIRED)
2121
find_package(Fcitx5Core 5.0.6 REQUIRED)
2222
find_package(Fcitx5Utils 5.0.6 REQUIRED)
2323

24-
pkg_check_modules(LIBCSKK REQUIRED IMPORTED_TARGET "cskk>=0.10.0")
24+
pkg_check_modules(LIBCSKK REQUIRED IMPORTED_TARGET "cskk>=0.12.0")
2525

2626
option(ENABLE_QT "Enable Qt for GUI configuration" On)
2727

src/cskk.cpp

Lines changed: 133 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -351,11 +351,10 @@ void FcitxCskkContext::updateUI() {
351351
}
352352

353353
// Preedit
354-
auto preedit = skk_context_get_preedit(context_);
355-
Text preeditText;
356-
// FIXME: Pretty text format someday.
357-
preeditText.append(std::string(preedit));
358-
preeditText.setCursor(static_cast<int>(strlen(preedit)));
354+
uint32_t stateStackLen;
355+
auto preeditDetail = skk_context_get_preedit_detail(context_, &stateStackLen);
356+
auto [mainPreedit, supplementPreedit] =
357+
FcitxCskkContext::formatPreedit(preeditDetail, stateStackLen);
359358

360359
// CandidateList
361360
int currentCursorPosition =
@@ -383,10 +382,11 @@ void FcitxCskkContext::updateUI() {
383382
}
384383

385384
if (ic_->capabilityFlags().test(CapabilityFlag::Preedit)) {
386-
inputPanel.setClientPreedit(preeditText);
385+
inputPanel.setClientPreedit(mainPreedit);
386+
inputPanel.setPreedit(supplementPreedit);
387387
ic_->updatePreedit();
388388
} else {
389-
inputPanel.setPreedit(preeditText);
389+
inputPanel.setPreedit(mainPreedit);
390390
}
391391

392392
// StatusArea for status icon
@@ -432,6 +432,132 @@ int FcitxCskkContext::getInputMode() {
432432
}
433433
return skk_context_get_input_mode(context_);
434434
}
435+
/**
436+
* format preedit state into Text.
437+
* Returns tuple of <Main content Text, Supplement content Text>
438+
* Main content is something you always want to show, supplement content is
439+
* something you may show when you have space.
440+
*/
441+
std::tuple<Text, Text>
442+
FcitxCskkContext::formatPreedit(CskkStateInfoFfi *cskkStateInfoArray,
443+
uint32_t stateLen) {
444+
std::string precomposition_marker = "";
445+
std::string selection_marker = "";
446+
Text mainContent = Text(""), supplementContent = Text("");
447+
size_t mainCursorIdx = 0;
448+
for (uint32_t i = 0; i < stateLen; i++) {
449+
auto cskkStateInfo = cskkStateInfoArray[i];
450+
switch (cskkStateInfo.tag) {
451+
case DirectStateInfo: {
452+
auto directStateInfo = cskkStateInfo.direct_state_info;
453+
if (directStateInfo.confirmed) {
454+
mainCursorIdx += strlen(directStateInfo.confirmed);
455+
mainContent.append(directStateInfo.confirmed, TextFormatFlag::NoFlag);
456+
}
457+
if (directStateInfo.unconverted) {
458+
mainCursorIdx += strlen(directStateInfo.unconverted);
459+
mainContent.append(directStateInfo.unconverted,
460+
TextFormatFlag::Underline);
461+
}
462+
} break;
463+
case PreCompositionStateInfo: {
464+
auto precompositionStateInfo = cskkStateInfo.pre_composition_state_info;
465+
mainCursorIdx += precomposition_marker.length();
466+
mainContent.append(precomposition_marker, TextFormatFlag::DontCommit);
467+
if (precompositionStateInfo.confirmed) {
468+
mainCursorIdx += strlen(precompositionStateInfo.confirmed);
469+
mainContent.append(precompositionStateInfo.confirmed,
470+
TextFormatFlag::NoFlag);
471+
}
472+
if (precompositionStateInfo.kana_to_composite) {
473+
mainCursorIdx += strlen(precompositionStateInfo.kana_to_composite);
474+
mainContent.append(precompositionStateInfo.kana_to_composite,
475+
TextFormatFlag::Underline);
476+
}
477+
if (precompositionStateInfo.unconverted) {
478+
mainCursorIdx += strlen(precompositionStateInfo.unconverted);
479+
mainContent.append(precompositionStateInfo.unconverted,
480+
TextFormatFlag::Underline);
481+
}
482+
} break;
483+
case PreCompositionOkuriganaStateInfo: {
484+
auto precompositionOkuriganaStateInfo =
485+
cskkStateInfo.pre_composition_okurigana_state_info;
486+
mainContent.append(precomposition_marker, TextFormatFlag::DontCommit);
487+
mainCursorIdx += precomposition_marker.length();
488+
if (precompositionOkuriganaStateInfo.confirmed) {
489+
mainCursorIdx += strlen(precompositionOkuriganaStateInfo.confirmed);
490+
mainContent.append(precompositionOkuriganaStateInfo.confirmed,
491+
TextFormatFlag::NoFlag);
492+
}
493+
if (precompositionOkuriganaStateInfo.kana_to_composite) {
494+
mainCursorIdx +=
495+
strlen(precompositionOkuriganaStateInfo.kana_to_composite);
496+
mainContent.append(precompositionOkuriganaStateInfo.kana_to_composite,
497+
TextFormatFlag::Underline);
498+
}
499+
if (precompositionOkuriganaStateInfo.unconverted) {
500+
mainContent.append("*", TextFormatFlags{TextFormatFlag::Underline,
501+
TextFormatFlag::DontCommit});
502+
mainCursorIdx +=
503+
strlen(precompositionOkuriganaStateInfo.unconverted) + 1;
504+
mainContent.append(precompositionOkuriganaStateInfo.unconverted,
505+
TextFormatFlag::Underline);
506+
}
507+
} break;
508+
case CompositionSelectionStateInfo: {
509+
auto compositionSelectionStateInfo =
510+
cskkStateInfo.composition_selection_state_info;
511+
mainContent.append(selection_marker, TextFormatFlag::DontCommit);
512+
mainCursorIdx += selection_marker.length();
513+
if (compositionSelectionStateInfo.composited) {
514+
mainCursorIdx += strlen(compositionSelectionStateInfo.composited);
515+
mainContent.append(compositionSelectionStateInfo.composited,
516+
TextFormatFlag::Underline);
517+
}
518+
if (compositionSelectionStateInfo.okuri) {
519+
mainCursorIdx += strlen(compositionSelectionStateInfo.okuri);
520+
mainContent.append(compositionSelectionStateInfo.okuri,
521+
TextFormatFlag::Underline);
522+
}
523+
if (compositionSelectionStateInfo.annotation) {
524+
supplementContent.clear();
525+
supplementContent.append(compositionSelectionStateInfo.annotation,
526+
TextFormatFlag::DontCommit);
527+
}
528+
} break;
529+
case RegisterStateInfo: {
530+
auto registerStateInfo = cskkStateInfo.register_state_info;
531+
mainContent.append(selection_marker, TextFormatFlag::DontCommit);
532+
mainCursorIdx += selection_marker.length();
533+
if (registerStateInfo.confirmed) {
534+
mainCursorIdx += strlen(registerStateInfo.confirmed);
535+
mainContent.append(registerStateInfo.confirmed,
536+
TextFormatFlag::DontCommit);
537+
}
538+
if (registerStateInfo.kana_to_composite) {
539+
mainCursorIdx += strlen(registerStateInfo.kana_to_composite);
540+
mainContent.append(registerStateInfo.kana_to_composite,
541+
TextFormatFlag::DontCommit);
542+
}
543+
if (registerStateInfo.okuri) {
544+
mainCursorIdx += strlen(registerStateInfo.okuri);
545+
mainContent.append(registerStateInfo.okuri, TextFormatFlag::DontCommit);
546+
}
547+
mainCursorIdx += strlen("");
548+
mainContent.append("", TextFormatFlag::DontCommit);
549+
} break;
550+
}
551+
}
552+
// FIXME: Silently assuming length is less than int_max here. May fail when
553+
// length is over UINT_MAX. very unlikely, not high priority.
554+
mainContent.setCursor((int)mainCursorIdx);
555+
for (uint32_t i = 1; i < stateLen; i++) {
556+
mainContent.append("", TextFormatFlag::DontCommit);
557+
}
558+
559+
return {mainContent, supplementContent};
560+
}
435561

436562
/*******************************************************************************
437563
* FcitxCskkFactory

src/cskk.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class FcitxCskkEngine final : public InputMethodEngineV2 {
7272

7373
void loadDictionary();
7474
void freeDictionaries();
75+
char *formatPreedit(CskkStateInfoFfi* cskkStateInfo, uint32_t state_len);
7576
};
7677

7778
class FcitxCskkContext final : public InputContextProperty {
@@ -103,6 +104,7 @@ class FcitxCskkContext final : public InputContextProperty {
103104
bool handleCandidateSelection(
104105
const std::shared_ptr<FcitxCskkCandidateList> &candidateList,
105106
KeyEvent &keyEvent);
107+
static std::tuple<Text, Text> formatPreedit(CskkStateInfoFfi *cskkStateInfo, uint32_t stateLen);
106108
};
107109

108110
class FcitxCskkFactory final : public AddonFactory {

0 commit comments

Comments
 (0)