0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめてのアドベントカレンダーAdvent Calendar 2024

Day 13

英日キーボードが混在する環境で生きる:IME切り替え

Posted at

英日キーボードが混在する環境で生きる

新しいノートPCを買ったらキーボードが英字キーボードでした。

手持ちの外付けキーボードは日本語キーボードばっかり。

英字キーボードは以前使っていたから、日本語キーボードも印字の違いは気にせずに使う。

問題は、IMEの切り替えだ。

文章を入力しているときに、「今IMEがオンかオフか」はあまり気にしたくない。あるキーを押せばオン、別のキーを押せばオフにしてほしい。

英字キーボードの場合は左右のAltだし、日本語キーボードの場合は、無変換と変換を使いたい。

いくつかの選択肢

こちらに、英日混在環境の作り方がきちんと書いてある。

まあ、この通りにすればいいんだけど、Alt+Tabがどうも使えなくなるみたい。僕はかなりAlt+Tabを使うので、ストレスが大きくなってしまった。

というわけで、自分でやることにした。

候補はKeyhacAutoHotKey

ChatGPTに聞きながら、両者を並行してスクリプトを作成してみた。最終的になんとなくうまく行ったのが、Keyhacの方だ。AutoHotKeyの方が、OSのより深いレベルで制御しているそうなので、Keyhacでどうしようもなくなれば、AutoHotKeyに頼るべきなのかも知れない。ただ、KeyhacはスクリプトをPythonで書けるということもあり、先にKeyhac版が完成した。

開発の悩みは、Altを押すとMenuにフォーカスが移ってしまうという挙動の制御。Altをもう一度押すと良いアプリとか、Escを押すべきなアプリ、はたまたフォーカスが移らないアプリなど、いろいろだ。

上記サイトで紹介されていたTAALTというツールを使えば、この問題は一発で解決する。が、別のツールを入れずにKeyhacかAutoHotKey単独で実現するならそれがベストだ。

そのへんの制御を入れつつ、作っていったが、MicrosoftOfficeの挙動がまた特殊で、事前にESCを送信する処理をいれるとうまく行った。が、Officeのばあい、ESCを送出するとダイアログが閉じてしまうので、ファイル名等の入力には使えない。この問題は未だに解決できていない。

解答例

この記事はエッセイではないので、僕の現時点での解答を以下に示す。

keyhac.py
import sys
import os
import datetime
import time

import pyauto
from keyhac import *

def configure(keymap):
    # グローバルキー設定
    keymap_global = keymap.defineWindowKeymap()
    # 特定アプリケーションでESCなどを送信する処理
    office_apps = ["winword.exe", "excel.exe", "powerpnt.exe"]
    esc_apps = office_apps + ["chrome.exe", "notepad.exe"]
    # C-h l でキーログを見る

    def set_ime(status):
        if status in [0, 1]:  # 有効な値か確認
            keymap.getWindow().setImeStatus(status)
            #print(f"IME is {'ON' if status == 1 else 'OFF'}")
        else:
            print("Invalid status: Use 0 (OFF) or 1 (ON)")

    def set_ime_on_simple():
        set_ime(1)
    def set_ime_off_simple():
        set_ime(0)

    # IMEをオンにする関数
    def set_ime_on():
        active_window = keymap.getWindow().getProcessName()
        if any(app in active_window.lower() for app in office_apps):
            keymap.InputKeyCommand("Esc")()  # ESCキーを送信
        set_ime(1)
        if any(app in active_window.lower() for app in esc_apps):
            time.sleep(0.5)
            keymap.InputKeyCommand("Esc")()  # ESCキーを送信
        elif "emacs.exe"  in active_window.lower():
            return
        else:
            keymap.InputKeyCommand("Alt")()  # Altキーを再送信してフォーカスをリセット

    # IMEをオフにする関数
    def set_ime_off():
        active_window = keymap.getWindow().getProcessName()
        if any(app in active_window.lower() for app in office_apps):
            time.sleep(0.2)
            keymap.InputKeyCommand("Esc")()  # ESCキーを送信
        set_ime(0)
        if any(app in active_window.lower() for app in esc_apps):
            keymap.InputKeyCommand("Esc")()  # ESCキーを送信
        elif "emacs.exe"  in active_window.lower():
            return
        else:
            keymap.InputKeyCommand("Alt")()  # Altキーを再送信してフォーカスをリセット

    # 右Altキー単押しでIMEをオンに設定
    keymap_global["O-RAlt"] = set_ime_on  # IMEオンの処理を呼び出す
    # 「変換」キーでIMEをオンに設定
    keymap_global["O-(255)"] = set_ime_on_simple

    # 左Altキー単押しでIMEをオフに設定
    keymap_global["O-LAlt"] = set_ime_off
    # 「無変換」キーでIMEをオフに設定
    keymap_global["O-(235)"] = set_ime_off_simple
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?