From 745087fd08bb10feaa96b516b7b0201e4c4eac9a Mon Sep 17 00:00:00 2001 From: Qijia Liu Date: Thu, 3 Oct 2024 23:41:42 -0400 Subject: [PATCH] build static spell (#5) --- iosfrontend/CMakeLists.txt | 12 +--- keyboard/CMakeLists.txt | 1 + keyboard/KeyboardViewController.swift | 1 + keyboard/fcitx.cpp | 24 +++++++- keyboard/fcitx.h | 1 + keyboard/util.h | 26 ++++++++ patches/fcitx5.patch | 89 ++++++++++++++++++++++++++- src/CMakeLists.txt | 24 ++------ 8 files changed, 147 insertions(+), 31 deletions(-) create mode 100644 keyboard/util.h diff --git a/iosfrontend/CMakeLists.txt b/iosfrontend/CMakeLists.txt index fb3a2d1..2708a52 100644 --- a/iosfrontend/CMakeLists.txt +++ b/iosfrontend/CMakeLists.txt @@ -7,15 +7,9 @@ fcitx5_translate_desktop_file(${CMAKE_CURRENT_BINARY_DIR}/iosfrontend.conf.in io add_custom_command( TARGET iosfrontend POST_BUILD COMMAND /bin/sh -c - \"COMMAND_DONE=0 \; - if ${CMAKE_COMMAND} -E copy + \" + ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/iosfrontend.conf ${PROJECT_BINARY_DIR}/keyboard/$${CMAKE_XCODE_EFFECTIVE_PLATFORMS}/keyboard.appex/share/fcitx5/addon/iosfrontend.conf - \&\>/dev/null \; then - COMMAND_DONE=1 \; - fi \; - if [ \\$$COMMAND_DONE -eq 0 ] \; then - echo Failed to copy the conf into the app bundle \; - exit 1 \; - fi\" + \" ) diff --git a/keyboard/CMakeLists.txt b/keyboard/CMakeLists.txt index 7c1ef91..e7e3532 100644 --- a/keyboard/CMakeLists.txt +++ b/keyboard/CMakeLists.txt @@ -16,5 +16,6 @@ target_compile_options(keyboard PUBLIC target_link_libraries(keyboard PRIVATE Fcitx5::Core + spell iosfrontend ) diff --git a/keyboard/KeyboardViewController.swift b/keyboard/KeyboardViewController.swift index 3354ccf..8a5fe91 100644 --- a/keyboard/KeyboardViewController.swift +++ b/keyboard/KeyboardViewController.swift @@ -18,6 +18,7 @@ class KeyboardViewController: UIInputViewController { super.viewDidLoad() startFcitx(Bundle.main.bundlePath) + focusIn() // Perform custom UI setup here self.nextKeyboardButton = UIButton(type: .system) diff --git a/keyboard/fcitx.cpp b/keyboard/fcitx.cpp index 961d438..a1dd086 100644 --- a/keyboard/fcitx.cpp +++ b/keyboard/fcitx.cpp @@ -1,21 +1,32 @@ +#include "../fcitx5/src/modules/spell/spell.h" #include "../iosfrontend/iosfrontend.h" #include "nativestreambuf.h" +#include +#include #include #include #include #include "fcitx.h" +#include "util.h" namespace fs = std::filesystem; +fcitx::SpellModuleFactory SpellModuleFactory; fcitx::IosFrontendFactory IosFrontendFactory; + fcitx::StaticAddonRegistry addons = { + std::make_pair("spell", + &SpellModuleFactory), std::make_pair("iosfrontend", &IosFrontendFactory), }; native_streambuf log_streambuf; std::unique_ptr instance; +std::unique_ptr dispatcher; +fcitx::IosFrontend *frontend; + std::ostream stream(&log_streambuf); std::thread fcitx_thread; @@ -26,7 +37,9 @@ void setupLog() { void setupEnv(const char *bundlePath) { fs::path bundle = bundlePath; + std::string xdg_data_dirs = bundle / "share"; std::string fcitx_data_home = bundle / "share/fcitx5"; + setenv("XDG_DATA_DIRS", xdg_data_dirs.c_str(), 1); setenv("FCITX_DATA_HOME", fcitx_data_home.c_str(), 1); } @@ -40,6 +53,15 @@ void startFcitx(const char *bundlePath) { instance = std::make_unique(0, nullptr); auto &addonMgr = instance->addonManager(); addonMgr.registerDefaultLoader(&addons); - fcitx_thread = std::thread([] { instance->exec(); }); + instance->initialize(); + frontend = + dynamic_cast(addonMgr.addon("iosfrontend")); + dispatcher = std::make_unique(); + dispatcher->attach(&instance->eventLoop()); + fcitx_thread = std::thread([] { instance->eventLoop().exec(); }); return; } + +void focusIn() { + return with_fcitx([] { frontend->focusIn(); }); +} diff --git a/keyboard/fcitx.h b/keyboard/fcitx.h index 5336628..a8cee72 100644 --- a/keyboard/fcitx.h +++ b/keyboard/fcitx.h @@ -1 +1,2 @@ void startFcitx(const char *bundlePath); +void focusIn(); diff --git a/keyboard/util.h b/keyboard/util.h new file mode 100644 index 0000000..3aad523 --- /dev/null +++ b/keyboard/util.h @@ -0,0 +1,26 @@ + +#include +#include + +extern std::unique_ptr dispatcher; + +template > +inline T with_fcitx(F func) { + std::promise prom; + std::future fut = prom.get_future(); + dispatcher->schedule([&prom, func = std::move(func)]() { + try { + if constexpr (std::is_void_v) { + func(); + prom.set_value(); + } else { + T result = func(); + prom.set_value(std::move(result)); + } + } catch (...) { + prom.set_exception(std::current_exception()); + } + }); + fut.wait(); + return fut.get(); +} diff --git a/patches/fcitx5.patch b/patches/fcitx5.patch index de70b1f..2595886 100644 --- a/patches/fcitx5.patch +++ b/patches/fcitx5.patch @@ -133,6 +133,20 @@ index df15dd57..3c1d3ff2 100644 EXPORT_NAME Core ) target_include_directories(Fcitx5Core PUBLIC +diff --git a/src/lib/fcitx/addoninfo.cpp b/src/lib/fcitx/addoninfo.cpp +index 49d8c6e4..f6acad08 100644 +--- a/src/lib/fcitx/addoninfo.cpp ++++ b/src/lib/fcitx/addoninfo.cpp +@@ -109,7 +109,8 @@ const I18NString &AddonInfo::comment() const { + + const std::string &AddonInfo::type() const { + FCITX_D(); +- return d->addon->type.value(); ++ static const std::string t = "StaticLibrary"; ++ return t; + } + + AddonCategory AddonInfo::category() const { diff --git a/src/lib/fcitx/instance.cpp b/src/lib/fcitx/instance.cpp index d2e9aa23..72f82213 100644 --- a/src/lib/fcitx/instance.cpp @@ -146,19 +160,88 @@ index d2e9aa23..72f82213 100644 void Instance::configureAddon(const std::string &) {} diff --git a/src/modules/spell/CMakeLists.txt b/src/modules/spell/CMakeLists.txt -index 094e1a58..ab1ce4df 100644 +index 094e1a58..106a010c 100644 --- a/src/modules/spell/CMakeLists.txt +++ b/src/modules/spell/CMakeLists.txt -@@ -17,6 +17,7 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/spell.conf" DESTINATION "${FCITX_INST +@@ -5,7 +5,7 @@ if (TARGET PkgConfig::Enchant) + set(SPELL_SOURCES ${SPELL_SOURCES} spell-enchant.cpp) + endif() + +-add_library(spell MODULE ${SPELL_SOURCES}) ++add_library(spell STATIC ${SPELL_SOURCES}) + target_link_libraries(spell Fcitx5::Core) + if (TARGET PkgConfig::Enchant) + target_link_libraries(spell PkgConfig::Enchant) +@@ -17,6 +17,17 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/spell.conf" DESTINATION "${FCITX_INST COMPONENT config) fcitx5_export_module(Spell TARGET spell BUILD_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}" HEADERS spell_public.h INSTALL) ++add_custom_command( ++ TARGET spell ++ POST_BUILD COMMAND /bin/sh -c ++ \" ++ ${CMAKE_COMMAND} -E copy ++ ${CMAKE_CURRENT_BINARY_DIR}/spell.conf ++ ${CMAKE_BINARY_DIR}/keyboard/$${CMAKE_XCODE_EFFECTIVE_PLATFORMS}/keyboard.appex/share/fcitx5/addon/spell.conf ++ \" ++) ++ +if (BUILD_SPELL_DICT) set(DICT_COMP_SRC comp_spell_dict.cpp ) -@@ -46,3 +47,4 @@ add_custom_command( +@@ -46,3 +57,4 @@ add_custom_command( "${SPELL_EN_DICT_SRC}" "${SPELL_EN_DICT}") add_custom_target(spell_en_dict ALL DEPENDS "${SPELL_EN_DICT}") install(FILES "${SPELL_EN_DICT}" DESTINATION "${FCITX_INSTALL_PKGDATADIR}/spell") +endif() +diff --git a/src/modules/spell/spell.cpp b/src/modules/spell/spell.cpp +index cc3d951f..a4229234 100644 +--- a/src/modules/spell/spell.cpp ++++ b/src/modules/spell/spell.cpp +@@ -7,7 +7,6 @@ + + #include "spell.h" + #include "fcitx-config/iniparser.h" +-#include "fcitx/addonmanager.h" + #include "config.h" + #include "spell-custom.h" + #ifdef ENABLE_ENCHANT +@@ -110,12 +109,6 @@ Spell::hintForDisplay(const std::string &language, SpellProvider provider, + + return iter->second->hint(language, word, limit); + } +- +-class SpellModuleFactory : public AddonFactory { +- AddonInstance *create(AddonManager *manager) override { +- return new Spell(manager->instance()); +- } +-}; + } // namespace fcitx + + FCITX_ADDON_FACTORY(fcitx::SpellModuleFactory) +diff --git a/src/modules/spell/spell.h b/src/modules/spell/spell.h +index 60778962..3cfa2db5 100644 +--- a/src/modules/spell/spell.h ++++ b/src/modules/spell/spell.h +@@ -13,6 +13,7 @@ + #include "fcitx-utils/i18n.h" + #include "fcitx/addonfactory.h" + #include "fcitx/addoninstance.h" ++#include "fcitx/addonmanager.h" + #include "fcitx/instance.h" + #include "spell_public.h" + +@@ -104,6 +105,12 @@ public: + private: + Spell *parent_; + }; ++ ++class SpellModuleFactory : public AddonFactory { ++ AddonInstance *create(AddonManager *manager) override { ++ return new Spell(manager->instance()); ++ } ++}; + } // namespace fcitx + + #endif // _FCITX_MODULES_SPELL_SPELL_H_ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4d3284e..2029b88 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,17 +8,11 @@ add_executable( add_custom_command( TARGET ${BUNDLE_NAME} POST_BUILD COMMAND /bin/sh -c - \"COMMAND_DONE=0 \; - if ${CMAKE_COMMAND} -E copy + \" + ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/assets/${ICON_FILE} ${PROJECT_BINARY_DIR}/src/$${CMAKE_XCODE_EFFECTIVE_PLATFORMS}/${BUNDLE_NAME}.app - \&\>/dev/null \; then - COMMAND_DONE=1 \; - fi \; - if [ \\$$COMMAND_DONE -eq 0 ] \; then - echo Failed to copy the icon into the app bundle \; - exit 1 \; - fi\" + \" ) add_dependencies(${BUNDLE_NAME} keyboard) @@ -30,15 +24,9 @@ set_target_properties(${BUNDLE_NAME} PROPERTIES add_custom_command( TARGET ${BUNDLE_NAME} POST_BUILD COMMAND /bin/sh -c - \"COMMAND_DONE=0 \; - if ${CMAKE_COMMAND} -E copy_directory + \" + ${CMAKE_COMMAND} -E copy_directory ${PROJECT_BINARY_DIR}/keyboard/$${CMAKE_XCODE_EFFECTIVE_PLATFORMS}/keyboard.appex ${PROJECT_BINARY_DIR}/src/$${CMAKE_XCODE_EFFECTIVE_PLATFORMS}/${BUNDLE_NAME}.app/PlugIns/keyboard.appex - \&\>/dev/null \; then - COMMAND_DONE=1 \; - fi \; - if [ \\$$COMMAND_DONE -eq 0 ] \; then - echo Failed to copy the extension into the app bundle \; - exit 1 \; - fi\" + \" )