diff --git a/Squirrel.xcodeproj/project.pbxproj b/Squirrel.xcodeproj/project.pbxproj index 402780bdb..e3ca6ca1c 100644 --- a/Squirrel.xcodeproj/project.pbxproj +++ b/Squirrel.xcodeproj/project.pbxproj @@ -592,7 +592,7 @@ CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.99.1; + CURRENT_PROJECT_VERSION = 0.99.2; DEAD_CODE_STRIPPING = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -649,7 +649,7 @@ CODE_SIGN_ENTITLEMENTS = Squirrel.entitlements; CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 0.99.1; + CURRENT_PROJECT_VERSION = 0.99.2; DEAD_CODE_STRIPPING = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", diff --git a/SquirrelInputController.swift b/SquirrelInputController.swift index 125ed6714..82e99c371 100644 --- a/SquirrelInputController.swift +++ b/SquirrelInputController.swift @@ -525,7 +525,7 @@ private extension SquirrelInputController { let remainingRange = NSMakeRange(start, preedit.utf16.count - start) let attrs = mark(forStyle: kTSMHiliteSelectedRawText, at: remainingRange)! as! [NSAttributedString.Key : Any] attrString.setAttributes(attrs, range: remainingRange) - client().setMarkedText(attrString, selectionRange: NSMakeRange(caretPos, 0), replacementRange: NSMakeRange(NSNotFound, NSNotFound)) + client().setMarkedText(attrString, selectionRange: NSMakeRange(caretPos, 0), replacementRange: NSMakeRange(NSNotFound, 0)) } func showPanel(preedit: String, selRange: NSRange, caretPos: Int, candidates: [String], comments: [String], labels: [String], highlighted: Int) { diff --git a/SquirrelPanel.swift b/SquirrelPanel.swift index 4bb58a2d5..ae5973e2c 100644 --- a/SquirrelPanel.swift +++ b/SquirrelPanel.swift @@ -414,8 +414,8 @@ private extension SquirrelPanel { } // Make the first candidate fixed at the left of cursor panelRect.origin.x = position.minX - panelRect.width - SquirrelTheme.offsetHeight - if view.preeditRange.length > 0 { - let preeditRect = view.contentRect(range: view.convert(range: view.preeditRange)) + if view.preeditRange.length > 0, let preeditTextRange = view.convert(range: view.preeditRange) { + let preeditRect = view.contentRect(range: preeditTextRange) panelRect.origin.x += preeditRect.height + theme.edgeInset.width } } else { diff --git a/SquirrelView.swift b/SquirrelView.swift index bdedd197f..a5a3cba6e 100644 --- a/SquirrelView.swift +++ b/SquirrelView.swift @@ -53,11 +53,10 @@ class SquirrelView: NSView { NSApp.effectiveAppearance.bestMatch(from: [.aqua, .darkAqua]) == .darkAqua } - func convert(range: NSRange) -> NSTextRange { - let nullRange = NSTextRange(location: textLayoutManager.documentRange.location) - guard range.location != NSNotFound else { return nullRange } - guard let startLocation = textLayoutManager.location(textLayoutManager.documentRange.location, offsetBy: range.location) else { return nullRange } - guard let endLocation = textLayoutManager.location(startLocation, offsetBy: range.length) else { return nullRange } + func convert(range: NSRange) -> NSTextRange? { + guard range.location != NSNotFound else { return nil } + guard let startLocation = textLayoutManager.location(textLayoutManager.documentRange.location, offsetBy: range.location) else { return nil } + guard let endLocation = textLayoutManager.location(startLocation, offsetBy: range.length) else { return nil } return NSTextRange(location: startLocation, end: endLocation) ?? textLayoutManager.documentRange } @@ -69,11 +68,13 @@ class SquirrelView: NSView { } var x0 = CGFloat.infinity, x1 = -CGFloat.infinity, y0 = CGFloat.infinity, y1 = -CGFloat.infinity for range in ranges { - let rect = self.contentRect(range: convert(range: range)) - x0 = min(NSMinX(rect), x0) - x1 = max(NSMaxX(rect), x1) - y0 = min(NSMinY(rect), y0) - y1 = max(NSMaxY(rect), y1) + if let textRange = convert(range: range) { + let rect = contentRect(range: textRange) + x0 = min(NSMinX(rect), x0) + x1 = max(NSMaxX(rect), x1) + y0 = min(NSMinY(rect), y0) + y1 = max(NSMaxY(rect), y1) + } } return NSMakeRect(x0, y0, x1-x0, y1-y0) } @@ -113,8 +114,8 @@ class SquirrelView: NSView { // Draw preedit Rect var preeditRect = NSZeroRect - if (preeditRange.length > 0) { - preeditRect = contentRect(range: convert(range: preeditRange)) + if preeditRange.length > 0, let preeditTextRange = convert(range: preeditRange) { + preeditRect = contentRect(range: preeditTextRange) preeditRect.size.width = backgroundRect.size.width preeditRect.size.height += theme.edgeInset.height + theme.preeditLinespace / 2 + theme.hilitedCornerRadius / 2 preeditRect.origin = backgroundRect.origin @@ -152,7 +153,7 @@ class SquirrelView: NSView { } // Draw highlighted part of preedit text - if (highlightedPreeditRange.length > 0) && (theme.highlightedPreeditColor != nil) { + if (highlightedPreeditRange.length > 0) && (theme.highlightedPreeditColor != nil), let highlightedPreeditTextRange = convert(range: highlightedPreeditRange) { var innerBox = preeditRect innerBox.size.width -= (theme.edgeInset.width + 1) * 2 innerBox.origin.x += theme.edgeInset.width + 1 @@ -168,7 +169,7 @@ class SquirrelView: NSView { outerBox.origin.x += max(0, theme.hilitedCornerRadius + theme.borderLineWidth) / 2 outerBox.origin.y += max(0, theme.hilitedCornerRadius + theme.borderLineWidth) / 2 - let (leadingRect, bodyRect, trailingRect) = multilineRects(forRange: convert(range: highlightedPreeditRange), extraSurounding: 0, bounds: outerBox) + let (leadingRect, bodyRect, trailingRect) = multilineRects(forRange: highlightedPreeditTextRange, extraSurounding: 0, bounds: outerBox) var (highlightedPoints, highlightedPoints2, rightCorners, rightCorners2) = linearMultilineFor(body: bodyRect, leading: leadingRect, trailing: trailingRect) containingRect = carveInset(rect: preeditRect) @@ -276,7 +277,7 @@ class SquirrelView: NSView { point = NSMakePoint(point.x - NSMinX(lineFragment.typographicBounds), point.y - NSMinY(lineFragment.typographicBounds)) index += lineFragment.characterIndex(for: point) - if index >= (preeditRange.location == NSNotFound ? 0 : preeditRange.upperBound) && index < preeditRange.upperBound { + if index >= preeditRange.location && index < preeditRange.upperBound { preeditIndex = index } else { for i in 0..