Improve IME location updates (#1170)

* Avoid updating IME input rect if it hasn't changed
* Update the IME input rect even when the composition didn't change
* Apply IME input blocking workaround to non-Linux only
This commit is contained in:
Guldoman 2022-12-21 01:11:13 +01:00 committed by GitHub
parent 24179bbb23
commit c42f01ed1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 7 deletions

View File

@ -62,6 +62,7 @@ function DocView:new(doc)
self.font = "code_font" self.font = "code_font"
self.last_x_offset = {} self.last_x_offset = {}
self.ime_selection = { from = 0, size = 0 } self.ime_selection = { from = 0, size = 0 }
self.ime_status = false
self.hovering_gutter = false self.hovering_gutter = false
self.v_scrollbar:set_forced_status(config.force_scrollbar_status) self.v_scrollbar:set_forced_status(config.force_scrollbar_status)
self.h_scrollbar:set_forced_status(config.force_scrollbar_status) self.h_scrollbar:set_forced_status(config.force_scrollbar_status)
@ -332,11 +333,23 @@ end
function DocView:on_ime_text_editing(text, start, length) function DocView:on_ime_text_editing(text, start, length)
self.doc:ime_text_editing(text, start, length) self.doc:ime_text_editing(text, start, length)
self.ime_status = #text > 0
self.ime_selection.from = start self.ime_selection.from = start
self.ime_selection.size = length self.ime_selection.size = length
-- Set the composition bounding box that the system IME -- Set the composition bounding box that the system IME
-- will consider when drawing its interface -- will consider when drawing its interface
local line1, col1, line2, col2 = self.doc:get_selection(true)
local col = math.min(col1, col2)
self:update_ime_location()
self:scroll_to_make_visible(line1, col + start)
end
---Update the composition bounding box that the system IME
---will consider when drawing its interface
function DocView:update_ime_location()
if not self.ime_status then return end
local line1, col1, line2, col2 = self.doc:get_selection(true) local line1, col1, line2, col2 = self.doc:get_selection(true)
local x, y = self:get_line_screen_position(line1) local x, y = self:get_line_screen_position(line1)
local h = self:get_line_height() local h = self:get_line_height()
@ -344,10 +357,10 @@ function DocView:on_ime_text_editing(text, start, length)
local x1, x2 = 0, 0 local x1, x2 = 0, 0
if length > 0 then if self.ime_selection.size > 0 then
-- focus on a part of the text -- focus on a part of the text
local from = col + start local from = col + self.ime_selection.from
local to = from + length local to = from + self.ime_selection.size
x1 = self:get_col_x_offset(line1, from) x1 = self:get_col_x_offset(line1, from)
x2 = self:get_col_x_offset(line1, to) x2 = self:get_col_x_offset(line1, to)
else else
@ -357,7 +370,6 @@ function DocView:on_ime_text_editing(text, start, length)
end end
ime.set_location(x + x1, y, x2 - x1, h) ime.set_location(x + x1, y, x2 - x1, h)
self:scroll_to_make_visible(line1, col + start)
end end
function DocView:update() function DocView:update()
@ -383,6 +395,8 @@ function DocView:update()
core.blink_timer = tb core.blink_timer = tb
end end
self:update_ime_location()
DocView.super.update(self) DocView.super.update(self)
end end

View File

@ -4,6 +4,7 @@ local ime = { }
function ime.reset() function ime.reset()
ime.editing = false ime.editing = false
ime.last_location = { x = 0, y = 0, w = 0, h = 0 }
end end
---Convert from utf-8 offset and length (from SDL) to byte offsets ---Convert from utf-8 offset and length (from SDL) to byte offsets
@ -76,7 +77,15 @@ end
---@param w number ---@param w number
---@param h number ---@param h number
function ime.set_location(x, y, w, h) function ime.set_location(x, y, w, h)
system.set_text_input_rect(x, y, w, h) if not ime.last_location or
ime.last_location.x ~= x or
ime.last_location.y ~= y or
ime.last_location.w ~= w or
ime.last_location.h ~= h
then
ime.last_location.x, ime.last_location.y, ime.last_location.w, ime.last_location.h = x, y, w, h
system.set_text_input_rect(x, y, w, h)
end
end end
ime.reset() ime.reset()

View File

@ -178,9 +178,9 @@ end
-- Events listening -- Events listening
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function keymap.on_key_pressed(k, ...) function keymap.on_key_pressed(k, ...)
-- In Windows during IME composition, input is still sent to us -- In MacOS and Windows during IME composition input is still sent to us
-- so we just ignore it -- so we just ignore it
if ime.editing then return false end if PLATFORM ~= "Linux" and ime.editing then return false end
local mk = modkey_map[k] local mk = modkey_map[k]
if mk then if mk then