Merge nucleic/dapper-velvet-badger-dtr3 into dev
This commit is contained in:
@@ -266,6 +266,15 @@ struct ChatInputField: NSViewRepresentable {
|
|||||||
/// so the fitted height can be recomputed for the new text wrapping.
|
/// so the fitted height can be recomputed for the new text wrapping.
|
||||||
final class HeightTrackingScrollView: NSScrollView {
|
final class HeightTrackingScrollView: NSScrollView {
|
||||||
var onLayout: (() -> Void)?
|
var onLayout: (() -> Void)?
|
||||||
|
/// `NSTextView` installs the I-beam directly when it handles a click. In a normal AppKit
|
||||||
|
/// hierarchy the next cursor rect under the pointer replaces it as soon as the pointer leaves,
|
||||||
|
/// but the SwiftUI views surrounding this representable do not consistently install an arrow
|
||||||
|
/// rect. That is especially visible in Home's tall, otherwise-empty hero field: the I-beam can
|
||||||
|
/// remain current across the whole window until AppKit's next cursor-rect rebuild.
|
||||||
|
///
|
||||||
|
/// Track the scroll view rather than its document view so this covers the field's exact visible
|
||||||
|
/// bounds even when an empty `NSTextView` is shorter than the Home composer's minimum height.
|
||||||
|
private var cursorExitTrackingArea: NSTrackingArea?
|
||||||
|
|
||||||
/// Force overlay-style scrollers, rejecting the system's legacy style ("Show scroll
|
/// Force overlay-style scrollers, rejecting the system's legacy style ("Show scroll
|
||||||
/// bars: Always", common with a mouse attached). A legacy scroller consumes layout
|
/// bars: Always", common with a mouse attached). A legacy scroller consumes layout
|
||||||
@@ -283,6 +292,25 @@ final class HeightTrackingScrollView: NSScrollView {
|
|||||||
set { _ = newValue; super.scrollerStyle = .overlay }
|
set { _ = newValue; super.scrollerStyle = .overlay }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func updateTrackingAreas() {
|
||||||
|
super.updateTrackingAreas()
|
||||||
|
if let cursorExitTrackingArea { removeTrackingArea(cursorExitTrackingArea) }
|
||||||
|
let area = NSTrackingArea(
|
||||||
|
rect: .zero,
|
||||||
|
options: [.mouseEnteredAndExited, .activeInKeyWindow, .inVisibleRect],
|
||||||
|
owner: self,
|
||||||
|
userInfo: nil)
|
||||||
|
addTrackingArea(area)
|
||||||
|
cursorExitTrackingArea = area
|
||||||
|
}
|
||||||
|
|
||||||
|
override func mouseExited(with event: NSEvent) {
|
||||||
|
// `set()` is intentional: the text view also sets (rather than pushes) its cursor, so
|
||||||
|
// there is no balanced cursor-stack entry to pop here.
|
||||||
|
NSCursor.arrow.set()
|
||||||
|
super.mouseExited(with: event)
|
||||||
|
}
|
||||||
|
|
||||||
override func layout() {
|
override func layout() {
|
||||||
super.layout()
|
super.layout()
|
||||||
onLayout?()
|
onLayout?()
|
||||||
|
|||||||
Reference in New Issue
Block a user