LoginSignup
4
1

More than 5 years have passed since last update.

macOSXのinput source の確認・切替のメモ

Last updated at Posted at 2018-08-19

macOSXのinput source の確認・切替のメモ

Summary

macOSXinput source の確認と切替のメモ

Information source

about Cocoa text api

Apple Developer > documentation > AppKit > TextKit > NSTextInputContext

about pyobjc

introduction

Python's library

$ pip3 install pyobjc
$ pip3 install pyobjc-core
$ pip3 install pyobjc-framework-Cocoa

Environment

(ins)$ sw_vers 
ProductName:    Mac OS X
ProductVersion: 10.13.6
BuildVersion:   17G65

(ins)$ python3 --version
Python 3.7.0

(ins)$ pip3 list
Package                Version
---------------------- -------
pyobjc                 4.2.2  
pyobjc-core            4.2.2  
pyobjc-framework-Cocoa 4.2.2  

こんな感じ

input source の確認

from AppKit import NSTextInputContext , NSTextView

txt = NSTextInputContext.alloc().initWithClient_( NSTextView.new() )
print( txt.selectedKeyboardInputSource() )

# => com.apple.keylayout.US

input source の切替

from AppKit import NSTextInputContext , NSTextView

txt = NSTextInputContext.alloc().initWithClient_( NSTextView.new() )
txt.setValue_forKey_('com.apple.inputmethod.Kotoeri.Japanese', 'selectedKeyboardInputSource')

# => Kotoeri に切り替わる

input source 切替の通知

import Foundation
from AppKit import NSObject, NSTextInputContext , NSTextView, NSTextInputContextKeyboardSelectionDidChangeNotification
from PyObjCTools import AppHelper
import objc

class Observer(NSObject):

    # initialize method
    def initWithValue_(self, txtObj):
        self = objc.super(Observer, self).init()
        self.text_input_context = txtObj
        return self

    # add handler
    def bundle_(self, aNotification):
        print( self.text_input_context.selectedKeyboardInputSource() )

# create Cocoa's text obj
txtObj = NSTextInputContext.alloc().initWithClient_( NSTextView.new() )

# createt observer obj
obs = Observer.new().initWithValue_( txtObj )

# create notify obj
notify_obj = Foundation.NSNotificationCenter.defaultCenter()

# add event to notify obj
notify_obj.addObserver_selector_name_object_(
      obs
    , 'bundle:'
    , NSTextInputContextKeyboardSelectionDidChangeNotification
    , None
)

# do console-loop
AppHelper.runConsoleEventLoop()

# --- Kotoeri に切り替える ---
# => com.apple.inputmethod.Kotoeri.Japanese
# --- US に切り替える ---
# => com.apple.keylayout.US

課題

通知を使わずに現在の input source を知る方法がわからない

下記のコードは最初の input source しかわからない

from AppKit import NSTextInputContext , NSTextView

def loop():

    txt = NSTextInputContext.alloc().initWithClient_( NSTextView.new() )

    while True:
        if input() == '':
            break
        else:
            print( txt.selectedKeyboardInputSource() )

loop()


# a
# => com.apple.keylayout.US
# あ
# => com.apple.keylayout.US
# a
# => com.apple.keylayout.US
# あ
# => com.apple.keylayout.US

teratailで質問なげたった

(macOSX) selectedKeyboardInputSource がうまくはたらないです

Carbon's way

input source の確認

from Foundation import NSBundle
import objc

# use HITToolbox's functions
HIToolbox_bundle = NSBundle.bundleWithIdentifier_("com.apple.HIToolbox")

# bundle many...
HIToolbox_functions = [ ('TISGetInputSourceProperty', b'@@@'), ('TISCopyCurrentKeyboardInputSource', b'@') ]
HIToolbox_constants = [ ('kTISPropertyInputModeID', b'@') ]

objc.loadBundleFunctions(HIToolbox_bundle, globals(), HIToolbox_functions)
objc.loadBundleVariables(HIToolbox_bundle, globals(), HIToolbox_constants)

print( TISGetInputSourceProperty(TISCopyCurrentKeyboardInputSource() , kTISPropertyInputModeID ) )

input source の切替

import CoreFoundation
import ctypes
import ctypes.util

# add carbon lib
carbon = ctypes.cdll.LoadLibrary(ctypes.util.find_library('Carbon'))

# re-define arg and return types
carbon.TISSelectInputSource.restype               = ctypes.c_void_p
carbon.TISSelectInputSource.argtypes              = [ctypes.c_void_p]
carbon.TISCopyInputSourceForLanguage.argtypes     = [ctypes.c_void_p]
carbon.TISCopyInputSourceForLanguage.restype      = ctypes.c_void_p

lang = 'en'
carbon.TISSelectInputSource(
    carbon.TISCopyInputSourceForLanguage(
        CoreFoundation.CFSTR(lang).__c_void_p__())
)

Carbon's references

pudquick/input_sources.py

Khande/auto_switch_kb.py

How can we reading / coerce CFArray and CFString etc values from within OS X JXA?

4
1
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
4
1