From 7a6554691f0cde483f916292e7035bdf0b1a4563 Mon Sep 17 00:00:00 2001 From: groverlynn Date: Tue, 14 Nov 2023 06:11:05 +0100 Subject: [PATCH] cleanup codes --- SquirrelApplicationDelegate.m | 12 +- SquirrelInputController.h | 13 +- SquirrelInputController.m | 80 +++++++----- SquirrelPanel.h | 12 +- SquirrelPanel.m | 238 ++++++++++++++++------------------ macos_keycode.m | 7 +- 6 files changed, 182 insertions(+), 180 deletions(-) diff --git a/SquirrelApplicationDelegate.m b/SquirrelApplicationDelegate.m index afd067bc3..ac49c4266 100644 --- a/SquirrelApplicationDelegate.m +++ b/SquirrelApplicationDelegate.m @@ -148,8 +148,8 @@ - (void)loadSettings { _enableNotifications = ![[_config getString:@"show_notifications_when"] isEqualToString:@"never"]; - [self.panel loadConfig:_config forDarkMode:NO]; - [self.panel loadConfig:_config forDarkMode:YES]; + [self.panel loadConfig:_config forAppearance:defaultAppear]; + [self.panel loadConfig:_config forAppearance:darkAppear]; } - (void)loadSchemaSpecificSettings:(NSString *)schemaId { @@ -159,11 +159,11 @@ - (void)loadSchemaSpecificSettings:(NSString *)schemaId { SquirrelConfig *schema = [[SquirrelConfig alloc] init]; if ([schema openWithSchemaId:schemaId baseConfig:self.config] && [schema hasSection:@"style"]) { - [self.panel loadConfig:schema forDarkMode:NO]; - [self.panel loadConfig:schema forDarkMode:YES]; + [self.panel loadConfig:schema forAppearance:defaultAppear]; + [self.panel loadConfig:schema forAppearance:darkAppear]; } else { - [self.panel loadConfig:self.config forDarkMode:NO]; - [self.panel loadConfig:self.config forDarkMode:YES]; + [self.panel loadConfig:self.config forAppearance:defaultAppear]; + [self.panel loadConfig:self.config forAppearance:darkAppear]; } [schema close]; } diff --git a/SquirrelInputController.h b/SquirrelInputController.h index ca1f93a4a..0177b1a28 100644 --- a/SquirrelInputController.h +++ b/SquirrelInputController.h @@ -4,18 +4,21 @@ @interface SquirrelInputController : IMKInputController typedef enum { - kSELECT = 1, - kDELETE = 2, - kCHOOSE = 3 + kSELECT = 1, // accepts indices in both digits and selection keys + kDELETE = 2, // only accepts indices in digits, e.g. (int) 1 + kCHOOSE = 3 // only accepts indices in selection keys, e.g. (char) '1' / 'A' } rimeAction; typedef enum { - // 0 ... 9 are ordinals, 0x21 ... 0x7e are ascii chars + // 0 ... 9 are ordinal digits, used as (int) index + // 0x21 ... 0x7e are ASCII chars (as selection keys) + // other rime keycodes (as function keys), for paging etc. kPageUp = 0xff55, // XK_Page_Up kPageDown = 0xff56, // XK_Page_Down kVoidSymbol = 0xffffff // XK_VoidSymbol } rimeIndex; -- (void)perform:(rimeAction)action onIndex:(rimeIndex)index; +- (void)perform:(rimeAction)action + onIndex:(rimeIndex)index; @end diff --git a/SquirrelInputController.m b/SquirrelInputController.m index 52b132d59..b5d49392e 100644 --- a/SquirrelInputController.m +++ b/SquirrelInputController.m @@ -49,7 +49,8 @@ @implementation SquirrelInputController { @abstract Receive incoming event @discussion This method receives key events from the client application. */ -- (BOOL)handleEvent:(NSEvent *)event client:(id)sender +- (BOOL)handleEvent:(NSEvent *)event + client:(id)sender { // Return YES to indicate the the key input was received and dealt with. // Key processing will not continue in that case. In other words the @@ -93,36 +94,34 @@ - (BOOL)handleEvent:(NSEvent *)event client:(id)sender CGEventSourceCounterForEventType(kCGEventSourceStateCombinedSessionState, kCGEventOtherMouseDown); _lastModifier = modifiers; switch (keyCode) { - case kVK_CapsLock: { + case kVK_CapsLock: rime_modifiers ^= kLockMask; [self processKey:rime_keycode modifiers:rime_modifiers]; - } break; + break; case kVK_Shift: - case kVK_RightShift: { + case kVK_RightShift: release_mask = modifiers & NSEventModifierFlagShift ? 0 : kReleaseMask | (eventCount - _lastEventCount == 1 ? 0 : kIgnoredMask); [self processKey:rime_keycode modifiers:(rime_modifiers | release_mask)]; - } break; + break; case kVK_Control: - case kVK_RightControl: { + case kVK_RightControl: release_mask = modifiers & NSEventModifierFlagControl ? 0 : kReleaseMask | (eventCount - _lastEventCount == 1 ? 0 : kIgnoredMask); [self processKey:rime_keycode modifiers:(rime_modifiers | release_mask)]; - } break; + break; case kVK_Option: - case kVK_RightOption: { + case kVK_RightOption: release_mask = modifiers & NSEventModifierFlagOption ? 0 : kReleaseMask | (eventCount - _lastEventCount == 1 ? 0 : kIgnoredMask); [self processKey:rime_keycode modifiers:(rime_modifiers | release_mask)]; - } break; - case kVK_Function: { + break; + case kVK_Function: release_mask = modifiers & NSEventModifierFlagFunction ? 0 : kReleaseMask | (eventCount - _lastEventCount == 1 ? 0 : kIgnoredMask); [self processKey:rime_keycode modifiers:(rime_modifiers | release_mask)]; - } break; + break; case kVK_Command: - case kVK_RightCommand: { + case kVK_RightCommand: release_mask = modifiers & NSEventModifierFlagCommand ? 0 : kReleaseMask | (eventCount - _lastEventCount == 1 ? 0 : kIgnoredMask); [self processKey:rime_keycode modifiers:(rime_modifiers | release_mask)]; goto saveStatus; - } - default: break; } [self rimeUpdate]; @@ -162,7 +161,8 @@ - (BOOL)handleEvent:(NSEvent *)event client:(id)sender return handled; } -- (BOOL)processKey:(int)rime_keycode modifiers:(int)rime_modifiers +- (BOOL)processKey:(int)rime_keycode + modifiers:(int)rime_modifiers { // with linear candidate list, arrow keys may behave differently. Bool is_linear = NSApp.squirrelAppDelegate.panel.linear; @@ -209,7 +209,8 @@ - (BOOL)processKey:(int)rime_keycode modifiers:(int)rime_modifiers return handled; } -- (void)perform:(rimeAction)action onIndex:(rimeIndex)index { +- (void)perform:(rimeAction)action + onIndex:(rimeIndex)index { bool handled = false; if (action == kSELECT && ((index >= '!' && index <= '~') || index == kPageUp || index == kPageDown)) { @@ -244,7 +245,8 @@ - (void)onChordTimer:(NSTimer *)timer } } -- (void)updateChord:(int)keycode modifiers:(int)modifiers +- (void)updateChord:(int)keycode + modifiers:(int)modifiers { //NSLog(@"update chord: {%s} << %x", _chord, keycode); for (uint i = 0; i < _chordKeyCount; ++i) { @@ -308,7 +310,9 @@ - (void)activateServer:(id)sender } } -- (instancetype)initWithServer:(IMKServer *)server delegate:(id)delegate client:(id)inputClient +- (instancetype)initWithServer:(IMKServer *)server + delegate:(id)delegate + client:(id)inputClient { //NSLog(@"initWithServer:delegate:client:"); if (self = [super initWithServer:server delegate:delegate client:inputClient]) { @@ -391,7 +395,7 @@ - (id)composedString:(id)sender return _composedString; } -- (NSArray *)candidates:(id)sender +- (NSArray *)candidates:(id)sender { return _candidates; } @@ -486,17 +490,24 @@ - (void)showPanelWithPreedit:(NSString *)preedit SquirrelPanel *panel = NSApp.squirrelAppDelegate.panel; if (@available(macOS 14.0, *)) { // avoid overlapping with cursor effects view if (_lastModifier & NSEventModifierFlagCapsLock) { - if (NSHeight(inputPos) > NSWidth(inputPos)) { - inputPos.size.height += 26; - inputPos.origin.y -= 26; - } else { - inputPos.size.width += 33; - inputPos.origin.x -= 33; - } + NSRect screenRect = [[NSScreen mainScreen] visibleFrame]; + NSRect capslockAccessory = NSWidth(inputPos) > NSHeight(inputPos) ? + NSMakeRect(NSMinX(inputPos) - 30, NSMinY(inputPos) - 13, 27, 27) : + NSMakeRect(NSMinX(inputPos) - 13, NSMinY(inputPos) - 33, 27, 30); + if (NSMinX(capslockAccessory) < NSMinX(screenRect)) + capslockAccessory.origin.x = NSMinX(screenRect); + if (NSMaxX(capslockAccessory) > NSMaxX(screenRect)) + capslockAccessory.origin.x = NSMaxX(screenRect) - NSWidth(capslockAccessory); + if (NSMinY(capslockAccessory) < NSMinY(screenRect)) + capslockAccessory.origin.y = NSWidth(inputPos) > NSHeight(inputPos) ? NSMinY(screenRect) : NSMaxY(inputPos) + 3; + if (NSMaxY(capslockAccessory) > NSMaxY(screenRect)) + capslockAccessory.origin.y = NSMaxY(screenRect) - NSHeight(capslockAccessory); + inputPos = NSUnionRect(inputPos, capslockAccessory); } } panel.position = inputPos; panel.inputController = self; + panel.level = self.client.windowLevel + 1; [panel showPreedit:preedit selRange:selRange caretPos:caretPos @@ -504,9 +515,7 @@ - (void)showPanelWithPreedit:(NSString *)preedit comments:comments highlighted:index pageNum:pageNum - lastPage:lastPage - turnPage:NSNotFound - update:YES]; + lastPage:lastPage]; } @end // SquirrelController @@ -633,7 +642,7 @@ - (void)rimeUpdate if (RimeGetContext(_session, &ctx)) { // update raw input const char *raw_input = RimeGetInput(_session); - _originalString = @(raw_input); + _originalString = raw_input ? @(raw_input) : @""; // update preedit text const char *preedit = ctx.composition.preedit; @@ -662,16 +671,19 @@ - (void)rimeUpdate NSString *candidatePreviewText = candidatePreview ? @(candidatePreview) : @""; if (_inlinePreedit) { if ((caretPos >= end) && (caretPos < length)) { - candidatePreviewText = [candidatePreviewText stringByAppendingString:[preeditText substringWithRange:NSMakeRange(caretPos, length - caretPos)]]; + candidatePreviewText = [candidatePreviewText stringByAppendingString: + [preeditText substringWithRange:NSMakeRange(caretPos, length - caretPos)]]; } [self showPreeditString:candidatePreviewText selRange:NSMakeRange(start, candidatePreviewText.length - (length - end) - start) caretPos:caretPos <= start ? caretPos - 1 : candidatePreviewText.length - (length - caretPos)]; } else { if ((end < caretPos) && (caretPos > start)) { - candidatePreviewText = [candidatePreviewText substringWithRange:NSMakeRange(0, candidatePreviewText.length - (caretPos - end))]; + candidatePreviewText = [candidatePreviewText substringWithRange: + NSMakeRange(0, candidatePreviewText.length - (caretPos - end))]; } else if ((end < length) && (caretPos < end)) { - candidatePreviewText = [candidatePreviewText substringWithRange:NSMakeRange(0, candidatePreviewText.length - (length - end))]; + candidatePreviewText = [candidatePreviewText substringWithRange: + NSMakeRange(0, candidatePreviewText.length - (length - end))]; } [self showPreeditString:candidatePreviewText selRange:NSMakeRange(start - (caretPos < end), candidatePreviewText.length - start + (caretPos < end)) @@ -703,7 +715,7 @@ - (void)rimeUpdate lastPage:(BOOL)ctx.menu.is_last_page]; RimeFreeContext(&ctx); } else { - [NSApp.squirrelAppDelegate.panel hide]; + [self hidePalettes]; } } diff --git a/SquirrelPanel.h b/SquirrelPanel.h index 180b3e7be..928d4ab52 100644 --- a/SquirrelPanel.h +++ b/SquirrelPanel.h @@ -4,6 +4,12 @@ @class SquirrelConfig; @class SquirrelOptionSwitcher; +typedef enum { + defaultAppear = 0, + lightAppear = 0, + darkAppear = 1 +} SquirrelAppear; + @interface SquirrelPanel : NSPanel // Linear candidate list, as opposed to stacked candidate list. @@ -30,9 +36,7 @@ comments:(NSArray *)comments highlighted:(NSUInteger)index pageNum:(NSUInteger)pageNum - lastPage:(BOOL)lastPage - turnPage:(NSUInteger)turnPage - update:(BOOL)update; + lastPage:(BOOL)lastPage; - (void)hide; @@ -40,7 +44,7 @@ statusShort:(NSString *)messageShort; - (void)loadConfig:(SquirrelConfig *)config - forDarkMode:(BOOL)isDark; + forAppearance:(SquirrelAppear)appear; - (void)loadLabelConfig:(SquirrelConfig *)config; diff --git a/SquirrelPanel.m b/SquirrelPanel.m index 0023b0e38..558de6f27 100644 --- a/SquirrelPanel.m +++ b/SquirrelPanel.m @@ -62,7 +62,8 @@ - (CGPathRef)quartzPath { } } -@end +@end // NSBezierPath (BezierPathQuartzUtilities) + @implementation NSMutableAttributedString (NSMutableAttributedStringMarkDownFormatting) @@ -180,7 +181,8 @@ - (CGFloat)annotateRubyInRange:(NSRange)range return rubyLineHeight; } -@end +@end // NSMutableAttributedString (NSMutableAttributedStringMarkDownFormatting) + @interface SquirrelTheme : NSObject @@ -520,7 +522,8 @@ - (void)setParagraphStyle:(NSParagraphStyle *)paragraphStyle _statusParagraphStyle = statusParagraphStyle; } -- (void)setSelectKeys:(NSString *)selectKeys labels:(NSArray *)labels { +- (void)setSelectKeys:(NSString *)selectKeys + labels:(NSArray *)labels { _selectKeys = selectKeys; _labels = labels; } @@ -586,7 +589,8 @@ - (void)setAnnotationHeight:(CGFloat)height { } } -@end +@end // SquirrelTheme + @interface SquirrelLayoutManager : NSLayoutManager @end @@ -662,7 +666,8 @@ - (NSRect) layoutManager:(NSLayoutManager *)layoutManager return NSMakeRect(glyphPosition.x, 0.0, width, glyphPosition.y); } -@end +@end // SquirrelLayoutManager + API_AVAILABLE(macos(12.0)) @interface SquirrelTextLayoutFragment : NSTextLayoutFragment @@ -681,7 +686,8 @@ - (void)drawAtPoint:(CGPoint)point } } -@end +@end // SquirrelTextLayoutFragment + API_AVAILABLE(macos(12.0)) @interface SquirrelTextLayoutManager : NSTextLayoutManager @@ -695,7 +701,8 @@ - (NSTextLayoutFragment *)textLayoutManager:(NSTextLayoutManager *)textLayoutMan return [[SquirrelTextLayoutFragment alloc] initWithTextElement:textElement range:textElement.elementRange]; } -@end +@end // SquirrelTextLayoutManager + @interface SquirrelView : NSView @@ -713,7 +720,7 @@ @interface SquirrelView : NSView @property(nonatomic, readonly) NSUInteger pagingButton; @property(nonatomic, readonly) CAShapeLayer *shape; @property(nonatomic, readonly, strong) SquirrelTheme *currentTheme; -@property(nonatomic, readonly) BOOL isDark; +@property(nonatomic, readonly) SquirrelAppear appear; - (void)drawViewWithInsets:(NSEdgeInsets)insets candidateRanges:(NSArray *)candidateRanges @@ -741,23 +748,24 @@ - (BOOL)wantsUpdateLayer { return YES; } -- (BOOL)isDark { - if ([NSApp.effectiveAppearance bestMatchFromAppearancesWithNames:@[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]] == NSAppearanceNameDarkAqua) { - return YES; +- (SquirrelAppear)appear { + if ([NSApp.effectiveAppearance bestMatchFromAppearancesWithNames: + @[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]] == NSAppearanceNameDarkAqua) { + return darkAppear; } - return NO; + return defaultAppear; } - (BOOL)allowsVibrancy { return YES; } -- (SquirrelTheme *)selectTheme:(BOOL)isDark { - return isDark ? _darkTheme : _defaultTheme; +- (SquirrelTheme *)selectTheme:(SquirrelAppear)appear { + return appear == darkAppear ? _darkTheme : _defaultTheme; } - (SquirrelTheme *)currentTheme { - return [self selectTheme:self.isDark]; + return [self selectTheme:self.appear]; } - (instancetype)initWithFrame:(NSRect)frameRect { @@ -1426,13 +1434,15 @@ - (void)updateLayer { if (theme.tabled) { CAShapeLayer *horzGridLayer = [[CAShapeLayer alloc] init]; horzGridLayer.path = [candidateHorzGridPath quartzPath]; - horzGridLayer.strokeColor = [[theme.backgroundColor blendedColorWithFraction:kBlendedBackgroundColorFraction ofColor:(self.isDark ? [NSColor lightGrayColor] : [NSColor blackColor])] CGColor]; + horzGridLayer.strokeColor = [[theme.backgroundColor blendedColorWithFraction:kBlendedBackgroundColorFraction + ofColor:(self.appear == darkAppear ? [NSColor lightGrayColor] : [NSColor blackColor])] CGColor]; horzGridLayer.lineWidth = theme.edgeInset.height / 2; horzGridLayer.lineCap = kCALineCapRound; [panelLayer addSublayer:horzGridLayer]; CAShapeLayer *vertGridLayer = [[CAShapeLayer alloc] init]; vertGridLayer.path = [candidateVertGridPath quartzPath]; - vertGridLayer.strokeColor = [[theme.backgroundColor blendedColorWithFraction:kBlendedBackgroundColorFraction ofColor:(self.isDark ? [NSColor lightGrayColor] : [NSColor blackColor])] CGColor]; + vertGridLayer.strokeColor = [[theme.backgroundColor blendedColorWithFraction:kBlendedBackgroundColorFraction + ofColor:(self.appear == darkAppear ? [NSColor lightGrayColor] : [NSColor blackColor])] CGColor]; vertGridLayer.lineWidth = theme.edgeInset.width / 2; vertGridLayer.lineCap = kCALineCapRound; [panelLayer addSublayer:vertGridLayer]; @@ -1469,7 +1479,8 @@ - (BOOL)convertClickSpot:(NSPoint)spot toIndex:(NSUInteger *)index { return NO; } -@end +@end // SquirrelView + @implementation SquirrelPanel { SquirrelView *_view; @@ -1479,14 +1490,10 @@ @implementation SquirrelPanel { NSSize _maxSize; CGFloat _textWidthLimit; - NSString *_preedit; - NSRange _selRange; - NSUInteger _caretPos; - NSArray *_candidates; - NSArray *_comments; + NSUInteger _numCandidates; NSUInteger _index; - NSUInteger _pageNum; NSUInteger _turnPage; + BOOL _firstPage; BOOL _lastPage; NSPoint _scrollLocus; @@ -1520,8 +1527,8 @@ - (BOOL)inlineCandidate { return _view.currentTheme.inlineCandidate; } -- (void)initializeUIStyleForDarkMode:(BOOL)isDark { - SquirrelTheme *theme = [_view selectTheme:isDark]; +- (void)initializeUIStyleForAppearance:(SquirrelAppear)appear { + SquirrelTheme *theme = [_view selectTheme:appear]; NSFont *userFont = [NSFont fontWithDescriptor:getFontDescriptor([NSFont userFontOfSize:0.0].fontName) size:kDefaultFontSize]; @@ -1616,8 +1623,8 @@ - (void)initializeUIStyleForDarkMode:(BOOL)isDark { pagingParagraphStyle:pagingParagraphStyle statusParagraphStyle:statusParagraphStyle]; - [theme setSelectKeys:@"1234567890" - labels:@[@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"0"]]; + [theme setSelectKeys:@"12345" + labels:@[@"1", @"2", @"3", @"4", @"5"]]; [theme setCandidateFormat:kDefaultCandidateFormat]; } @@ -1647,8 +1654,8 @@ - (instancetype)init { [contentView addSubview:_view.textView]; self.contentView = contentView; - [self initializeUIStyleForDarkMode:NO]; - [self initializeUIStyleForDarkMode:YES]; + [self initializeUIStyleForAppearance:defaultAppear]; + [self initializeUIStyleForAppearance:darkAppear]; _maxSize = NSZeroSize; _initPosition = YES; } @@ -1656,63 +1663,59 @@ - (instancetype)init { } - (void)sendEvent:(NSEvent *)event { + NSPoint spot = [_view convertPoint:self.mouseLocationOutsideOfEventStream + fromView:nil]; + NSUInteger cursorIndex = NSNotFound; switch (event.type) { - case NSEventTypeLeftMouseUp: { - NSPoint spot = [_view convertPoint:self.mouseLocationOutsideOfEventStream - fromView:nil]; - NSUInteger cursorIndex = NSNotFound; + case NSEventTypeLeftMouseUp: if (event.clickCount == 1 && [_view convertClickSpot:spot toIndex:&cursorIndex]) { if (cursorIndex == _index) { rimeIndex indexChar = [_view.currentTheme.selectKeys characterAtIndex:cursorIndex]; [_inputController perform:kSELECT onIndex:indexChar]; } else if (cursorIndex == _turnPage) { rimeIndex indexChar = cursorIndex == NSPageUpFunctionKey ? kPageUp : - (cursorIndex == NSPageDownFunctionKey ? kPageDown : kVoidSymbol); + (cursorIndex == NSPageDownFunctionKey ? kPageDown : kVoidSymbol); [_inputController perform:kSELECT onIndex:indexChar]; } } - } break; - case NSEventTypeRightMouseUp: { - NSPoint spot = [_view convertPoint:self.mouseLocationOutsideOfEventStream - fromView:nil]; - NSUInteger cursorIndex = NSNotFound; + break; + case NSEventTypeRightMouseUp: if (event.clickCount == 1 && [_view convertClickSpot:spot toIndex:&cursorIndex]) { if (cursorIndex == _index) { [_inputController perform:kDELETE onIndex:(rimeIndex)cursorIndex]; } } - } break; - case NSEventTypeMouseEntered: { - self.acceptsMouseMovedEvents = YES; - } break; - case NSEventTypeMouseExited: { - self.acceptsMouseMovedEvents = NO; - } break; - case NSEventTypeMouseMoved: { - NSPoint spot = [_view convertPoint:self.mouseLocationOutsideOfEventStream - fromView:nil]; - NSUInteger cursorIndex = NSNotFound; + break; + case NSEventTypeMouseMoved: if ([_view convertClickSpot:spot toIndex:&cursorIndex]) { - if (cursorIndex >= 0 && cursorIndex < _candidates.count && _index != cursorIndex) { + if (cursorIndex >= 0 && cursorIndex < _numCandidates && _index != cursorIndex) { _index = cursorIndex; rimeIndex indexChar = [_view.currentTheme.selectKeys characterAtIndex:cursorIndex]; [_inputController perform:kCHOOSE onIndex:indexChar]; } else if ((cursorIndex == NSPageUpFunctionKey || cursorIndex == NSPageDownFunctionKey) && _turnPage != cursorIndex) { _turnPage = cursorIndex; - [_view drawViewWithInsets:_view.insets + if (_turnPage == NSPageUpFunctionKey) { + [_view.textStorage addAttributes:_view.currentTheme.pagingHighlightedAttrs range:NSMakeRange(_view.pagingRange.location, 1)]; + cursorIndex = _firstPage ? NSBeginFunctionKey : NSPageUpFunctionKey; + } else if (_turnPage == NSPageDownFunctionKey) { + [_view.textStorage addAttributes:_view.currentTheme.pagingHighlightedAttrs range:NSMakeRange(NSMaxRange(_view.pagingRange) - 1, 1)]; + cursorIndex = _lastPage ? NSEndFunctionKey : NSPageDownFunctionKey; + } + [_view drawViewWithInsets:_view.insets candidateRanges:_view.candidateRanges highlightedIndex:_view.highlightedIndex preeditRange:_view.preeditRange highlightedPreeditRange:_view.highlightedPreeditRange pagingRange:_view.pagingRange pagingButton:cursorIndex]; + [self show]; } } - } break; - case NSEventTypeLeftMouseDragged: { + break; + case NSEventTypeLeftMouseDragged: _maxSize = NSZeroSize; // reset the remember_size references after moving the panel [self performWindowDragWithEvent:event]; - } break; + break; case NSEventTypeScrollWheel: { SquirrelTheme *theme = _view.currentTheme; CGFloat scrollThreshold = [theme.attrs[NSParagraphStyleAttributeName] maximumLineHeight] + @@ -1744,9 +1747,9 @@ - (void)sendEvent:(NSEvent *)event { } } break; default: + [super sendEvent:event]; break; } - [super sendEvent:event]; } - (void)getCurrentScreen { @@ -1779,7 +1782,7 @@ - (void)getTextWidthLimit { // Get the window size, it will be the dirtyRect in SquirrelView.drawRect - (void)show { NSAppearance *requestedAppearance = [NSAppearance appearanceNamed: - (_view.isDark ? NSAppearanceNameDarkAqua : NSAppearanceNameAqua)]; + (_view.appear == darkAppear ? NSAppearanceNameDarkAqua : NSAppearanceNameAqua)]; if (self.appearance != requestedAppearance) { self.appearance = requestedAppearance; } @@ -1788,7 +1791,6 @@ - (void)show { SquirrelTheme *theme = _view.currentTheme; NSTextContainer *textContainer = _view.textView.textContainer; NSEdgeInsets insets = _view.insets; - CGFloat offsetHeight = MAX(kOffsetHeight, round(MAX(NSWidth(_position), NSHeight(_position)) / 2)); CGFloat textWidthRatio = MIN(1.0, 1.0 / (theme.vertical ? 4 : 3) + [theme.attrs[NSFontAttributeName] pointSize] / 144.0); NSRect screenRect = _screen.visibleFrame; CGFloat textHeightLimit = (theme.vertical ? NSWidth(screenRect) : NSHeight(screenRect)) * textWidthRatio - insets.top - insets.bottom; @@ -1803,8 +1805,8 @@ - (void)show { } } if (theme.rememberSize) { // remember panel size (fix the top leading anchor of the panel in screen coordiantes) - if ((theme.vertical ? (NSMinY(_position) - NSMinY(screenRect) <= NSHeight(screenRect) * textWidthRatio + offsetHeight) - : (sweepVertical ? (NSMinX(_position) - NSMinX(screenRect) > NSWidth(screenRect) * textWidthRatio + offsetHeight) + if ((theme.vertical ? (NSMinY(_position) - NSMinY(screenRect) <= NSHeight(screenRect) * textWidthRatio + kOffsetHeight) + : (sweepVertical ? (NSMinX(_position) - NSMinX(screenRect) > NSWidth(screenRect) * textWidthRatio + kOffsetHeight) : (NSMinX(_position) + MAX(NSWidth(maxContentRect), _maxSize.width) + insets.right > NSMaxX(screenRect)))) && theme.lineLength == 0) { if (NSWidth(maxContentRect) >= _maxSize.width) { @@ -1814,8 +1816,8 @@ - (void)show { [textContainer setSize:NSMakeSize(_maxSize.width, textHeightLimit)]; } } - if (theme.vertical ? (NSMinX(_position) - NSMinX(screenRect) < MAX(NSHeight(maxContentRect), _maxSize.height) + insets.top + insets.bottom + (sweepVertical ? offsetHeight : 0)) - : (NSMinY(_position) - NSMinY(screenRect) < MAX(NSHeight(maxContentRect), _maxSize.height) + insets.top + insets.bottom + (sweepVertical ? 0 : offsetHeight))) { + if (theme.vertical ? (NSMinX(_position) - NSMinX(screenRect) < MAX(NSHeight(maxContentRect), _maxSize.height) + insets.top + insets.bottom + (sweepVertical ? kOffsetHeight : 0)) + : (NSMinY(_position) - NSMinY(screenRect) < MAX(NSHeight(maxContentRect), _maxSize.height) + insets.top + insets.bottom + (sweepVertical ? 0 : kOffsetHeight))) { if (NSHeight(maxContentRect) >= _maxSize.height) { _maxSize.height = NSHeight(maxContentRect); } else { @@ -1824,9 +1826,8 @@ - (void)show { } } - _initPosition |= NSIntersectsRect(self.frame, _position); NSRect windowRect; - if (theme.vertical) { + if (theme.vertical) { // anchor is the top right corner in screen coordinates (MaxX, MaxY) windowRect = NSMakeRect(NSMaxX(self.frame) - NSHeight(maxContentRect) - insets.top - insets.bottom, NSMaxY(self.frame) - NSWidth(maxContentRect) - insets.left - insets.right, NSHeight(maxContentRect) + insets.top + insets.bottom, @@ -1834,19 +1835,19 @@ - (void)show { _initPosition |= NSIntersectsRect(windowRect, _position); if (_initPosition) { // To avoid jumping up and down while typing, use the lower screen when typing on upper, and vice versa - if (NSMinY(_position) - NSMinY(screenRect) > NSHeight(screenRect) * textWidthRatio + offsetHeight) { - windowRect.origin.y = NSMinY(_position) + (sweepVertical ? insets.left : -offsetHeight) - NSHeight(windowRect); + if (NSMinY(_position) - NSMinY(screenRect) > NSHeight(screenRect) * textWidthRatio + kOffsetHeight) { + windowRect.origin.y = NSMinY(_position) - (sweepVertical ? 0 : insets.left + kOffsetHeight) - NSWidth(maxContentRect) - insets.right; } else { - windowRect.origin.y = NSMaxY(_position) + (sweepVertical ? 0 : offsetHeight); + windowRect.origin.y = NSMaxY(_position) + (sweepVertical ? 0 : kOffsetHeight); } // Make the right edge of candidate block fixed at the left of cursor - windowRect.origin.x = NSMinX(_position) - (sweepVertical ? offsetHeight : 0) - NSWidth(windowRect); + windowRect.origin.x = NSMinX(_position) - (sweepVertical ? kOffsetHeight : 0) - NSHeight(maxContentRect) - insets.top - insets.bottom; if (!sweepVertical && _view.preeditRange.length > 0) { NSRect preeditRect = [_view contentRectForRange:_view.preeditRange]; windowRect.origin.x += round(NSHeight(preeditRect) + [theme.preeditAttrs[NSFontAttributeName] descender] + insets.top); } } - } else { + } else { // anchor is the top left corner in screen coordinates (MinX, MaxY) windowRect = NSMakeRect(NSMinX(self.frame), NSMaxY(self.frame) - NSHeight(maxContentRect) - insets.top - insets.bottom, NSWidth(maxContentRect) + insets.left + insets.right, @@ -1855,30 +1856,30 @@ - (void)show { if (_initPosition) { if (sweepVertical) { // To avoid jumping left and right while typing, use the lefter screen when typing on righter, and vice versa - if (NSMinX(_position) - NSMinX(screenRect) > NSWidth(screenRect) * textWidthRatio + offsetHeight) { - windowRect.origin.x = NSMinX(_position) - offsetHeight - NSWidth(windowRect); + if (NSMinX(_position) - NSMinX(screenRect) > NSWidth(screenRect) * textWidthRatio + kOffsetHeight) { + windowRect.origin.x = NSMinX(_position) - kOffsetHeight - NSWidth(windowRect); } else { - windowRect.origin.x = NSMaxX(_position) + offsetHeight; + windowRect.origin.x = NSMaxX(_position) + kOffsetHeight; } windowRect.origin.y = NSMinY(_position) - NSHeight(windowRect); } else { - windowRect.origin = NSMakePoint(NSMinX(_position) - insets.left, - NSMinY(_position) - offsetHeight - NSHeight(windowRect)); + windowRect.origin.x = NSMinX(_position) - insets.left; + windowRect.origin.y = NSMinY(_position) - kOffsetHeight - NSHeight(windowRect); } } } if (NSMaxX(windowRect) > NSMaxX(screenRect)) { - windowRect.origin.x = (_initPosition && sweepVertical ? NSMinX(_position) - offsetHeight : NSMaxX(screenRect)) - NSWidth(windowRect); + windowRect.origin.x = (_initPosition && sweepVertical ? MIN(NSMinX(_position) - kOffsetHeight, NSMaxX(screenRect)) : NSMaxX(screenRect)) - NSWidth(windowRect); } if (NSMinX(windowRect) < NSMinX(screenRect)) { - windowRect.origin.x = _initPosition && sweepVertical ? NSMaxX(_position) + offsetHeight : NSMinX(screenRect); + windowRect.origin.x = _initPosition && sweepVertical ? MAX(NSMaxX(_position) + kOffsetHeight, NSMinX(screenRect)) : NSMinX(screenRect); } if (NSMinY(windowRect) < NSMinY(screenRect)) { - windowRect.origin.y = _initPosition && !sweepVertical ? NSMaxY(_position) + offsetHeight : NSMinY(screenRect); + windowRect.origin.y = _initPosition && !sweepVertical ? MAX(NSMaxY(_position) + kOffsetHeight, NSMinY(screenRect)) : NSMinY(screenRect); } if (NSMaxY(windowRect) > NSMaxY(screenRect)) { - windowRect.origin.y = (_initPosition && !sweepVertical ? NSMinY(_position) - offsetHeight : NSMaxY(screenRect)) - NSHeight(windowRect); + windowRect.origin.y = (_initPosition && !sweepVertical ? MIN(NSMinY(_position) - kOffsetHeight, NSMaxY(screenRect)) : NSMaxY(screenRect)) - NSHeight(windowRect); } if (theme.vertical) { @@ -1934,8 +1935,11 @@ - (void)hide { - (void)setLayoutForRange:(NSRange)charRange { BOOL verticalLayout = _view.currentTheme.vertical; - NSFont *refFont = [_view.textStorage attribute:CFBridgingRelease(kCTBaselineReferenceInfoAttributeName) atIndex:charRange.location effectiveRange:NULL][CFBridgingRelease(kCTBaselineReferenceFont)]; - NSParagraphStyle *style = [_view.textStorage attribute:NSParagraphStyleAttributeName atIndex:charRange.location effectiveRange:NULL]; + NSFont *refFont = [_view.textStorage attribute:CFBridgingRelease(kCTBaselineReferenceInfoAttributeName) + atIndex:charRange.location + effectiveRange:NULL][CFBridgingRelease(kCTBaselineReferenceFont)]; + NSParagraphStyle *style = [_view.textStorage attribute:NSParagraphStyleAttributeName + atIndex:charRange.location effectiveRange:NULL]; CGFloat refFontHeight = refFont.ascender - refFont.descender; CGFloat lineHeight = MAX(style.lineHeightMultiple > 0 ? refFontHeight * style.lineHeightMultiple : refFontHeight, style.minimumLineHeight); @@ -2068,23 +2072,14 @@ - (void)showPreedit:(NSString *)preedit comments:(NSArray *)comments highlighted:(NSUInteger)index pageNum:(NSUInteger)pageNum - lastPage:(BOOL)lastPage - turnPage:(NSUInteger)turnPage - update:(BOOL)update { - if (update) { - _preedit = preedit; - _selRange = selRange; - _caretPos = caretPos; - _candidates = candidates; - _comments = comments; - _index = index; - _pageNum = pageNum; - _lastPage = lastPage; - } - + lastPage:(BOOL)lastPage { [self getTextWidthLimit]; - NSUInteger numCandidates = candidates.count; - if (numCandidates > 0 || (preedit && preedit.length)) { + _numCandidates = candidates.count; + _index = _numCandidates == 0 ? NSNotFound : index; + _firstPage = pageNum == 0; + _lastPage = lastPage; + _turnPage = NSNotFound; + if (_numCandidates > 0 || (preedit && preedit.length)) { _statusMessage = nil; if (_statusTimer) { [_statusTimer invalidate]; @@ -2100,16 +2095,6 @@ - (void)showPreedit:(NSString *)preedit return; } - if (numCandidates == 0) { - _index = index = NSNotFound; - } - _turnPage = turnPage; - if (_turnPage == NSPageUpFunctionKey) { - turnPage = pageNum ? NSPageUpFunctionKey : NSBeginFunctionKey; - } else if (_turnPage == NSPageDownFunctionKey) { - turnPage = lastPage ? NSEndFunctionKey : NSPageDownFunctionKey; - } - SquirrelTheme *theme = _view.currentTheme; _view.textView.layoutOrientation = theme.vertical ? NSTextLayoutOrientationVertical : NSTextLayoutOrientationHorizontal; @@ -2121,7 +2106,7 @@ - (void)showPreedit:(NSString *)preedit [text setAttributedString:[[NSMutableAttributedString alloc] init]]; NSRange preeditRange = NSMakeRange(NSNotFound, 0); NSRange highlightedPreeditRange = NSMakeRange(NSNotFound, 0); - NSMutableArray *candidateRanges = [[NSMutableArray alloc] initWithCapacity:numCandidates]; + NSMutableArray *candidateRanges = [[NSMutableArray alloc] initWithCapacity:_numCandidates]; NSRange pagingRange = NSMakeRange(NSNotFound, 0); NSMutableParagraphStyle *paragraphStyleCandidate; @@ -2148,13 +2133,13 @@ - (void)showPreedit:(NSString *)preedit } // force caret to be rendered horizontally in vertical layout if (caretPos != NSNotFound) { - [preeditLine addAttributes:@{NSVerticalGlyphFormAttributeName: @NO} - range:NSMakeRange(caretPos - (caretPos < NSMaxRange(selRange)), 1)]; + [preeditLine addAttribute:NSVerticalGlyphFormAttributeName value:@NO + range:NSMakeRange(caretPos - (caretPos < NSMaxRange(selRange)), 1)]; } preeditRange = NSMakeRange(0, preeditLine.length); [text appendAttributedString:preeditLine]; - if (numCandidates > 0) { + if (_numCandidates > 0) { [text appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n" attributes:theme.preeditAttrs]]; } else { goto typesetter; @@ -2168,7 +2153,7 @@ - (void)showPreedit:(NSString *)preedit paragraphStyleCandidate = [theme.paragraphStyle copy]; } CGFloat tabInterval = theme.separatorWidth * 2; - for (NSUInteger idx = 0; idx < numCandidates; ++idx) { + for (NSUInteger idx = 0; idx < _numCandidates; ++idx) { // attributed labels are already included in candidateFormats NSMutableAttributedString *item = (idx == index) ? [theme.candidateHighlightedFormats[idx] mutableCopy] : [theme.candidateFormats[idx] mutableCopy]; NSRange candidateRange = [item.string rangeOfString:@"%@"]; @@ -2230,7 +2215,7 @@ - (void)showPreedit:(NSString *)preedit } // for linear layout, middle-truncate candidates that are longer than one line if (theme.linear && ceil(item.size.width + theme.separatorWidth) > _textWidthLimit) { - if (idx < numCandidates - 1 || theme.showPaging) { + if (idx < _numCandidates - 1 || theme.showPaging) { [text appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n" attributes:theme.commentAttrs]]; } NSMutableParagraphStyle *paragraphStyleTruncating = [paragraphStyleCandidate mutableCopy]; @@ -2251,11 +2236,6 @@ - (void)showPreedit:(NSString *)preedit initWithString:[NSString stringWithFormat:@" %lu ", pageNum + 1] attributes:theme.pagingAttrs]]; [paging appendAttributedString:[[NSAttributedString alloc] initWithAttributedString:(lastPage ? theme.symbolForwardStroke : theme.symbolForwardFill)]]; - if (_turnPage == NSPageUpFunctionKey) { - [paging addAttributes:theme.pagingHighlightedAttrs range:NSMakeRange(0, 1)]; - } else if (_turnPage == NSPageDownFunctionKey) { - [paging addAttributes:theme.pagingHighlightedAttrs range:NSMakeRange(paging.length - 1, 1)]; - } [text appendAttributedString:theme.separator]; NSUInteger pagingStart = text.length; @@ -2307,7 +2287,7 @@ - (void)showPreedit:(NSString *)preedit [self setLayoutForRange:preeditRange]; insets.top = theme.edgeInset.height; } - if (numCandidates > 0) { + if (_numCandidates > 0) { NSRange candidateBlockRange = NSMakeRange(candidateBlockStart, (!theme.linear && pagingRange.length > 0 ? pagingRange.location : text.length) - candidateBlockStart); [self setLayoutForRange:candidateBlockRange]; if (!theme.linear && pagingRange.length > 0) { @@ -2327,7 +2307,7 @@ - (void)showPreedit:(NSString *)preedit preeditRange:preeditRange highlightedPreeditRange:highlightedPreeditRange pagingRange:pagingRange - pagingButton:turnPage]; + pagingButton:_turnPage]; [self show]; } @@ -2512,9 +2492,9 @@ - (void)setAnnotationHeight:(CGFloat)height { } - (void)loadLabelConfig:(SquirrelConfig *)config { - SquirrelTheme *theme = [_view selectTheme:NO]; + SquirrelTheme *theme = [_view selectTheme:defaultAppear]; [SquirrelPanel updateTheme:theme withLabelConfig:config]; - SquirrelTheme *darkTheme = [_view selectTheme:YES]; + SquirrelTheme *darkTheme = [_view selectTheme:darkAppear]; [SquirrelPanel updateTheme:darkTheme withLabelConfig:config]; } @@ -2547,16 +2527,16 @@ + (void)updateTheme:(SquirrelTheme *)theme } - (void)loadConfig:(SquirrelConfig *)config - forDarkMode:(BOOL)isDark { - SquirrelTheme *theme = [_view selectTheme:isDark]; + forAppearance:(SquirrelAppear)appear { + SquirrelTheme *theme = [_view selectTheme:appear]; NSSet *styleOptions = [NSSet setWithArray:self.optionSwitcher.optionStates]; - [SquirrelPanel updateTheme:theme withConfig:config styleOptions:styleOptions forDarkMode:isDark]; + [SquirrelPanel updateTheme:theme withConfig:config styleOptions:styleOptions forAppearance:appear]; } + (void)updateTheme:(SquirrelTheme *)theme withConfig:(SquirrelConfig *)config styleOptions:(NSSet *)styleOptions - forDarkMode:(BOOL)isDark { + forAppearance:(SquirrelAppear)appear { // INTERFACE BOOL linear = NO; BOOL tabled = NO; @@ -2603,7 +2583,7 @@ + (void)updateTheme:(SquirrelTheme *)theme NSColor *highlightedCommentTextColor; NSString *colorScheme; - if (isDark) { + if (appear == darkAppear) { for (NSString *option in styleOptions) { if ((colorScheme = [config getString:[NSString stringWithFormat:@"style/%@/color_scheme_dark", option]])) break; } @@ -2792,7 +2772,7 @@ + (void)updateTheme:(SquirrelTheme *)theme pagingAttrs[NSVerticalGlyphFormAttributeName] = @(NO); // CHROMATICS refinement - if (theme.translucency > 0 && ABS(backgroundColor.brightnessComponent - isDark) >= 0.6) { + if (theme.translucency > 0 && ABS(backgroundColor.brightnessComponent - appear == darkAppear) <= 0.4) { backgroundColor = inverseColor(backgroundColor); borderColor = inverseColor(borderColor); preeditBackgroundColor = inverseColor(preeditBackgroundColor); @@ -2882,4 +2862,4 @@ + (void)updateTheme:(SquirrelTheme *)theme [theme setStatusMessageType:statusMessageType]; } -@end +@end // SquirrelPanel diff --git a/macos_keycode.m b/macos_keycode.m index 32eefe081..de427b026 100644 --- a/macos_keycode.m +++ b/macos_keycode.m @@ -43,7 +43,7 @@ int osx_modifiers_to_rime_modifiers(unsigned long modifiers) { //OSX_VK_ENTER_POWERBOOK -> ? { OSX_VK_ESCAPE, XK_Escape }, { OSX_VK_FORWARD_DELETE, XK_Delete }, - //{OSX_VK_HELP, XK_Help}, // the same keycode with OSX_VK_PC_INSERT + //{OSX_VK_HELP, XK_Help}, // the same keycode as OSX_VK_PC_INSERT { OSX_VK_RETURN, XK_Return }, { OSX_VK_SPACE, XK_space }, { OSX_VK_TAB, XK_Tab }, @@ -102,12 +102,15 @@ int osx_modifiers_to_rime_modifiers(unsigned long modifiers) { // pc keyboard { OSX_VK_PC_APPLICATION, XK_Menu }, { OSX_VK_PC_INSERT, XK_Insert }, - { OSX_VK_PC_KEYPAD_NUMLOCK, XK_Num_Lock }, + //{OSX_VK_PC_KEYPAD_NUMLOCK, XK_Num_Lock}, // the same keycode as OSX_VK_KEYPAD_CLEAR { OSX_VK_PC_PAUSE, XK_Pause }, //OSX_VK_PC_POWER -> ? { OSX_VK_PC_PRINTSCREEN, XK_Print }, { OSX_VK_PC_SCROLLLOCK, XK_Scroll_Lock }, + // JIS keyboard + { OSX_VK_JIS_EISUU, XK_Eisu_toggle }, + { -1, -1 } };