Browse Source

display(iOS): moved instance variables to private properties

osy 2 years ago
parent
commit
a388342316

+ 12 - 11
Platform/iOS/Display/VMDisplayMetalViewController+Gamepad.m

@@ -16,6 +16,7 @@
 
 #import "VMCursor.h"
 #import "VMScroll.h"
+#import "VMDisplayMetalViewController+Private.h"
 #import "VMDisplayMetalViewController+Gamepad.h"
 #import "VMDisplayMetalViewController+Touch.h"
 #import "CSDisplay.h"
@@ -53,7 +54,7 @@ const CGFloat kThumbstickSpeedMultiplier = 1000; // in points per second
 - (void)setupController:(GCController *)controller {
     GCExtendedGamepad *gamepad = controller.extendedGamepad;
     __weak typeof(self) _self = self;
-    _controller = controller;
+    self.controller = controller;
     UTMLog(@"active controller switched to: %@", controller.vendorName);
     
     gamepad.leftTrigger.pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
@@ -107,20 +108,20 @@ const CGFloat kThumbstickSpeedMultiplier = 1000; // in points per second
     gamepad.leftThumbstick.valueChangedHandler = ^(GCControllerDirectionPad * _Nonnull dpad, float xValue, float yValue) {
         VMDisplayMetalViewController *s = _self;
         CGPoint velocity = CGPointMake(xValue * kThumbstickSpeedMultiplier, -yValue * kThumbstickSpeedMultiplier);
-        [s->_scroll startMovement:CGPointZero];
-        [s->_scroll updateMovement:CGPointMake(xValue, yValue)];
-        [s->_scroll endMovementWithVelocity:velocity resistance:0];
+        [s.scroll startMovement:CGPointZero];
+        [s.scroll updateMovement:CGPointMake(xValue, yValue)];
+        [s.scroll endMovementWithVelocity:velocity resistance:0];
     };
     
     gamepad.rightThumbstick.valueChangedHandler = ^(GCControllerDirectionPad * _Nonnull dpad, float xValue, float yValue) {
         NSInteger speed = [_self integerForSetting:@"GCThumbstickRightSpeed"];
         VMDisplayMetalViewController *s = _self;
-        CGPoint center = s->_cursor.center;
+        CGPoint center = s.cursor.center;
         CGPoint start = CGPointMake(xValue * speed, -yValue * speed);
         CGPoint velocity = CGPointMake(xValue * kThumbstickSpeedMultiplier, -yValue * kThumbstickSpeedMultiplier);
-        [s->_cursor startMovement:center];
-        [s->_cursor updateMovement:CGPointMake(center.x + start.x, center.y + start.y)];
-        [s->_cursor endMovementWithVelocity:velocity resistance:0];
+        [s.cursor startMovement:center];
+        [s.cursor updateMovement:CGPointMake(center.x + start.x, center.y + start.y)];
+        [s.cursor endMovementWithVelocity:velocity resistance:0];
     };
     
     if (@available(iOS 13.0, *)) {
@@ -138,15 +139,15 @@ const CGFloat kThumbstickSpeedMultiplier = 1000; // in points per second
             break;
         case -1:
             [self.vmInput sendMouseButton:kCSInputButtonLeft pressed:isPressed];
-            _mouseLeftDown = isPressed;
+            self.mouseLeftDown = isPressed;
             break;
         case -3:
             [self.vmInput sendMouseButton:kCSInputButtonRight pressed:isPressed];
-            _mouseRightDown = isPressed;
+            self.mouseRightDown = isPressed;
             break;
         case -2:
             [self.vmInput sendMouseButton:kCSInputButtonMiddle pressed:isPressed];
-            _mouseMiddleDown = isPressed;
+            self.mouseMiddleDown = isPressed;
             break;
         default:
             [self sendExtendedKey:isPressed ? kCSInputKeyPress : kCSInputKeyRelease code:(int)value];

+ 1 - 0
Platform/iOS/Display/VMDisplayMetalViewController+Keyboard.m

@@ -15,6 +15,7 @@
 //
 
 #import "VMDisplayMetalViewController+Keyboard.h"
+#import "VMDisplayMetalViewController+Private.h"
 #import "UTMLogging.h"
 #import "VMKeyboardView.h"
 #import "VMKeyboardButton.h"

+ 2 - 1
Platform/iOS/Display/VMDisplayMetalViewController+Pencil.m

@@ -16,6 +16,7 @@
 
 #import "UIKit/UIKit.h"
 #import "VMDisplayMetalViewController.h"
+#import "VMDisplayMetalViewController+Private.h"
 #import "VMDisplayMetalViewController+Pencil.h"
 
 NS_AVAILABLE_IOS(12.1)
@@ -31,7 +32,7 @@ NS_AVAILABLE_IOS(12.1)
 - (void)pencilInteractionDidTap:(UIPencilInteraction *)interaction {
     // ignore interaction type as we only support one action:
     // switching to right click for the next click
-    _pencilForceRightClickOnce = true;
+    self.pencilForceRightClickOnce = true;
 }
 
 @end

+ 5 - 8
Platform/iOS/Display/VMDisplayMetalViewController+Pointer.m

@@ -15,6 +15,7 @@
 //
 
 #import "VMDisplayMetalViewController.h"
+#import "VMDisplayMetalViewController+Private.h"
 #import "VMDisplayMetalViewController+Touch.h"
 #import "VMDisplayMetalViewController+Pointer.h"
 #import "VMCursor.h"
@@ -68,16 +69,16 @@ NS_AVAILABLE_IOS(13.4)
         [self.vmInput sendMouseMotion:self.mouseButtonDown relativePoint:CGPointMake(deltaX, -deltaY)];
     };
     mouse.mouseInput.leftButton.pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
-        self->_mouseLeftDown = pressed;
+        self.mouseLeftDown = pressed;
         [self.vmInput sendMouseButton:kCSInputButtonLeft pressed:pressed];
     };
     mouse.mouseInput.rightButton.pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
-        self->_mouseRightDown = pressed;
+        self.mouseRightDown = pressed;
         [self.vmInput sendMouseButton:kCSInputButtonRight pressed:pressed];
 
     };
     mouse.mouseInput.middleButton.pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
-        self->_mouseMiddleDown = pressed;
+        self.mouseMiddleDown = pressed;
         [self.vmInput sendMouseButton:kCSInputButtonMiddle pressed:pressed];
     };
     for (int i = 0; i < MIN(4, mouse.mouseInput.auxiliaryButtons.count); i++) {
@@ -133,10 +134,6 @@ NS_AVAILABLE_IOS(13.4)
     return nil;
 }
 
-static CGFloat CGPointToPixel(CGFloat point) {
-    return point * [UIScreen mainScreen].scale; // FIXME: multiple screens?
-}
-
 - (bool)isPointOnVMDisplay:(CGPoint)pos {
     CGSize screenSize = self.mtkView.drawableSize;
     CGSize scaledSize = {
@@ -171,7 +168,7 @@ static CGFloat CGPointToPixel(CGFloat point) {
         
         if ([self isPointOnVMDisplay:translated]) {
             // move vm cursor, hide iOS cursor
-            [_cursor updateMovement:location];
+            [self.cursor updateMovement:location];
             return [UIPointerRegion regionWithRect:[self.mtkView bounds] identifier:@"vm view"];
         } else {
             // don't move vm cursor, show iOS cursor

+ 69 - 0
Platform/iOS/Display/VMDisplayMetalViewController+Private.h

@@ -0,0 +1,69 @@
+//
+// Copyright © 2023 osy. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#import "VMDisplayMetalViewController.h"
+#import <TargetConditionals.h>
+
+@class VMCursor;
+@class VMScroll;
+@class GCController;
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface VMDisplayMetalViewController ()
+
+// cursor handling
+@property (nonatomic) CGPoint lastTwoPanOrigin;
+@property (nonatomic) BOOL mouseLeftDown;
+@property (nonatomic) BOOL mouseRightDown;
+@property (nonatomic) BOOL mouseMiddleDown;
+@property (nonatomic) BOOL pencilForceRightClickOnce;
+@property (nonatomic) VMCursor *cursor;
+@property (nonatomic) VMScroll *scroll;
+
+// Gestures
+@property (nonatomic) UISwipeGestureRecognizer *swipeUp;
+@property (nonatomic) UISwipeGestureRecognizer *swipeDown;
+@property (nonatomic) UISwipeGestureRecognizer *swipeScrollUp;
+@property (nonatomic) UISwipeGestureRecognizer *swipeScrollDown;
+@property (nonatomic) UIPanGestureRecognizer *pan;
+@property (nonatomic) UIPanGestureRecognizer *twoPan;
+@property (nonatomic) UIPanGestureRecognizer *threePan;
+@property (nonatomic) UITapGestureRecognizer *tap;
+@property (nonatomic) UITapGestureRecognizer *tapPencil;
+@property (nonatomic) UITapGestureRecognizer *twoTap;
+@property (nonatomic) UILongPressGestureRecognizer *longPress;
+@property (nonatomic) UIPinchGestureRecognizer *pinch;
+
+//Gamepad
+@property (nonatomic) GCController *controller;
+
+#if !defined(TARGET_OS_VISION) || !TARGET_OS_VISION
+// Feedback generators
+@property (nonatomic) UISelectionFeedbackGenerator *clickFeedbackGenerator;
+#endif
+
+@end
+
+NS_ASSUME_NONNULL_END
+
+static inline CGFloat CGPointToPixel(CGFloat point) {
+#if defined(TARGET_OS_VISION) && TARGET_OS_VISION
+    return 2.0;
+#else
+    return point * [UIScreen mainScreen].scale; // FIXME: multiple screens?
+#endif
+}

+ 126 - 122
Platform/iOS/Display/VMDisplayMetalViewController+Touch.m

@@ -15,8 +15,11 @@
 //
 
 #import "VMDisplayMetalViewController.h"
+#import "VMDisplayMetalViewController+Private.h"
 #import "VMDisplayMetalViewController+Touch.h"
+#if !defined(TARGET_OS_VISION) || !TARGET_OS_VISION
 #import "VMDisplayMetalViewController+Pencil.h"
+#endif
 #import "VMCursor.h"
 #import "VMScroll.h"
 #import "CSDisplay.h"
@@ -32,85 +35,86 @@ const CGFloat kScrollResistance = 10.0f;
 
 - (void)initTouch {
     // mouse cursor
-    _cursor = [[VMCursor alloc] initWithVMViewController:self];
-    _scroll = [[VMScroll alloc] initWithVMViewController:self];
+    self.cursor = [[VMCursor alloc] initWithVMViewController:self];
+    self.scroll = [[VMScroll alloc] initWithVMViewController:self];
     
     // Set up gesture recognizers because Storyboards is BROKEN and doing it there crashes!
-    _swipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(gestureSwipeUp:)];
-    _swipeUp.numberOfTouchesRequired = 3;
-    _swipeUp.direction = UISwipeGestureRecognizerDirectionUp;
-    _swipeUp.delegate = self;
-    _swipeDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(gestureSwipeDown:)];
-    _swipeDown.numberOfTouchesRequired = 3;
-    _swipeDown.direction = UISwipeGestureRecognizerDirectionDown;
-    _swipeDown.delegate = self;
-    _swipeScrollUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(gestureSwipeScroll:)];
-    _swipeScrollUp.numberOfTouchesRequired = 2;
-    _swipeScrollUp.direction = UISwipeGestureRecognizerDirectionUp;
-    _swipeScrollUp.delegate = self;
-    _swipeScrollDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(gestureSwipeScroll:)];
-    _swipeScrollDown.numberOfTouchesRequired = 2;
-    _swipeScrollDown.direction = UISwipeGestureRecognizerDirectionDown;
-    _swipeScrollDown.delegate = self;
-    _pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(gesturePan:)];
-    _pan.minimumNumberOfTouches = 1;
-    _pan.maximumNumberOfTouches = 1;
-    _pan.delegate = self;
-    _pan.cancelsTouchesInView = NO;
-    _twoPan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(gestureTwoPan:)];
-    _twoPan.minimumNumberOfTouches = 2;
-    _twoPan.maximumNumberOfTouches = 2;
-    _twoPan.delegate = self;
-    _threePan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(gestureThreePan:)];
-    _threePan.minimumNumberOfTouches = 3;
-    _threePan.maximumNumberOfTouches = 3;
-    _threePan.delegate = self;
-    _tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(gestureTap:)];
-    _tap.delegate = self;
-    _tap.allowedTouchTypes = @[ @(UITouchTypeDirect) ];
-    _tap.cancelsTouchesInView = NO;
-    _tapPencil = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(gestureTapPencil:)];
-    _tapPencil.delegate = self;
-    _tapPencil.allowedTouchTypes = @[ @(UITouchTypePencil) ];
-    _tapPencil.cancelsTouchesInView = NO;
-    _twoTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(gestureTwoTap:)];
-    _twoTap.numberOfTouchesRequired = 2;
-    _twoTap.delegate = self;
-    _twoTap.allowedTouchTypes = @[ @(UITouchTypeDirect) ];
-    _longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(gestureLongPress:)];
-    _longPress.delegate = self;
-    _longPress.allowedTouchTypes = @[ @(UITouchTypeDirect) ];
-    _pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(gesturePinch:)];
-    _pinch.delegate = self;
-    [self.mtkView addGestureRecognizer:_swipeUp];
-    [self.mtkView addGestureRecognizer:_swipeDown];
-    [self.mtkView addGestureRecognizer:_swipeScrollUp];
-    [self.mtkView addGestureRecognizer:_swipeScrollDown];
-    [self.mtkView addGestureRecognizer:_pan];
-    [self.mtkView addGestureRecognizer:_twoPan];
-    [self.mtkView addGestureRecognizer:_threePan];
-    [self.mtkView addGestureRecognizer:_tap];
-    [self.mtkView addGestureRecognizer:_tapPencil];
-    [self.mtkView addGestureRecognizer:_twoTap];
-    [self.mtkView addGestureRecognizer:_longPress];
-    [self.mtkView addGestureRecognizer:_pinch];
+    self.swipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(gestureSwipeUp:)];
+    self.swipeUp.numberOfTouchesRequired = 3;
+    self.swipeUp.direction = UISwipeGestureRecognizerDirectionUp;
+    self.swipeUp.delegate = self;
+    self.swipeDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(gestureSwipeDown:)];
+    self.swipeDown.numberOfTouchesRequired = 3;
+    self.swipeDown.direction = UISwipeGestureRecognizerDirectionDown;
+    self.swipeDown.delegate = self;
+    self.swipeScrollUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(gestureSwipeScroll:)];
+    self.swipeScrollUp.numberOfTouchesRequired = 2;
+    self.swipeScrollUp.direction = UISwipeGestureRecognizerDirectionUp;
+    self.swipeScrollUp.delegate = self;
+    self.swipeScrollDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(gestureSwipeScroll:)];
+    self.swipeScrollDown.numberOfTouchesRequired = 2;
+    self.swipeScrollDown.direction = UISwipeGestureRecognizerDirectionDown;
+    self.swipeScrollDown.delegate = self;
+    self.pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(gesturePan:)];
+    self.pan.minimumNumberOfTouches = 1;
+    self.pan.maximumNumberOfTouches = 1;
+    self.pan.delegate = self;
+    self.pan.cancelsTouchesInView = NO;
+    self.twoPan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(gestureTwoPan:)];
+    self.twoPan.minimumNumberOfTouches = 2;
+    self.twoPan.maximumNumberOfTouches = 2;
+    self.twoPan.delegate = self;
+    self.threePan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(gestureThreePan:)];
+    self.threePan.minimumNumberOfTouches = 3;
+    self.threePan.maximumNumberOfTouches = 3;
+    self.threePan.delegate = self;
+    self.tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(gestureTap:)];
+    self.tap.delegate = self;
+    self.tap.allowedTouchTypes = @[ @(UITouchTypeDirect) ];
+    self.tap.cancelsTouchesInView = NO;
+    self.tapPencil = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(gestureTapPencil:)];
+    self.tapPencil.delegate = self;
+    self.tapPencil.allowedTouchTypes = @[ @(UITouchTypePencil) ];
+    self.tapPencil.cancelsTouchesInView = NO;
+    self.twoTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(gestureTwoTap:)];
+    self.twoTap.numberOfTouchesRequired = 2;
+    self.twoTap.delegate = self;
+    self.twoTap.allowedTouchTypes = @[ @(UITouchTypeDirect) ];
+    self.longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(gestureLongPress:)];
+    self.longPress.delegate = self;
+    self.longPress.allowedTouchTypes = @[ @(UITouchTypeDirect) ];
+    self.pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(gesturePinch:)];
+    self.pinch.delegate = self;
+    [self.mtkView addGestureRecognizer:self.swipeUp];
+    [self.mtkView addGestureRecognizer:self.swipeDown];
+    [self.mtkView addGestureRecognizer:self.swipeScrollUp];
+    [self.mtkView addGestureRecognizer:self.swipeScrollDown];
+    [self.mtkView addGestureRecognizer:self.pan];
+    [self.mtkView addGestureRecognizer:self.twoPan];
+    [self.mtkView addGestureRecognizer:self.threePan];
+    [self.mtkView addGestureRecognizer:self.tap];
+    [self.mtkView addGestureRecognizer:self.tapPencil];
+    [self.mtkView addGestureRecognizer:self.twoTap];
+    [self.mtkView addGestureRecognizer:self.longPress];
+    [self.mtkView addGestureRecognizer:self.pinch];
     
+#if !defined(TARGET_OS_VISION) || !TARGET_OS_VISION
     // Feedback generator for clicks
-    _clickFeedbackGenerator = [[UISelectionFeedbackGenerator alloc] init];
-    _resizeFeedbackGenerator = [[UIImpactFeedbackGenerator alloc] init];
+    self.clickFeedbackGenerator = [[UISelectionFeedbackGenerator alloc] init];
+#endif
 }
 
 #pragma mark - Properties from instance
 
 - (CSInputButton)mouseButtonDown {
     CSInputButton button = kCSInputButtonNone;
-    if (_mouseLeftDown) {
+    if (self.mouseLeftDown) {
         button |= kCSInputButtonLeft;
     }
-    if (_mouseRightDown) {
+    if (self.mouseRightDown) {
         button |= kCSInputButtonRight;
     }
-    if (_mouseMiddleDown) {
+    if (self.mouseMiddleDown) {
         button |= kCSInputButtonMiddle;
     }
     return button;
@@ -192,10 +196,6 @@ static CGRect CGRectClipToBounds(CGRect rect1, CGRect rect2) {
     return rect2;
 }
 
-static CGFloat CGPointToPixel(CGFloat point) {
-    return point * [UIScreen mainScreen].scale; // FIXME: multiple screens?
-}
-
 - (CGPoint)clipCursorToDisplay:(CGPoint)pos {
     CGSize screenSize = self.mtkView.drawableSize;
     CGSize scaledSize = {
@@ -260,13 +260,13 @@ static CGFloat CGPointToPixel(CGFloat point) {
     CGPoint location = [sender locationInView:sender.view];
     CGPoint velocity = [sender velocityInView:sender.view];
     if (sender.state == UIGestureRecognizerStateBegan) {
-        [_cursor startMovement:location];
+        [self.cursor startMovement:location];
     }
     if (sender.state != UIGestureRecognizerStateCancelled) {
-        [_cursor updateMovement:location];
+        [self.cursor updateMovement:location];
     }
     if (sender.state == UIGestureRecognizerStateEnded) {
-        [_cursor endMovementWithVelocity:velocity resistance:kCursorResistance];
+        [self.cursor endMovementWithVelocity:velocity resistance:kCursorResistance];
     }
 }
 
@@ -274,13 +274,13 @@ static CGFloat CGPointToPixel(CGFloat point) {
     CGPoint location = [sender locationInView:sender.view];
     CGPoint velocity = [sender velocityInView:sender.view];
     if (sender.state == UIGestureRecognizerStateBegan) {
-        [_scroll startMovement:location];
+        [self.scroll startMovement:location];
     }
     if (sender.state != UIGestureRecognizerStateCancelled) {
-        [_scroll updateMovement:location];
+        [self.scroll updateMovement:location];
     }
     if (sender.state == UIGestureRecognizerStateEnded) {
-        [_scroll endMovementWithVelocity:velocity resistance:kScrollResistance];
+        [self.scroll endMovementWithVelocity:velocity resistance:kScrollResistance];
     }
 }
 
@@ -292,13 +292,13 @@ static CGFloat CGPointToPixel(CGFloat point) {
 
 - (void)moveScreen:(UIPanGestureRecognizer *)sender {
     if (sender.state == UIGestureRecognizerStateBegan) {
-        _lastTwoPanOrigin = self.vmDisplay.viewportOrigin;
+        self.lastTwoPanOrigin = self.vmDisplay.viewportOrigin;
     }
     if (sender.state != UIGestureRecognizerStateCancelled) {
         CGPoint translation = [sender translationInView:sender.view];
         CGPoint viewport = self.vmDisplay.viewportOrigin;
-        viewport.x = CGPointToPixel(translation.x) + _lastTwoPanOrigin.x;
-        viewport.y = CGPointToPixel(translation.y) + _lastTwoPanOrigin.y;
+        viewport.x = CGPointToPixel(translation.x) + self.lastTwoPanOrigin.x;
+        viewport.y = CGPointToPixel(translation.y) + self.lastTwoPanOrigin.y;
         self.vmDisplay.viewportOrigin = [self clipDisplayToView:viewport];
         // persist this change in viewState
         self.delegate.displayOrigin = self.vmDisplay.viewportOrigin;
@@ -378,35 +378,39 @@ static CGFloat CGPointToPixel(CGFloat point) {
 
 - (void)mouseClick:(CSInputButton)button location:(CGPoint)location {
     if (!self.serverModeCursor) {
-        _cursor.center = location;
+        self.cursor.center = location;
     }
     [self.vmInput sendMouseButton:button pressed:YES];
     [self onDelay:0.05f action:^{
-        self->_mouseLeftDown = NO;
-        self->_mouseRightDown = NO;
-        self->_mouseMiddleDown = NO;
+        self.mouseLeftDown = NO;
+        self.mouseRightDown = NO;
+        self.mouseMiddleDown = NO;
         [self.vmInput sendMouseButton:button pressed:NO];
     }];
-    [_clickFeedbackGenerator selectionChanged];
+#if !defined(TARGET_OS_VISION) || !TARGET_OS_VISION
+    [self.clickFeedbackGenerator selectionChanged];
+#endif
 }
 
 - (void)dragCursor:(UIGestureRecognizerState)state primary:(BOOL)primary secondary:(BOOL)secondary middle:(BOOL)middle {
     if (state == UIGestureRecognizerStateBegan) {
-        [_clickFeedbackGenerator selectionChanged];
+#if !defined(TARGET_OS_VISION) || !TARGET_OS_VISION
+        [self.clickFeedbackGenerator selectionChanged];
+#endif
         if (primary) {
-            _mouseLeftDown = YES;
+            self.mouseLeftDown = YES;
         }
         if (secondary) {
-            _mouseRightDown = YES;
+            self.mouseRightDown = YES;
         }
         if (middle) {
-            _mouseMiddleDown = YES;
+            self.mouseMiddleDown = YES;
         }
         [self.vmInput sendMouseButton:self.mouseButtonDown pressed:YES];
     } else if (state == UIGestureRecognizerStateEnded) {
-        _mouseLeftDown = NO;
-        _mouseRightDown = NO;
-        _mouseMiddleDown = NO;
+        self.mouseLeftDown = NO;
+        self.mouseRightDown = NO;
+        self.mouseMiddleDown = NO;
         [self.vmInput sendMouseButton:self.mouseButtonDown pressed:NO];
     }
 }
@@ -425,9 +429,9 @@ static CGFloat CGPointToPixel(CGFloat point) {
         CSInputButton button = kCSInputButtonLeft;
         
         if (@available(iOS 12.1, *)) {
-            if (_pencilForceRightClickOnce) {
+            if (self.pencilForceRightClickOnce) {
                 button = kCSInputButtonRight;
-                _pencilForceRightClickOnce = false;
+                self.pencilForceRightClickOnce = false;
             }
         }
         
@@ -482,9 +486,9 @@ static CGFloat CGPointToPixel(CGFloat point) {
 - (IBAction)gestureSwipeScroll:(UISwipeGestureRecognizer *)sender {
     if (sender.state == UIGestureRecognizerStateEnded &&
         self.twoFingerScrollType == VMGestureTypeMouseWheel) {
-        if (sender == _swipeScrollUp) {
+        if (sender == self.swipeScrollUp) {
             [self.vmInput sendMouseScroll:kCSInputScrollUp button:self.mouseButtonDown dy:0];
-        } else if (sender == _swipeScrollDown) {
+        } else if (sender == self.swipeScrollDown) {
             [self.vmInput sendMouseScroll:kCSInputScrollDown button:self.mouseButtonDown dy:0];
         } else {
             NSAssert(0, @"Invalid call to gestureSwipeScroll");
@@ -495,57 +499,57 @@ static CGFloat CGPointToPixel(CGFloat point) {
 #pragma mark - UIGestureRecognizerDelegate
 
 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
-    if (gestureRecognizer == _twoPan && otherGestureRecognizer == _swipeUp) {
+    if (gestureRecognizer == self.twoPan && otherGestureRecognizer == self.swipeUp) {
         return YES;
     }
-    if (gestureRecognizer == _twoPan && otherGestureRecognizer == _swipeDown) {
+    if (gestureRecognizer == self.twoPan && otherGestureRecognizer == self.swipeDown) {
         return YES;
     }
-    if (gestureRecognizer == _twoTap && otherGestureRecognizer == _swipeDown) {
+    if (gestureRecognizer == self.twoTap && otherGestureRecognizer == self.swipeDown) {
         return YES;
     }
-    if (gestureRecognizer == _twoTap && otherGestureRecognizer == _swipeUp) {
+    if (gestureRecognizer == self.twoTap && otherGestureRecognizer == self.swipeUp) {
         return YES;
     }
-    if (gestureRecognizer == _tap && otherGestureRecognizer == _twoTap) {
+    if (gestureRecognizer == self.tap && otherGestureRecognizer == self.twoTap) {
         return YES;
     }
-    if (gestureRecognizer == _tapPencil && otherGestureRecognizer == _twoTap) {
+    if (gestureRecognizer == self.tapPencil && otherGestureRecognizer == self.twoTap) {
         return YES;
     }
-    if (gestureRecognizer == _longPress && otherGestureRecognizer == _tap) {
+    if (gestureRecognizer == self.longPress && otherGestureRecognizer == self.tap) {
         return YES;
     }
-    if (gestureRecognizer == _longPress && otherGestureRecognizer == _tapPencil) {
+    if (gestureRecognizer == self.longPress && otherGestureRecognizer == self.tapPencil) {
         return YES;
     }
-    if (gestureRecognizer == _longPress && otherGestureRecognizer == _twoTap) {
+    if (gestureRecognizer == self.longPress && otherGestureRecognizer == self.twoTap) {
         return YES;
     }
-    if (gestureRecognizer == _pinch && otherGestureRecognizer == _swipeDown) {
+    if (gestureRecognizer == self.pinch && otherGestureRecognizer == self.swipeDown) {
         return YES;
     }
-    if (gestureRecognizer == _pinch && otherGestureRecognizer == _swipeUp) {
+    if (gestureRecognizer == self.pinch && otherGestureRecognizer == self.swipeUp) {
         return YES;
     }
-    if (gestureRecognizer == _pan && otherGestureRecognizer == _swipeUp) {
+    if (gestureRecognizer == self.pan && otherGestureRecognizer == self.swipeUp) {
         return YES;
     }
-    if (gestureRecognizer == _pan && otherGestureRecognizer == _swipeDown) {
+    if (gestureRecognizer == self.pan && otherGestureRecognizer == self.swipeDown) {
         return YES;
     }
-    if (gestureRecognizer == _threePan && otherGestureRecognizer == _swipeUp) {
+    if (gestureRecognizer == self.threePan && otherGestureRecognizer == self.swipeUp) {
         return YES;
     }
-    if (gestureRecognizer == _threePan && otherGestureRecognizer == _swipeDown) {
+    if (gestureRecognizer == self.threePan && otherGestureRecognizer == self.swipeDown) {
         return YES;
     }
     // only if we do not disable two finger swipe
     if (self.twoFingerScrollType != VMGestureTypeNone) {
-        if (gestureRecognizer == _twoPan && otherGestureRecognizer == _swipeScrollUp) {
+        if (gestureRecognizer == self.twoPan && otherGestureRecognizer == self.swipeScrollUp) {
             return YES;
         }
-        if (gestureRecognizer == _twoPan && otherGestureRecognizer == _swipeScrollDown) {
+        if (gestureRecognizer == self.twoPan && otherGestureRecognizer == self.swipeScrollDown) {
             return YES;
         }
     }
@@ -553,19 +557,19 @@ static CGFloat CGPointToPixel(CGFloat point) {
 }
 
 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
-    if (gestureRecognizer == _twoPan && otherGestureRecognizer == _pinch) {
+    if (gestureRecognizer == self.twoPan && otherGestureRecognizer == self.pinch) {
         if (self.twoFingerPanType == VMGestureTypeMoveScreen) {
             return YES;
         } else {
             return NO;
         }
-    } else if (gestureRecognizer == _pan && otherGestureRecognizer == _longPress) {
+    } else if (gestureRecognizer == self.pan && otherGestureRecognizer == self.longPress) {
         return YES;
-    } else if (self.twoFingerScrollType == VMGestureTypeNone && otherGestureRecognizer == _twoPan) {
+    } else if (self.twoFingerScrollType == VMGestureTypeNone && otherGestureRecognizer == self.twoPan) {
         // if two finger swipe is disabled, we can also recognize two finger pans
-        if (gestureRecognizer == _swipeScrollUp) {
+        if (gestureRecognizer == self.swipeScrollUp) {
             return YES;
-        } else if (gestureRecognizer == _swipeScrollDown) {
+        } else if (gestureRecognizer == self.swipeScrollDown) {
             return YES;
         } else {
             return NO;
@@ -644,13 +648,13 @@ static CGFloat CGPointToPixel(CGFloat point) {
                 // Apple Pencil 2 right click mode
                 if (@available(iOS 12.1, *)) {
                     if (touch.type == UITouchTypePencil) {
-                        primary = !_pencilForceRightClickOnce;
-                        secondary = _pencilForceRightClickOnce;
-                        _pencilForceRightClickOnce = false;
+                        primary = !self.pencilForceRightClickOnce;
+                        secondary = self.pencilForceRightClickOnce;
+                        self.pencilForceRightClickOnce = false;
                     }
                 }
-                [_cursor startMovement:pos];
-                [_cursor updateMovement:pos];
+                [self.cursor startMovement:pos];
+                [self.cursor updateMovement:pos];
                 [self dragCursor:UIGestureRecognizerStateBegan primary:primary secondary:secondary middle:middle];
             }
             break; // handle a single touch only
@@ -665,7 +669,7 @@ static CGFloat CGPointToPixel(CGFloat point) {
     // move cursor in client mode, in server mode we handle in gesturePan
     if (!self.delegate.qemuInputLegacy && !self.vmInput.serverModeCursor) {
         for (UITouch *touch in touches) {
-            [_cursor updateMovement:[touch locationInView:self.mtkView]];
+            [self.cursor updateMovement:[touch locationInView:self.mtkView]];
             break; // handle single touch
         }
     }

+ 7 - 36
Platform/iOS/Display/VMDisplayMetalViewController.h

@@ -16,52 +16,23 @@
 
 #import <UIKit/UIKit.h>
 #import "VMDisplayViewController.h"
+#if defined(WITH_QEMU_TCI)
+@import CocoaSpiceNoUsb;
+#else
+@import CocoaSpice;
+#endif
 
-@class UTMVirtualMachine;
-@class VMCursor;
-@class VMScroll;
 @class VMKeyboardView;
 @class VMKeyboardButton;
-@class GCController;
 
 NS_ASSUME_NONNULL_BEGIN
 
-@interface VMDisplayMetalViewController : VMDisplayViewController {
-    // cursor handling
-    CGPoint _lastTwoPanOrigin;
-    BOOL _mouseLeftDown;
-    BOOL _mouseRightDown;
-    BOOL _mouseMiddleDown;
-    BOOL _pencilForceRightClickOnce;
-    VMCursor *_cursor;
-    VMScroll *_scroll;
-    
-    // Gestures
-    UISwipeGestureRecognizer *_swipeUp;
-    UISwipeGestureRecognizer *_swipeDown;
-    UISwipeGestureRecognizer *_swipeScrollUp;
-    UISwipeGestureRecognizer *_swipeScrollDown;
-    UIPanGestureRecognizer *_pan;
-    UIPanGestureRecognizer *_twoPan;
-    UIPanGestureRecognizer *_threePan;
-    UITapGestureRecognizer *_tap;
-    UITapGestureRecognizer *_tapPencil;
-    UITapGestureRecognizer *_twoTap;
-    UILongPressGestureRecognizer *_longPress;
-    UIPinchGestureRecognizer *_pinch;
-    
-    //Gamepad
-    GCController *_controller;
-    
-    // Feedback generators
-    UISelectionFeedbackGenerator *_clickFeedbackGenerator;
-    UIImpactFeedbackGenerator *_resizeFeedbackGenerator;
-}
+@interface VMDisplayMetalViewController : VMDisplayViewController
 
 @property (strong, nonatomic) IBOutlet UIInputView *inputAccessoryView;
 @property (strong, nonatomic) IBOutletCollection(VMKeyboardButton) NSArray *customKeyModifierButtons;
 
-@property (nonatomic) IBOutlet MTKView *mtkView;
+@property (nonatomic) IBOutlet CSMTKView *mtkView;
 @property (nonatomic) IBOutlet VMKeyboardView *keyboardView;
 
 @property (nonatomic, nullable) CSInput *vmInput;

+ 10 - 1
Platform/iOS/Display/VMDisplayMetalViewController.m

@@ -15,10 +15,13 @@
 //
 
 #import "VMDisplayMetalViewController.h"
+#import "VMDisplayMetalViewController+Private.h"
 #import "VMDisplayMetalViewController+Keyboard.h"
 #import "VMDisplayMetalViewController+Touch.h"
 #import "VMDisplayMetalViewController+Pointer.h"
+#if !defined(TARGET_OS_VISION) || !TARGET_OS_VISION
 #import "VMDisplayMetalViewController+Pencil.h"
+#endif
 #import "VMDisplayMetalViewController+Gamepad.h"
 #import "VMKeyboardView.h"
 #import "UTMLogging.h"
@@ -46,7 +49,7 @@
 - (void)loadView {
     [super loadView];
     self.keyboardView = [[VMKeyboardView alloc] initWithFrame:CGRectZero];
-    self.mtkView = [[MTKView alloc] initWithFrame:CGRectZero];
+    self.mtkView = [[CSMTKView alloc] initWithFrame:CGRectZero];
     self.keyboardView.delegate = self;
     [self.view insertSubview:self.keyboardView atIndex:0];
     [self.view insertSubview:self.mtkView atIndex:1];
@@ -104,10 +107,12 @@
             [self initPointerInteraction];
         }
     }
+#if !defined(TARGET_OS_VISION) || !TARGET_OS_VISION
     // Apple Pencil 2 double tap support on iOS 12.1+
     if (@available(iOS 12.1, *)) {
         [self initPencilInteraction];
     }
+#endif
 }
 
 - (void)viewWillAppear:(BOOL)animated {
@@ -188,11 +193,15 @@
     UTMLog(@"resizing to (%f, %f)", size.width, size.height);
     CGRect bounds = CGRectMake(0, 0, size.width, size.height);
     if (self.delegate.qemuDisplayIsNativeResolution) {
+#if defined(TARGET_OS_VISION) && TARGET_OS_VISION
+        CGFloat scale = 2.0;
+#else
         UIScreen *screen = self.view.window.screen;
         if (screen == nil) {
             screen = UIScreen.mainScreen;
         }
         CGFloat scale = screen.scale;
+#endif
         CGAffineTransform transform = CGAffineTransformMakeScale(scale, scale);
         bounds = CGRectApplyAffineTransform(bounds, transform);
     }

+ 2 - 2
Services/Swift-Bridging-Header.h

@@ -34,10 +34,10 @@
 #if TARGET_OS_IPHONE
 #include "UTMLocationManager.h"
 #include "VMDisplayViewController.h"
-#if !defined(TARGET_OS_VISION) || !TARGET_OS_VISION
+//#if !defined(TARGET_OS_VISION) || !TARGET_OS_VISION
 #include "VMDisplayMetalViewController.h"
 #include "VMDisplayMetalViewController+Keyboard.h"
-#endif
+//#endif
 #include "VMKeyboardButton.h"
 #include "VMKeyboardView.h"
 #elif TARGET_OS_OSX

+ 2 - 0
UTM.xcodeproj/project.pbxproj

@@ -1650,6 +1650,7 @@
 		CEE0421124418F2E0001680F /* UTMLegacyQemuConfiguration+Miscellaneous.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UTMLegacyQemuConfiguration+Miscellaneous.m"; sourceTree = "<group>"; };
 		CEE7E934287CFDB100282049 /* UTMLegacyQemuConfiguration+Constants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UTMLegacyQemuConfiguration+Constants.m"; sourceTree = "<group>"; };
 		CEE7E935287CFDB100282049 /* UTMLegacyQemuConfiguration+Constants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UTMLegacyQemuConfiguration+Constants.h"; sourceTree = "<group>"; };
+		CEE7ED472A90256100E6B4AB /* VMDisplayMetalViewController+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "VMDisplayMetalViewController+Private.h"; sourceTree = "<group>"; };
 		CEEB66442284B942002737B2 /* VMKeyboardButton.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VMKeyboardButton.h; sourceTree = "<group>"; };
 		CEEB66452284B942002737B2 /* VMKeyboardButton.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VMKeyboardButton.m; sourceTree = "<group>"; };
 		CEEC811A24E48EC600ACB0B3 /* SettingsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
@@ -2364,6 +2365,7 @@
 				8401868E288A50B90050AC51 /* VMDisplayViewControllerDelegate.swift */,
 				5286EC93243748C3007E6CBC /* VMDisplayMetalViewController.h */,
 				5286EC94243748C3007E6CBC /* VMDisplayMetalViewController.m */,
+				CEE7ED472A90256100E6B4AB /* VMDisplayMetalViewController+Private.h */,
 				CE3ADD65240EFBCA002D6A5F /* VMDisplayMetalViewController+Keyboard.h */,
 				CE3ADD66240EFBCA002D6A5F /* VMDisplayMetalViewController+Keyboard.m */,
 				CE5076D9250AB55D00C26C19 /* VMDisplayMetalViewController+Pencil.h */,