Skip to content

Commit f6be7bd

Browse files
committed
Handle input connection close
1 parent b058b01 commit f6be7bd

File tree

5 files changed

+27
-1
lines changed

5 files changed

+27
-1
lines changed

Sources/Shaft/Core/Backend.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ public protocol NativeView: AnyObject {
6161
/// and begin receiving these events.
6262
var onTextComposed: TextComposedCallback? { get set }
6363

64+
/// A callback that is invoked when the text input connection is closed.
65+
var onTextInputClosed: VoidCallback? { get set }
66+
6467
/// Getting/Setting the title of the view if possible.
6568
var title: String { get set }
6669

Sources/Shaft/Services/TextInput.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public class TextInput {
1010
self.view = view
1111
view.onTextEditing = handleTextEditing
1212
view.onTextComposed = handleTextComposed
13+
view.onTextInputClosed = handleTextInputClosed
1314
}
1415

1516
public weak var view: NativeView!
@@ -34,6 +35,11 @@ public class TextInput {
3435
currentConnection?.client?.onTextComposed(text: text)
3536
}
3637

38+
private func handleTextInputClosed() {
39+
currentConnection?.client?.onTextInputClosed()
40+
currentConnection = nil
41+
}
42+
3743
fileprivate func setComposingRect(_ rect: Rect) {
3844
view.setComposingRect(rect)
3945
}
@@ -75,6 +81,9 @@ public protocol TextInputClient: AnyObject {
7581

7682
/// Called when the text has been composed and committed.
7783
func onTextComposed(text: String)
84+
85+
/// Called when the text input connection is closed.
86+
func onTextInputClosed()
7887
}
7988

8089
/// An interface for interacting with a text input control.

Sources/Shaft/Widgets/Text/EditableText.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1296,6 +1296,13 @@ public final class EditableTextState: State<EditableText>, TextSelectionDelegate
12961296
// no-op
12971297
}
12981298

1299+
public func onTextInputClosed() {
1300+
if hasInputConnection {
1301+
textInputConnection = nil
1302+
widget.focusNode.unfocus()
1303+
}
1304+
}
1305+
12991306
/// Sends the current composing rect to the embedder's text input plugin.
13001307
///
13011308
/// In cases where the composing rect hasn't been updated in the embedder due
@@ -1752,7 +1759,7 @@ public final class EditableTextState: State<EditableText>, TextSelectionDelegate
17521759
}
17531760

17541761
private var textInputConnection: TextInputConnection?
1755-
private var hasInputConnection: Bool { textInputConnection != nil }
1762+
private var hasInputConnection: Bool { textInputConnection?.isActive ?? false }
17561763

17571764
private func openOrCloseInputConnectionIfNeeded() {
17581765
if hasFocus && widget.focusNode.consumeKeyboardToken() {

Sources/ShaftSDL3/SDLView.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ public class SDLView: NativeView {
187187

188188
if SDL_StopTextInput(sdlWindow) {
189189
backend?.textEditingView = nil
190+
onTextInputClosed?()
190191
} else {
191192
mark("SDL_StopTextInput failed")
192193
}
@@ -246,6 +247,10 @@ public class SDLView: NativeView {
246247
/// events are received.
247248
public var onTextComposed: TextComposedCallback?
248249

250+
/// It's the backend's responsibility to call this method when the text input
251+
/// connection is closed.
252+
public var onTextInputClosed: VoidCallback?
253+
249254
fileprivate func handleEventSync(_ event: inout SDL_Event) -> Bool {
250255
switch SDL_EventType(event.type.cast()) {
251256
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:

Tests/ShaftTests/TestUtils/WidgetTester.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,8 @@ class TestBackend: Backend {
491491

492492
var onTextComposed: TextComposedCallback?
493493

494+
var onTextInputClosed: VoidCallback?
495+
494496
var onKeyEvent: KeyEventCallback?
495497

496498
var targetPlatform: TargetPlatform? {

0 commit comments

Comments
 (0)