源码阅读笔记-配置

如何切换中/英键盘?

  • 问题简述:

3.2.13 前,可以通过 *.trime.yaml 文件的配置,切换中/英文键盘。 切换过程中,中/英文输入模式也跟着切换。在新版中如何实现?

  • 解决方式:

在中文模式和英文模式的键盘中,都加入 reset_ascii_mode: true 配置项 例子:

#键盘布局
preset_keyboards:
  default:
    author: "Shitlime"
    name: 26键默认布局
    width: 10
    lock: true
    ascii_mode: 0
    # 在这里加入新的配置项:
    reset_ascii_mode: true
    keys:
      - {click: q, long_click: 1, swipe_up: '!', key_back_color: bh1, key_text_color: wk}
      - {click: w, long_click: 2, swipe_up: '@', key_back_color: bh1, key_text_color: wk}
      - {click: e, long_click: 3, swipe_up: '#', key_back_color: bh1, key_text_color: wk}
      - {click: r, long_click: 4, swipe_up: '$', key_back_color: bh1, key_text_color: wk}
      - {click: t, long_click: 5, swipe_up: '%', key_back_color: bh1, key_text_color: wk}
      - {click: y, long_click: 6, swipe_up: '^', key_back_color: bh1, key_text_color: wk}
      - {click: u, long_click: 7, swipe_up: '&', key_back_color: bh1, key_text_color: wk}
      - {click: i, long_click: 8, swipe_up: '*', key_back_color: bh1, key_text_color: wk}
      # ……
  • 对应源码片段:

TextInputManager.kt 中,存在这段代码:

KeyEvent.KEYCODE_EISU -> { // Switch keyboard
                KeyboardSwitcher.switchKeyboard(event.select)
                /** Set ascii mode according to keyboard's settings, can not place into [Rime.handleRimeNotification] */
                if (shouldResetAsciiMode && KeyboardSwitcher.currentKeyboard.isResetAsciiMode) {
                    Rime.setOption("ascii_mode", KeyboardSwitcher.currentKeyboard.asciiMode)
                }
                trime.bindKeyboardToInputView()
                trime.updateComposing()
            }

悬浮窗消失问题

  • 问题描述:

使用同文风主题可以复现:

  1. 先打开键盘,输入任意字符可以看到编码悬浮窗;

  2. 打开液体键盘(liquid keyboard);

  3. 返回到主键盘

  4. 输入任意字符,发现编码悬浮窗消失,并且之后都消失了;

但是默认的 trime.yaml 主题却表现正常。

  • 解决方式:

在以后的版本中将解决这个bug,如果使用旧版,可以按如下方式解决这个问题:

给有这个bug的主题配置文件( *.trime.yaml )加上 liquid\_keyboard\_window

  liquid_keyboard_window: #液态键盘模式下显示的悬浮窗口組件
    - {start: "", click: "space", label: " 空格 "}
    - {start: "", click: "BackSpace", label: " 删除 "}
    - {start: "", click: "Return", label: " 回车 "}
    - {start: "", click: "liquid_keyboard_exit", label: " 返回 "}
  • bug对应源码片段:

trime/app/src/main/java/com/osfans/trime/ime/text/Composition.java

  /** 设置悬浮窗, 用于liquidKeyboard的悬浮窗工具栏 */
  public void setWindow() {
    if (getVisibility() != View.VISIBLE) return;
    if (liquid_keyboard_window_comp.isEmpty()) {
      this.setVisibility(GONE);
      return;
    }

    ss = new SpannableStringBuilder();

    for (Map<String, Object> m : liquid_keyboard_window_comp) {
      if (m.containsKey("composition")) appendComposition(m);
      else if (m.containsKey("click")) appendButton(m);
    }
    setSingleLine(!ss.toString().contains("\n"));

    setText(ss);
    setMovementMethod(LinkMovementMethod.getInstance());
  }

在上面这个方法中使用了 this.setVisibility(GONE); 导致编码悬浮窗不可见, 然后在下面的方法中执行 mComposition.getRootView().setVisibility(View.VISIBLE); 但是 .getRootView() 获取的是View,并不是 Composition 本身,所以 setVisibility(View.VISIBLE) 实际并没有产生效果。

trime/app/src/main/java/com/osfans/trime/ime/core/Trime.java

 /** 更新Rime的中西文狀態、編輯區文本 */
  public int updateComposing() {
    final @Nullable InputConnection ic = getCurrentInputConnection();
    activeEditorInstance.updateComposingText();
    if (ic != null && !isWinFixed()) isCursorUpdated = ic.requestCursorUpdates(1);
    int startNum = 0;
    if (mCandidateRoot != null) {
      if (isPopupWindowEnabled) {
        Timber.d("updateComposing() SymbolKeyboardType=%s", symbolKeyboardType.toString());
        if (symbolKeyboardType != SymbolKeyboardType.NO_KEY
            && symbolKeyboardType != SymbolKeyboardType.CANDIDATE) {
          mComposition.setWindow();
          showCompositionView(false);
        } else {
          mComposition.getRootView().setVisibility(View.VISIBLE);
          startNum = mComposition.setWindow(minPopupSize, minPopupCheckSize, Integer.MAX_VALUE);
          mCandidate.setText(startNum);
          // if isCursorUpdated, showCompositionView will be called in onUpdateCursorAnchorInfo
          // otherwise we need to call it here
          if (!isCursorUpdated) showCompositionView(true);
        }
      } else {
        mCandidate.setText(0);
      }

Last updated