mirror of
https://github.com/utmapp/UTM.git
synced 2026-10-12 02:24:01 +00:00
In the touch modes the left button goes down the moment a finger lands, because the touch itself is the drag. Every other gesture starts with a finger landing too, so a two finger tap, scroll or pinch first clicked and dragged whatever was under the first finger until the gesture was recognized, and a long press held the left button for half a second before its right click. Add "Touch mode (drag to scroll)" as a third touch mode that behaves like a touch screen and never presses a button on touch down. A tap is a left click, a long press runs the long press action, and dragging one finger scrolls the mouse wheel so that the content follows the finger. Since a touch no longer drags, a long press that moves turns into a left button drag so windows and selections can still be moved with one finger. A ring is shown when the long press is recognized because nothing in the guest reacts until the finger lifts. A finger never lands on the same spot twice, and a guest only counts two clicks on the same spot as a double click, so a second tap that follows quickly and close by clicks where the first one did. The existing touch modes are unchanged. Reworked from #7697. Assisted-by: Claude:claude-fable-5-1
99 lines
3.2 KiB
Objective-C
99 lines
3.2 KiB
Objective-C
//
|
|
// 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>
|
|
#if !defined(WITH_USB)
|
|
@import CocoaSpiceNoUsb;
|
|
#else
|
|
@import CocoaSpice;
|
|
#endif
|
|
|
|
@class VMCursor;
|
|
@class VMScroll;
|
|
@class GCController;
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
|
|
@interface VMDisplayMetalViewController ()
|
|
|
|
@property (nonatomic, nullable) CSMetalRenderer *renderer;
|
|
|
|
// cursor handling
|
|
@property (nonatomic) CGPoint lastTwoPanOrigin;
|
|
@property (nonatomic) CGPoint lastLongPressOrigin;
|
|
@property (nonatomic) CGPoint lastTapLocation;
|
|
@property (nonatomic) NSTimeInterval lastTapTime;
|
|
@property (nonatomic) BOOL isTouchScrolling;
|
|
@property (nonatomic) BOOL mouseLeftDown;
|
|
@property (nonatomic) BOOL mouseRightDown;
|
|
@property (nonatomic) BOOL mouseMiddleDown;
|
|
@property (nonatomic) BOOL mouseSideDown;
|
|
@property (nonatomic) BOOL mouseExtraDown;
|
|
@property (nonatomic) BOOL pencilForceRightClickOnce;
|
|
@property (nonatomic, nullable) VMCursor *cursor;
|
|
@property (nonatomic, nullable) VMScroll *scroll;
|
|
|
|
// Gestures
|
|
@property (nonatomic, nullable) UISwipeGestureRecognizer *swipeUp;
|
|
@property (nonatomic, nullable) UISwipeGestureRecognizer *swipeDown;
|
|
@property (nonatomic, nullable) UISwipeGestureRecognizer *swipeScrollUp;
|
|
@property (nonatomic, nullable) UISwipeGestureRecognizer *swipeScrollDown;
|
|
@property (nonatomic, nullable) UIPanGestureRecognizer *pan;
|
|
@property (nonatomic, nullable) UIPanGestureRecognizer *twoPan;
|
|
@property (nonatomic, nullable) UIPanGestureRecognizer *threePan;
|
|
@property (nonatomic, nullable) UITapGestureRecognizer *tap;
|
|
@property (nonatomic, nullable) UITapGestureRecognizer *tapPencil;
|
|
@property (nonatomic, nullable) UITapGestureRecognizer *twoTap;
|
|
@property (nonatomic, nullable) UILongPressGestureRecognizer *longPress;
|
|
@property (nonatomic, nullable) UIPinchGestureRecognizer *pinch;
|
|
|
|
//Gamepad
|
|
@property (nonatomic, nullable) GCController *controller;
|
|
|
|
#if !defined(TARGET_OS_VISION) || !TARGET_OS_VISION
|
|
// Feedback generators
|
|
@property (nonatomic, nullable) UISelectionFeedbackGenerator *clickFeedbackGenerator;
|
|
#endif
|
|
|
|
@end
|
|
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
static inline CGFloat CGPointToPixel(UIView * _Nonnull view, CGFloat point) {
|
|
#if defined(TARGET_OS_VISION) && TARGET_OS_VISION
|
|
return point * 2.0;
|
|
#else
|
|
UIScreen *screen = view.window.screen;
|
|
if (!screen) {
|
|
screen = [UIScreen mainScreen];
|
|
}
|
|
return point * screen.nativeScale;
|
|
#endif
|
|
}
|
|
|
|
static inline CGFloat CGPixelToPoint(UIView * _Nonnull view, CGFloat pixel) {
|
|
#if defined(TARGET_OS_VISION) && TARGET_OS_VISION
|
|
return pixel / 2.0;
|
|
#else
|
|
UIScreen *screen = view.window.screen;
|
|
if (!screen) {
|
|
screen = [UIScreen mainScreen];
|
|
}
|
|
return pixel / screen.nativeScale;
|
|
#endif
|
|
}
|