88---
99--- spoon.InputSourceSwitch:setApplications({
1010--- ["WeChat"] = "Pinyin - Simplified",
11- --- ["Mail"] = "ABC"
11+ --- ["Mail"] = "ABC",
12+ --- -- Use application watcher for apps that window filter can't capture
13+ --- ["kitty-quick-access"] = { source = "ABC", watcher = "application" }
1214--- })
1315---
1416--- spoon.InputSourceSwitch:start()
@@ -21,7 +23,7 @@ obj.__index = obj
2123
2224-- Metadata
2325obj .name = " InputSourceSwitch"
24- obj .version = " 1.0 "
26+ obj .version = " 1.1 "
2527obj .author = " eks5115 <eks5115@gmail.com>"
2628obj .homepage = " https://github.com/Hammerspoon/Spoons"
2729obj .license = " MIT - https://opensource.org/licenses/MIT"
@@ -52,24 +54,38 @@ local function isMethod(methodName)
5254 return false
5355end
5456
55- local function setAppInputSource (appName , sourceName , event )
57+ local function switchInputSource (sourceName , appName )
58+ local r = true
59+
60+ if (isLayout (sourceName )) then
61+ r = hs .keycodes .setLayout (sourceName )
62+ elseif isMethod (sourceName ) then
63+ r = hs .keycodes .setMethod (sourceName )
64+ else
65+ hs .alert .show (string.format (' sourceName: %s is not layout or method' , sourceName ))
66+ end
67+
68+ if (not r ) then
69+ hs .alert .show (string.format (' set %s to %s failure' , appName , sourceName ))
70+ end
71+ end
72+
73+ local function setAppInputSourceWithWindowFilter (appName , sourceName , event )
5674 event = event or hs .window .filter .windowFocused
5775
5876 hs .window .filter .new (appName ):subscribe (event , function ()
59- local r = true
60-
61- if (isLayout (sourceName )) then
62- r = hs .keycodes .setLayout (sourceName )
63- elseif isMethod (sourceName ) then
64- r = hs .keycodes .setMethod (sourceName )
65- else
66- hs .alert .show (string.format (' sourceName: %s is not layout or method' , sourceName ))
67- end
77+ switchInputSource (sourceName , appName )
78+ end )
79+ end
6880
69- if (not r ) then
70- hs .alert .show (string.format (' set %s to %s failure' , appName , sourceName ))
81+ local function setAppInputSourceWithAppWatcher (appName , sourceName )
82+ local watcher = hs .application .watcher .new (function (name , eventType , appObj )
83+ if eventType == hs .application .watcher .activated and name == appName then
84+ switchInputSource (sourceName , appName )
7185 end
72- end )
86+ end )
87+ watcher :start ()
88+ return watcher
7389end
7490
7591--- InputSourceSwitch.applicationMap
@@ -83,12 +99,16 @@ obj.applicationsMap = {}
8399---
84100--- Parameters:
85101--- * applications - A table containing that mapping the application name to the input source
86- --- key is the application name and value is the input source name
102+ --- key is the application name
103+ --- value can be:
104+ --- - a string: the input source name (uses window filter, default)
105+ --- - a table: { source = "input source name", watcher = "window" | "application" }
87106--- example:
88107--- ```
89108--- {
90109--- ["WeChat"] = "Pinyin - Simplified",
91- --- ["Mail"] = "ABC"
110+ --- ["Mail"] = "ABC",
111+ --- ["kitty-quick-access"] = { source = "ABC", watcher = "application" }
92112--- }
93113--- ```
94114function obj :setApplications (applications )
104124--- Parameters:
105125--- * None
106126function obj :start ()
107- for k ,v in pairs (self .applicationsMap ) do
108- setAppInputSource (k , v )
127+ for appName , config in pairs (self .applicationsMap ) do
128+ local sourceName , watcherType
129+
130+ if type (config ) == " string" then
131+ sourceName = config
132+ watcherType = " window"
133+ else
134+ sourceName = config .source
135+ watcherType = config .watcher or " window"
136+ end
137+
138+ if watcherType == " application" then
139+ setAppInputSourceWithAppWatcher (appName , sourceName )
140+ else
141+ setAppInputSourceWithWindowFilter (appName , sourceName )
142+ end
109143 end
110144 return self
111145end
0 commit comments