Skip to content

Instantly share code, notes, and snippets.

@verygoodlee
Last active March 1, 2025 11:12
Show Gist options
  • Save verygoodlee/51a54415b4e77191da97db029aef383d to your computer and use it in GitHub Desktop.
Save verygoodlee/51a54415b4e77191da97db029aef383d to your computer and use it in GitHub Desktop.
mpv-disableIME
-- 取消mpv窗口与输入上下文的关联,达到禁用IME的效果
-- https://learn.microsoft.com/zh-cn/windows/win32/api/imm/nf-imm-immassociatecontext
local ffi_ok, ffi = pcall(require, 'ffi')
if not ffi_ok then return end
ffi.cdef[[
typedef void* HWND;
typedef void* HIMC;
typedef int BOOL;
typedef unsigned int DWORD;
typedef unsigned int LPDWORD[1];
typedef int LPARAM;
typedef BOOL (*WNDENUMPROC)(HWND, LPARAM);
HIMC ImmAssociateContext(HWND hwnd, HIMC himc);
BOOL ImmReleaseContext(HWND hwnd, HIMC himc);
DWORD GetCurrentThreadId();
HWND GetForegroundWindow();
BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam);
DWORD GetWindowThreadProcessId(HWND hwnd, LPDWORD lpdwProcessId);
BOOL AttachThreadInput(DWORD idAttach, DWORD idAttachTo, BOOL fAttach);
HWND SetFocus(HWND hWnd);
]]
local imm32 = ffi.load('imm32')
local kernel32 = ffi.load('kernel32')
local user32 = ffi.load('user32')
local mpv_pid = require('mp.utils').getpid()
-- https://mpv.io/manual/master/#lua-scripting-exit()
if not _G.exit then
function exit() mp.keep_running = false end
end
-- 在首次获取焦点后执行,确保mpv窗口已经初始化
function on_focused_change(_, val)
if not val then return end
mp.unobserve_property(on_focused_change)
disable_ime()
exit()
end
mp.observe_property('focused', 'bool', on_focused_change)
-- 禁用mpv窗口的IME
function disable_ime()
local mpv_hwnd = find_mpv_window()
if not mpv_hwnd then return end
-- 取消窗口与输入上下文的关联
local himc = imm32.ImmAssociateContext(mpv_hwnd, nil)
imm32.ImmReleaseContext(mpv_hwnd, himc)
refocus(mpv_hwnd)
end
-- 查找mpv窗口句柄
function find_mpv_window()
local mpv_hwnd = nil
local foreground_hwnd = user32.GetForegroundWindow()
if is_mpv_window(foreground_hwnd) then
mpv_hwnd = foreground_hwnd
else
user32.EnumWindows(function(each_hwnd, _)
if is_mpv_window(each_hwnd) then
mpv_hwnd = each_hwnd
return false
end
return true
end, 0)
end
if not mpv_hwnd then mp.msg.warn('mpv window not found') end
return mpv_hwnd
end
function is_mpv_window(hwnd)
if not hwnd then return false end
local lpdwProcessId = ffi.new('LPDWORD')
user32.GetWindowThreadProcessId(hwnd, lpdwProcessId)
return lpdwProcessId[0] == mpv_pid
end
-- 窗口重新获取输入焦点,触发IME状态刷新
function refocus(mpv_hwnd)
local curr_tid = kernel32.GetCurrentThreadId()
local mpv_tid = user32.GetWindowThreadProcessId(mpv_hwnd, _)
user32.AttachThreadInput(curr_tid, mpv_tid, 1)
user32.SetFocus(nil)
user32.SetFocus(mpv_hwnd)
user32.AttachThreadInput(curr_tid, mpv_tid, 0)
end
@verygoodlee
Copy link
Author

此脚本已过时,--input-ime选项现在已经支持Windows系统了,
mpv-player/mpv@bebecdf

@nanachisol
Copy link

nanachisol commented Feb 20, 2025

此脚本已过时,--input-ime选项现在已经支持Windows系统了, mpv-player/mpv@bebecdf

但是现在启用控制台时,默认选择中文输入法,请问这应该如何解决?

@zhongfly
Copy link

zhongfly commented Mar 1, 2025

但是现在启用控制台时,默认选择中文输入法,请问这应该如何解决?

要不就自己修改下console.lua(控制台也是用lua脚本实现的),去掉启用ime的功能(删掉几行即可),并且禁用自带的console.lua
console.lua的修改反着这个来即可:mpv-player/mpv@7e346a2

@verygoodlee
Copy link
Author

但是现在启用控制台时,默认选择中文输入法,请问这应该如何解决?

这不是只跟输入法的默认模式有关吗,我用微软拼音,常年默认英文模式,
进控制台就是默认英文,如果在控制台切换到中文模式后关闭控制台再打开控制台,还是会是中文模式

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment