1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-04-08 08:43:42 +00:00

Merge pull request #1497 from TomHarte/LargeWindowMousing

Correct potential SCSI crash; tweak macOS mouse behaviour.
This commit is contained in:
Thomas Harte 2025-03-18 21:46:41 -04:00 committed by GitHub
commit 966b41313d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 72 additions and 48 deletions

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="19162" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="23504" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="19162"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23504"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -13,7 +13,7 @@
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<visualEffectView hidden="YES" wantsLayer="YES" appearanceType="vibrantDark" blendingMode="withinWindow" material="HUDWindow" state="followsWindowActiveState" translatesAutoresizingMaskIntoConstraints="NO" id="tpZ-0B-QQu">
<visualEffectView hidden="YES" wantsLayer="YES" focusRingType="none" appearanceType="vibrantDark" blendingMode="withinWindow" material="HUDWindow" state="followsWindowActiveState" translatesAutoresizingMaskIntoConstraints="NO" id="tpZ-0B-QQu">
<rect key="frame" x="0.0" y="0.0" width="200" height="261"/>
<subviews>
<levelIndicator verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ySY-ir-hzb" userLabel="First indicator">
@ -23,7 +23,7 @@
</constraints>
<levelIndicatorCell key="cell" alignment="left" maxValue="1" warningValue="2" criticalValue="2" levelIndicatorStyle="continuousCapacity" id="DhQ-Di-tRT"/>
</levelIndicator>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Tah-UQ-vdf">
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Tah-UQ-vdf">
<rect key="frame" x="30" y="237" width="59" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Activity 1" id="a5P-Ci-RzC">
<font key="font" metaFont="system"/>
@ -38,7 +38,7 @@
</constraints>
<levelIndicatorCell key="cell" alignment="left" maxValue="1" warningValue="2" criticalValue="2" levelIndicatorStyle="continuousCapacity" id="jlb-bk-FPd"/>
</levelIndicator>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="14O-Lq-Npx">
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="14O-Lq-Npx">
<rect key="frame" x="30" y="213" width="61" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Activity 2" id="NE1-CO-pGI">
<font key="font" metaFont="system"/>
@ -53,7 +53,7 @@
</constraints>
<levelIndicatorCell key="cell" alignment="left" maxValue="1" warningValue="2" criticalValue="2" levelIndicatorStyle="continuousCapacity" id="CJy-Jn-eCL"/>
</levelIndicator>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Acy-tT-OFH">
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Acy-tT-OFH">
<rect key="frame" x="30" y="189" width="61" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Activity 3" id="FSR-y6-7WE">
<font key="font" metaFont="system"/>
@ -68,7 +68,7 @@
</constraints>
<levelIndicatorCell key="cell" alignment="left" maxValue="1" warningValue="2" criticalValue="2" levelIndicatorStyle="continuousCapacity" id="eoN-hl-30l"/>
</levelIndicator>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="R0g-Oa-VB5">
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="R0g-Oa-VB5">
<rect key="frame" x="30" y="165" width="62" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Activity 4" id="aGr-cd-jC0">
<font key="font" metaFont="system"/>
@ -79,11 +79,12 @@
<levelIndicator verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="pn9-7S-9kS" userLabel="Fourth indicator">
<rect key="frame" x="8" y="139" width="16" height="18"/>
<constraints>
<constraint firstAttribute="width" secondItem="pn9-7S-9kS" secondAttribute="height" multiplier="1:1" id="7f0-Op-CDm"/>
<constraint firstAttribute="width" secondItem="pn9-7S-9kS" secondAttribute="height" multiplier="1:1" id="yUR-uX-jII"/>
</constraints>
<levelIndicatorCell key="cell" alignment="left" maxValue="1" warningValue="2" criticalValue="2" levelIndicatorStyle="continuousCapacity" id="iCv-RT-Jg8"/>
</levelIndicator>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="nDC-Fi-3fv">
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="nDC-Fi-3fv">
<rect key="frame" x="30" y="141" width="61" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Activity 5" id="b74-7q-OOK">
<font key="font" metaFont="system"/>
@ -94,11 +95,13 @@
<levelIndicator verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Bf9-wO-fc9" userLabel="Fourth indicator">
<rect key="frame" x="8" y="115" width="16" height="18"/>
<constraints>
<constraint firstAttribute="width" secondItem="Bf9-wO-fc9" secondAttribute="height" multiplier="1:1" id="DT1-FT-Ilb"/>
<constraint firstAttribute="width" secondItem="Bf9-wO-fc9" secondAttribute="height" multiplier="1:1" id="K3C-ua-qwN"/>
<constraint firstAttribute="width" secondItem="Bf9-wO-fc9" secondAttribute="height" multiplier="1:1" id="WOL-cc-xiX"/>
</constraints>
<levelIndicatorCell key="cell" alignment="left" maxValue="1" warningValue="2" criticalValue="2" levelIndicatorStyle="continuousCapacity" id="NyB-3g-1td"/>
</levelIndicator>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="DMC-js-ACH">
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="DMC-js-ACH">
<rect key="frame" x="30" y="117" width="61" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Activity 6" id="X6z-Td-IZP">
<font key="font" metaFont="system"/>
@ -110,10 +113,12 @@
<rect key="frame" x="8" y="91" width="16" height="18"/>
<constraints>
<constraint firstAttribute="width" secondItem="BEi-xM-JeY" secondAttribute="height" multiplier="1:1" id="OrY-a0-81h"/>
<constraint firstAttribute="width" secondItem="BEi-xM-JeY" secondAttribute="height" multiplier="1:1" id="RNt-qR-jIr"/>
<constraint firstAttribute="width" secondItem="BEi-xM-JeY" secondAttribute="height" multiplier="1:1" id="f23-rG-rct"/>
</constraints>
<levelIndicatorCell key="cell" alignment="left" maxValue="1" warningValue="2" criticalValue="2" levelIndicatorStyle="continuousCapacity" id="ZWa-VF-jLa"/>
</levelIndicator>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Q3c-5Q-sZh">
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Q3c-5Q-sZh">
<rect key="frame" x="30" y="93" width="61" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Activity 7" id="3MD-ZQ-jTk">
<font key="font" metaFont="system"/>
@ -121,7 +126,7 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="6ff-xA-HJ2">
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="6ff-xA-HJ2">
<rect key="frame" x="30" y="69" width="61" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Activity 8" id="5EX-Qj-ovC">
<font key="font" metaFont="system"/>
@ -132,6 +137,8 @@
<levelIndicator verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Nnc-64-Nyi" userLabel="Fourth indicator">
<rect key="frame" x="8" y="67" width="16" height="18"/>
<constraints>
<constraint firstAttribute="width" secondItem="Nnc-64-Nyi" secondAttribute="height" multiplier="1:1" id="5Oi-JS-jcm"/>
<constraint firstAttribute="width" secondItem="Nnc-64-Nyi" secondAttribute="height" multiplier="1:1" id="ALZ-2x-OdL"/>
<constraint firstAttribute="width" secondItem="Nnc-64-Nyi" secondAttribute="height" multiplier="1:1" id="UIo-c7-UFR"/>
</constraints>
<levelIndicatorCell key="cell" alignment="left" maxValue="1" warningValue="2" criticalValue="2" levelIndicatorStyle="continuousCapacity" id="FcS-7N-VDW"/>
@ -140,14 +147,10 @@
<constraints>
<constraint firstItem="14O-Lq-Npx" firstAttribute="centerY" secondItem="ncQ-wN-C61" secondAttribute="centerY" id="0Ht-U2-sPg"/>
<constraint firstItem="bvH-EJ-TYb" firstAttribute="top" secondItem="0rV-Th-Zwt" secondAttribute="bottom" constant="8" symbolic="YES" id="0xw-qA-6vP"/>
<constraint firstItem="Nnc-64-Nyi" firstAttribute="width" secondItem="Nnc-64-Nyi" secondAttribute="height" multiplier="1:1" id="5Oi-JS-jcm"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="14O-Lq-Npx" secondAttribute="trailing" constant="8" id="5eo-XI-a3W"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="6ff-xA-HJ2" secondAttribute="trailing" constant="8" id="5vx-2i-7ZX"/>
<constraint firstItem="Tah-UQ-vdf" firstAttribute="centerY" secondItem="ySY-ir-hzb" secondAttribute="centerY" id="6Hn-ts-mTi"/>
<constraint firstItem="pn9-7S-9kS" firstAttribute="width" secondItem="pn9-7S-9kS" secondAttribute="height" multiplier="1:1" id="7f0-Op-CDm"/>
<constraint firstItem="Nnc-64-Nyi" firstAttribute="width" secondItem="Nnc-64-Nyi" secondAttribute="height" multiplier="1:1" id="ALZ-2x-OdL"/>
<constraint firstItem="pn9-7S-9kS" firstAttribute="top" secondItem="bvH-EJ-TYb" secondAttribute="bottom" constant="8" symbolic="YES" id="ALk-8e-nCA"/>
<constraint firstItem="Bf9-wO-fc9" firstAttribute="width" secondItem="Bf9-wO-fc9" secondAttribute="height" multiplier="1:1" id="DT1-FT-Ilb"/>
<constraint firstItem="R0g-Oa-VB5" firstAttribute="leading" secondItem="bvH-EJ-TYb" secondAttribute="trailing" constant="8" symbolic="YES" id="Dgy-JI-nA1"/>
<constraint firstItem="Nnc-64-Nyi" firstAttribute="top" secondItem="BEi-xM-JeY" secondAttribute="bottom" constant="8" symbolic="YES" id="GAa-X8-Mys"/>
<constraint firstItem="R0g-Oa-VB5" firstAttribute="centerY" secondItem="bvH-EJ-TYb" secondAttribute="centerY" id="Gfq-mB-Y1z"/>
@ -158,18 +161,15 @@
<constraint firstItem="Nnc-64-Nyi" firstAttribute="leading" secondItem="tpZ-0B-QQu" secondAttribute="leading" constant="8" id="NA2-Ni-jh8"/>
<constraint firstItem="0rV-Th-Zwt" firstAttribute="top" secondItem="ncQ-wN-C61" secondAttribute="bottom" constant="8" symbolic="YES" id="Q2g-yM-nlJ"/>
<constraint firstItem="ncQ-wN-C61" firstAttribute="leading" secondItem="tpZ-0B-QQu" secondAttribute="leading" constant="8" id="QUI-Hc-Bcl"/>
<constraint firstItem="BEi-xM-JeY" firstAttribute="width" secondItem="BEi-xM-JeY" secondAttribute="height" multiplier="1:1" id="RNt-qR-jIr"/>
<constraint firstItem="nDC-Fi-3fv" firstAttribute="leading" secondItem="pn9-7S-9kS" secondAttribute="trailing" constant="8" symbolic="YES" id="RWP-AR-rBQ"/>
<constraint firstItem="BEi-xM-JeY" firstAttribute="top" secondItem="Bf9-wO-fc9" secondAttribute="bottom" constant="8" symbolic="YES" id="SfL-e8-tGf"/>
<constraint firstItem="6ff-xA-HJ2" firstAttribute="leading" secondItem="Nnc-64-Nyi" secondAttribute="trailing" constant="8" symbolic="YES" id="Td2-d9-JUG"/>
<constraint firstItem="Bf9-wO-fc9" firstAttribute="width" secondItem="Bf9-wO-fc9" secondAttribute="height" multiplier="1:1" id="WOL-cc-xiX"/>
<constraint firstItem="BEi-xM-JeY" firstAttribute="leading" secondItem="tpZ-0B-QQu" secondAttribute="leading" constant="8" id="WpG-KW-b5w"/>
<constraint firstItem="pn9-7S-9kS" firstAttribute="leading" secondItem="tpZ-0B-QQu" secondAttribute="leading" constant="8" id="YgV-sN-mDf"/>
<constraint firstItem="6ff-xA-HJ2" firstAttribute="centerY" secondItem="Nnc-64-Nyi" secondAttribute="centerY" id="atz-8g-UGI"/>
<constraint firstItem="0rV-Th-Zwt" firstAttribute="leading" secondItem="tpZ-0B-QQu" secondAttribute="leading" constant="8" id="bKh-4L-mqj"/>
<constraint firstItem="DMC-js-ACH" firstAttribute="leading" secondItem="Bf9-wO-fc9" secondAttribute="trailing" constant="8" symbolic="YES" id="c1E-R8-Qqu"/>
<constraint firstItem="bvH-EJ-TYb" firstAttribute="leading" secondItem="tpZ-0B-QQu" secondAttribute="leading" constant="8" id="cPA-Ls-fLj"/>
<constraint firstItem="BEi-xM-JeY" firstAttribute="width" secondItem="BEi-xM-JeY" secondAttribute="height" multiplier="1:1" id="f23-rG-rct"/>
<constraint firstItem="Bf9-wO-fc9" firstAttribute="leading" secondItem="tpZ-0B-QQu" secondAttribute="leading" constant="8" id="fBh-Va-Ijc"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="Tah-UQ-vdf" secondAttribute="trailing" constant="8" id="igX-7U-TeE"/>
<constraint firstItem="Q3c-5Q-sZh" firstAttribute="centerY" secondItem="BEi-xM-JeY" secondAttribute="centerY" id="jY4-r7-doR"/>

View File

@ -21,7 +21,7 @@
<windowCollectionBehavior key="collectionBehavior" fullScreenPrimary="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="80" y="250" width="600" height="450"/>
<rect key="screenRect" x="0.0" y="0.0" width="1470" height="924"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1440"/>
<value key="minSize" type="size" width="228" height="171"/>
<view key="contentView" id="gIp-Ho-8D9" customClass="CSScanTargetView">
<rect key="frame" x="0.0" y="0.0" width="600" height="450"/>

View File

@ -28,6 +28,7 @@ static const NSTimeInterval quickMouseHideInterval = 0.1;
NSTrackingArea *_subviewTrackingArea;
NSTimer *_mouseHideTimer;
BOOL _mouseIsCaptured;
BOOL _ignoreNextMotion;
atomic_int _isDrawingFlag;
BOOL _isInvalid;
@ -223,10 +224,16 @@ static CVReturn DisplayLinkCallback(__unused CVDisplayLinkRef displayLink, const
- (void)setShouldCaptureMouse:(BOOL)shouldCaptureMouse {
_shouldCaptureMouse = shouldCaptureMouse;
[self recalculateWindowTrackingArea];
}
- (void)recalculateWindowTrackingArea {
if(_windowTrackingArea) {
[self removeTrackingArea:_windowTrackingArea];
}
if(!_shouldCaptureMouse) {
return;
}
_windowTrackingArea =
[[NSTrackingArea alloc]
initWithRect:self.bounds
@ -275,6 +282,7 @@ static CVReturn DisplayLinkCallback(__unused CVDisplayLinkRef displayLink, const
- (void)updateTrackingAreas {
[super updateTrackingAreas];
[self recalculateSubviewTrackingAreas];
[self recalculateWindowTrackingArea];
}
- (void)didAddSubview:(NSView *)subview {
@ -323,17 +331,48 @@ static CVReturn DisplayLinkCallback(__unused CVDisplayLinkRef displayLink, const
}
- (void)releaseMouse {
if(_mouseIsCaptured) {
_mouseIsCaptured = NO;
CGAssociateMouseAndMouseCursorPosition(true);
[NSCursor unhide];
[self.responderDelegate scanTargetViewDidReleaseMouse:self];
((CSApplication *)[NSApplication sharedApplication]).eventDelegate = nil;
if(!_mouseIsCaptured) {
return;
}
_mouseIsCaptured = NO;
CGAssociateMouseAndMouseCursorPosition(true);
[NSCursor unhide];
[self.responderDelegate scanTargetViewDidReleaseMouse:self];
((CSApplication *)[NSApplication sharedApplication]).eventDelegate = nil;
}
- (BOOL)captureMouse {
if(_mouseIsCaptured) {
return NO;
}
_ignoreNextMotion = _mouseIsCaptured = YES;
[NSCursor hide];
CGAssociateMouseAndMouseCursorPosition(false);
[self recentreCursor];
[self.responderDelegate scanTargetViewWouldHideOSMouseCursor:self];
[self.responderDelegate scanTargetViewDidCaptureMouse:self];
if(self.shouldUsurpCommand) {
((CSApplication *)[NSApplication sharedApplication]).eventDelegate = self;
}
return YES;
}
#pragma mark - Mouse motion
- (void)recentreCursor {
// TODO: should I really need to invert the y coordinate myself? It suggests I
// might have an error in mapping here.
const NSPoint windowCentre = [self convertPoint:CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height * 0.5) toView:nil];
const NSPoint screenCentre = [self.window convertPointToScreen:windowCentre];
const CGRect screenFrame = self.window.screen.frame;
CGWarpMouseCursorPosition(NSMakePoint(
screenFrame.origin.x + screenCentre.x,
screenFrame.origin.y + screenFrame.size.height - screenCentre.y
));
}
- (void)applyMouseMotion:(NSEvent *)event {
if(!_mouseIsCaptured) {
// Mouse capture is off, so don't play games with the cursor, just schedule it to
@ -349,18 +388,12 @@ static CVReturn DisplayLinkCallback(__unused CVDisplayLinkRef displayLink, const
} else {
// Mouse capture is on, so move the cursor back to the middle of the window, and
// forward the deltas to the listener.
//
// TODO: should I really need to invert the y coordinate myself? It suggests I
// might have an error in mapping here.
const NSPoint windowCentre = [self convertPoint:CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height * 0.5) toView:nil];
const NSPoint screenCentre = [self.window convertPointToScreen:windowCentre];
const CGRect screenFrame = self.window.screen.frame;
CGWarpMouseCursorPosition(NSMakePoint(
screenFrame.origin.x + screenCentre.x,
screenFrame.origin.y + screenFrame.size.height - screenCentre.y
));
[self.responderDelegate mouseMoved:event];
[self recentreCursor];
if(!_ignoreNextMotion) {
// Ignore the first motion that comes in; it seems to be spurious.
[self.responderDelegate mouseMoved:event];
}
_ignoreNextMotion = NO;
}
}
@ -388,16 +421,7 @@ static CVReturn DisplayLinkCallback(__unused CVDisplayLinkRef displayLink, const
- (void)applyButtonDown:(NSEvent *)event {
if(self.shouldCaptureMouse) {
if(!_mouseIsCaptured) {
_mouseIsCaptured = YES;
[NSCursor hide];
CGAssociateMouseAndMouseCursorPosition(false);
[self.responderDelegate scanTargetViewWouldHideOSMouseCursor:self];
[self.responderDelegate scanTargetViewDidCaptureMouse:self];
if(self.shouldUsurpCommand) {
((CSApplication *)[NSApplication sharedApplication]).eventDelegate = self;
}
if([self captureMouse]) {
// Don't report the first click to the delegate; treat that as merely
// an invitation to capture the cursor.
return;

View File

@ -99,7 +99,7 @@ void Bus::run_for(HalfCycles time) {
const auto old_index = dispatch_index_;
const auto time_as_int = time_in_state_.as_integral();
while(time_as_int >= dispatch_times_[dispatch_index_] && dispatch_index_ < dispatch_times_.size()) {
while(dispatch_index_ < dispatch_times_.size() && time_as_int >= dispatch_times_[dispatch_index_]) {
++dispatch_index_;
}