Merge pull request #43 from xzzpig/ExternalScreen

Add AirPlay support & Enhanced keyboard and mouse experience
This commit is contained in:
TrueZhuanJia authored and GitHub committed 2024-12-03 21:25:03 +08:00
commit 2b98543125
22 files changed
+801 -51

No files matched your search

+46 -9
View File
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="22505" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES" initialViewController="EVd-wq-ego"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES" initialViewController="EVd-wq-ego">
<device id="ipad11_0rounded" orientation="portrait" layout="fullscreen" appearance="light"/> <device id="ipad11_0rounded" orientation="portrait" layout="fullscreen" appearance="light"/>
<dependencies> <dependencies>
<deployment identifier="iOS"/> <deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22504"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<scenes> <scenes>
@@ -12,7 +12,7 @@
<objects> <objects>
<viewController id="wb7-af-jn8" customClass="MainFrameViewController" sceneMemberID="viewController"> <viewController id="wb7-af-jn8" customClass="MainFrameViewController" sceneMemberID="viewController">
<collectionView key="view" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" indicatorStyle="black" dataMode="prototypes" id="TZj-Lc-M9d" customClass="AppCollectionView"> <collectionView key="view" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" indicatorStyle="black" dataMode="prototypes" id="TZj-Lc-M9d" customClass="AppCollectionView">
<rect key="frame" x="0.0" y="0.0" width="834" height="1120"/> <rect key="frame" x="0.0" y="0.0" width="834" height="1136"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="0.3333333432674408" green="0.3333333432674408" blue="0.3333333432674408" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="backgroundColor" red="0.3333333432674408" green="0.3333333432674408" blue="0.3333333432674408" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="20" minimumInteritemSpacing="20" id="f7l-kG-hJc"> <collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="20" minimumInteritemSpacing="20" id="f7l-kG-hJc">
@@ -547,6 +547,41 @@ ICAgICAgICAgICAgICA
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="External Display Mode" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="4Qy-hB-oa5">
<rect key="frame" x="16" y="1946" width="170" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.93902439019999995" green="0.9625305918" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Mouse Mode" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tAd-bm-2IO">
<rect key="frame" x="16" y="2014" width="99" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.93902439019999995" green="0.9625305918" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<segmentedControl opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="VWB-YB-Ptj" userLabel="External Display Mode">
<rect key="frame" x="15" y="1975" width="459" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<segments>
<segment title="Stage Manager"/>
<segment title="AirPlay"/>
</segments>
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="selectedSegmentTintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</segmentedControl>
<segmentedControl opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="4FU-iP-c6T" userLabel="Mouse Mode">
<rect key="frame" x="15" y="2041" width="459" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<segments>
<segment title="Capture"/>
<segment title="Hidden"/>
<segment title="Visible"/>
</segments>
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="selectedSegmentTintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</segmentedControl>
</subviews> </subviews>
<color key="backgroundColor" systemColor="viewFlipsideBackgroundColor"/> <color key="backgroundColor" systemColor="viewFlipsideBackgroundColor"/>
</view> </view>
@@ -559,6 +594,7 @@ ICAgICAgICAgICAgICA
<outlet property="btMouseSelector" destination="KMg-3j-F9p" id="W45-AB-sJf"/> <outlet property="btMouseSelector" destination="KMg-3j-F9p" id="W45-AB-sJf"/>
<outlet property="cmdToolScreenEdgeSelector" destination="yY7-Sf-Zes" id="fgL-xr-obH"/> <outlet property="cmdToolScreenEdgeSelector" destination="yY7-Sf-Zes" id="fgL-xr-obH"/>
<outlet property="codecSelector" destination="aFy-0w-YPe" id="DlU-0l-gwz"/> <outlet property="codecSelector" destination="aFy-0w-YPe" id="DlU-0l-gwz"/>
<outlet property="externalDisplayModeSelector" destination="VWB-YB-Ptj" id="0ak-pc-evb"/>
<outlet property="framePacingSelector" destination="7va-uJ-IfD" id="Tbv-s2-u2k"/> <outlet property="framePacingSelector" destination="7va-uJ-IfD" id="Tbv-s2-u2k"/>
<outlet property="framerateSelector" destination="lGK-vl-pdw" id="Kc8-Zv-hdm"/> <outlet property="framerateSelector" destination="lGK-vl-pdw" id="Kc8-Zv-hdm"/>
<outlet property="goBackToStreamViewButton" destination="uSS-ev-IFe" id="2MV-Fl-nIz"/> <outlet property="goBackToStreamViewButton" destination="uSS-ev-IFe" id="2MV-Fl-nIz"/>
@@ -567,6 +603,7 @@ ICAgICAgICAgICAgICA
<outlet property="keyboardToggleFingerNumSlider" destination="4wJ-Gd-Dmp" id="fbp-o8-KRA"/> <outlet property="keyboardToggleFingerNumSlider" destination="4wJ-Gd-Dmp" id="fbp-o8-KRA"/>
<outlet property="largerStickLR1Selector" destination="sIU-PH-H7V" id="YWg-40-eKd"/> <outlet property="largerStickLR1Selector" destination="sIU-PH-H7V" id="YWg-40-eKd"/>
<outlet property="liftStreamViewForKeyboardSelector" destination="hm3-EV-h6d" id="fHG-J1-eQL"/> <outlet property="liftStreamViewForKeyboardSelector" destination="hm3-EV-h6d" id="fHG-J1-eQL"/>
<outlet property="mouseModeSelector" destination="4FU-iP-c6T" id="4Gz-ao-xH2"/>
<outlet property="mousePointerVelocityFactorSlider" destination="Ei2-FJ-9oC" id="1T3-QA-Jua"/> <outlet property="mousePointerVelocityFactorSlider" destination="Ei2-FJ-9oC" id="1T3-QA-Jua"/>
<outlet property="mousePointerVelocityFactorUILabel" destination="oPM-G6-u5O" id="Eco-5u-PRR"/> <outlet property="mousePointerVelocityFactorUILabel" destination="oPM-G6-u5O" id="Eco-5u-PRR"/>
<outlet property="multiControllerSelector" destination="KlC-fG-wEi" id="giM-F7-So5"/> <outlet property="multiControllerSelector" destination="KlC-fG-wEi" id="giM-F7-So5"/>
@@ -607,7 +644,7 @@ ICAgICAgICAgICAgICA
<viewControllerLayoutGuide type="bottom" id="YRO-Lg-RCg"/> <viewControllerLayoutGuide type="bottom" id="YRO-Lg-RCg"/>
</layoutGuides> </layoutGuides>
<view key="view" contentMode="scaleToFill" id="hGs-BR-t4b"> <view key="view" contentMode="scaleToFill" id="hGs-BR-t4b">
<rect key="frame" x="0.0" y="0.0" width="834" height="1194"/> <rect key="frame" x="0.0" y="0.0" width="834" height="1210"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view> </view>
@@ -647,7 +684,7 @@ ICAgICAgICAgICAgICA
<viewControllerLayoutGuide type="bottom" id="vu8-3s-HlY"/> <viewControllerLayoutGuide type="bottom" id="vu8-3s-HlY"/>
</layoutGuides> </layoutGuides>
<view key="view" multipleTouchEnabled="YES" contentMode="scaleToFill" id="SMn-1j-R3I"> <view key="view" multipleTouchEnabled="YES" contentMode="scaleToFill" id="SMn-1j-R3I">
<rect key="frame" x="0.0" y="0.0" width="834" height="1194"/> <rect key="frame" x="0.0" y="0.0" width="834" height="1210"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.3333357871" green="0.33332890269999998" blue="0.33333355190000002" alpha="1" colorSpace="custom" customColorSpace="displayP3"/> <color key="backgroundColor" red="0.3333357871" green="0.33332890269999998" blue="0.33333355190000002" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
</view> </view>
@@ -669,7 +706,7 @@ ICAgICAgICAgICAgICA
<viewControllerLayoutGuide type="bottom" id="YZj-An-sqS"/> <viewControllerLayoutGuide type="bottom" id="YZj-An-sqS"/>
</layoutGuides> </layoutGuides>
<view key="view" contentMode="scaleToFill" id="le1-tU-NEp"> <view key="view" contentMode="scaleToFill" id="le1-tU-NEp">
<rect key="frame" x="0.0" y="0.0" width="834" height="1194"/> <rect key="frame" x="0.0" y="0.0" width="834" height="1210"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" animating="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="N0D-dj-EuF"> <activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" animating="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="N0D-dj-EuF">
@@ -696,7 +733,7 @@ ICAgICAgICAgICAgICA
<viewControllerLayoutGuide type="bottom" id="eaS-aj-VtA"/> <viewControllerLayoutGuide type="bottom" id="eaS-aj-VtA"/>
</layoutGuides> </layoutGuides>
<view key="view" opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="Acw-S4-f8a"> <view key="view" opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="Acw-S4-f8a">
<rect key="frame" x="0.0" y="0.0" width="834" height="1194"/> <rect key="frame" x="0.0" y="0.0" width="834" height="1210"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<view alpha="0.75" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fZU-G0-fgM" userLabel="Toolbar Root View" customClass="ToolBarContainerView"> <view alpha="0.75" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fZU-G0-fgM" userLabel="Toolbar Root View" customClass="ToolBarContainerView">
@@ -893,11 +930,11 @@ ICAgICAgICAgICAgICA
<viewControllerLayoutGuide type="bottom" id="8ja-wQ-jbJ"/> <viewControllerLayoutGuide type="bottom" id="8ja-wQ-jbJ"/>
</layoutGuides> </layoutGuides>
<view key="view" contentMode="scaleToFill" id="PlJ-LJ-d1p"> <view key="view" contentMode="scaleToFill" id="PlJ-LJ-d1p">
<rect key="frame" x="0.0" y="0.0" width="834" height="1194"/> <rect key="frame" x="0.0" y="0.0" width="834" height="1210"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<tableView opaque="NO" clearsContextBeforeDrawing="NO" alpha="0.5" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="-1" estimatedSectionHeaderHeight="-1" sectionFooterHeight="-1" estimatedSectionFooterHeight="-1" translatesAutoresizingMaskIntoConstraints="NO" id="BA3-hd-bDp"> <tableView opaque="NO" clearsContextBeforeDrawing="NO" alpha="0.5" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="-1" estimatedSectionHeaderHeight="-1" sectionFooterHeight="-1" estimatedSectionFooterHeight="-1" translatesAutoresizingMaskIntoConstraints="NO" id="BA3-hd-bDp">
<rect key="frame" x="0.0" y="44" width="834" height="1150"/> <rect key="frame" x="0.0" y="44" width="834" height="1166"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</tableView> </tableView>
<navigationBar contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="62V-DN-FUk"> <navigationBar contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="62V-DN-FUk">
+39 -2
View File
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="22505" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES" initialViewController="DL0-L5-LOv"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES" initialViewController="DL0-L5-LOv">
<device id="retina6_1" orientation="portrait" appearance="light"/> <device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies> <dependencies>
<deployment identifier="iOS"/> <deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22504"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/> <capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
@@ -563,6 +563,41 @@ ICAgICAgICAgICAgIA
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="selectedSegmentTintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="selectedSegmentTintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</segmentedControl> </segmentedControl>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="External Display Mode" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="4Qy-hB-oa5">
<rect key="frame" x="20" y="1872" width="181" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<color key="textColor" red="0.93902439019999995" green="0.9625305918" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<segmentedControl opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="VWB-YB-Ptj" userLabel="External Display Mode">
<rect key="frame" x="19" y="1901" width="450" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<segments>
<segment title="Stage Manager"/>
<segment title="AirPlay"/>
</segments>
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="selectedSegmentTintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</segmentedControl>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Mouse Mode" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VGn-Oc-mKc">
<rect key="frame" x="22" y="1940" width="104" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<color key="textColor" red="0.93902439019999995" green="0.9625305918" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<segmentedControl opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="F96-Um-Q6t" userLabel="Mouse Mode">
<rect key="frame" x="19" y="1969" width="450" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<segments>
<segment title="Capture"/>
<segment title="Hidden"/>
<segment title="Visible"/>
</segments>
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="selectedSegmentTintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</segmentedControl>
</subviews> </subviews>
<color key="backgroundColor" red="0.12156862745098039" green="0.12941176470588237" blue="0.14117647058823529" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="backgroundColor" red="0.12156862745098039" green="0.12941176470588237" blue="0.14117647058823529" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view> </view>
@@ -575,6 +610,7 @@ ICAgICAgICAgICAgIA
<outlet property="btMouseSelector" destination="o4O-hO-teB" id="bLu-uv-yUX"/> <outlet property="btMouseSelector" destination="o4O-hO-teB" id="bLu-uv-yUX"/>
<outlet property="cmdToolScreenEdgeSelector" destination="zDR-Ss-JPc" id="cUd-Ot-bZg"/> <outlet property="cmdToolScreenEdgeSelector" destination="zDR-Ss-JPc" id="cUd-Ot-bZg"/>
<outlet property="codecSelector" destination="AbS-CW-fjP" id="ohH-Tc-UzM"/> <outlet property="codecSelector" destination="AbS-CW-fjP" id="ohH-Tc-UzM"/>
<outlet property="externalDisplayModeSelector" destination="VWB-YB-Ptj" id="0ak-pc-evb"/>
<outlet property="framePacingSelector" destination="d2a-Ka-H2c" id="Ocv-3E-lIm"/> <outlet property="framePacingSelector" destination="d2a-Ka-H2c" id="Ocv-3E-lIm"/>
<outlet property="framerateSelector" destination="dLF-qJ-2nY" id="hE3-hk-iwa"/> <outlet property="framerateSelector" destination="dLF-qJ-2nY" id="hE3-hk-iwa"/>
<outlet property="goBackToStreamViewButton" destination="FqF-bM-afQ" id="Xoj-dC-gEa"/> <outlet property="goBackToStreamViewButton" destination="FqF-bM-afQ" id="Xoj-dC-gEa"/>
@@ -583,6 +619,7 @@ ICAgICAgICAgICAgIA
<outlet property="keyboardToggleFingerNumSlider" destination="9rm-7X-TVH" id="SOR-7r-clv"/> <outlet property="keyboardToggleFingerNumSlider" destination="9rm-7X-TVH" id="SOR-7r-clv"/>
<outlet property="largerStickLR1Selector" destination="XbO-CV-orB" id="7vF-xY-n4F"/> <outlet property="largerStickLR1Selector" destination="XbO-CV-orB" id="7vF-xY-n4F"/>
<outlet property="liftStreamViewForKeyboardSelector" destination="pQE-vU-Nr7" id="avO-LL-zes"/> <outlet property="liftStreamViewForKeyboardSelector" destination="pQE-vU-Nr7" id="avO-LL-zes"/>
<outlet property="mouseModeSelector" destination="F96-Um-Q6t" id="Q9r-Wa-ths"/>
<outlet property="mousePointerVelocityFactorSlider" destination="cS3-8R-rEd" id="pcU-fp-Fzg"/> <outlet property="mousePointerVelocityFactorSlider" destination="cS3-8R-rEd" id="pcU-fp-Fzg"/>
<outlet property="mousePointerVelocityFactorUILabel" destination="ecG-dC-PT1" id="MCr-m1-WHm"/> <outlet property="mousePointerVelocityFactorUILabel" destination="ecG-dC-PT1" id="MCr-m1-WHm"/>
<outlet property="multiControllerSelector" destination="OCT-oL-Dqb" id="bLT-gB-FcH"/> <outlet property="multiControllerSelector" destination="OCT-oL-Dqb" id="bLT-gB-FcH"/>
+3 -1
View File
@@ -43,7 +43,9 @@
touchMode:(NSInteger)touchMode touchMode:(NSInteger)touchMode
statsOverlay:(BOOL)statsOverlay statsOverlay:(BOOL)statsOverlay
allowPortrait:(BOOL)allowPortrait allowPortrait:(BOOL)allowPortrait
resolutionSelected:(NSInteger)resolutionSelected; resolutionSelected:(NSInteger)resolutionSelected
externalDisplayMode:(NSInteger)externalDisplayMode
mouseMode:(NSInteger)mouseMode;
- (NSArray*) getHosts; - (NSArray*) getHosts;
- (void) updateHost:(TemporaryHost*)host; - (void) updateHost:(TemporaryHost*)host;
+5 -2
View File
@@ -82,7 +82,9 @@
touchMode:(NSInteger)touchMode touchMode:(NSInteger)touchMode
statsOverlay:(BOOL)statsOverlay statsOverlay:(BOOL)statsOverlay
allowPortrait:(BOOL)allowPortrait allowPortrait:(BOOL)allowPortrait
resolutionSelected:(NSInteger)resolutionSelected { resolutionSelected:(NSInteger)resolutionSelected
externalDisplayMode:(NSInteger)externalDisplayMode
mouseMode:(NSInteger)mouseMode {
[_managedObjectContext performBlockAndWait:^{ [_managedObjectContext performBlockAndWait:^{
Settings* settingsToSave = [self retrieveSettings]; Settings* settingsToSave = [self retrieveSettings];
@@ -117,7 +119,8 @@
settingsToSave.statsOverlay = statsOverlay; settingsToSave.statsOverlay = statsOverlay;
settingsToSave.allowPortrait = allowPortrait; settingsToSave.allowPortrait = allowPortrait;
settingsToSave.resolutionSelected = [NSNumber numberWithInteger:resolutionSelected]; settingsToSave.resolutionSelected = [NSNumber numberWithInteger:resolutionSelected];
settingsToSave.externalDisplayMode = [NSNumber numberWithInteger:externalDisplayMode];
settingsToSave.mouseMode = [NSNumber numberWithInteger:mouseMode];
[self saveData]; [self saveData];
}]; }];
} }
+2
View File
@@ -34,6 +34,8 @@
@property (nonatomic, retain) NSNumber * pointerVelocityModeDivider; @property (nonatomic, retain) NSNumber * pointerVelocityModeDivider;
@property (nonatomic, retain) NSString * uniqueId; @property (nonatomic, retain) NSString * uniqueId;
@property (nonatomic, retain) NSNumber * resolutionSelected; @property (nonatomic, retain) NSNumber * resolutionSelected;
@property (nonatomic, retain) NSNumber * externalDisplayMode;
@property (nonatomic, retain) NSNumber * mouseMode;
@property (nonatomic) enum { @property (nonatomic) enum {
CODEC_PREF_AUTO, CODEC_PREF_AUTO,
CODEC_PREF_H264, CODEC_PREF_H264,
+2
View File
@@ -100,6 +100,8 @@
self.pointerVelocityModeDivider = settings.pointerVelocityModeDivider; self.pointerVelocityModeDivider = settings.pointerVelocityModeDivider;
self.allowPortrait = settings.allowPortrait; self.allowPortrait = settings.allowPortrait;
self.resolutionSelected = settings.resolutionSelected; self.resolutionSelected = settings.resolutionSelected;
self.externalDisplayMode = settings.externalDisplayMode;
self.mouseMode = settings.mouseMode;
#endif #endif
self.uniqueId = settings.uniqueId; self.uniqueId = settings.uniqueId;
+18 -11
View File
@@ -46,6 +46,7 @@ static const double MOUSE_SPEED_DIVISOR = 1.25;
char _controllerNumbers; char _controllerNumbers;
bool _multiController; bool _multiController;
bool _swapABXYButtons; bool _swapABXYButtons;
bool _captureMouse;
} }
// UPDATE_BUTTON_FLAG(controller, flag, pressed) // UPDATE_BUTTON_FLAG(controller, flag, pressed)
@@ -864,20 +865,25 @@ static const double MOUSE_SPEED_DIVISOR = 1.25;
} }
-(void) registerMouseCallbacks:(GCMouse*) mouse API_AVAILABLE(ios(14.0)) { -(void) registerMouseCallbacks:(GCMouse*) mouse API_AVAILABLE(ios(14.0)) {
mouse.mouseInput.mouseMovedHandler = ^(GCMouseInput * _Nonnull mouse, float deltaX, float deltaY) { if (_captureMouse){
self->accumulatedDeltaX += deltaX / MOUSE_SPEED_DIVISOR; mouse.mouseInput.mouseMovedHandler = ^(GCMouseInput * _Nonnull mouse, float deltaX, float deltaY) {
self->accumulatedDeltaY += -deltaY / MOUSE_SPEED_DIVISOR; self->accumulatedDeltaX += deltaX / MOUSE_SPEED_DIVISOR;
self->accumulatedDeltaY += -deltaY / MOUSE_SPEED_DIVISOR;
short truncatedDeltaX = (short)self->accumulatedDeltaX; short truncatedDeltaX = (short)self->accumulatedDeltaX;
short truncatedDeltaY = (short)self->accumulatedDeltaY; short truncatedDeltaY = (short)self->accumulatedDeltaY;
if (truncatedDeltaX != 0 || truncatedDeltaY != 0) { if (truncatedDeltaX != 0 || truncatedDeltaY != 0) {
LiSendMouseMoveEvent(truncatedDeltaX, truncatedDeltaY); LiSendMouseMoveEvent(truncatedDeltaX, truncatedDeltaY);
self->accumulatedDeltaX -= truncatedDeltaX;
self->accumulatedDeltaY -= truncatedDeltaY;
}
};
} else {
mouse.mouseInput.mouseMovedHandler = nil;
}
self->accumulatedDeltaX -= truncatedDeltaX;
self->accumulatedDeltaY -= truncatedDeltaY;
}
};
mouse.mouseInput.leftButton.pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) { mouse.mouseInput.leftButton.pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
LiSendMouseButtonEvent(pressed ? BUTTON_ACTION_PRESS : BUTTON_ACTION_RELEASE, BUTTON_LEFT); LiSendMouseButtonEvent(pressed ? BUTTON_ACTION_PRESS : BUTTON_ACTION_RELEASE, BUTTON_LEFT);
@@ -1120,6 +1126,7 @@ static const double MOUSE_SPEED_DIVISOR = 1.25;
} }
} }
_captureMouse = (streamConfig.mouseMode == 0);
if (@available(iOS 14.0, tvOS 14.0, *)) { if (@available(iOS 14.0, tvOS 14.0, *)) {
for (GCMouse* mouse in [GCMouse mice]) { for (GCMouse* mouse in [GCMouse mice]) {
[self registerMouseCallbacks:mouse]; [self registerMouseCallbacks:mouse];
+3
View File
@@ -248,6 +248,9 @@
case UIKeyboardHIDUsageKeyboardRightAlt: case UIKeyboardHIDUsageKeyboardRightAlt:
keyCode = 0xA5; keyCode = 0xA5;
break; break;
case UIKeyboardHIDUsageKeyboardErrorUndefined:
NSLog(@"Undefined key pressed");
return false;
case 669: // This value corresponds to the "Globe" or "Language" key on most Apple branded iPad keyboards. case 669: // This value corresponds to the "Globe" or "Language" key on most Apple branded iPad keyboards.
keyCode = 0x1B; // This value corresponds to "Escape", which is missing from most Apple branded iPad keyboards. keyCode = 0x1B; // This value corresponds to "Escape", which is missing from most Apple branded iPad keyboards.
break; break;
+4
View File
@@ -15,6 +15,10 @@
- (void) userInteractionBegan; - (void) userInteractionBegan;
- (void) userInteractionEnded; - (void) userInteractionEnded;
- (void) streamExitRequested;
- (void) toggleStatsOverlay;
- (void) toggleMouseCapture;
- (void) toggleMouseVisible;
@end @end
+36 -3
View File
@@ -48,6 +48,8 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
double accumulatedMouseDeltaX; double accumulatedMouseDeltaX;
double accumulatedMouseDeltaY; double accumulatedMouseDeltaY;
int mouseMode;
UIResponder* touchHandler; UIResponder* touchHandler;
id<UserInteractionDelegate> interactionDelegate; id<UserInteractionDelegate> interactionDelegate;
@@ -62,12 +64,15 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
UIHoverGestureRecognizer *stylusHoverRecognizer; UIHoverGestureRecognizer *stylusHoverRecognizer;
#endif #endif
CGFloat HeightViewLiftedTo; CGFloat HeightViewLiftedTo;
UIKeyModifierFlags comboKeyModifierFlags;
} }
- (void) setupStreamView:(ControllerSupport*)controllerSupport - (void) setupStreamView:(ControllerSupport*)controllerSupport
interactionDelegate:(id<UserInteractionDelegate>)interactionDelegate interactionDelegate:(id<UserInteractionDelegate>)interactionDelegate
config:(StreamConfiguration*)streamConfig config:(StreamConfiguration*)streamConfig
streamFrameTopLayerView:(UIView* )topLayerView{ streamFrameTopLayerView:(UIView* )topLayerView{
self->comboKeyModifierFlags = (UIKeyModifierControl|UIKeyModifierAlternate|UIKeyModifierShift);
self->streamFrameTopLayerView = topLayerView; self->streamFrameTopLayerView = topLayerView;
self.streamFrameTopLayerView = topLayerView; // this will be used as a read-only pointer for other class self.streamFrameTopLayerView = topLayerView; // this will be used as a read-only pointer for other class
@@ -76,6 +81,8 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
settings = [[[DataManager alloc] init] getSettings]; settings = [[[DataManager alloc] init] getSettings];
mouseMode = streamConfig.mouseMode;
keysDown = [[NSMutableSet alloc] init]; keysDown = [[NSMutableSet alloc] init];
keyInputField = [[KeyboardInputField alloc] initWithFrame:CGRectZero]; keyInputField = [[KeyboardInputField alloc] initWithFrame:CGRectZero];
[keyInputField setKeyboardType:UIKeyboardTypeDefault]; [keyInputField setKeyboardType:UIKeyboardTypeDefault];
@@ -751,11 +758,34 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
else if(![onScreenControls handleTouchMovedEvent:touches]) [touchHandler touchesMoved:touches withEvent:event]; else if(![onScreenControls handleTouchMovedEvent:touches]) [touchHandler touchesMoved:touches withEvent:event];
} }
- (void) handleKeyCombos:(UIPress*) press{
if(press.key.modifierFlags != comboKeyModifierFlags){
return;
}
switch (press.key.keyCode) {
case UIKeyboardHIDUsageKeyboardQ:
[interactionDelegate streamExitRequested];
break;
case UIKeyboardHIDUsageKeyboardS:
[interactionDelegate toggleStatsOverlay];
break;
case UIKeyboardHIDUsageKeyboardM:
[interactionDelegate toggleMouseCapture];
break;
case UIKeyboardHIDUsageKeyboardC:
[interactionDelegate toggleMouseVisible];
break;
default:
break;
}
}
- (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event { - (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event {
BOOL handled = NO; BOOL handled = NO;
if (@available(iOS 13.4, tvOS 13.4, *)) { if (@available(iOS 13.4, tvOS 13.4, *)) {
for (UIPress* press in presses) { for (UIPress* press in presses) {
[self handleKeyCombos:press];
// For now, we'll treated it as handled if we handle at least one of the // For now, we'll treated it as handled if we handle at least one of the
// UIPress events inside the set. // UIPress events inside the set.
if ([KeyboardSupport sendKeyEventForPress:press down:YES]) { if ([KeyboardSupport sendKeyEventForPress:press down:YES]) {
@@ -869,7 +899,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
regionForRequest:(UIPointerRegionRequest *)request regionForRequest:(UIPointerRegionRequest *)request
defaultRegion:(UIPointerRegion *)defaultRegion API_AVAILABLE(ios(13.4)) { defaultRegion:(UIPointerRegion *)defaultRegion API_AVAILABLE(ios(13.4)) {
if (@available(iOS 14.0, *)) { if (@available(iOS 14.0, *)) {
if ([GCMouse current] != nil) { if ([GCMouse current] != nil && mouseMode == 0) {
// We'll handle this with GCMouse. Do nothing here. // We'll handle this with GCMouse. Do nothing here.
return nil; return nil;
} }
@@ -897,8 +927,11 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5;
} }
- (UIPointerStyle *)pointerInteraction:(UIPointerInteraction *)interaction styleForRegion:(UIPointerRegion *)region API_AVAILABLE(ios(13.4)) { - (UIPointerStyle *)pointerInteraction:(UIPointerInteraction *)interaction styleForRegion:(UIPointerRegion *)region API_AVAILABLE(ios(13.4)) {
// Always hide the mouse cursor over our stream view if(mouseMode != 2){
return [UIPointerStyle hiddenPointerStyle]; return [UIPointerStyle hiddenPointerStyle];
}else{
return nil;
}
} }
- (void)mouseWheelMovedContinuous:(UIPanGestureRecognizer *)gesture { - (void)mouseWheelMovedContinuous:(UIPanGestureRecognizer *)gesture {
+1 -1
View File
@@ -74,7 +74,7 @@
<string>armv7</string> <string>armv7</string>
</array> </array>
<key>UIRequiresFullScreen</key> <key>UIRequiresFullScreen</key>
<true/> <false/>
<key>UIStatusBarHidden</key> <key>UIStatusBarHidden</key>
<true/> <true/>
<key>UISupportedInterfaceOrientations</key> <key>UISupportedInterfaceOrientations</key>
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="22522" systemVersion="22G313" minimumToolsVersion="Xcode 7.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier=""> <model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="23507" systemVersion="24B91" minimumToolsVersion="Xcode 7.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<entity name="App" representedClassName="App" syncable="YES" codeGenerationType="class"> <entity name="App" representedClassName="App" syncable="YES" codeGenerationType="class">
<attribute name="hdrSupported" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/> <attribute name="hdrSupported" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="hidden" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/> <attribute name="hidden" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
@@ -27,11 +27,13 @@
<attribute name="btMouseSupport" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/> <attribute name="btMouseSupport" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="deviceGyroMode" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/> <attribute name="deviceGyroMode" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="enableHdr" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/> <attribute name="enableHdr" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="externalDisplayMode" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="framerate" attributeType="Integer 32" defaultValueString="60" usesScalarValueType="NO" syncable="YES"/> <attribute name="framerate" attributeType="Integer 32" defaultValueString="60" usesScalarValueType="NO" syncable="YES"/>
<attribute name="height" attributeType="Integer 32" defaultValueString="720" usesScalarValueType="NO" syncable="YES"/> <attribute name="height" attributeType="Integer 32" defaultValueString="720" usesScalarValueType="NO" syncable="YES"/>
<attribute name="keyboardToggleFingers" optional="YES" attributeType="Integer 16" defaultValueString="3" usesScalarValueType="NO" syncable="YES"/> <attribute name="keyboardToggleFingers" optional="YES" attributeType="Integer 16" defaultValueString="3" usesScalarValueType="NO" syncable="YES"/>
<attribute name="largerStickLR1" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/> <attribute name="largerStickLR1" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="liftStreamViewForKeyboard" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/> <attribute name="liftStreamViewForKeyboard" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="mouseMode" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="mousePointerVelocityFactor" optional="YES" attributeType="Float" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/> <attribute name="mousePointerVelocityFactor" optional="YES" attributeType="Float" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
<attribute name="multiController" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/> <attribute name="multiController" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES" syncable="YES"/>
<attribute name="onscreenControls" attributeType="Integer 32" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/> <attribute name="onscreenControls" attributeType="Integer 32" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
@@ -27,6 +27,7 @@
<attribute name="btMouseSupport" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/> <attribute name="btMouseSupport" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="deviceGyroMode" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/> <attribute name="deviceGyroMode" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="enableHdr" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/> <attribute name="enableHdr" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES" syncable="YES"/>
<attribute name="externalDisplayMode" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
<attribute name="framerate" attributeType="Integer 32" defaultValueString="60" usesScalarValueType="NO" syncable="YES"/> <attribute name="framerate" attributeType="Integer 32" defaultValueString="60" usesScalarValueType="NO" syncable="YES"/>
<attribute name="height" attributeType="Integer 32" defaultValueString="720" usesScalarValueType="NO" syncable="YES"/> <attribute name="height" attributeType="Integer 32" defaultValueString="720" usesScalarValueType="NO" syncable="YES"/>
<attribute name="keyboardToggleFingers" optional="YES" attributeType="Integer 16" defaultValueString="3" usesScalarValueType="NO" syncable="YES"/> <attribute name="keyboardToggleFingers" optional="YES" attributeType="Integer 16" defaultValueString="3" usesScalarValueType="NO" syncable="YES"/>
+1
View File
@@ -32,5 +32,6 @@
@property BOOL multiController; @property BOOL multiController;
@property BOOL useFramePacing; @property BOOL useFramePacing;
@property NSData* serverCert; @property NSData* serverCert;
@property int mouseMode;
@end @end
+5
View File
@@ -90,6 +90,11 @@ extern int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size,
[self reinitializeDisplayLayer]; [self reinitializeDisplayLayer];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reinitializeDisplayLayer)
name:@"ScreenChanged"
object:nil];
return self; return self;
} }
@@ -18,7 +18,7 @@ static CGFloat screenWidthInPoints;
- (instancetype)initWithTarget:(nullable id)target action:(nullable SEL)action { - (instancetype)initWithTarget:(nullable id)target action:(nullable SEL)action {
self = [super initWithTarget:target action:action]; self = [super initWithTarget:target action:action];
screenWidthInPoints = CGRectGetWidth([[UIScreen mainScreen] bounds]); // Get the screen's bounds (in points) screenWidthInPoints = CGRectGetWidth([UIApplication.sharedApplication.windows.firstObject.screen bounds]); // Get the screen's bounds (in points)
_immediateTriggering = false; _immediateTriggering = false;
_EDGE_TOLERANCE = 15.0f; _EDGE_TOLERANCE = 15.0f;
return self; return self;
@@ -617,6 +617,7 @@ static NSMutableSet* hostList;
} }
- (void) prepareToStreamApp:(TemporaryApp *)app { - (void) prepareToStreamApp:(TemporaryApp *)app {
[self updateResolutionAccordingly];
self.revealViewController.isStreaming = true; // tell the revealViewController streaming is started. self.revealViewController.isStreaming = true; // tell the revealViewController streaming is started.
_streamConfig = [[StreamConfiguration alloc] init]; _streamConfig = [[StreamConfiguration alloc] init];
_streamConfig.host = app.host.activeAddress; _streamConfig.host = app.host.activeAddress;
@@ -634,9 +635,14 @@ static NSMutableSet* hostList;
_streamConfig.frameRate = [streamSettings.framerate intValue]; _streamConfig.frameRate = [streamSettings.framerate intValue];
if (@available(iOS 10.3, *)) { if (@available(iOS 10.3, *)) {
UIWindow *window = UIApplication.sharedApplication.windows.firstObject;
NSInteger maximumFramesPerSecond = window.screen.maximumFramesPerSecond;
if(UIScreen.screens.count > 1 && streamSettings.externalDisplayMode.intValue == 1){ //AirPlaying
maximumFramesPerSecond = UIScreen.screens.lastObject.maximumFramesPerSecond;
}
// Don't stream more FPS than the display can show // Don't stream more FPS than the display can show
if (_streamConfig.frameRate > [UIScreen mainScreen].maximumFramesPerSecond) { if (_streamConfig.frameRate > maximumFramesPerSecond) {
_streamConfig.frameRate = (int)[UIScreen mainScreen].maximumFramesPerSecond; _streamConfig.frameRate = (int)maximumFramesPerSecond;
Log(LOG_W, @"Clamping FPS to maximum refresh rate: %d", _streamConfig.frameRate); Log(LOG_W, @"Clamping FPS to maximum refresh rate: %d", _streamConfig.frameRate);
} }
} }
@@ -664,6 +670,7 @@ static NSMutableSet* hostList;
// multiController must be set before calling getConnectedGamepadMask // multiController must be set before calling getConnectedGamepadMask
_streamConfig.multiController = streamSettings.multiController; _streamConfig.multiController = streamSettings.multiController;
_streamConfig.gamepadMask = [ControllerSupport getConnectedGamepadMask:_streamConfig]; _streamConfig.gamepadMask = [ControllerSupport getConnectedGamepadMask:_streamConfig];
_streamConfig.mouseMode = streamSettings.mouseMode.intValue;
// Probe for supported channel configurations // Probe for supported channel configurations
int physicalOutputChannels = (int)[AVAudioSession sharedInstance].maximumOutputNumberOfChannels; int physicalOutputChannels = (int)[AVAudioSession sharedInstance].maximumOutputNumberOfChannels;
@@ -1171,7 +1178,7 @@ static NSMutableSet* hostList;
//if([SettingsViewController isLandscapeNow] != _streamConfig.width > _streamConfig.height) //if([SettingsViewController isLandscapeNow] != _streamConfig.width > _streamConfig.height)
//[self simulateSettingsButtonPress]; //force expand setting view if orientation changed since last quit from app. //[self simulateSettingsButtonPress]; //force expand setting view if orientation changed since last quit from app.
//[self simulateSettingsButtonPress]; //force expand setting view if orientation changed since last quit from app. //[self simulateSettingsButtonPress]; //force expand setting view if orientation changed since last quit from app.
[self updateResolutionAccordingly]; //[self updateResolutionAccordingly];
// SettingsViewController* settingsViewController = (SettingsViewController*)[self.revealViewController rearViewController]; // SettingsViewController* settingsViewController = (SettingsViewController*)[self.revealViewController rearViewController];
// [settingsViewController updateResolutionTable]; // [settingsViewController updateResolutionTable];
@@ -1219,17 +1226,17 @@ static NSMutableSet* hostList;
} }
// this will also be called back when device orientation changes // this will also be called back when device orientation changes
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator { //- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; // [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
//
double delayInSeconds = 0.7; // double delayInSeconds = 0.7;
// Convert the delay into a dispatch_time_t value // // Convert the delay into a dispatch_time_t value
dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); // dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
// Perform some task after the delay // // Perform some task after the delay
dispatch_after(delayTime, dispatch_get_main_queue(), ^{// Code to execute after the delay // dispatch_after(delayTime, dispatch_get_main_queue(), ^{// Code to execute after the delay
[self updateResolutionAccordingly]; // [self updateResolutionAccordingly];
}); // });
} //}
-(void) updateResolutionAccordingly { -(void) updateResolutionAccordingly {
DataManager* dataMan = [[DataManager alloc] init]; DataManager* dataMan = [[DataManager alloc] init];
@@ -1241,6 +1248,13 @@ static NSMutableSet* hostList;
CGFloat screenWidthInPoints = CGRectGetWidth([[UIScreen mainScreen] bounds]); CGFloat screenWidthInPoints = CGRectGetWidth([[UIScreen mainScreen] bounds]);
CGFloat screenHeightInPoints = CGRectGetHeight([[UIScreen mainScreen] bounds]); CGFloat screenHeightInPoints = CGRectGetHeight([[UIScreen mainScreen] bounds]);
if(currentSettings.externalDisplayMode.intValue == 1 && UIScreen.screens.count > 1){
CGRect bounds = [UIScreen.screens.lastObject bounds];
screenScale = [UIScreen.screens.lastObject scale];
appWindowWidth = bounds.size.width * screenScale;
appWindowHeight = bounds.size.height * screenScale;
}
bool needSwap = false; bool needSwap = false;
if([self isFullScreenRequired]){ // if force fullscreen is enabled in app bundle, we use screen bounds to tell if a swap between width & height is needed if([self isFullScreenRequired]){ // if force fullscreen is enabled in app bundle, we use screen bounds to tell if a swap between width & height is needed
@@ -1398,7 +1412,7 @@ static NSMutableSet* hostList;
object: nil]; object: nil];
//[self simulateSettingsButtonPress]; //force reload resolution table in the setting //[self simulateSettingsButtonPress]; //force reload resolution table in the setting
//[self simulateSettingsButtonPress]; //[self simulateSettingsButtonPress];
[self updateResolutionAccordingly]; //[self updateResolutionAccordingly];
} }
@@ -57,6 +57,8 @@
@property (strong, nonatomic) LayoutOnScreenControlsViewController *layoutOnScreenControlsVC; @property (strong, nonatomic) LayoutOnScreenControlsViewController *layoutOnScreenControlsVC;
@property (nonatomic, strong) MainFrameViewController *mainFrameViewController; @property (nonatomic, strong) MainFrameViewController *mainFrameViewController;
@property (strong, nonatomic) IBOutlet UISegmentedControl *externalDisplayModeSelector;
@property (strong, nonatomic) IBOutlet UISegmentedControl *mouseModeSelector;
#pragma clang diagnostic push #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability" #pragma clang diagnostic ignored "-Wunguarded-availability"
@@ -222,6 +222,9 @@ BOOL isCustomResolution(CGSize res) {
return true; return true;
} }
- (bool)isAirPlayEnabled{
return [self.externalDisplayModeSelector selectedSegmentIndex] == 1;
}
- (void)updateResolutionTable{ - (void)updateResolutionTable{
UIWindow *window = UIApplication.sharedApplication.windows.firstObject; UIWindow *window = UIApplication.sharedApplication.windows.firstObject;
@@ -229,6 +232,12 @@ BOOL isCustomResolution(CGSize res) {
CGFloat safeAreaWidth = (window.frame.size.width - window.safeAreaInsets.left - window.safeAreaInsets.right) * screenScale; CGFloat safeAreaWidth = (window.frame.size.width - window.safeAreaInsets.left - window.safeAreaInsets.right) * screenScale;
CGFloat appWindowWidth = window.frame.size.width * screenScale; CGFloat appWindowWidth = window.frame.size.width * screenScale;
CGFloat appWindowHeight = window.frame.size.height * screenScale; CGFloat appWindowHeight = window.frame.size.height * screenScale;
if([self isAirPlayEnabled] && UIScreen.screens.count > 1){
CGRect bounds = [UIScreen.screens.lastObject bounds];
screenScale = [UIScreen.screens.lastObject scale];
appWindowWidth = bounds.size.width * screenScale;
appWindowHeight = bounds.size.height * screenScale;
}
bool needSwapWidthAndHeight = appWindowWidth > appWindowHeight; bool needSwapWidthAndHeight = appWindowWidth > appWindowHeight;
resolutionTable[4] = CGSizeMake(safeAreaWidth, appWindowHeight); resolutionTable[4] = CGSizeMake(safeAreaWidth, appWindowHeight);
@@ -248,7 +257,7 @@ BOOL isCustomResolution(CGSize res) {
// this will also be called back when device orientation changes // this will also be called back when device orientation changes
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator { - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
double delayInSeconds = 1.0; double delayInSeconds = 0.2;
// Convert the delay into a dispatch_time_t value // Convert the delay into a dispatch_time_t value
dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
// Perform some task after the delay // Perform some task after the delay
@@ -549,6 +558,9 @@ BOOL isCustomResolution(CGSize res) {
self.layoutOnScreenControlsVC = [storyboard instantiateViewControllerWithIdentifier:@"LayoutOnScreenControlsViewController"]; self.layoutOnScreenControlsVC = [storyboard instantiateViewControllerWithIdentifier:@"LayoutOnScreenControlsViewController"];
self.layoutOnScreenControlsVC.modalPresentationStyle = UIModalPresentationFullScreen; self.layoutOnScreenControlsVC.modalPresentationStyle = UIModalPresentationFullScreen;
} }
[self.externalDisplayModeSelector setSelectedSegmentIndex:currentSettings.externalDisplayMode.integerValue];
[self.mouseModeSelector setSelectedSegmentIndex:currentSettings.mouseMode.integerValue];
} }
- (void)slideToSettingsScreenEdgeChanged{ - (void)slideToSettingsScreenEdgeChanged{
@@ -1055,6 +1067,8 @@ BOOL isCustomResolution(CGSize res) {
BOOL enableHdr = [self.hdrSelector selectedSegmentIndex] == 1; BOOL enableHdr = [self.hdrSelector selectedSegmentIndex] == 1;
BOOL allowPortrait = [self.allowPortraitSelector selectedSegmentIndex] == 1; BOOL allowPortrait = [self.allowPortraitSelector selectedSegmentIndex] == 1;
NSInteger resolutionSelected = [self.resolutionSelector selectedSegmentIndex]; NSInteger resolutionSelected = [self.resolutionSelector selectedSegmentIndex];
NSInteger externalDisplayMode = [self.externalDisplayModeSelector selectedSegmentIndex];
NSInteger mouseMode = [self.mouseModeSelector selectedSegmentIndex];
[dataMan saveSettingsWithBitrate:_bitrate [dataMan saveSettingsWithBitrate:_bitrate
framerate:framerate framerate:framerate
height:height height:height
@@ -1085,7 +1099,9 @@ BOOL isCustomResolution(CGSize res) {
touchMode:touchMode touchMode:touchMode
statsOverlay:statsOverlay statsOverlay:statsOverlay
allowPortrait:allowPortrait allowPortrait:allowPortrait
resolutionSelected:resolutionSelected]; resolutionSelected:resolutionSelected
externalDisplayMode:externalDisplayMode
mouseMode:mouseMode];
} }
- (void)didReceiveMemoryWarning { - (void)didReceiveMemoryWarning {
@@ -54,6 +54,10 @@
UIScrollView *_scrollView; UIScrollView *_scrollView;
BOOL _userIsInteracting; BOOL _userIsInteracting;
CGSize _keyboardSize; CGSize _keyboardSize;
UIWindow *_extWindow;
UIView *_renderView;
UIWindow *_deviceWindow;
dispatch_block_t _delayedRemoveExtScreen;
#if !TARGET_OS_TV #if !TARGET_OS_TV
CustomEdgeSlideGestureRecognizer *_slideToSettingsRecognizer; CustomEdgeSlideGestureRecognizer *_slideToSettingsRecognizer;
CustomEdgeSlideGestureRecognizer *_slideToCmdToolRecognizer; CustomEdgeSlideGestureRecognizer *_slideToCmdToolRecognizer;
@@ -162,6 +166,9 @@
[self->_streamView reloadOnScreenControlsRealtimeWith:(ControllerSupport*)_controllerSupport [self->_streamView reloadOnScreenControlsRealtimeWith:(ControllerSupport*)_controllerSupport
andConfig:(StreamConfiguration*)_streamConfig]; //reload OSC here. andConfig:(StreamConfiguration*)_streamConfig]; //reload OSC here.
[self->_streamView reloadOnScreenButtonViews]; //reload keyboard buttons here. the keyboard button view will be added to the streamframe view instead streamview, the highest layer, which saves a lot of reengineering [self->_streamView reloadOnScreenButtonViews]; //reload keyboard buttons here. the keyboard button view will be added to the streamframe view instead streamview, the highest layer, which saves a lot of reengineering
[self reloadAirPlayConfig];
[self mousePresenceChanged];
//reconfig statsOverlay //reconfig statsOverlay
self->_statsUpdateTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f self->_statsUpdateTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f
target:self target:self
@@ -180,6 +187,29 @@
{ {
[super viewDidAppear:animated]; [super viewDidAppear:animated];
_deviceWindow = self.view.window;
if (UIScreen.screens.count > 1 && [self isAirPlayEnabled]) {
[self prepExtScreen:UIScreen.screens.lastObject];
}
else {
dispatch_async(dispatch_get_main_queue(), ^{
[self.view insertSubview:self->_renderView atIndex:0];
});
}
// check to see if external screen is connected/disconnected
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(extScreenDidConnect:)
name: UIScreenDidConnectNotification
object: nil];
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(extScreenDidDisconnect:)
name: UIScreenDidDisconnectNotification
object: nil];
#if !TARGET_OS_TV #if !TARGET_OS_TV
[[self revealViewController] setPrimaryViewController:self]; [[self revealViewController] setPrimaryViewController:self];
[[NSNotificationCenter defaultCenter] addObserver:self [[NSNotificationCenter defaultCenter] addObserver:self
@@ -239,7 +269,9 @@
_controllerSupport = [[ControllerSupport alloc] initWithConfig:self.streamConfig delegate:self]; _controllerSupport = [[ControllerSupport alloc] initWithConfig:self.streamConfig delegate:self];
_inactivityTimer = nil; _inactivityTimer = nil;
_renderView = (StreamView*)[[UIView alloc] initWithFrame:self.view.frame];
_streamView = [[StreamView alloc] initWithFrame:self.view.frame]; _streamView = [[StreamView alloc] initWithFrame:self.view.frame];
_renderView.bounds = _streamView.bounds;
//[_streamView setupStreamView:_controllerSupport interactionDelegate:self config:self.streamConfig]; //[_streamView setupStreamView:_controllerSupport interactionDelegate:self config:self.streamConfig];
[self reConfigStreamViewRealtime]; // call this method again to make sure all gestures are configured & added to the superview(self.view), including the gestures added from inside the streamview. [self reConfigStreamViewRealtime]; // call this method again to make sure all gestures are configured & added to the superview(self.view), including the gestures added from inside the streamview.
@@ -281,7 +313,7 @@
_tipLabel.center = CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height * 0.9); _tipLabel.center = CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height * 0.9);
_streamMan = [[StreamManager alloc] initWithConfig:self.streamConfig _streamMan = [[StreamManager alloc] initWithConfig:self.streamConfig
renderView:_streamView renderView:_renderView
connectionCallbacks:self]; connectionCallbacks:self];
NSOperationQueue* opQueue = [[NSOperationQueue alloc] init]; NSOperationQueue* opQueue = [[NSOperationQueue alloc] init];
[opQueue addOperation:_streamMan]; [opQueue addOperation:_streamMan];
@@ -449,8 +481,86 @@
_statsUpdateTimer = nil; _statsUpdateTimer = nil;
[self.navigationController popToRootViewControllerAnimated:YES]; [self.navigationController popToRootViewControllerAnimated:YES];
_extWindow = nil;
} }
// External Screen connected
- (void)extScreenDidConnect:(NSNotification *)notification {
Log(LOG_I, @"External Screen Connected");
dispatch_async(dispatch_get_main_queue(), ^{
[self prepExtScreen:notification.object];
});
}
// External Screen disconnected
- (void)extScreenDidDisconnect:(NSNotification *)notification {
Log(LOG_I, @"External Screen Disconnected");
if(UIScreen.screens.count < 2)
{
dispatch_async(dispatch_get_main_queue(), ^{
[self removeExtScreen];
});
}
}
- (BOOL) isAirPlaying{
return _extWindow != nil && _extWindow.hidden == NO;
}
- (BOOL) isAirPlayEnabled{
return _settings.externalDisplayMode.intValue == 1;
}
- (void) reloadAirPlayConfig{
if (UIScreen.screens.count == 1){return;}
if (![self isAirPlaying] && [self isAirPlayEnabled]){
[self prepExtScreen:UIScreen.screens.lastObject];
}else if ([self isAirPlaying] && ![self isAirPlayEnabled]){
[self removeExtScreen];
}
}
// Prepare Screen
- (void)prepExtScreen:(UIScreen*)extScreen {
Log(LOG_I, @"Preparing External Screen");
if(![self isAirPlayEnabled]){
return;
}
CGRect frame = extScreen.bounds;
extScreen.overscanCompensation = UIScreenOverscanCompensationNone;
if(_extWindow==nil){
_extWindow = [[UIWindow alloc] initWithFrame:frame];
}
_extWindow.screen = extScreen;
_renderView.bounds = frame;
_renderView.frame = frame;
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
[nc postNotificationName:@"ScreenChanged" object:self];
[_extWindow addSubview:_renderView];
_extWindow.hidden = NO;
}
- (void)removeExtScreen {
Log(LOG_I, @"Removing External Screen");
_extWindow.hidden = YES;
[self handleViewResize];
[self.view insertSubview:_renderView atIndex:0];
}
- (void) handleViewResize{
_streamView.bounds = _deviceWindow.bounds;
_streamView.frame = _deviceWindow.frame;
if(![self isAirPlaying]){
_renderView.bounds = _deviceWindow.bounds;
_renderView.frame = _deviceWindow.frame;
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
[nc postNotificationName:@"ScreenChanged" object:self];
}
[self reConfigStreamViewRealtime];
}
// This will fire if the user opens control center or gets a low battery message // This will fire if the user opens control center or gets a low battery message
- (void)applicationWillResignActive:(NSNotification *)notification { - (void)applicationWillResignActive:(NSNotification *)notification {
if (_inactivityTimer != nil) { if (_inactivityTimer != nil) {
@@ -523,6 +633,7 @@
// the first frame of video. // the first frame of video.
self->_stageLabel.hidden = YES; self->_stageLabel.hidden = YES;
self->_tipLabel.hidden = YES; self->_tipLabel.hidden = YES;
self->_spinner.hidden = YES;
[self->_streamView showOnScreenControls]; [self->_streamView showOnScreenControls];
@@ -825,6 +936,44 @@
#endif #endif
} }
- (void)toggleStatsOverlay{
DataManager* dataMan = [[DataManager alloc] init];
Settings *currentSettings = [dataMan retrieveSettings];
currentSettings.statsOverlay = !currentSettings.statsOverlay;
[dataMan saveData];
[self reConfigStreamViewRealtime];
}
- (void)toggleMouseCapture{
DataManager* dataMan = [[DataManager alloc] init];
Settings *currentSettings = [dataMan retrieveSettings];
if(currentSettings.mouseMode.intValue == 0){
currentSettings.mouseMode = @1;
}else{
currentSettings.mouseMode = @0;
}
[dataMan saveData];
[self reConfigStreamViewRealtime];
}
- (void)toggleMouseVisible{
DataManager* dataMan = [[DataManager alloc] init];
Settings *currentSettings = [dataMan retrieveSettings];
if(currentSettings.mouseMode.intValue == 2){
currentSettings.mouseMode = @1;
}else{
currentSettings.mouseMode = @2;
}
[dataMan saveData];
[self reConfigStreamViewRealtime];
}
#if !TARGET_OS_TV #if !TARGET_OS_TV
// Require a confirmation when streaming to activate a system gesture // Require a confirmation when streaming to activate a system gesture
- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures { - (UIRectEdge)preferredScreenEdgesDeferringSystemGestures {
@@ -856,7 +1005,7 @@
// Pointer lock breaks the UIKit mouse APIs, which is a problem because // Pointer lock breaks the UIKit mouse APIs, which is a problem because
// GCMouse is horribly broken on iOS 14.0 for certain mice. Only lock // GCMouse is horribly broken on iOS 14.0 for certain mice. Only lock
// the cursor if there is a GCMouse present. // the cursor if there is a GCMouse present.
return [GCMouse mice].count > 0; return ([GCMouse mice].count > 0) && [_settings mouseMode].intValue == 0;
} }
#endif #endif
@@ -864,7 +1013,17 @@
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
Log(LOG_I, @"View size changed, terminating stream"); Log(LOG_I, @"View size changed, terminating stream");
// [self returnToMainFrame];
double delayInSeconds = 0.2;
if (_delayedRemoveExtScreen) {
dispatch_block_cancel(_delayedRemoveExtScreen);
}
dispatch_block_t block = dispatch_block_create(0, ^{
[self handleViewResize];
});
_delayedRemoveExtScreen = block;
dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(delayTime, dispatch_get_main_queue(), block);
} }
@end @end
+210
View File
@@ -91,6 +91,126 @@
} }
} }
}, },
"4FU-iP-c6T.segmentTitles[0]" : {
"comment" : "Class = \"UISegmentedControl\"; 4FU-iP-c6T.segmentTitles[0] = \"Capture\"; ObjectID = \"4FU-iP-c6T\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Capture"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "捕获"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "捕获"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "捕获"
}
}
}
},
"4FU-iP-c6T.segmentTitles[1]" : {
"comment" : "Class = \"UISegmentedControl\"; 4FU-iP-c6T.segmentTitles[1] = \"Hidden\"; ObjectID = \"4FU-iP-c6T\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Hidden"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "隐藏"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "隐藏"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "隐藏"
}
}
}
},
"4FU-iP-c6T.segmentTitles[2]" : {
"comment" : "Class = \"UISegmentedControl\"; 4FU-iP-c6T.segmentTitles[2] = \"Visible\"; ObjectID = \"4FU-iP-c6T\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Visible"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "可见"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "可见"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "可见"
}
}
}
},
"4Qy-hB-oa5.text" : {
"comment" : "Class = \"UILabel\"; text = \"External Display Mode\"; ObjectID = \"4Qy-hB-oa5\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "External Display Mode"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "外接显示模式"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "外接显示模式"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "外接显示模式"
}
}
}
},
"6w5-Md-NpV.text" : { "6w5-Md-NpV.text" : {
"comment" : "Class = \"UILabel\"; text = \"Preferred Codec \"; ObjectID = \"6w5-Md-NpV\";", "comment" : "Class = \"UILabel\"; text = \"Preferred Codec \"; ObjectID = \"6w5-Md-NpV\";",
"extractionState" : "extracted_with_value", "extractionState" : "extracted_with_value",
@@ -2137,6 +2257,36 @@
} }
} }
}, },
"tAd-bm-2IO.text" : {
"comment" : "Class = \"UILabel\"; text = \"Mouse Mode\"; ObjectID = \"tAd-bm-2IO\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Mouse Mode"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "鼠标模式"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "鼠标模式"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "鼠标模式"
}
}
}
},
"uSS-ev-IFe.configuration.title" : { "uSS-ev-IFe.configuration.title" : {
"comment" : "Class = \"UIButton\"; configuration.title = \"Go Back to Stream View\"; ObjectID = \"uSS-ev-IFe\";", "comment" : "Class = \"UIButton\"; configuration.title = \"Go Back to Stream View\"; ObjectID = \"uSS-ev-IFe\";",
"extractionState" : "extracted_with_value", "extractionState" : "extracted_with_value",
@@ -2191,6 +2341,66 @@
} }
} }
}, },
"VWB-YB-Ptj.segmentTitles[0]" : {
"comment" : "Class = \"UISegmentedControl\"; VWB-YB-Ptj.segmentTitles[0] = \"Stage Manager\"; ObjectID = \"VWB-YB-Ptj\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Stage Manager"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "台前调度"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "台前调度"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "台前调度"
}
}
}
},
"VWB-YB-Ptj.segmentTitles[1]" : {
"comment" : "Class = \"UISegmentedControl\"; VWB-YB-Ptj.segmentTitles[1] = \"AirPlay\"; ObjectID = \"VWB-YB-Ptj\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "AirPlay"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "隔空播放"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "隔空播放"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "隔空播放"
}
}
}
},
"WDY-9o-6Hb.segmentTitles[0]" : { "WDY-9o-6Hb.segmentTitles[0]" : {
"comment" : "Class = \"UISegmentedControl\"; WDY-9o-6Hb.segmentTitles[0] = \"No\"; ObjectID = \"WDY-9o-6Hb\";", "comment" : "Class = \"UISegmentedControl\"; WDY-9o-6Hb.segmentTitles[0] = \"No\"; ObjectID = \"WDY-9o-6Hb\";",
"extractionState" : "extracted_with_value", "extractionState" : "extracted_with_value",
+210
View File
@@ -271,6 +271,36 @@
} }
} }
}, },
"4Qy-hB-oa5.text" : {
"comment" : "Class = \"UILabel\"; text = \"External Display Mode\"; ObjectID = \"4Qy-hB-oa5\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "External Display Mode"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "外接显示模式"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "外接显示模式"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "外接显示模式"
}
}
}
},
"5pN-Sn-SCN.title" : { "5pN-Sn-SCN.title" : {
"comment" : "Class = \"UINavigationItem\"; title = \"Controller & Button Profiles\"; ObjectID = \"5pN-Sn-SCN\";", "comment" : "Class = \"UINavigationItem\"; title = \"Controller & Button Profiles\"; ObjectID = \"5pN-Sn-SCN\";",
"extractionState" : "extracted_with_value", "extractionState" : "extracted_with_value",
@@ -931,6 +961,96 @@
} }
} }
}, },
"F96-Um-Q6t.segmentTitles[0]" : {
"comment" : "Class = \"UISegmentedControl\"; F96-Um-Q6t.segmentTitles[0] = \"Capture\"; ObjectID = \"F96-Um-Q6t\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Capture"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "捕获"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "捕获"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "捕获"
}
}
}
},
"F96-Um-Q6t.segmentTitles[1]" : {
"comment" : "Class = \"UISegmentedControl\"; F96-Um-Q6t.segmentTitles[1] = \"Hidden\"; ObjectID = \"F96-Um-Q6t\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Hidden"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "隐藏"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "隐藏"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "隐藏"
}
}
}
},
"F96-Um-Q6t.segmentTitles[2]" : {
"comment" : "Class = \"UISegmentedControl\"; F96-Um-Q6t.segmentTitles[2] = \"Visible\"; ObjectID = \"F96-Um-Q6t\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Visible"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "可见"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "可见"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "可见"
}
}
}
},
"FqF-bM-afQ.configuration.title" : { "FqF-bM-afQ.configuration.title" : {
"comment" : "Class = \"UIButton\"; configuration.title = \"Go Back to Stream View\"; ObjectID = \"FqF-bM-afQ\";", "comment" : "Class = \"UIButton\"; configuration.title = \"Go Back to Stream View\"; ObjectID = \"FqF-bM-afQ\";",
"extractionState" : "extracted_with_value", "extractionState" : "extracted_with_value",
@@ -1999,6 +2119,36 @@
} }
} }
}, },
"VGn-Oc-mKc.text" : {
"comment" : "Class = \"UILabel\"; text = \"Mouse Mode\"; ObjectID = \"VGn-Oc-mKc\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Mouse Mode"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "鼠标模式"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "鼠标模式"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "鼠标模式"
}
}
}
},
"VlN-ZW-1gm.text" : { "VlN-ZW-1gm.text" : {
"comment" : "Class = \"UILabel\"; text = \"Touch Pointer Velocity: Scaled on 0% of Right Screen \"; ObjectID = \"VlN-ZW-1gm\";", "comment" : "Class = \"UILabel\"; text = \"Touch Pointer Velocity: Scaled on 0% of Right Screen \"; ObjectID = \"VlN-ZW-1gm\";",
"extractionState" : "extracted_with_value", "extractionState" : "extracted_with_value",
@@ -2011,6 +2161,66 @@
} }
} }
}, },
"VWB-YB-Ptj.segmentTitles[0]" : {
"comment" : "Class = \"UISegmentedControl\"; VWB-YB-Ptj.segmentTitles[0] = \"Stage Manager\"; ObjectID = \"VWB-YB-Ptj\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "Stage Manager"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "台前调度"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "台前调度"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "台前调度"
}
}
}
},
"VWB-YB-Ptj.segmentTitles[1]" : {
"comment" : "Class = \"UISegmentedControl\"; VWB-YB-Ptj.segmentTitles[1] = \"AirPlay\"; ObjectID = \"VWB-YB-Ptj\";",
"extractionState" : "extracted_with_value",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "new",
"value" : "AirPlay"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "隔空播放"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "隔空播放"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "隔空播放"
}
}
}
},
"WGf-9d-eAm.segmentTitles[0]" : { "WGf-9d-eAm.segmentTitles[0]" : {
"comment" : "Class = \"UISegmentedControl\"; WGf-9d-eAm.segmentTitles[0] = \"Off\"; ObjectID = \"WGf-9d-eAm\";", "comment" : "Class = \"UISegmentedControl\"; WGf-9d-eAm.segmentTitles[0] = \"Off\"; ObjectID = \"WGf-9d-eAm\";",
"extractionState" : "extracted_with_value", "extractionState" : "extracted_with_value",