Skip to content

Commit 14c9cae

Browse files
committed
Fix tvOS pointer issues
1 parent 91229e6 commit 14c9cae

File tree

5 files changed

+128
-87
lines changed

5 files changed

+128
-87
lines changed

Sources/GateEngine/Game.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public final class Game {
3838
do {
3939
// Allow the main window to be created even though we're not rendering
4040
self.renderingIsPermitted = true
41-
try delegate.createMainWindow(game: self, identifier: windowManager.mainWindowIdentifier)
41+
_ = try delegate.createMainWindow(game: self, identifier: windowManager.mainWindowIdentifier)
4242
assert(windowManager.mainWindow?.identifier == windowManager.mainWindowIdentifier, "Must use the provided identifier to make the mainWindow.")
4343
self.renderingIsPermitted = false
4444
}catch{

Sources/GateEngine/System/HID/Keyboard.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,28 @@ public extension Keyboard {
3838
internal var currentRecipt: UInt8 = 0
3939

4040
nonisolated public var description: String {
41+
if case .unhandledPlatformKeyCode(let keyCode, let character) = key {
42+
let keyCodeString: String
43+
if let keyCode {
44+
keyCodeString = "\(keyCode)"
45+
}else{
46+
keyCodeString = "nil"
47+
}
48+
var characterString: String
49+
if let character, character.isEmpty == false {
50+
switch character {
51+
case "\r":
52+
characterString = "\\r"
53+
case "\n":
54+
characterString = "\\n"
55+
default:
56+
characterString = character
57+
}
58+
}else{
59+
characterString = "nil"
60+
}
61+
return "unhandledPlatformKeyCode(\(keyCodeString), \(characterString))"
62+
}
4163
return "\(key)"
4264
}
4365

Sources/GateEngine/System/Platforms/Apple/UIKit/UIKit/UIKitGLKitView.swift

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
import Foundation
1111
import GLKit
1212

13+
class VK: GLKViewController {
14+
15+
}
16+
1317
internal class GLKitView: GLKView {
1418
unowned let viewController: UIKitViewController
1519
static let shareGroup = EAGLSharegroup()
@@ -18,32 +22,31 @@ internal class GLKitView: GLKView {
1822
self.viewController = viewController
1923
let context = EAGLContext(api: .openGLES3, sharegroup: Self.shareGroup)!
2024
super.init(frame: CGRect(origin: .zero, size: size), context: context)
21-
2225
self.setup()
23-
24-
#if os(iOS)
25-
self.isMultipleTouchEnabled = true
26-
self.isExclusiveTouch = true
27-
#endif
2826
}
2927

3028
required init(coder: NSCoder) {
3129
fatalError("init(coder:) has not been implemented")
3230
}
3331

3432
func setup() {
33+
#if os(iOS)
34+
self.isMultipleTouchEnabled = true
35+
self.isExclusiveTouch = true
36+
#endif
3537
EAGLContext.setCurrent(context)
3638
self.bindDrawable()
3739
glFlush()
3840
}
3941

40-
override func draw(_ rect: CGRect) {
41-
drawOpenUG()
42+
override func layoutSubviews() {
43+
super.layoutSubviews()
44+
self.viewController.window.window.newSize = Size2(Float(self.drawableWidth), Float(self.drawableHeight))
4245
}
4346

44-
func drawOpenUG() {
45-
EAGLContext.setCurrent(context)
47+
override func draw(_ rect: CGRect) {
4648
self.bindDrawable()
49+
viewController.window.window?.vSyncCalled()
4750
glFlush()
4851
}
4952
}

Sources/GateEngine/System/Platforms/Apple/UIKit/UIKit/UIKitViewController.swift

Lines changed: 91 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@ import Foundation
1010
import GameController
1111
import GameMath
1212

13-
internal class UIKitViewController: GCEventViewController, UIPointerInteractionDelegate {
13+
internal class UIKitViewController: GCEventViewController {
1414
unowned let window: UIKitWindow
1515
init(window: UIKitWindow) {
1616
self.window = window
1717
super.init(nibName: nil, bundle: nil)
18+
self.loadViewIfNeeded()
1819
}
1920

2021
override func loadView() {
@@ -34,10 +35,11 @@ internal class UIKitViewController: GCEventViewController, UIPointerInteractionD
3435

3536
override func viewDidLoad() {
3637
super.viewDidLoad()
38+
39+
#if os(iOS)
3740
if #available(iOS 13.4, *) {
3841
self.view.interactions.append(UIPointerInteraction(delegate: self))
3942
}
40-
#if os(iOS)
4143
if #available(iOS 11.0, *) {
4244
self.setNeedsUpdateOfHomeIndicatorAutoHidden()
4345
self.setNeedsUpdateOfScreenEdgesDeferringSystemGestures()
@@ -96,14 +98,16 @@ internal class UIKitViewController: GCEventViewController, UIPointerInteractionD
9698
}
9799
}
98100

101+
#if !os(tvOS)
99102
@inline(__always)
100103
func deltaLocationOfTouch(_ touch: UITouch, from event: UIEvent?) -> Position2 {
101104
let cgL = touch.preciseLocation(in: nil)
102105
let cgPL = touch.precisePreviousLocation(in: nil)
103106
return Position2(Float(cgPL.x - cgL.x), Float(cgPL.y - cgL.y))
104107
}
105108

106-
@available(iOS 13.4, *) @inline(__always)
109+
@available(iOS 13.4, *)
110+
@inline(__always)
107111
func mouseButtonFromEvent(_ event: UIEvent?) -> MouseButton {
108112
guard let event else {return .unknown(nil)}
109113
switch event.buttonMask {
@@ -122,28 +126,31 @@ internal class UIKitViewController: GCEventViewController, UIPointerInteractionD
122126
return .unknown(nil)
123127
}
124128
}
129+
#endif
125130

126131
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
127132
super.touchesBegan(touches, with: event)
128133

129134
for touch in touches {
130135
guard let position = locationOfTouch(touch, from: event) else {continue}
136+
#if !os(tvOS)
131137
if #available(iOS 13.4, *), touch.type == .indirectPointer {
132138
if let event = event {
133139
let button = mouseButtonFromEvent(event)
134140
Game.shared.windowManager.mouseClick(event: .buttonDown, button: button, count: touch.tapCount)
135141
}
136-
}else{
137-
let id = ObjectIdentifier(touch)
138-
switch touch.type {
139-
case .direct, .pencil:
140-
let type = type(for: touch)
141-
Game.shared.windowManager.screenTouchChange(id: id, kind: type, event: .began, position: position)
142-
case .indirect:
143-
Game.shared.windowManager.surfaceTouchChange(id: id, event: .began, surfaceID: ObjectIdentifier(UIDevice.current), normalizedPosition: position)
144-
default:
145-
break
146-
}
142+
continue
143+
}
144+
#endif
145+
let id = ObjectIdentifier(touch)
146+
switch touch.type {
147+
case .direct, .pencil:
148+
let type = type(for: touch)
149+
Game.shared.windowManager.screenTouchChange(id: id, kind: type, event: .began, position: position)
150+
case .indirect:
151+
Game.shared.windowManager.surfaceTouchChange(id: id, event: .began, surfaceID: ObjectIdentifier(UIDevice.current), normalizedPosition: position)
152+
default:
153+
break
147154
}
148155
}
149156
}
@@ -152,20 +159,22 @@ internal class UIKitViewController: GCEventViewController, UIPointerInteractionD
152159

153160
for touch in touches {
154161
guard let position = locationOfTouch(touch, from: event) else {continue}
162+
#if !os(tvOS)
155163
if #available(iOS 13.4, *), touch.type == .indirectPointer {
156164
let deltaPosition = deltaLocationOfTouch(touch, from: event)
157165
Game.shared.windowManager.mouseChange(event: .moved, position: position, delta: deltaPosition, window: self.window.window)
158-
}else{
159-
let id = ObjectIdentifier(touch)
160-
switch touch.type {
161-
case .direct, .pencil:
162-
let type = type(for: touch)
163-
Game.shared.windowManager.screenTouchChange(id: id, kind: type, event: .moved, position: position)
164-
case .indirect:
165-
Game.shared.windowManager.surfaceTouchChange(id: id, event: .moved, surfaceID: ObjectIdentifier(UIDevice.current), normalizedPosition: position)
166-
default:
167-
break
168-
}
166+
continue
167+
}
168+
#endif
169+
let id = ObjectIdentifier(touch)
170+
switch touch.type {
171+
case .direct, .pencil:
172+
let type = type(for: touch)
173+
Game.shared.windowManager.screenTouchChange(id: id, kind: type, event: .moved, position: position)
174+
case .indirect:
175+
Game.shared.windowManager.surfaceTouchChange(id: id, event: .moved, surfaceID: ObjectIdentifier(UIDevice.current), normalizedPosition: position)
176+
default:
177+
break
169178
}
170179
}
171180
}
@@ -174,20 +183,22 @@ internal class UIKitViewController: GCEventViewController, UIPointerInteractionD
174183

175184
for touch in touches {
176185
guard let position = locationOfTouch(touch, from: event) else {continue}
186+
#if !os(tvOS)
177187
if #available(iOS 13.4, *), touch.type == .indirectPointer {
178188
let button = mouseButtonFromEvent(event)
179189
Game.shared.windowManager.mouseClick(event: .buttonUp, button: button, count: touch.tapCount)
180-
}else{
181-
let id = ObjectIdentifier(touch)
182-
switch touch.type {
183-
case .direct, .pencil:
184-
let type = type(for: touch)
185-
Game.shared.windowManager.screenTouchChange(id: id, kind: type, event: .ended, position: position)
186-
case .indirect:
187-
Game.shared.windowManager.surfaceTouchChange(id: id, event: .ended, surfaceID: ObjectIdentifier(UIDevice.current), normalizedPosition: position)
188-
default:
189-
break
190-
}
190+
continue
191+
}
192+
#endif
193+
let id = ObjectIdentifier(touch)
194+
switch touch.type {
195+
case .direct, .pencil:
196+
let type = type(for: touch)
197+
Game.shared.windowManager.screenTouchChange(id: id, kind: type, event: .ended, position: position)
198+
case .indirect:
199+
Game.shared.windowManager.surfaceTouchChange(id: id, event: .ended, surfaceID: ObjectIdentifier(UIDevice.current), normalizedPosition: position)
200+
default:
201+
break
191202
}
192203
}
193204
}
@@ -196,52 +207,26 @@ internal class UIKitViewController: GCEventViewController, UIPointerInteractionD
196207

197208
for touch in touches {
198209
guard let position = locationOfTouch(touch, from: event) else {continue}
210+
#if !os(tvOS)
199211
if #available(iOS 13.4, *), touch.type == .indirectPointer {
200212
let button = mouseButtonFromEvent(event)
201213
Game.shared.windowManager.mouseClick(event: .buttonUp, button: button, count: touch.tapCount)
202-
}else{
203-
let id = ObjectIdentifier(touch)
204-
switch touch.type {
205-
case .direct, .pencil:
206-
let type = type(for: touch)
207-
Game.shared.windowManager.screenTouchChange(id: id, kind: type, event: .canceled, position: position)
208-
case .indirect:
209-
Game.shared.windowManager.surfaceTouchChange(id: id, event: .canceled, surfaceID: ObjectIdentifier(UIDevice.current), normalizedPosition: position)
210-
default:
211-
break
212-
}
214+
continue
215+
}
216+
#endif
217+
let id = ObjectIdentifier(touch)
218+
switch touch.type {
219+
case .direct, .pencil:
220+
let type = type(for: touch)
221+
Game.shared.windowManager.screenTouchChange(id: id, kind: type, event: .canceled, position: position)
222+
case .indirect:
223+
Game.shared.windowManager.surfaceTouchChange(id: id, event: .canceled, surfaceID: ObjectIdentifier(UIDevice.current), normalizedPosition: position)
224+
default:
225+
break
213226
}
214227
}
215228
}
216229

217-
// MARK: - Mouse
218-
@available(iOS 13.4, *)
219-
func pointerInteraction(_ interaction: UIPointerInteraction, regionFor request: UIPointerRegionRequest, defaultRegion: UIPointerRegion) -> UIPointerRegion? {
220-
Game.shared.windowManager.mouseChange(event: .moved, position: Position2(request.location), delta: .zero, window: self.window.window)
221-
return defaultRegion
222-
}
223-
224-
// Called after the interaction receives a new UIPointerRegion from pointerInteraction:regionForRequest:defaultRegion:.
225-
@available(iOS 13.4, *)
226-
func pointerInteraction(_ interaction: UIPointerInteraction, styleFor region: UIPointerRegion) -> UIPointerStyle? {
227-
if Game.shared.hid.mouse.hidden {
228-
return UIPointerStyle.hidden()
229-
}
230-
return nil
231-
}
232-
233-
// Called when the pointer enters a given region.
234-
@available(iOS 13.4, *)
235-
func pointerInteraction(_ interaction: UIPointerInteraction, willEnter region: UIPointerRegion, animator: UIPointerInteractionAnimating) {
236-
Game.shared.windowManager.mouseChange(event: .entered, position: .zero, delta: .zero, window: self.window.window)
237-
}
238-
239-
// Called when the pointer exists a given region.
240-
@available(iOS 13.4, *)
241-
func pointerInteraction(_ interaction: UIPointerInteraction, willExit region: UIPointerRegion, animator: UIPointerInteractionAnimating) {
242-
Game.shared.windowManager.mouseChange(event: .exited, position: .zero, delta: .zero, window: self.window.window)
243-
}
244-
245230
// MARK: - Keyboard
246231
@inline(__always)
247232
func keysFromEvent(_ event: UIPressesEvent) -> Set<KeyboardKey> {
@@ -349,4 +334,35 @@ internal class UIKitViewController: GCEventViewController, UIPointerInteractionD
349334
}
350335
}
351336
}
337+
338+
// MARK: - Mouse
339+
#if !os(tvOS)
340+
@available(iOS 13.4, *)
341+
extension UIKitViewController: UIPointerInteractionDelegate {
342+
343+
// Called as the pointer moves within the interaction's view.
344+
func pointerInteraction(_ interaction: UIPointerInteraction, regionFor request: UIPointerRegionRequest, defaultRegion: UIPointerRegion) -> UIPointerRegion? {
345+
Game.shared.windowManager.mouseChange(event: .moved, position: Position2(request.location), delta: .zero, window: self.window.window)
346+
return defaultRegion
347+
}
348+
349+
// Called after the interaction receives a new UIPointerRegion from pointerInteraction:regionForRequest:defaultRegion:.
350+
func pointerInteraction(_ interaction: UIPointerInteraction, styleFor region: UIPointerRegion) -> UIPointerStyle? {
351+
if Game.shared.hid.mouse.hidden {
352+
return UIPointerStyle.hidden()
353+
}
354+
return nil
355+
}
356+
357+
// Called when the pointer enters a given region.
358+
func pointerInteraction(_ interaction: UIPointerInteraction, willEnter region: UIPointerRegion, animator: UIPointerInteractionAnimating) {
359+
Game.shared.windowManager.mouseChange(event: .entered, position: .zero, delta: .zero, window: self.window.window)
360+
}
361+
362+
// Called when the pointer exists a given region.
363+
func pointerInteraction(_ interaction: UIPointerInteraction, willExit region: UIPointerRegion, animator: UIPointerInteractionAnimating) {
364+
Game.shared.windowManager.mouseChange(event: .exited, position: .zero, delta: .zero, window: self.window.window)
365+
}
366+
}
367+
#endif
352368
#endif

Sources/GateEngine/System/Platforms/Apple/UIKit/UIKit/UIKitWindow.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class UIKitWindow: WindowBacking {
3737
displayLink.add(to: .main, forMode: .default)
3838
if #available(iOS 15.0, tvOS 15.0, *) {
3939
displayLink.preferredFrameRateRange = CAFrameRateRange(minimum: 30, maximum: Float(self.uiWindow.screen.maximumFramesPerSecond))
40-
} else {
40+
}else{
4141
displayLink.preferredFramesPerSecond = self.uiWindow.screen.maximumFramesPerSecond
4242
}
4343
return displayLink

0 commit comments

Comments
 (0)