Skip to content

Commit

Permalink
list input methods (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
eagleoflqj authored Nov 9, 2024
1 parent aa16c2e commit 1b3fafa
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 15 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ jobs:
- name: Install dependencies
run: |
brew install \
nlohmann-json \
extra-cmake-modules
IOS_PLATFORM=SIMULATOR ./scripts/install-deps.sh
wget https://github.com/fcitx-contrib/fcitx5-macos-prebuilder/releases/download/latest/marisa-$(uname -m).tar.bz2
Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ option(BUILD_SPELL_DICT "" OFF)

find_host_package(PkgConfig)
find_host_package(Gettext)
find_host_package(nlohmann_json)

add_subdirectory(fcitx5)

Expand Down
7 changes: 5 additions & 2 deletions common/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
add_library(FcitxCommon common.cpp)
add_library(FcitxCommon
common.cpp
inputmethod.cpp
)
target_include_directories(FcitxCommon PRIVATE
"${PROJECT_SOURCE_DIR}/fcitx5/src/modules/notifications"
)
target_link_libraries(FcitxCommon Fcitx5::Core)
target_link_libraries(FcitxCommon Fcitx5::Core nlohmann_json)

add_library(SwiftUtil util.swift)
set_target_properties(SwiftUtil PROPERTIES Swift_MODULE_NAME SwiftUtil)
3 changes: 3 additions & 0 deletions common/common-public.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include <string>

std::string getInputMethods();
35 changes: 35 additions & 0 deletions common/inputmethod.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "common-public.h"
#include "common.h"
#include <fcitx/inputmethodentry.h>
#include <fcitx/inputmethodmanager.h>
#include <nlohmann/json.hpp>

static nlohmann::json jsonDescribeIm(const fcitx::InputMethodEntry *entry) {
nlohmann::json j;
j["name"] = entry->uniqueName();
j["displayName"] = entry->nativeName() != "" ? entry->nativeName()
: entry->name() != "" ? entry->name()
: entry->uniqueName();
j["languageCode"] = entry->languageCode();
return j;
}

std::string getInputMethods() {
static std::string ret;
nlohmann::json j;
auto &imMgr = instance->inputMethodManager();
auto group = imMgr.currentGroup();
bool empty = true;
for (const auto &im : group.inputMethodList()) {
auto entry = imMgr.entry(im.name());
if (!entry)
continue;
empty = false;
j.push_back(jsonDescribeIm(entry));
}
if (empty) { // j is not treated array
return "[]";
}
ret = j.dump();
return ret.c_str();
}
3 changes: 3 additions & 0 deletions common/module.modulemap
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module FcitxCommon {
header "common-public.h"
}
8 changes: 8 additions & 0 deletions src/App.swift
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import SwiftUI
import SwiftUtil

@main
struct Fcitx5App: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
@Environment(\.scenePhase) private var scenePhase

// Dummy. Actual Scene in managed by SceneDelegate. But onOpenURL is
// always called on open from URL no matter app is running or not.
var body: some Scene {
WindowGroup {
EmptyView().onOpenURL { url in
SceneDelegate.contentView?.handleURL(url)
}.onChange(of: scenePhase) { newPhase in
if newPhase == .active {
logger.info("App is active")
sync(
documents.appendingPathComponent("rime"), appGroupData.appendingPathComponent("rime"))
}
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ add_executable(
${BUNDLE_NAME}
MACOSX_BUNDLE
ContentView.swift
ConfigView.swift
App.swift
AppDelegate.swift
SceneDelegate.swift
Expand All @@ -10,6 +11,7 @@ add_executable(

target_include_directories(${BUNDLE_NAME} PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}"
"${PROJECT_SOURCE_DIR}/common"
"${PROJECT_BINARY_DIR}/common/$<CONFIG>${CMAKE_XCODE_EFFECTIVE_PLATFORMS}"
"${PROJECT_BINARY_DIR}/iosnotifications/$<CONFIG>${CMAKE_XCODE_EFFECTIVE_PLATFORMS}"
"${PROJECT_BINARY_DIR}/deps/AlertToast/$<CONFIG>${CMAKE_XCODE_EFFECTIVE_PLATFORMS}"
Expand Down
12 changes: 12 additions & 0 deletions src/ConfigView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import SwiftUI

struct ConfigView: View {
let inputMethod: InputMethod

var body: some View {
VStack {
}
.navigationTitle(inputMethod.displayName)
.navigationBarTitleDisplayMode(.inline)
}
}
37 changes: 24 additions & 13 deletions src/ContentView.swift
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
import AlertToast
import Fcitx
import FcitxCommon
import NotifySwift
import SwiftUI
import SwiftUtil

struct InputMethod: Codable {
let name: String
let displayName: String
let languageCode: String
}

private class ViewModel: ObservableObject {
@Published var url: URL?
@Published var inputMethods = [InputMethod]()

func refresh() {
inputMethods = try! JSONDecoder().decode(
[InputMethod].self, from: String(getInputMethods()).data(using: .utf8)!)
}
}

struct ContentView: View {
@Environment(\.scenePhase) private var scenePhase
@ObservedObject private var viewModel = ViewModel()

// AlertToast fields
Expand All @@ -25,15 +37,18 @@ struct ContentView: View {
}

var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
if let url = viewModel.url {
Text("\(url)")
NavigationView {
List {
Section(header: Text("Input Methods")) {
ForEach(viewModel.inputMethods, id: \.name) { inputMethod in
NavigationLink(destination: ConfigView(inputMethod: inputMethod)) {
Text(inputMethod.displayName)
}
}
}
}
.navigationTitle("Fcitx5")
}
.padding()
.toast(isPresenting: $showToast, duration: duration) {
AlertToast(
displayMode: .alert,
Expand Down Expand Up @@ -71,11 +86,7 @@ struct ContentView: View {
}
}
})
}
.onChange(of: scenePhase) { newPhase in
if newPhase == .active {
sync(documents.appendingPathComponent("rime"), appGroupData.appendingPathComponent("rime"))
}
viewModel.refresh()
}
}
}

0 comments on commit 1b3fafa

Please sign in to comment.