mirror of
https://github.com/coteditor/CotEditor.git
synced 2024-09-11 11:25:57 +03:00
Fix multi cursor drawing
This commit is contained in:
parent
a5e3872f20
commit
0354f9cb29
@ -3,6 +3,10 @@
|
||||
4.8.0-beta.3 (unreleased)
|
||||
--------------------------
|
||||
|
||||
### Fixes
|
||||
|
||||
- [beta] Fix an issue on macOS 14 that multiple cursors in editors were not drawn when the editor becomes active again.
|
||||
|
||||
|
||||
|
||||
4.8.0-beta.2 (635)
|
||||
|
@ -230,16 +230,6 @@ class EditorTextView: NSTextView, Themable, CurrentLineHighlighting, MultiCursor
|
||||
.filter { !$0 }
|
||||
.sink { [unowned self] _ in self.layoutManager?.removeTemporaryAttribute(.roundedBackgroundColor, forCharacterRange: self.string.nsRange) },
|
||||
]
|
||||
|
||||
// workaround the issue that indicators display even the application is inactive
|
||||
// (2023-08 macOS 14 beta 5, FB12968177)
|
||||
if #available(macOS 14, *) {
|
||||
self.keyStateObserver = Publishers.Merge3(
|
||||
NotificationCenter.default.publisher(for: NSApplication.didResignActiveNotification, object: NSApp),
|
||||
NotificationCenter.default.publisher(for: NSApplication.didBecomeActiveNotification, object: NSApp),
|
||||
NotificationCenter.default.publisher(for: NSWindow.didBecomeKeyNotification))
|
||||
.sink { [unowned self] _ in self.invalidateInsertionPointDisplayMode(isFirstResponder: self.window?.firstResponder == self) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -320,8 +310,8 @@ class EditorTextView: NSTextView, Themable, CurrentLineHighlighting, MultiCursor
|
||||
// post notification about becoming the first responder
|
||||
NotificationCenter.default.post(name: EditorTextView.didBecomeFirstResponderNotification, object: self)
|
||||
|
||||
if #available(macOS 14, *) {
|
||||
self.invalidateInsertionPointDisplayMode(isFirstResponder: true)
|
||||
defer {
|
||||
self.invalidateInsertionIndicatorDisplayMode()
|
||||
}
|
||||
|
||||
return true
|
||||
@ -332,8 +322,8 @@ class EditorTextView: NSTextView, Themable, CurrentLineHighlighting, MultiCursor
|
||||
|
||||
guard super.resignFirstResponder() else { return false }
|
||||
|
||||
if #available(macOS 14, *) {
|
||||
self.invalidateInsertionPointDisplayMode(isFirstResponder: false)
|
||||
defer {
|
||||
self.invalidateInsertionIndicatorDisplayMode()
|
||||
}
|
||||
|
||||
return true
|
||||
@ -356,6 +346,16 @@ class EditorTextView: NSTextView, Themable, CurrentLineHighlighting, MultiCursor
|
||||
self?.enclosingScrollView?.drawsBackground = $0
|
||||
self?.lineHighlightColor = self?.theme?.lineHighlightColor(forOpaqueBackground: $0)
|
||||
}
|
||||
|
||||
|
||||
// observe key window state for insertion points drawing
|
||||
if #available(macOS 14, *), let window {
|
||||
self.keyStateObserver = Publishers.Merge(
|
||||
NotificationCenter.default.publisher(for: NSWindow.didBecomeKeyNotification, object: window),
|
||||
NotificationCenter.default.publisher(for: NSWindow.didResignKeyNotification, object: window)
|
||||
)
|
||||
.sink { [unowned self] _ in self.invalidateInsertionIndicatorDisplayMode() }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -397,7 +397,7 @@ extension MultiCursorEditing {
|
||||
|
||||
// reuse existing indicators
|
||||
var indicators = ArraySlice(self.insertionIndicators) // slice for popFirst()
|
||||
let isActive = (self.window?.firstResponder == self && NSApp.isActive)
|
||||
let shouldDraw = self.shouldDrawInsertionPoints
|
||||
|
||||
self.insertionIndicators = insertionLocations
|
||||
.compactMap { layoutManager.insertionPointRect(at: $0) } // ignore split cursors
|
||||
@ -409,7 +409,7 @@ extension MultiCursorEditing {
|
||||
} else {
|
||||
let indicator = NSTextInsertionIndicator(frame: rect)
|
||||
indicator.color = self.insertionPointColor
|
||||
indicator.displayMode = isActive ? .automatic : .hidden
|
||||
indicator.displayMode = shouldDraw ? .automatic : .hidden
|
||||
self.addSubview(indicator)
|
||||
return indicator
|
||||
}
|
||||
@ -422,17 +422,14 @@ extension MultiCursorEditing {
|
||||
|
||||
/// Workarounds the issue that indicators display even the editor is inactive (2023-08 macOS 14, FB12964703 and FB12968177)
|
||||
///
|
||||
/// This method should be Invoked when the receiver is changed whether it is the key editor receiving text input in the system.
|
||||
///
|
||||
/// - Parameter isFirstResponder: Whether the receiver is the first responder in the window.
|
||||
@available(macOS 14, *)
|
||||
func invalidateInsertionPointDisplayMode(isFirstResponder: Bool) {
|
||||
/// This method should be Invoked when changing the state whether the receiver is the key editor receiving text input in the system.
|
||||
func invalidateInsertionIndicatorDisplayMode() {
|
||||
|
||||
guard !self.insertionIndicators.isEmpty else { return }
|
||||
guard #available(macOS 14, *), !self.insertionIndicators.isEmpty else { return }
|
||||
|
||||
let isActive = NSApp.isActive && self.window == NSApp.keyWindow && isFirstResponder
|
||||
let shouldDraw = self.shouldDrawInsertionPoints
|
||||
for indicator in self.insertionIndicators {
|
||||
indicator.displayMode = isActive ? .automatic : .hidden
|
||||
indicator.displayMode = shouldDraw ? .automatic : .hidden
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -440,6 +437,13 @@ extension MultiCursorEditing {
|
||||
|
||||
extension NSTextView {
|
||||
|
||||
/// Whether the editor should draw insertion points.
|
||||
fileprivate final var shouldDrawInsertionPoints: Bool {
|
||||
|
||||
NSApp.isActive && self.window?.isKeyWindow == true && self.window?.firstResponder == self && self.isEditable
|
||||
}
|
||||
|
||||
|
||||
/// Finds the location for the insertion point where one (visual) line above to the given insertion point location.
|
||||
///
|
||||
/// - Parameter index: The character index of the reference insertion point.
|
||||
|
Loading…
Reference in New Issue
Block a user