From 68e3d2e87775bf5e7d39597a35103b1bd0afac17 Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Tue, 26 Mar 2019 01:05:23 -0700 Subject: [PATCH 01/30] Render a vertical guide over the column the cursor is in (Metal View implementation). --- .../Metal/Infrastructure/iTermMetalRenderer.h | 1 + .../Renderers/iTermCursorGuideRenderer.h | 4 +- .../Renderers/iTermCursorGuideRenderer.m | 53 +++++++++++++++---- sources/Metal/iTermMetalDriver.m | 9 +--- 4 files changed, 47 insertions(+), 20 deletions(-) diff --git a/sources/Metal/Infrastructure/iTermMetalRenderer.h b/sources/Metal/Infrastructure/iTermMetalRenderer.h index aee0e34db4..4206a8299e 100644 --- a/sources/Metal/Infrastructure/iTermMetalRenderer.h +++ b/sources/Metal/Infrastructure/iTermMetalRenderer.h @@ -46,6 +46,7 @@ NS_CLASS_AVAILABLE(10_11, NA) @interface iTermMetalRendererTransientState : NSObject @property (nonatomic, strong, readonly) __kindof iTermRenderConfiguration *configuration; @property (nonatomic, strong) id vertexBuffer; +@property (nonatomic, strong) id vvertexBuffer; @property (nonatomic, readonly) iTermMetalBufferPoolContext *poolContext; @property (nonatomic, weak) iTermMetalDebugInfo *debugInfo; @property (nonatomic, strong) NSImage *renderedOutputForDebugging; diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.h b/sources/Metal/Renderers/iTermCursorGuideRenderer.h index d9178e07c6..cb9cb27faf 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.h +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.h @@ -1,12 +1,12 @@ #import #import "iTermMetalCellRenderer.h" +#import "VT100GridTypes.h" NS_ASSUME_NONNULL_BEGIN @interface iTermCursorGuideRendererTransientState : iTermMetalCellRendererTransientState -// set to -1 if cursor's row is not currently visible. -- (void)setRow:(int)row; +- (void)setCursorCoord:(VT100GridCoord)coord within:(VT100GridSize)bounds; @end @interface iTermCursorGuideRenderer : NSObject diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.m b/sources/Metal/Renderers/iTermCursorGuideRenderer.m index b7326aaf78..1c842b52a9 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.m +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.m @@ -3,14 +3,17 @@ @interface iTermCursorGuideRendererTransientState() @property (nonatomic, strong) id texture; @property (nonatomic) int row; +@property (nonatomic) int col; @end @implementation iTermCursorGuideRendererTransientState { int _row; + int _col; } -- (void)setRow:(int)row { - _row = row; +- (void)setCursorCoord:(VT100GridCoord)coord within:(VT100GridSize)bounds { + _row = (0 <= coord.y && coord.y < bounds.height) ? coord.y : -1; + _col = (0 <= coord.x && coord.x < bounds.width) ? coord.x : -1; } - (void)initializeVerticesWithPool:(iTermMetalBufferPool *)verticesPool { @@ -35,6 +38,23 @@ - (void)initializeVerticesWithPool:(iTermMetalBufferPool *)verticesPool { self.vertexBuffer = [verticesPool requestBufferFromContext:self.poolContext withBytes:vertices checkIfChanged:YES]; + + const CGRect vQuad = CGRectMake(self.margins.left + self.col * cellSize.width, + self.margins.top, + cellSize.width, + cellSize.height * gridSize.height); + const iTermVertex vvertices[] = { + { { CGRectGetMaxX(vQuad), CGRectGetMinY(vQuad) }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { CGRectGetMinX(vQuad), CGRectGetMinY(vQuad) }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { CGRectGetMinX(vQuad), CGRectGetMaxY(vQuad) }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, + + { { CGRectGetMaxX(vQuad), CGRectGetMinY(vQuad) }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { CGRectGetMinX(vQuad), CGRectGetMaxY(vQuad) }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, + { { CGRectGetMaxX(vQuad), CGRectGetMaxY(vQuad) }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, + }; + self.vvertexBuffer = [verticesPool requestBufferFromContext:self.poolContext + withBytes:vvertices + checkIfChanged:YES]; } - (void)writeDebugInfoToFolder:(NSURL *)folder { @@ -106,19 +126,30 @@ - (void)setColor:(NSColor *)color { - (void)drawWithFrameData:(iTermMetalFrameData *)frameData transientState:(__kindof iTermMetalCellRendererTransientState *)transientState { iTermCursorGuideRendererTransientState *tState = transientState; - if (tState.row < 0) { - // Cursor is offscreen. We set it to -1 to signal this. + if (tState.row < 0 || tState.col < 0) { return; } [tState initializeVerticesWithPool:_cellRenderer.verticesPool]; - [_cellRenderer drawWithTransientState:tState - renderEncoder:frameData.renderEncoder - numberOfVertices:6 - numberOfPIUs:0 - vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.vertexBuffer } - fragmentBuffers:@{} - textures:@{ @(iTermTextureIndexPrimary): tState.texture } ]; + if (tState.row >= 0 && self.enabled) { + [_cellRenderer drawWithTransientState:tState + renderEncoder:frameData.renderEncoder + numberOfVertices:6 + numberOfPIUs:0 + vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.vertexBuffer } + fragmentBuffers:@{} + textures:@{ @(iTermTextureIndexPrimary): tState.texture } ]; + } + + if (tState.col >= 0 && self.enabled) { + [_cellRenderer drawWithTransientState:tState + renderEncoder:frameData.renderEncoder + numberOfVertices:6 + numberOfPIUs:0 + vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.vvertexBuffer } + fragmentBuffers:@{} + textures:@{ @(iTermTextureIndexPrimary): tState.texture } ]; + } } #pragma mark - Private diff --git a/sources/Metal/iTermMetalDriver.m b/sources/Metal/iTermMetalDriver.m index 0d48797703..904e73a31d 100644 --- a/sources/Metal/iTermMetalDriver.m +++ b/sources/Metal/iTermMetalDriver.m @@ -1219,13 +1219,8 @@ - (void)populateHighlightRowRendererTransientStateWithFrameData:(iTermMetalFrame - (void)populateCursorGuideRendererTransientStateWithFrameData:(iTermMetalFrameData *)frameData { iTermCursorGuideRendererTransientState *tState = [frameData transientStateForRenderer:_cursorGuideRenderer]; - iTermMetalCursorInfo *cursorInfo = frameData.perFrameState.metalDriverCursorInfo; - if (cursorInfo.coord.y >= 0 && - cursorInfo.coord.y < frameData.gridSize.height) { - [tState setRow:frameData.perFrameState.metalDriverCursorInfo.coord.y]; - } else { - [tState setRow:-1]; - } + VT100GridCoord coord = frameData.perFrameState.metalDriverCursorInfo.coord; + [tState setCursorCoord:coord within:frameData.gridSize]; } - (void)populateTimestampsRendererTransientStateWithFrameData:(iTermMetalFrameData *)frameData { From 6827cb36ef397b70be210115c4256f3fa5f70d85 Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Tue, 26 Mar 2019 01:21:01 -0700 Subject: [PATCH 02/30] Separate control of the vertical cursor guide from the horizontal guide. --- Interfaces/MainMenu.xib | 6 ++++ Interfaces/PreferencePanel.xib | 17 ++++++++-- iTerm2XCTests/VT100ScreenTest.m | 6 ++++ sources/ITAddressBookMgr.h | 1 + .../Renderers/iTermCursorGuideRenderer.h | 1 + .../Renderers/iTermCursorGuideRenderer.m | 2 +- sources/Metal/iTermMetalDriver.h | 1 + sources/Metal/iTermMetalDriver.m | 4 ++- sources/PTYSession.h | 1 + sources/PTYSession.m | 33 +++++++++++++++++++ sources/PTYTextView.h | 3 ++ sources/PTYTextView.m | 8 +++++ .../ProfilesColorsPreferencesViewController.m | 5 +++ sources/PseudoTerminal.m | 9 +++++ sources/VT100Screen.m | 4 +++ sources/VT100ScreenDelegate.h | 1 + sources/VT100Terminal.m | 2 ++ sources/VT100TerminalDelegate.h | 1 + sources/iTermMetalPerFrameState.m | 4 +++ .../iTermMetalPerFrameStateConfiguration.h | 1 + .../iTermMetalPerFrameStateConfiguration.m | 1 + sources/iTermProfilePreferences.m | 3 +- sources/iTermTextDrawingHelper.h | 3 ++ 23 files changed, 112 insertions(+), 5 deletions(-) diff --git a/Interfaces/MainMenu.xib b/Interfaces/MainMenu.xib index 39b2e2fccd..eedfcfe25a 100644 --- a/Interfaces/MainMenu.xib +++ b/Interfaces/MainMenu.xib @@ -668,6 +668,12 @@ Gw + + + + + + diff --git a/Interfaces/PreferencePanel.xib b/Interfaces/PreferencePanel.xib index e58e497655..325debd784 100644 --- a/Interfaces/PreferencePanel.xib +++ b/Interfaces/PreferencePanel.xib @@ -1545,6 +1545,7 @@ DQ + @@ -2272,7 +2273,7 @@ DQ - + @@ -2323,7 +2324,7 @@ DQ + diff --git a/iTerm2XCTests/VT100ScreenTest.m b/iTerm2XCTests/VT100ScreenTest.m index 5474e776d1..b1b5aa68c0 100644 --- a/iTerm2XCTests/VT100ScreenTest.m +++ b/iTerm2XCTests/VT100ScreenTest.m @@ -748,6 +748,12 @@ - (void)screenSetHighlightCursorLine:(BOOL)highlight { - (void)screenCursorDidMoveToLine:(int)line { } +- (void)screenSetHighlightCursorCol:(BOOL)highlight { +} + +- (void)screenCursorDidMoveToCol:(int)line { +} + - (void)screenSaveScrollPosition { } diff --git a/sources/ITAddressBookMgr.h b/sources/ITAddressBookMgr.h index 408a1664e8..30c0c27541 100644 --- a/sources/ITAddressBookMgr.h +++ b/sources/ITAddressBookMgr.h @@ -114,6 +114,7 @@ #define KEY_USE_UNDERLINE_COLOR @"Use Underline Color" #define KEY_CURSOR_BOOST @"Cursor Boost" #define KEY_USE_CURSOR_GUIDE @"Use Cursor Guide" +#define KEY_USE_VERT_CURSOR_GUIDE @"Use Vertical Cursor Guide" #define KEY_CURSOR_GUIDE_COLOR @"Cursor Guide Color" #define KEY_BADGE_COLOR @"Badge Color" diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.h b/sources/Metal/Renderers/iTermCursorGuideRenderer.h index cb9cb27faf..92e4d448c8 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.h +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.h @@ -12,6 +12,7 @@ NS_ASSUME_NONNULL_BEGIN @interface iTermCursorGuideRenderer : NSObject @property (nonatomic) BOOL enabled; +@property (nonatomic) BOOL venabled; - (nullable instancetype)initWithDevice:(id)device NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE; diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.m b/sources/Metal/Renderers/iTermCursorGuideRenderer.m index 1c842b52a9..16dcad904f 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.m +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.m @@ -141,7 +141,7 @@ - (void)drawWithFrameData:(iTermMetalFrameData *)frameData textures:@{ @(iTermTextureIndexPrimary): tState.texture } ]; } - if (tState.col >= 0 && self.enabled) { + if (tState.col >= 0 && self.venabled) { [_cellRenderer drawWithTransientState:tState renderEncoder:frameData.renderEncoder numberOfVertices:6 diff --git a/sources/Metal/iTermMetalDriver.h b/sources/Metal/iTermMetalDriver.h index c3e724ff94..d2e04157f6 100644 --- a/sources/Metal/iTermMetalDriver.h +++ b/sources/Metal/iTermMetalDriver.h @@ -61,6 +61,7 @@ NS_CLASS_AVAILABLE(10_11, NA) @property (nonatomic, readonly) BOOL showBroadcastStripes; @property (nonatomic, readonly) NSColor *cursorGuideColor; @property (nonatomic, readonly) BOOL cursorGuideEnabled; +@property (nonatomic, readonly) BOOL cursorVGuideEnabled; @property (nonatomic, readonly) vector_float4 fullScreenFlashColor; @property (nonatomic, readonly) BOOL timestampsEnabled; @property (nonatomic, readonly) NSColor *timestampsBackgroundColor; diff --git a/sources/Metal/iTermMetalDriver.m b/sources/Metal/iTermMetalDriver.m index 904e73a31d..41d14444bc 100644 --- a/sources/Metal/iTermMetalDriver.m +++ b/sources/Metal/iTermMetalDriver.m @@ -644,7 +644,8 @@ - (BOOL)shouldCreateIntermediateRenderPassDescriptor:(iTermMetalFrameData *)fram if (!_broadcastStripesRenderer.rendererDisabled && frameData.perFrameState.showBroadcastStripes) { return YES; } - if (!_cursorGuideRenderer.rendererDisabled && frameData.perFrameState.cursorGuideEnabled) { + if (!_cursorGuideRenderer.rendererDisabled && (frameData.perFrameState.cursorGuideEnabled + || frameData.perFrameState.cursorVGuideEnabled)) { return YES; } @@ -970,6 +971,7 @@ - (void)updateCursorGuideRendererForFrameData:(iTermMetalFrameData *)frameData { } [_cursorGuideRenderer setColor:frameData.perFrameState.cursorGuideColor]; _cursorGuideRenderer.enabled = frameData.perFrameState.cursorGuideEnabled; + _cursorGuideRenderer.venabled = frameData.perFrameState.cursorVGuideEnabled; } - (void)updateTimestampsRendererForFrameData:(iTermMetalFrameData *)frameData { diff --git a/sources/PTYSession.h b/sources/PTYSession.h index ecb63938b4..998a35fb4a 100644 --- a/sources/PTYSession.h +++ b/sources/PTYSession.h @@ -422,6 +422,7 @@ typedef enum { @property(nonatomic, readonly) BOOL hasSelection; @property(nonatomic, assign) BOOL highlightCursorLine; +@property(nonatomic, assign) BOOL highlightCursorCol; // Used to help remember total ordering on views while one is maximized @property(nonatomic, assign) NSPoint savedRootRelativeOrigin; diff --git a/sources/PTYSession.m b/sources/PTYSession.m index 3dcd6cf76d..38c60e2b6e 100644 --- a/sources/PTYSession.m +++ b/sources/PTYSession.m @@ -205,6 +205,7 @@ static NSString *const SESSION_ARRANGEMENT_DIRECTORIES = @"Directories"; // Array of strings static NSString *const SESSION_ARRANGEMENT_HOSTS = @"Hosts"; // Array of VT100RemoteHost static NSString *const SESSION_ARRANGEMENT_CURSOR_GUIDE = @"Cursor Guide"; // BOOL +static NSString *const SESSION_ARRANGEMENT_VCURSOR_GUIDE = @"Vertical Cursor Guide"; // BOOL static NSString *const SESSION_ARRANGEMENT_LAST_DIRECTORY = @"Last Directory"; // NSString static NSString *const SESSION_ARRANGEMENT_LAST_DIRECTORY_IS_UNSUITABLE_FOR_OLD_PWD = @"Last Directory Is Remote"; // BOOL static NSString *const SESSION_ARRANGEMENT_SELECTION = @"Selection"; // Dictionary for iTermSelection. @@ -1175,6 +1176,9 @@ + (void)finishInitializingArrangementOriginatedSession:(PTYSession *)aSession if (arrangement[SESSION_ARRANGEMENT_CURSOR_GUIDE]) { aSession.textview.highlightCursorLine = [arrangement[SESSION_ARRANGEMENT_CURSOR_GUIDE] boolValue]; } + if (arrangement[SESSION_ARRANGEMENT_VCURSOR_GUIDE]) { + aSession.textview.highlightCursorLine = [arrangement[SESSION_ARRANGEMENT_VCURSOR_GUIDE] boolValue]; + } aSession->_lastMark = [aSession.screen.lastMark retain]; aSession.lastRemoteHost = aSession.screen.lastRemoteHost; if (arrangement[SESSION_ARRANGEMENT_LAST_DIRECTORY]) { @@ -3463,6 +3467,8 @@ - (void)loadInitialColorTable } _textview.highlightCursorLine = [iTermProfilePreferences boolForKey:KEY_USE_CURSOR_GUIDE inProfile:_profile]; + _textview.highlightCursorCol = [iTermProfilePreferences boolForKey:KEY_USE_VERT_CURSOR_GUIDE + inProfile:_profile]; } - (NSColor *)tabColorInProfile:(NSDictionary *)profile @@ -3645,6 +3651,8 @@ - (void)setPreferencesFromAddressBookEntry:(NSDictionary *)aePrefs { if (!_cursorGuideSettingHasChanged) { _textview.highlightCursorLine = [iTermProfilePreferences boolForKey:KEY_USE_CURSOR_GUIDE inProfile:aDict]; + _textview.highlightCursorCol = [iTermProfilePreferences boolForKey:KEY_USE_VERT_CURSOR_GUIDE + inProfile:aDict]; } for (i = 0; i < 16; i++) { @@ -4371,6 +4379,7 @@ - (NSDictionary *)arrangementWithContents:(BOOL)includeContents { [NSDictionary dictionaryWithGridCoordRange:range]; result[SESSION_ARRANGEMENT_ALERT_ON_NEXT_MARK] = @(_alertOnNextMark); result[SESSION_ARRANGEMENT_CURSOR_GUIDE] = @(_textview.highlightCursorLine); + result[SESSION_ARRANGEMENT_VCURSOR_GUIDE] = @(_textview.highlightCursorCol); if (self.lastDirectory) { result[SESSION_ARRANGEMENT_LAST_DIRECTORY] = self.lastDirectory; result[SESSION_ARRANGEMENT_LAST_DIRECTORY_IS_UNSUITABLE_FOR_OLD_PWD] = @(self.lastDirectoryIsUnsuitableForOldPWD); @@ -8298,6 +8307,8 @@ - (void)screenDidReset { _cursorGuideSettingHasChanged = NO; _textview.highlightCursorLine = [iTermProfilePreferences boolForKey:KEY_USE_CURSOR_GUIDE inProfile:_profile]; + _textview.highlightCursorCol = [iTermProfilePreferences boolForKey:KEY_USE_VERT_CURSOR_GUIDE + inProfile:_profile]; [_textview setNeedsDisplay:YES]; _screen.trackCursorLineMovement = NO; } @@ -8570,6 +8581,28 @@ - (BOOL)highlightCursorLine { return _textview.highlightCursorLine; } +- (void)screenCursorDidMoveToCol:(int)col { + if (_textview.cursorVisible) { + [_textview setNeedsDisplayOnCol:col]; + } +} + +- (void)screenSetHighlightCursorCol:(BOOL)highlight { + _cursorGuideSettingHasChanged = YES; + self.highlightCursorCol = highlight; +} + +- (void)setHighlightCursorCol:(BOOL)highlight { + _cursorGuideSettingHasChanged = YES; + _textview.highlightCursorCol = highlight; + [_textview setNeedsDisplay:YES]; + _screen.trackCursorColMovement = highlight; +} + +- (BOOL)highlightCursorCol { + return _textview.highlightCursorCol; +} + - (BOOL)screenHasView { return _textview != nil; } diff --git a/sources/PTYTextView.h b/sources/PTYTextView.h index 86e55ca2db..7803550e6e 100644 --- a/sources/PTYTextView.h +++ b/sources/PTYTextView.h @@ -235,6 +235,9 @@ typedef NS_ENUM(NSInteger, PTYTextViewSelectionExtensionUnit) { // Draw a highlight along the entire line the cursor is on. @property(nonatomic, assign) BOOL highlightCursorLine; +// Draw a highlight along the entire column the cursor is in. +@property(nonatomic, assign) BOOL highlightCursorCol; + // Use the non-ascii font? If not set, use the regular font for all characters. @property(nonatomic, assign) BOOL useNonAsciiFont; diff --git a/sources/PTYTextView.m b/sources/PTYTextView.m index 639c32d509..7d3d0df4ec 100644 --- a/sources/PTYTextView.m +++ b/sources/PTYTextView.m @@ -581,6 +581,14 @@ - (BOOL)highlightCursorLine { return _drawingHelper.highlightCursorLine; } +- (void)setHighlightCursorCol:(BOOL)highlightCursorCol { + _drawingHelper.highlightCursorCol = highlightCursorCol; +} + +- (BOOL)highlightCursorCol { + return _drawingHelper.highlightCursorCol; +} + - (void)setUseNonAsciiFont:(BOOL)useNonAsciiFont { _drawingHelper.useNonAsciiFont = useNonAsciiFont; _useNonAsciiFont = useNonAsciiFont; diff --git a/sources/ProfilesColorsPreferencesViewController.m b/sources/ProfilesColorsPreferencesViewController.m index f4f4057ac7..f1efd6f0c0 100644 --- a/sources/ProfilesColorsPreferencesViewController.m +++ b/sources/ProfilesColorsPreferencesViewController.m @@ -62,6 +62,7 @@ @implementation ProfilesColorsPreferencesViewController { IBOutlet NSMenu *_presetsMenu; IBOutlet NSButton *_useGuide; + IBOutlet NSButton *_useVGuide; IBOutlet CPKColorWell *_guideColor; IBOutlet NSPopUpButton *_presetsPopupButton; @@ -171,6 +172,10 @@ - (void)awakeFromNib { key:KEY_USE_CURSOR_GUIDE type:kPreferenceInfoTypeCheckbox]; + [self defineControl:_useVGuide + key:KEY_USE_VERT_CURSOR_GUIDE + type:kPreferenceInfoTypeCheckbox]; + info = [self defineControl:_useBrightBold key:KEY_USE_BOLD_COLOR type:kPreferenceInfoTypeCheckbox]; diff --git a/sources/PseudoTerminal.m b/sources/PseudoTerminal.m index 7cdee2312f..52959eda1d 100644 --- a/sources/PseudoTerminal.m +++ b/sources/PseudoTerminal.m @@ -1782,6 +1782,11 @@ - (IBAction)toggleCursorGuide:(id)sender { session.highlightCursorLine = !session.highlightCursorLine; } +- (IBAction)toggleVCursorGuide:(id)sender { + PTYSession *session = [self currentSession]; + session.highlightCursorCol = !session.highlightCursorCol; +} + - (IBAction)toggleSelectionRespectsSoftBoundaries:(id)sender { iTermController *controller = [iTermController sharedInstance]; controller.selectionRespectsSoftBoundaries = !controller.selectionRespectsSoftBoundaries; @@ -8590,6 +8595,10 @@ - (BOOL)validateMenuItem:(NSMenuItem *)item { PTYSession *session = [self currentSession]; [item setState:session.highlightCursorLine ? NSOnState : NSOffState]; result = YES; + } else if ([item action] == @selector(toggleVCursorGuide:)) { + PTYSession *session = [self currentSession]; + [item setState:session.highlightCursorCol ? NSOnState : NSOffState]; + result = YES; } else if ([item action] == @selector(toggleSelectionRespectsSoftBoundaries:)) { [item setState:[[iTermController sharedInstance] selectionRespectsSoftBoundaries] ? NSOnState : NSOffState]; result = YES; diff --git a/sources/VT100Screen.m b/sources/VT100Screen.m index 4be6d3e4b8..2f03f079e4 100644 --- a/sources/VT100Screen.m +++ b/sources/VT100Screen.m @@ -4139,6 +4139,10 @@ - (void)terminalSetHighlightCursorLine:(BOOL)highlight { [delegate_ screenSetHighlightCursorLine:highlight]; } +- (void)terminalSetHighlightCursorCol:(BOOL)highlight { + [delegate_ screenSetHighlightCursorCol:highlight]; +} + - (void)terminalPromptDidStart { [self promptDidStartAt:VT100GridAbsCoordMake(currentGrid_.cursor.x, currentGrid_.cursor.y + self.numberOfScrollbackLines + self.totalScrollbackOverflow)]; diff --git a/sources/VT100ScreenDelegate.h b/sources/VT100ScreenDelegate.h index 1936e9f128..2f48145ae7 100644 --- a/sources/VT100ScreenDelegate.h +++ b/sources/VT100ScreenDelegate.h @@ -185,6 +185,7 @@ - (void)screenSetCursorVisible:(BOOL)visible; - (void)screenSetHighlightCursorLine:(BOOL)highlight; +- (void)screenSetHighlightCursorCol:(BOOL)highlight; // Only called if the trackCursorLineMovement property is set. - (void)screenCursorDidMoveToLine:(int)line; diff --git a/sources/VT100Terminal.m b/sources/VT100Terminal.m index 562a197006..ac9f46526e 100644 --- a/sources/VT100Terminal.m +++ b/sources/VT100Terminal.m @@ -2367,6 +2367,8 @@ - (void)executeXtermSetKvp:(VT100Token *)token { [delegate_ terminalAddNote:(NSString *)value show:NO]; } else if ([key isEqualToString:@"HighlightCursorLine"]) { [delegate_ terminalSetHighlightCursorLine:value.length ? [value boolValue] : YES]; + } else if ([key isEqualToString:@"HighlightCursorCol"]) { + [delegate_ terminalSetHighlightCursorCol:value.length ? [value boolValue] : YES]; } else if ([key isEqualToString:@"CopyToClipboard"]) { if ([delegate_ terminalIsTrusted]) { [delegate_ terminalSetPasteboard:value]; diff --git a/sources/VT100TerminalDelegate.h b/sources/VT100TerminalDelegate.h index 5908d40c35..91e0aedbdf 100644 --- a/sources/VT100TerminalDelegate.h +++ b/sources/VT100TerminalDelegate.h @@ -366,6 +366,7 @@ typedef NS_ENUM(int, VT100TerminalColorIndex) { - (void)terminalSetCursorVisible:(BOOL)visible; - (void)terminalSetHighlightCursorLine:(BOOL)highlight; +- (void)terminalSetHighlightCursorCol:(BOOL)highlight; // FinalTerm features - (void)terminalPromptDidStart; diff --git a/sources/iTermMetalPerFrameState.m b/sources/iTermMetalPerFrameState.m index fa12ee3f3c..f85feb501d 100644 --- a/sources/iTermMetalPerFrameState.m +++ b/sources/iTermMetalPerFrameState.m @@ -582,6 +582,10 @@ - (BOOL)cursorGuideEnabled { return _configuration->_cursorGuideColor && _configuration->_cursorGuideEnabled; } +- (BOOL)cursorVGuideEnabled { + return _configuration->_cursorGuideColor && _configuration->_cursorVGuideEnabled; +} + - (NSColor *)cursorGuideColor { return _configuration->_cursorGuideColor; } diff --git a/sources/iTermMetalPerFrameStateConfiguration.h b/sources/iTermMetalPerFrameStateConfiguration.h index 9223b3b038..967666d5a7 100644 --- a/sources/iTermMetalPerFrameStateConfiguration.h +++ b/sources/iTermMetalPerFrameStateConfiguration.h @@ -62,6 +62,7 @@ NS_ASSUME_NONNULL_BEGIN // Cursor BOOL _shouldDrawFilledInCursor; BOOL _cursorGuideEnabled; + BOOL _cursorVGuideEnabled; // Size VT100GridSize _gridSize; diff --git a/sources/iTermMetalPerFrameStateConfiguration.m b/sources/iTermMetalPerFrameStateConfiguration.m index 0ccdce7f73..8b72b8c381 100644 --- a/sources/iTermMetalPerFrameStateConfiguration.m +++ b/sources/iTermMetalPerFrameStateConfiguration.m @@ -56,6 +56,7 @@ - (void)loadSettingsWithDrawingHelper:(iTermTextDrawingHelper *)drawingHelper // Cursor guide _cursorGuideEnabled = drawingHelper.highlightCursorLine; + _cursorVGuideEnabled = drawingHelper.highlightCursorCol; _cursorGuideColor = drawingHelper.cursorGuideColor; // Background image diff --git a/sources/iTermProfilePreferences.m b/sources/iTermProfilePreferences.m index af4ce1733e..c21e87bcda 100644 --- a/sources/iTermProfilePreferences.m +++ b/sources/iTermProfilePreferences.m @@ -184,7 +184,7 @@ + (BOOL)valueIsLegal:(id)value forKey:(NSString *)key { KEY_CURSOR_GUIDE_COLOR, KEY_BADGE_COLOR, KEY_TAB_COLOR, KEY_UNDERLINE_COLOR ]; - NSArray *number = @[ KEY_USE_CURSOR_GUIDE, KEY_USE_TAB_COLOR, KEY_USE_UNDERLINE_COLOR, + NSArray *number = @[ KEY_USE_CURSOR_GUIDE, KEY_USE_VERT_CURSOR_GUIDE, KEY_USE_TAB_COLOR, KEY_USE_UNDERLINE_COLOR, KEY_SMART_CURSOR_COLOR, KEY_MINIMUM_CONTRAST, KEY_CURSOR_BOOST, KEY_CURSOR_TYPE, KEY_BLINKING_CURSOR, KEY_USE_BOLD_FONT, KEY_THIN_STROKES, KEY_ASCII_LIGATURES, KEY_NON_ASCII_LIGATURES, KEY_USE_BOLD_COLOR, @@ -268,6 +268,7 @@ + (NSDictionary *)defaultValueMap { KEY_CURSOR_GUIDE_COLOR: [[NSColor colorWithCalibratedRed:0.650 green:0.910 blue:1.000 alpha:0.25] dictionaryValue], KEY_BADGE_COLOR: [[NSColor colorWithCalibratedRed:1.0 green:0.000 blue:0.000 alpha:0.5] dictionaryValue], KEY_USE_CURSOR_GUIDE: @NO, + KEY_USE_VERT_CURSOR_GUIDE: @NO, KEY_TAB_COLOR: [NSNull null], KEY_USE_TAB_COLOR: @NO, KEY_UNDERLINE_COLOR: [NSNull null], diff --git a/sources/iTermTextDrawingHelper.h b/sources/iTermTextDrawingHelper.h index 971272686c..c3a2b77e47 100644 --- a/sources/iTermTextDrawingHelper.h +++ b/sources/iTermTextDrawingHelper.h @@ -180,6 +180,9 @@ BOOL CheckFindMatchAtIndex(NSData *findMatches, int index); // Should the cursor guide be shown? @property(nonatomic, assign) BOOL highlightCursorLine; +// Should the vertical cursor guide be shown? +@property(nonatomic, assign) BOOL highlightCursorCol; + // Minimum contrast level, 0-1. @property(nonatomic, assign) double minimumContrast; From ed11a8e23f8e81c174cb55798caa79533374ff6c Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Tue, 26 Mar 2019 01:25:58 -0700 Subject: [PATCH 03/30] Render a vertical cursor guide in the software rendered view (known issue: only renders on the 3 lines centered on the cursor). --- iTerm2XCTests/PTYTextViewTest.m | 15 +++++++++++++++ sources/PTYSession.m | 2 ++ sources/PTYTextView.h | 1 + sources/PTYTextView.m | 23 +++++++++++++++++++++++ sources/iTermTextDrawingHelper.m | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 73 insertions(+) diff --git a/iTerm2XCTests/PTYTextViewTest.m b/iTerm2XCTests/PTYTextViewTest.m index 15e32aef92..471b0c5ed1 100644 --- a/iTerm2XCTests/PTYTextViewTest.m +++ b/iTerm2XCTests/PTYTextViewTest.m @@ -991,6 +991,21 @@ - (void)testCursorGuide { size:VT100GridSizeMake(5, 5)]; } +// Draws a cursor guide on the col with b. +- (void)testVCursorGuide { + [self doGoldenTestForInput:@"abcd\x1b[2A" + name:NSStringFromSelector(_cmd) + hook:^(PTYTextView *textView) { + textView.drawingHook = ^(iTermTextDrawingHelper *helper) { + helper.shouldDrawFilledInCursor = YES; + helper.highlightCursorCol = YES; + }; + } + profileOverrides:nil + createGolden:YES + size:VT100GridSizeMake(5, 5)]; +} + // Draws a badge which blends with nondefault background colors. - (void)testBadge { [self doGoldenTestForInput:@"\n\n\n\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\x1b[42mabc" diff --git a/sources/PTYSession.m b/sources/PTYSession.m index 38c60e2b6e..1e1b76eb1d 100644 --- a/sources/PTYSession.m +++ b/sources/PTYSession.m @@ -2364,6 +2364,7 @@ - (void)writeTaskNoBroadcast:(NSString *)string - (void)handleKeyPressInCopyMode:(NSEvent *)event { [self.textview setNeedsDisplayOnLine:_copyModeState.coord.y]; + [self.textview setNeedsDisplayOnCol:_copyModeState.coord.x]; BOOL wasSelecting = _copyModeState.selecting; NSString *string = event.charactersIgnoringModifiers; unichar code = [string length] > 0 ? [string characterAtIndex:0] : 0; @@ -2515,6 +2516,7 @@ - (void)handleKeyPressInCopyMode:(NSEvent *)event { [_textview scrollLineNumberRangeIntoView:VT100GridRangeMake(_copyModeState.coord.y, 1)]; } [self.textview setNeedsDisplayOnLine:_copyModeState.coord.y]; + [self.textview setNeedsDisplayOnCol:_copyModeState.coord.x]; } } diff --git a/sources/PTYTextView.h b/sources/PTYTextView.h index 7803550e6e..49253a2989 100644 --- a/sources/PTYTextView.h +++ b/sources/PTYTextView.h @@ -464,6 +464,7 @@ typedef void (^PTYTextViewDrawingHookBlock)(iTermTextDrawingHelper *); // onscreen is blinking. - (BOOL)refresh; - (void)setNeedsDisplayOnLine:(int)line; +- (void)setNeedsDisplayOnCol:(int)col; // selection - (IBAction)selectAll:(id)sender; diff --git a/sources/PTYTextView.m b/sources/PTYTextView.m index 7d3d0df4ec..52749f04b8 100644 --- a/sources/PTYTextView.m +++ b/sources/PTYTextView.m @@ -978,6 +978,11 @@ - (void)setNeedsDisplayOnLine:(int)line [self setNeedsDisplayOnLine:line inRange:VT100GridRangeMake(0, _dataSource.width)]; } +- (void)setNeedsDisplayOnCol:(int)col +{ + [self setNeedsDisplayOnCol:col inRange:VT100GridRangeMake(0, _dataSource.height)]; +} + // Overrides an NSView method. - (NSRect)adjustScroll:(NSRect)proposedVisibleRect { proposedVisibleRect.origin.y = (int)(proposedVisibleRect.origin.y / _lineHeight + 0.5) * _lineHeight; @@ -6402,6 +6407,24 @@ - (void)setNeedsDisplayOnLine:(int)y inRange:(VT100GridRange)range { [self setNeedsDisplayInRect:dirtyRect]; } +- (void)setNeedsDisplayOnCol:(int)x inRange:(VT100GridRange)range { + NSRect dirtyRect; + const int y = range.location; + const int maxY = range.location + range.length; + + dirtyRect.origin.y = [iTermAdvancedSettingsModel terminalMargin] + y * _lineHeight; // _charHeightWithoutSpacing; + dirtyRect.origin.x = x * _charWidth; + dirtyRect.size.height = (maxY - y) * _lineHeight; //- _charHeightWithoutSpacing; + dirtyRect.size.width = _charWidth; + + // Expand the rect in case we're drawing a changed cell with an oversize glyph. + dirtyRect = [self rectWithHalo:dirtyRect]; + + DLog(@"Column %d is dirty in range [%d, %d), set rect %@ dirty", + x, y, maxY, [NSValue valueWithRect:dirtyRect]); + [self setNeedsDisplayInRect:dirtyRect]; +} + // WARNING: Do not call this function directly. Call // -[refresh] instead, as it ensures scrollback overflow // is dealt with so that this function can dereference diff --git a/sources/iTermTextDrawingHelper.m b/sources/iTermTextDrawingHelper.m index 73198e92e9..b5422c57b1 100644 --- a/sources/iTermTextDrawingHelper.m +++ b/sources/iTermTextDrawingHelper.m @@ -653,6 +653,18 @@ - (void)drawAccessoriesInRect:(NSRect)bgRect { coordRange.end.x - coordRange.start.x) y:y]; } + + // Highlight cursor column if the cursor is in this column and it's on. + int cursorCol = _cursorCoord.x; + const BOOL drawVCursorGuide = (self.highlightCursorCol && + cursorCol >= coordRange.start.x && + cursorCol < coordRange.end.x); + if (drawVCursorGuide) { + CGFloat x = cursorCol * _cellSize.width; + [self drawCursorGuideForRows:NSMakeRange(coordRange.start.y, + coordRange.end.y - coordRange.start.y) + x:x]; + } } - (void)drawCursorGuideForColumns:(NSRange)range y:(CGFloat)yOrigin { @@ -674,6 +686,26 @@ - (void)drawCursorGuideForColumns:(NSRange)range y:(CGFloat)yOrigin { NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); } +- (void)drawCursorGuideForRows:(NSRange)range x:(CGFloat)xOrigin { + if (!_cursorVisible) { + return; + } + [_cursorGuideColor set]; + NSPoint textOrigin = NSMakePoint(xOrigin + [iTermAdvancedSettingsModel terminalMargin], + [iTermAdvancedSettingsModel terminalMargin] + range.location * _cellSize.height); + NSRect rect = NSMakeRect(textOrigin.x, + textOrigin.y, + _cellSize.width, + range.length * _cellSize.height); + NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); + + rect.size.width = 1; + NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); + + rect.origin.x += _cellSize.width - 1; + NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); +} + + (NSRect)frameForMarkContainedInRect:(NSRect)container cellSize:(CGSize)cellSize cellSizeWithoutSpacing:(CGSize)cellSizeWithoutSpacing From 51d1fedcd4e4b77790339d3e4c6cb749e15fd0f9 Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Tue, 26 Mar 2019 01:26:53 -0700 Subject: [PATCH 04/30] Fill out cursor column tracking API. --- iTerm2XCTests/VT100GridTest.m | 3 +++ sources/PTYSession.m | 1 + sources/VT100Grid.h | 1 + sources/VT100Grid.m | 1 + sources/VT100Screen.h | 1 + sources/VT100Screen.m | 9 +++++++++ sources/VT100ScreenDelegate.h | 3 +++ 7 files changed, 19 insertions(+) diff --git a/iTerm2XCTests/VT100GridTest.m b/iTerm2XCTests/VT100GridTest.m index c38e27dc7d..a4a12243ee 100644 --- a/iTerm2XCTests/VT100GridTest.m +++ b/iTerm2XCTests/VT100GridTest.m @@ -53,6 +53,9 @@ - (screen_char_t)gridBackgroundColorCode { - (void)gridCursorDidChangeLine { } +- (void)gridCursorDidChangeCol { +} + - (iTermUnicodeNormalization)gridUnicodeNormalizationForm { return iTermUnicodeNormalizationNone; } diff --git a/sources/PTYSession.m b/sources/PTYSession.m index 1e1b76eb1d..06f5da16ed 100644 --- a/sources/PTYSession.m +++ b/sources/PTYSession.m @@ -8313,6 +8313,7 @@ - (void)screenDidReset { inProfile:_profile]; [_textview setNeedsDisplay:YES]; _screen.trackCursorLineMovement = NO; + _screen.trackCursorColMovement = NO; } - (void)screenDidAppendStringToCurrentLine:(NSString *)string { diff --git a/sources/VT100Grid.h b/sources/VT100Grid.h index 25eff122bb..590be44446 100644 --- a/sources/VT100Grid.h +++ b/sources/VT100Grid.h @@ -21,6 +21,7 @@ - (iTermUnicodeNormalization)gridUnicodeNormalizationForm; - (void)gridCursorDidMove; - (void)gridCursorDidChangeLine; +- (void)gridCursorDidChangeCol; @end @interface VT100Grid : NSObject diff --git a/sources/VT100Grid.m b/sources/VT100Grid.m index 7c174d17e2..8cee331527 100644 --- a/sources/VT100Grid.m +++ b/sources/VT100Grid.m @@ -183,6 +183,7 @@ - (void)setCursorX:(int)cursorX { int newX = MIN(size_.width, MAX(0, cursorX)); if (newX != cursor_.x) { cursor_.x = newX; + [delegate_ gridCursorDidChangeCol]; [delegate_ gridCursorDidMove]; } } diff --git a/sources/VT100Screen.h b/sources/VT100Screen.h index 11f570b98a..187ab9742b 100644 --- a/sources/VT100Screen.h +++ b/sources/VT100Screen.h @@ -58,6 +58,7 @@ extern int kVT100ScreenMinRows; @property(nonatomic, assign) BOOL saveToScrollbackInAlternateScreen; @property(nonatomic, retain) DVR *dvr; @property(nonatomic, assign) BOOL trackCursorLineMovement; +@property(nonatomic, assign) BOOL trackCursorColMovement; @property(nonatomic, assign) BOOL appendToScrollbackWithStatusBar; @property(nonatomic, readonly) VT100GridAbsCoordRange lastCommandOutputRange; @property(nonatomic, assign) iTermUnicodeNormalization normalization; diff --git a/sources/VT100Screen.m b/sources/VT100Screen.m index 2f03f079e4..a91c1bbb05 100644 --- a/sources/VT100Screen.m +++ b/sources/VT100Screen.m @@ -52,6 +52,7 @@ NSString *const kScreenStateNextCommandOutputStartKey = @"Output Start"; NSString *const kScreenStateCursorVisibleKey = @"Cursor Visible"; NSString *const kScreenStateTrackCursorLineMovementKey = @"Track Cursor Line"; +NSString *const kScreenStateTrackCursorColMovementKey = @"Track Cursor Col"; NSString *const kScreenStateLastCommandOutputRangeKey = @"Last Command Output Range"; NSString *const kScreenStateShellIntegrationInstalledKey = @"Shell Integration Installed"; NSString *const kScreenStateLastCommandMarkKey = @"Last Command Mark"; @@ -5307,6 +5308,12 @@ - (void)gridCursorDidChangeLine { } } +- (void)gridCursorDidChangeCol { + if (_trackCursorColMovement) { + [delegate_ screenCursorDidMoveToCol:currentGrid_.cursorX]; + } +} + - (iTermUnicodeNormalization)gridUnicodeNormalizationForm { return _normalization; } @@ -5364,6 +5371,7 @@ - (NSDictionary *)contentsDictionary { kScreenStateNextCommandOutputStartKey: [NSDictionary dictionaryWithGridAbsCoord:_startOfRunningCommandOutput], kScreenStateCursorVisibleKey: @(_cursorVisible), kScreenStateTrackCursorLineMovementKey: @(_trackCursorLineMovement), + kScreenStateTrackCursorColMovementKey: @(_trackCursorColMovement), kScreenStateLastCommandOutputRangeKey: [NSDictionary dictionaryWithGridAbsCoordRange:_lastCommandOutputRange], kScreenStateShellIntegrationInstalledKey: @(_shellIntegrationInstalled), kScreenStateLastCommandMarkKey: _lastCommandMark.guid ?: [NSNull null], @@ -5478,6 +5486,7 @@ - (void)restoreFromDictionary:(NSDictionary *)dictionary _startOfRunningCommandOutput = [screenState[kScreenStateNextCommandOutputStartKey] gridAbsCoord]; _cursorVisible = [screenState[kScreenStateCursorVisibleKey] boolValue]; _trackCursorLineMovement = [screenState[kScreenStateTrackCursorLineMovementKey] boolValue]; + _trackCursorColMovement = [screenState[kScreenStateTrackCursorColMovementKey] boolValue]; _lastCommandOutputRange = [screenState[kScreenStateLastCommandOutputRangeKey] gridAbsCoordRange]; _shellIntegrationInstalled = [screenState[kScreenStateShellIntegrationInstalledKey] boolValue]; diff --git a/sources/VT100ScreenDelegate.h b/sources/VT100ScreenDelegate.h index 2f48145ae7..5ead6c1050 100644 --- a/sources/VT100ScreenDelegate.h +++ b/sources/VT100ScreenDelegate.h @@ -190,6 +190,9 @@ // Only called if the trackCursorLineMovement property is set. - (void)screenCursorDidMoveToLine:(int)line; +// Only called if the trackCursorColMovement property is set. +- (void)screenCursorDidMoveToCol:(int)col; + // Returns if there is a view. - (BOOL)screenHasView; From 5b8119b1cb05b232d0e2a22abb50b5a2c73ca537 Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Tue, 2 Apr 2019 00:57:16 -0700 Subject: [PATCH 05/30] Fix names and style inconsistencies. --- Interfaces/MainMenu.xib | 2 +- Interfaces/PreferencePanel.xib | 2 +- iTerm2XCTests/PTYTextViewTest.m | 4 +- iTerm2XCTests/VT100GridTest.m | 2 +- iTerm2XCTests/VT100ScreenTest.m | 4 +- sources/ITAddressBookMgr.h | 2 +- .../Renderers/iTermCursorGuideRenderer.h | 2 +- .../Renderers/iTermCursorGuideRenderer.m | 42 +++++++++---------- sources/Metal/iTermMetalDriver.h | 2 +- sources/Metal/iTermMetalDriver.m | 6 +-- sources/PTYSession.h | 2 +- sources/PTYSession.m | 40 +++++++++--------- sources/PTYTextView.h | 4 +- sources/PTYTextView.m | 15 ++++--- .../ProfilesColorsPreferencesViewController.m | 6 +-- sources/PseudoTerminal.m | 8 ++-- sources/VT100Grid.h | 2 +- sources/VT100Grid.m | 2 +- sources/VT100Screen.h | 2 +- sources/VT100Screen.m | 16 +++---- sources/VT100ScreenDelegate.h | 4 +- sources/VT100Terminal.m | 4 +- sources/VT100TerminalDelegate.h | 2 +- sources/iTermMetalPerFrameState.m | 4 +- .../iTermMetalPerFrameStateConfiguration.h | 2 +- .../iTermMetalPerFrameStateConfiguration.m | 2 +- sources/iTermProfilePreferences.m | 4 +- sources/iTermTextDrawingHelper.h | 2 +- sources/iTermTextDrawingHelper.m | 12 +++--- 29 files changed, 100 insertions(+), 101 deletions(-) diff --git a/Interfaces/MainMenu.xib b/Interfaces/MainMenu.xib index eedfcfe25a..db6e751c6a 100644 --- a/Interfaces/MainMenu.xib +++ b/Interfaces/MainMenu.xib @@ -671,7 +671,7 @@ Gw - + diff --git a/Interfaces/PreferencePanel.xib b/Interfaces/PreferencePanel.xib index 325debd784..bb579d4b96 100644 --- a/Interfaces/PreferencePanel.xib +++ b/Interfaces/PreferencePanel.xib @@ -1545,7 +1545,7 @@ DQ - + diff --git a/iTerm2XCTests/PTYTextViewTest.m b/iTerm2XCTests/PTYTextViewTest.m index 471b0c5ed1..283a0e8666 100644 --- a/iTerm2XCTests/PTYTextViewTest.m +++ b/iTerm2XCTests/PTYTextViewTest.m @@ -992,13 +992,13 @@ - (void)testCursorGuide { } // Draws a cursor guide on the col with b. -- (void)testVCursorGuide { +- (void)testVerticalCursorGuide { [self doGoldenTestForInput:@"abcd\x1b[2A" name:NSStringFromSelector(_cmd) hook:^(PTYTextView *textView) { textView.drawingHook = ^(iTermTextDrawingHelper *helper) { helper.shouldDrawFilledInCursor = YES; - helper.highlightCursorCol = YES; + helper.highlightCursorColumn = YES; }; } profileOverrides:nil diff --git a/iTerm2XCTests/VT100GridTest.m b/iTerm2XCTests/VT100GridTest.m index a4a12243ee..f6b106e713 100644 --- a/iTerm2XCTests/VT100GridTest.m +++ b/iTerm2XCTests/VT100GridTest.m @@ -53,7 +53,7 @@ - (screen_char_t)gridBackgroundColorCode { - (void)gridCursorDidChangeLine { } -- (void)gridCursorDidChangeCol { +- (void)gridCursorDidChangeColumn { } - (iTermUnicodeNormalization)gridUnicodeNormalizationForm { diff --git a/iTerm2XCTests/VT100ScreenTest.m b/iTerm2XCTests/VT100ScreenTest.m index b1b5aa68c0..24e6f08b39 100644 --- a/iTerm2XCTests/VT100ScreenTest.m +++ b/iTerm2XCTests/VT100ScreenTest.m @@ -748,10 +748,10 @@ - (void)screenSetHighlightCursorLine:(BOOL)highlight { - (void)screenCursorDidMoveToLine:(int)line { } -- (void)screenSetHighlightCursorCol:(BOOL)highlight { +- (void)screenSetHighlightCursorColumn:(BOOL)highlight { } -- (void)screenCursorDidMoveToCol:(int)line { +- (void)screenCursorDidMoveToColumn:(int)line { } - (void)screenSaveScrollPosition { diff --git a/sources/ITAddressBookMgr.h b/sources/ITAddressBookMgr.h index 30c0c27541..fd49fe2b31 100644 --- a/sources/ITAddressBookMgr.h +++ b/sources/ITAddressBookMgr.h @@ -114,7 +114,7 @@ #define KEY_USE_UNDERLINE_COLOR @"Use Underline Color" #define KEY_CURSOR_BOOST @"Cursor Boost" #define KEY_USE_CURSOR_GUIDE @"Use Cursor Guide" -#define KEY_USE_VERT_CURSOR_GUIDE @"Use Vertical Cursor Guide" +#define KEY_USE_VERTICAL_CURSOR_GUIDE @"Use Vertical Cursor Guide" #define KEY_CURSOR_GUIDE_COLOR @"Cursor Guide Color" #define KEY_BADGE_COLOR @"Badge Color" diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.h b/sources/Metal/Renderers/iTermCursorGuideRenderer.h index 92e4d448c8..d0dbc6963a 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.h +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.h @@ -12,7 +12,7 @@ NS_ASSUME_NONNULL_BEGIN @interface iTermCursorGuideRenderer : NSObject @property (nonatomic) BOOL enabled; -@property (nonatomic) BOOL venabled; +@property (nonatomic) BOOL verticalEnabled; - (nullable instancetype)initWithDevice:(id)device NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE; diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.m b/sources/Metal/Renderers/iTermCursorGuideRenderer.m index 16dcad904f..cc176bad24 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.m +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.m @@ -3,17 +3,17 @@ @interface iTermCursorGuideRendererTransientState() @property (nonatomic, strong) id texture; @property (nonatomic) int row; -@property (nonatomic) int col; +@property (nonatomic) int column; @end @implementation iTermCursorGuideRendererTransientState { int _row; - int _col; + int _column; } - (void)setCursorCoord:(VT100GridCoord)coord within:(VT100GridSize)bounds { _row = (0 <= coord.y && coord.y < bounds.height) ? coord.y : -1; - _col = (0 <= coord.x && coord.x < bounds.width) ? coord.x : -1; + _column = (0 <= coord.x && coord.x < bounds.width) ? coord.x : -1; } - (void)initializeVerticesWithPool:(iTermMetalBufferPool *)verticesPool { @@ -39,22 +39,22 @@ - (void)initializeVerticesWithPool:(iTermMetalBufferPool *)verticesPool { withBytes:vertices checkIfChanged:YES]; - const CGRect vQuad = CGRectMake(self.margins.left + self.col * cellSize.width, - self.margins.top, - cellSize.width, - cellSize.height * gridSize.height); - const iTermVertex vvertices[] = { - { { CGRectGetMaxX(vQuad), CGRectGetMinY(vQuad) }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { CGRectGetMinX(vQuad), CGRectGetMinY(vQuad) }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { CGRectGetMinX(vQuad), CGRectGetMaxY(vQuad) }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - - { { CGRectGetMaxX(vQuad), CGRectGetMinY(vQuad) }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { CGRectGetMinX(vQuad), CGRectGetMaxY(vQuad) }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - { { CGRectGetMaxX(vQuad), CGRectGetMaxY(vQuad) }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, + const CGRect verticalGuideQuad = CGRectMake(self.margins.left + self.column * cellSize.width, + self.margins.top, + cellSize.width, + cellSize.height * gridSize.height); + const iTermVertex verticalGuideVertices[] = { + { { CGRectGetMaxX(verticalGuideQuad), CGRectGetMinY(verticalGuideQuad) }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { CGRectGetMinX(verticalGuideQuad), CGRectGetMinY(verticalGuideQuad) }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { CGRectGetMinX(verticalGuideQuad), CGRectGetMaxY(verticalGuideQuad) }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, + + { { CGRectGetMaxX(verticalGuideQuad), CGRectGetMinY(verticalGuideQuad) }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { CGRectGetMinX(verticalGuideQuad), CGRectGetMaxY(verticalGuideQuad) }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, + { { CGRectGetMaxX(verticalGuideQuad), CGRectGetMaxY(verticalGuideQuad) }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, }; - self.vvertexBuffer = [verticesPool requestBufferFromContext:self.poolContext - withBytes:vvertices - checkIfChanged:YES]; + self.verticalGuideVertexBuffer = [verticesPool requestBufferFromContext:self.poolContext + withBytes:verticalGuideVertices + checkIfChanged:YES]; } - (void)writeDebugInfoToFolder:(NSURL *)folder { @@ -126,7 +126,7 @@ - (void)setColor:(NSColor *)color { - (void)drawWithFrameData:(iTermMetalFrameData *)frameData transientState:(__kindof iTermMetalCellRendererTransientState *)transientState { iTermCursorGuideRendererTransientState *tState = transientState; - if (tState.row < 0 || tState.col < 0) { + if (tState.row < 0 || tState.column < 0) { return; } @@ -141,12 +141,12 @@ - (void)drawWithFrameData:(iTermMetalFrameData *)frameData textures:@{ @(iTermTextureIndexPrimary): tState.texture } ]; } - if (tState.col >= 0 && self.venabled) { + if (tState.column >= 0 && self.verticalEnabled) { [_cellRenderer drawWithTransientState:tState renderEncoder:frameData.renderEncoder numberOfVertices:6 numberOfPIUs:0 - vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.vvertexBuffer } + vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.verticalGuideVertexBuffer } fragmentBuffers:@{} textures:@{ @(iTermTextureIndexPrimary): tState.texture } ]; } diff --git a/sources/Metal/iTermMetalDriver.h b/sources/Metal/iTermMetalDriver.h index d2e04157f6..0936f0aee4 100644 --- a/sources/Metal/iTermMetalDriver.h +++ b/sources/Metal/iTermMetalDriver.h @@ -61,7 +61,7 @@ NS_CLASS_AVAILABLE(10_11, NA) @property (nonatomic, readonly) BOOL showBroadcastStripes; @property (nonatomic, readonly) NSColor *cursorGuideColor; @property (nonatomic, readonly) BOOL cursorGuideEnabled; -@property (nonatomic, readonly) BOOL cursorVGuideEnabled; +@property (nonatomic, readonly) BOOL cursorVerticalGuideEnabled; @property (nonatomic, readonly) vector_float4 fullScreenFlashColor; @property (nonatomic, readonly) BOOL timestampsEnabled; @property (nonatomic, readonly) NSColor *timestampsBackgroundColor; diff --git a/sources/Metal/iTermMetalDriver.m b/sources/Metal/iTermMetalDriver.m index 41d14444bc..802f48f666 100644 --- a/sources/Metal/iTermMetalDriver.m +++ b/sources/Metal/iTermMetalDriver.m @@ -644,8 +644,8 @@ - (BOOL)shouldCreateIntermediateRenderPassDescriptor:(iTermMetalFrameData *)fram if (!_broadcastStripesRenderer.rendererDisabled && frameData.perFrameState.showBroadcastStripes) { return YES; } - if (!_cursorGuideRenderer.rendererDisabled && (frameData.perFrameState.cursorGuideEnabled - || frameData.perFrameState.cursorVGuideEnabled)) { + if (!_cursorGuideRenderer.rendererDisabled && (frameData.perFrameState.cursorGuideEnabled || + frameData.perFrameState.cursorVerticalGuideEnabled)) { return YES; } @@ -971,7 +971,7 @@ - (void)updateCursorGuideRendererForFrameData:(iTermMetalFrameData *)frameData { } [_cursorGuideRenderer setColor:frameData.perFrameState.cursorGuideColor]; _cursorGuideRenderer.enabled = frameData.perFrameState.cursorGuideEnabled; - _cursorGuideRenderer.venabled = frameData.perFrameState.cursorVGuideEnabled; + _cursorGuideRenderer.verticalEnabled = frameData.perFrameState.cursorVerticalGuideEnabled; } - (void)updateTimestampsRendererForFrameData:(iTermMetalFrameData *)frameData { diff --git a/sources/PTYSession.h b/sources/PTYSession.h index 998a35fb4a..e7f44ab970 100644 --- a/sources/PTYSession.h +++ b/sources/PTYSession.h @@ -422,7 +422,7 @@ typedef enum { @property(nonatomic, readonly) BOOL hasSelection; @property(nonatomic, assign) BOOL highlightCursorLine; -@property(nonatomic, assign) BOOL highlightCursorCol; +@property(nonatomic, assign) BOOL highlightCursorColumn; // Used to help remember total ordering on views while one is maximized @property(nonatomic, assign) NSPoint savedRootRelativeOrigin; diff --git a/sources/PTYSession.m b/sources/PTYSession.m index 06f5da16ed..5726695ce9 100644 --- a/sources/PTYSession.m +++ b/sources/PTYSession.m @@ -205,7 +205,7 @@ static NSString *const SESSION_ARRANGEMENT_DIRECTORIES = @"Directories"; // Array of strings static NSString *const SESSION_ARRANGEMENT_HOSTS = @"Hosts"; // Array of VT100RemoteHost static NSString *const SESSION_ARRANGEMENT_CURSOR_GUIDE = @"Cursor Guide"; // BOOL -static NSString *const SESSION_ARRANGEMENT_VCURSOR_GUIDE = @"Vertical Cursor Guide"; // BOOL +static NSString *const SESSION_ARRANGEMENT_VERTICAL_CURSOR_GUIDE = @"Vertical Cursor Guide"; // BOOL static NSString *const SESSION_ARRANGEMENT_LAST_DIRECTORY = @"Last Directory"; // NSString static NSString *const SESSION_ARRANGEMENT_LAST_DIRECTORY_IS_UNSUITABLE_FOR_OLD_PWD = @"Last Directory Is Remote"; // BOOL static NSString *const SESSION_ARRANGEMENT_SELECTION = @"Selection"; // Dictionary for iTermSelection. @@ -1176,8 +1176,8 @@ + (void)finishInitializingArrangementOriginatedSession:(PTYSession *)aSession if (arrangement[SESSION_ARRANGEMENT_CURSOR_GUIDE]) { aSession.textview.highlightCursorLine = [arrangement[SESSION_ARRANGEMENT_CURSOR_GUIDE] boolValue]; } - if (arrangement[SESSION_ARRANGEMENT_VCURSOR_GUIDE]) { - aSession.textview.highlightCursorLine = [arrangement[SESSION_ARRANGEMENT_VCURSOR_GUIDE] boolValue]; + if (arrangement[SESSION_ARRANGEMENT_VERTICAL_CURSOR_GUIDE]) { + aSession.textview.highlightCursorLine = [arrangement[SESSION_ARRANGEMENT_VERTICAL_CURSOR_GUIDE] boolValue]; } aSession->_lastMark = [aSession.screen.lastMark retain]; aSession.lastRemoteHost = aSession.screen.lastRemoteHost; @@ -2364,7 +2364,7 @@ - (void)writeTaskNoBroadcast:(NSString *)string - (void)handleKeyPressInCopyMode:(NSEvent *)event { [self.textview setNeedsDisplayOnLine:_copyModeState.coord.y]; - [self.textview setNeedsDisplayOnCol:_copyModeState.coord.x]; + [self.textview setNeedsDisplayOnColumn:_copyModeState.coord.x]; BOOL wasSelecting = _copyModeState.selecting; NSString *string = event.charactersIgnoringModifiers; unichar code = [string length] > 0 ? [string characterAtIndex:0] : 0; @@ -2516,7 +2516,7 @@ - (void)handleKeyPressInCopyMode:(NSEvent *)event { [_textview scrollLineNumberRangeIntoView:VT100GridRangeMake(_copyModeState.coord.y, 1)]; } [self.textview setNeedsDisplayOnLine:_copyModeState.coord.y]; - [self.textview setNeedsDisplayOnCol:_copyModeState.coord.x]; + [self.textview setNeedsDisplayOnColumn:_copyModeState.coord.x]; } } @@ -3469,7 +3469,7 @@ - (void)loadInitialColorTable } _textview.highlightCursorLine = [iTermProfilePreferences boolForKey:KEY_USE_CURSOR_GUIDE inProfile:_profile]; - _textview.highlightCursorCol = [iTermProfilePreferences boolForKey:KEY_USE_VERT_CURSOR_GUIDE + _textview.highlightCursorColumn = [iTermProfilePreferences boolForKey:KEY_USE_VERTICAL_CURSOR_GUIDE inProfile:_profile]; } @@ -3653,7 +3653,7 @@ - (void)setPreferencesFromAddressBookEntry:(NSDictionary *)aePrefs { if (!_cursorGuideSettingHasChanged) { _textview.highlightCursorLine = [iTermProfilePreferences boolForKey:KEY_USE_CURSOR_GUIDE inProfile:aDict]; - _textview.highlightCursorCol = [iTermProfilePreferences boolForKey:KEY_USE_VERT_CURSOR_GUIDE + _textview.highlightCursorColumn = [iTermProfilePreferences boolForKey:KEY_USE_VERTICAL_CURSOR_GUIDE inProfile:aDict]; } @@ -4381,7 +4381,7 @@ - (NSDictionary *)arrangementWithContents:(BOOL)includeContents { [NSDictionary dictionaryWithGridCoordRange:range]; result[SESSION_ARRANGEMENT_ALERT_ON_NEXT_MARK] = @(_alertOnNextMark); result[SESSION_ARRANGEMENT_CURSOR_GUIDE] = @(_textview.highlightCursorLine); - result[SESSION_ARRANGEMENT_VCURSOR_GUIDE] = @(_textview.highlightCursorCol); + result[SESSION_ARRANGEMENT_VERTICAL_CURSOR_GUIDE] = @(_textview.highlightCursorColumn); if (self.lastDirectory) { result[SESSION_ARRANGEMENT_LAST_DIRECTORY] = self.lastDirectory; result[SESSION_ARRANGEMENT_LAST_DIRECTORY_IS_UNSUITABLE_FOR_OLD_PWD] = @(self.lastDirectoryIsUnsuitableForOldPWD); @@ -8309,11 +8309,11 @@ - (void)screenDidReset { _cursorGuideSettingHasChanged = NO; _textview.highlightCursorLine = [iTermProfilePreferences boolForKey:KEY_USE_CURSOR_GUIDE inProfile:_profile]; - _textview.highlightCursorCol = [iTermProfilePreferences boolForKey:KEY_USE_VERT_CURSOR_GUIDE - inProfile:_profile]; + _textview.highlightCursorColumn = [iTermProfilePreferences boolForKey:KEY_USE_VERTICAL_CURSOR_GUIDE + inProfile:_profile]; [_textview setNeedsDisplay:YES]; _screen.trackCursorLineMovement = NO; - _screen.trackCursorColMovement = NO; + _screen.trackCursorColumnMovement = NO; } - (void)screenDidAppendStringToCurrentLine:(NSString *)string { @@ -8584,26 +8584,26 @@ - (BOOL)highlightCursorLine { return _textview.highlightCursorLine; } -- (void)screenCursorDidMoveToCol:(int)col { +- (void)screenCursorDidMoveToColumn:(int)column { if (_textview.cursorVisible) { - [_textview setNeedsDisplayOnCol:col]; + [_textview setNeedsDisplayOnColumn:column]; } } -- (void)screenSetHighlightCursorCol:(BOOL)highlight { +- (void)screenSetHighlightCursorColumn:(BOOL)highlight { _cursorGuideSettingHasChanged = YES; - self.highlightCursorCol = highlight; + self.highlightCursorColumn = highlight; } -- (void)setHighlightCursorCol:(BOOL)highlight { +- (void)setHighlightCursorColumn:(BOOL)highlight { _cursorGuideSettingHasChanged = YES; - _textview.highlightCursorCol = highlight; + _textview.highlightCursorColumn = highlight; [_textview setNeedsDisplay:YES]; - _screen.trackCursorColMovement = highlight; + _screen.trackCursorColumnMovement = highlight; } -- (BOOL)highlightCursorCol { - return _textview.highlightCursorCol; +- (BOOL)highlightCursorColumn { + return _textview.highlightCursorColumn; } - (BOOL)screenHasView { diff --git a/sources/PTYTextView.h b/sources/PTYTextView.h index 49253a2989..b90d46430c 100644 --- a/sources/PTYTextView.h +++ b/sources/PTYTextView.h @@ -236,7 +236,7 @@ typedef NS_ENUM(NSInteger, PTYTextViewSelectionExtensionUnit) { @property(nonatomic, assign) BOOL highlightCursorLine; // Draw a highlight along the entire column the cursor is in. -@property(nonatomic, assign) BOOL highlightCursorCol; +@property(nonatomic, assign) BOOL highlightCursorColumn; // Use the non-ascii font? If not set, use the regular font for all characters. @property(nonatomic, assign) BOOL useNonAsciiFont; @@ -464,7 +464,7 @@ typedef void (^PTYTextViewDrawingHookBlock)(iTermTextDrawingHelper *); // onscreen is blinking. - (BOOL)refresh; - (void)setNeedsDisplayOnLine:(int)line; -- (void)setNeedsDisplayOnCol:(int)col; +- (void)setNeedsDisplayOnColumn:(int)column; // selection - (IBAction)selectAll:(id)sender; diff --git a/sources/PTYTextView.m b/sources/PTYTextView.m index 52749f04b8..0dbb6a631b 100644 --- a/sources/PTYTextView.m +++ b/sources/PTYTextView.m @@ -581,12 +581,12 @@ - (BOOL)highlightCursorLine { return _drawingHelper.highlightCursorLine; } -- (void)setHighlightCursorCol:(BOOL)highlightCursorCol { - _drawingHelper.highlightCursorCol = highlightCursorCol; +- (void)setHighlightCursorColumn:(BOOL)highlightCursorColumn { + _drawingHelper.highlightCursorColumn = highlightCursorColumn; } -- (BOOL)highlightCursorCol { - return _drawingHelper.highlightCursorCol; +- (BOOL)highlightCursorColumn { + return _drawingHelper.highlightCursorColumn; } - (void)setUseNonAsciiFont:(BOOL)useNonAsciiFont { @@ -978,9 +978,8 @@ - (void)setNeedsDisplayOnLine:(int)line [self setNeedsDisplayOnLine:line inRange:VT100GridRangeMake(0, _dataSource.width)]; } -- (void)setNeedsDisplayOnCol:(int)col -{ - [self setNeedsDisplayOnCol:col inRange:VT100GridRangeMake(0, _dataSource.height)]; +- (void)setNeedsDisplayOnColumn:(int)col { + [self setNeedsDisplayOnColumn:col inRange:VT100GridRangeMake(0, _dataSource.height)]; } // Overrides an NSView method. @@ -6407,7 +6406,7 @@ - (void)setNeedsDisplayOnLine:(int)y inRange:(VT100GridRange)range { [self setNeedsDisplayInRect:dirtyRect]; } -- (void)setNeedsDisplayOnCol:(int)x inRange:(VT100GridRange)range { +- (void)setNeedsDisplayOnColumn:(int)x inRange:(VT100GridRange)range { NSRect dirtyRect; const int y = range.location; const int maxY = range.location + range.length; diff --git a/sources/ProfilesColorsPreferencesViewController.m b/sources/ProfilesColorsPreferencesViewController.m index f1efd6f0c0..828b7a0df1 100644 --- a/sources/ProfilesColorsPreferencesViewController.m +++ b/sources/ProfilesColorsPreferencesViewController.m @@ -62,7 +62,7 @@ @implementation ProfilesColorsPreferencesViewController { IBOutlet NSMenu *_presetsMenu; IBOutlet NSButton *_useGuide; - IBOutlet NSButton *_useVGuide; + IBOutlet NSButton *_useVerticalGuide; IBOutlet CPKColorWell *_guideColor; IBOutlet NSPopUpButton *_presetsPopupButton; @@ -172,8 +172,8 @@ - (void)awakeFromNib { key:KEY_USE_CURSOR_GUIDE type:kPreferenceInfoTypeCheckbox]; - [self defineControl:_useVGuide - key:KEY_USE_VERT_CURSOR_GUIDE + [self defineControl:_useVerticalGuide + key:KEY_USE_VERTICAL_CURSOR_GUIDE type:kPreferenceInfoTypeCheckbox]; info = [self defineControl:_useBrightBold diff --git a/sources/PseudoTerminal.m b/sources/PseudoTerminal.m index 52959eda1d..9799a0457e 100644 --- a/sources/PseudoTerminal.m +++ b/sources/PseudoTerminal.m @@ -1782,9 +1782,9 @@ - (IBAction)toggleCursorGuide:(id)sender { session.highlightCursorLine = !session.highlightCursorLine; } -- (IBAction)toggleVCursorGuide:(id)sender { +- (IBAction)toggleVerticalCursorGuide:(id)sender { PTYSession *session = [self currentSession]; - session.highlightCursorCol = !session.highlightCursorCol; + session.highlightCursorColumn = !session.highlightCursorColumn; } - (IBAction)toggleSelectionRespectsSoftBoundaries:(id)sender { @@ -8595,9 +8595,9 @@ - (BOOL)validateMenuItem:(NSMenuItem *)item { PTYSession *session = [self currentSession]; [item setState:session.highlightCursorLine ? NSOnState : NSOffState]; result = YES; - } else if ([item action] == @selector(toggleVCursorGuide:)) { + } else if ([item action] == @selector(toggleVerticalCursorGuide:)) { PTYSession *session = [self currentSession]; - [item setState:session.highlightCursorCol ? NSOnState : NSOffState]; + [item setState:session.highlightCursorColumn ? NSOnState : NSOffState]; result = YES; } else if ([item action] == @selector(toggleSelectionRespectsSoftBoundaries:)) { [item setState:[[iTermController sharedInstance] selectionRespectsSoftBoundaries] ? NSOnState : NSOffState]; diff --git a/sources/VT100Grid.h b/sources/VT100Grid.h index 590be44446..6e1a72ef08 100644 --- a/sources/VT100Grid.h +++ b/sources/VT100Grid.h @@ -21,7 +21,7 @@ - (iTermUnicodeNormalization)gridUnicodeNormalizationForm; - (void)gridCursorDidMove; - (void)gridCursorDidChangeLine; -- (void)gridCursorDidChangeCol; +- (void)gridCursorDidChangeColumn; @end @interface VT100Grid : NSObject diff --git a/sources/VT100Grid.m b/sources/VT100Grid.m index 8cee331527..72090b0069 100644 --- a/sources/VT100Grid.m +++ b/sources/VT100Grid.m @@ -183,7 +183,7 @@ - (void)setCursorX:(int)cursorX { int newX = MIN(size_.width, MAX(0, cursorX)); if (newX != cursor_.x) { cursor_.x = newX; - [delegate_ gridCursorDidChangeCol]; + [delegate_ gridCursorDidChangeColumn]; [delegate_ gridCursorDidMove]; } } diff --git a/sources/VT100Screen.h b/sources/VT100Screen.h index 187ab9742b..8f84967276 100644 --- a/sources/VT100Screen.h +++ b/sources/VT100Screen.h @@ -58,7 +58,7 @@ extern int kVT100ScreenMinRows; @property(nonatomic, assign) BOOL saveToScrollbackInAlternateScreen; @property(nonatomic, retain) DVR *dvr; @property(nonatomic, assign) BOOL trackCursorLineMovement; -@property(nonatomic, assign) BOOL trackCursorColMovement; +@property(nonatomic, assign) BOOL trackCursorColumnMovement; @property(nonatomic, assign) BOOL appendToScrollbackWithStatusBar; @property(nonatomic, readonly) VT100GridAbsCoordRange lastCommandOutputRange; @property(nonatomic, assign) iTermUnicodeNormalization normalization; diff --git a/sources/VT100Screen.m b/sources/VT100Screen.m index a91c1bbb05..575464833c 100644 --- a/sources/VT100Screen.m +++ b/sources/VT100Screen.m @@ -52,7 +52,7 @@ NSString *const kScreenStateNextCommandOutputStartKey = @"Output Start"; NSString *const kScreenStateCursorVisibleKey = @"Cursor Visible"; NSString *const kScreenStateTrackCursorLineMovementKey = @"Track Cursor Line"; -NSString *const kScreenStateTrackCursorColMovementKey = @"Track Cursor Col"; +NSString *const kScreenStateTrackCursorColumnMovementKey = @"Track Cursor Column"; NSString *const kScreenStateLastCommandOutputRangeKey = @"Last Command Output Range"; NSString *const kScreenStateShellIntegrationInstalledKey = @"Shell Integration Installed"; NSString *const kScreenStateLastCommandMarkKey = @"Last Command Mark"; @@ -4140,8 +4140,8 @@ - (void)terminalSetHighlightCursorLine:(BOOL)highlight { [delegate_ screenSetHighlightCursorLine:highlight]; } -- (void)terminalSetHighlightCursorCol:(BOOL)highlight { - [delegate_ screenSetHighlightCursorCol:highlight]; +- (void)terminalSetHighlightCursorColumn:(BOOL)highlight { + [delegate_ screenSetHighlightCursorColumn:highlight]; } - (void)terminalPromptDidStart { @@ -5308,9 +5308,9 @@ - (void)gridCursorDidChangeLine { } } -- (void)gridCursorDidChangeCol { - if (_trackCursorColMovement) { - [delegate_ screenCursorDidMoveToCol:currentGrid_.cursorX]; +- (void)gridCursorDidChangeColumn { + if (_trackCursorColumnMovement) { + [delegate_ screenCursorDidMoveToColumn:currentGrid_.cursorX]; } } @@ -5371,7 +5371,7 @@ - (NSDictionary *)contentsDictionary { kScreenStateNextCommandOutputStartKey: [NSDictionary dictionaryWithGridAbsCoord:_startOfRunningCommandOutput], kScreenStateCursorVisibleKey: @(_cursorVisible), kScreenStateTrackCursorLineMovementKey: @(_trackCursorLineMovement), - kScreenStateTrackCursorColMovementKey: @(_trackCursorColMovement), + kScreenStateTrackCursorColumnMovementKey: @(_trackCursorColumnMovement), kScreenStateLastCommandOutputRangeKey: [NSDictionary dictionaryWithGridAbsCoordRange:_lastCommandOutputRange], kScreenStateShellIntegrationInstalledKey: @(_shellIntegrationInstalled), kScreenStateLastCommandMarkKey: _lastCommandMark.guid ?: [NSNull null], @@ -5486,7 +5486,7 @@ - (void)restoreFromDictionary:(NSDictionary *)dictionary _startOfRunningCommandOutput = [screenState[kScreenStateNextCommandOutputStartKey] gridAbsCoord]; _cursorVisible = [screenState[kScreenStateCursorVisibleKey] boolValue]; _trackCursorLineMovement = [screenState[kScreenStateTrackCursorLineMovementKey] boolValue]; - _trackCursorColMovement = [screenState[kScreenStateTrackCursorColMovementKey] boolValue]; + _trackCursorColumnMovement = [screenState[kScreenStateTrackCursorColumnMovementKey] boolValue]; _lastCommandOutputRange = [screenState[kScreenStateLastCommandOutputRangeKey] gridAbsCoordRange]; _shellIntegrationInstalled = [screenState[kScreenStateShellIntegrationInstalledKey] boolValue]; diff --git a/sources/VT100ScreenDelegate.h b/sources/VT100ScreenDelegate.h index 5ead6c1050..ebf700e6e1 100644 --- a/sources/VT100ScreenDelegate.h +++ b/sources/VT100ScreenDelegate.h @@ -185,13 +185,13 @@ - (void)screenSetCursorVisible:(BOOL)visible; - (void)screenSetHighlightCursorLine:(BOOL)highlight; -- (void)screenSetHighlightCursorCol:(BOOL)highlight; +- (void)screenSetHighlightCursorColumn:(BOOL)highlight; // Only called if the trackCursorLineMovement property is set. - (void)screenCursorDidMoveToLine:(int)line; // Only called if the trackCursorColMovement property is set. -- (void)screenCursorDidMoveToCol:(int)col; +- (void)screenCursorDidMoveToColumn:(int)col; // Returns if there is a view. - (BOOL)screenHasView; diff --git a/sources/VT100Terminal.m b/sources/VT100Terminal.m index ac9f46526e..f8b6694321 100644 --- a/sources/VT100Terminal.m +++ b/sources/VT100Terminal.m @@ -2367,8 +2367,8 @@ - (void)executeXtermSetKvp:(VT100Token *)token { [delegate_ terminalAddNote:(NSString *)value show:NO]; } else if ([key isEqualToString:@"HighlightCursorLine"]) { [delegate_ terminalSetHighlightCursorLine:value.length ? [value boolValue] : YES]; - } else if ([key isEqualToString:@"HighlightCursorCol"]) { - [delegate_ terminalSetHighlightCursorCol:value.length ? [value boolValue] : YES]; + } else if ([key isEqualToString:@"HighlightCursorColumn"]) { + [delegate_ terminalSetHighlightCursorColumn:value.length ? [value boolValue] : YES]; } else if ([key isEqualToString:@"CopyToClipboard"]) { if ([delegate_ terminalIsTrusted]) { [delegate_ terminalSetPasteboard:value]; diff --git a/sources/VT100TerminalDelegate.h b/sources/VT100TerminalDelegate.h index 91e0aedbdf..9594b07835 100644 --- a/sources/VT100TerminalDelegate.h +++ b/sources/VT100TerminalDelegate.h @@ -366,7 +366,7 @@ typedef NS_ENUM(int, VT100TerminalColorIndex) { - (void)terminalSetCursorVisible:(BOOL)visible; - (void)terminalSetHighlightCursorLine:(BOOL)highlight; -- (void)terminalSetHighlightCursorCol:(BOOL)highlight; +- (void)terminalSetHighlightCursorColumn:(BOOL)highlight; // FinalTerm features - (void)terminalPromptDidStart; diff --git a/sources/iTermMetalPerFrameState.m b/sources/iTermMetalPerFrameState.m index f85feb501d..359c1c9b91 100644 --- a/sources/iTermMetalPerFrameState.m +++ b/sources/iTermMetalPerFrameState.m @@ -582,8 +582,8 @@ - (BOOL)cursorGuideEnabled { return _configuration->_cursorGuideColor && _configuration->_cursorGuideEnabled; } -- (BOOL)cursorVGuideEnabled { - return _configuration->_cursorGuideColor && _configuration->_cursorVGuideEnabled; +- (BOOL)cursorVerticalGuideEnabled { + return _configuration->_cursorGuideColor && _configuration->_cursorVerticalGuideEnabled; } - (NSColor *)cursorGuideColor { diff --git a/sources/iTermMetalPerFrameStateConfiguration.h b/sources/iTermMetalPerFrameStateConfiguration.h index 967666d5a7..c34c4b36ee 100644 --- a/sources/iTermMetalPerFrameStateConfiguration.h +++ b/sources/iTermMetalPerFrameStateConfiguration.h @@ -62,7 +62,7 @@ NS_ASSUME_NONNULL_BEGIN // Cursor BOOL _shouldDrawFilledInCursor; BOOL _cursorGuideEnabled; - BOOL _cursorVGuideEnabled; + BOOL _cursorVerticalGuideEnabled; // Size VT100GridSize _gridSize; diff --git a/sources/iTermMetalPerFrameStateConfiguration.m b/sources/iTermMetalPerFrameStateConfiguration.m index 8b72b8c381..2d41083775 100644 --- a/sources/iTermMetalPerFrameStateConfiguration.m +++ b/sources/iTermMetalPerFrameStateConfiguration.m @@ -56,7 +56,7 @@ - (void)loadSettingsWithDrawingHelper:(iTermTextDrawingHelper *)drawingHelper // Cursor guide _cursorGuideEnabled = drawingHelper.highlightCursorLine; - _cursorVGuideEnabled = drawingHelper.highlightCursorCol; + _cursorVerticalGuideEnabled = drawingHelper.highlightCursorColumn; _cursorGuideColor = drawingHelper.cursorGuideColor; // Background image diff --git a/sources/iTermProfilePreferences.m b/sources/iTermProfilePreferences.m index c21e87bcda..d022cdb2f3 100644 --- a/sources/iTermProfilePreferences.m +++ b/sources/iTermProfilePreferences.m @@ -184,7 +184,7 @@ + (BOOL)valueIsLegal:(id)value forKey:(NSString *)key { KEY_CURSOR_GUIDE_COLOR, KEY_BADGE_COLOR, KEY_TAB_COLOR, KEY_UNDERLINE_COLOR ]; - NSArray *number = @[ KEY_USE_CURSOR_GUIDE, KEY_USE_VERT_CURSOR_GUIDE, KEY_USE_TAB_COLOR, KEY_USE_UNDERLINE_COLOR, + NSArray *number = @[ KEY_USE_CURSOR_GUIDE, KEY_USE_VERTICAL_CURSOR_GUIDE, KEY_USE_TAB_COLOR, KEY_USE_UNDERLINE_COLOR, KEY_SMART_CURSOR_COLOR, KEY_MINIMUM_CONTRAST, KEY_CURSOR_BOOST, KEY_CURSOR_TYPE, KEY_BLINKING_CURSOR, KEY_USE_BOLD_FONT, KEY_THIN_STROKES, KEY_ASCII_LIGATURES, KEY_NON_ASCII_LIGATURES, KEY_USE_BOLD_COLOR, @@ -268,7 +268,7 @@ + (NSDictionary *)defaultValueMap { KEY_CURSOR_GUIDE_COLOR: [[NSColor colorWithCalibratedRed:0.650 green:0.910 blue:1.000 alpha:0.25] dictionaryValue], KEY_BADGE_COLOR: [[NSColor colorWithCalibratedRed:1.0 green:0.000 blue:0.000 alpha:0.5] dictionaryValue], KEY_USE_CURSOR_GUIDE: @NO, - KEY_USE_VERT_CURSOR_GUIDE: @NO, + KEY_USE_VERTICAL_CURSOR_GUIDE: @NO, KEY_TAB_COLOR: [NSNull null], KEY_USE_TAB_COLOR: @NO, KEY_UNDERLINE_COLOR: [NSNull null], diff --git a/sources/iTermTextDrawingHelper.h b/sources/iTermTextDrawingHelper.h index c3a2b77e47..1236479bf4 100644 --- a/sources/iTermTextDrawingHelper.h +++ b/sources/iTermTextDrawingHelper.h @@ -181,7 +181,7 @@ BOOL CheckFindMatchAtIndex(NSData *findMatches, int index); @property(nonatomic, assign) BOOL highlightCursorLine; // Should the vertical cursor guide be shown? -@property(nonatomic, assign) BOOL highlightCursorCol; +@property(nonatomic, assign) BOOL highlightCursorColumn; // Minimum contrast level, 0-1. @property(nonatomic, assign) double minimumContrast; diff --git a/sources/iTermTextDrawingHelper.m b/sources/iTermTextDrawingHelper.m index b5422c57b1..568c3396b8 100644 --- a/sources/iTermTextDrawingHelper.m +++ b/sources/iTermTextDrawingHelper.m @@ -655,12 +655,12 @@ - (void)drawAccessoriesInRect:(NSRect)bgRect { } // Highlight cursor column if the cursor is in this column and it's on. - int cursorCol = _cursorCoord.x; - const BOOL drawVCursorGuide = (self.highlightCursorCol && - cursorCol >= coordRange.start.x && - cursorCol < coordRange.end.x); - if (drawVCursorGuide) { - CGFloat x = cursorCol * _cellSize.width; + int cursorColumn = _cursorCoord.x; + const BOOL drawVerticalCursorGuide = (self.highlightCursorColumn && + cursorColumn >= coordRange.start.x && + cursorColumn < coordRange.end.x); + if (drawVerticalCursorGuide) { + CGFloat x = cursorColumn * _cellSize.width; [self drawCursorGuideForRows:NSMakeRange(coordRange.start.y, coordRange.end.y - coordRange.start.y) x:x]; From 1b12bae9f5336ca605d55d8f306687db91ccb256 Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Tue, 2 Apr 2019 01:05:16 -0700 Subject: [PATCH 06/30] Rename a couple more "col" variables to use full names. --- sources/PTYTextView.m | 4 ++-- sources/VT100ScreenDelegate.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sources/PTYTextView.m b/sources/PTYTextView.m index 0dbb6a631b..f58abe35af 100644 --- a/sources/PTYTextView.m +++ b/sources/PTYTextView.m @@ -978,8 +978,8 @@ - (void)setNeedsDisplayOnLine:(int)line [self setNeedsDisplayOnLine:line inRange:VT100GridRangeMake(0, _dataSource.width)]; } -- (void)setNeedsDisplayOnColumn:(int)col { - [self setNeedsDisplayOnColumn:col inRange:VT100GridRangeMake(0, _dataSource.height)]; +- (void)setNeedsDisplayOnColumn:(int)column { + [self setNeedsDisplayOnColumn:column inRange:VT100GridRangeMake(0, _dataSource.height)]; } // Overrides an NSView method. diff --git a/sources/VT100ScreenDelegate.h b/sources/VT100ScreenDelegate.h index ebf700e6e1..21819d8b26 100644 --- a/sources/VT100ScreenDelegate.h +++ b/sources/VT100ScreenDelegate.h @@ -191,7 +191,7 @@ - (void)screenCursorDidMoveToLine:(int)line; // Only called if the trackCursorColMovement property is set. -- (void)screenCursorDidMoveToColumn:(int)col; +- (void)screenCursorDidMoveToColumn:(int)column; // Returns if there is a view. - (BOOL)screenHasView; From 59f1be92dd1b4597f04ce6a21c1eb381ac015e7a Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Tue, 2 Apr 2019 01:22:33 -0700 Subject: [PATCH 07/30] Fix bug with variable name type ("...Line" should be "...Column"). Renamve vvertexBuffer into verticalGuideVertexBuffer. Finish separating out control over the horizontal cursor guide from the vertical cursor guide. --- sources/Metal/Infrastructure/iTermMetalRenderer.h | 2 +- sources/Metal/Renderers/iTermCursorGuideRenderer.h | 2 +- sources/Metal/Renderers/iTermCursorGuideRenderer.m | 4 ++-- sources/Metal/iTermMetalDriver.h | 2 +- sources/Metal/iTermMetalDriver.m | 4 ++-- sources/PTYSession.m | 2 +- sources/iTermMetalPerFrameState.m | 4 ++-- sources/iTermMetalPerFrameStateConfiguration.h | 2 +- sources/iTermMetalPerFrameStateConfiguration.m | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/sources/Metal/Infrastructure/iTermMetalRenderer.h b/sources/Metal/Infrastructure/iTermMetalRenderer.h index 4206a8299e..ec26f63902 100644 --- a/sources/Metal/Infrastructure/iTermMetalRenderer.h +++ b/sources/Metal/Infrastructure/iTermMetalRenderer.h @@ -46,7 +46,7 @@ NS_CLASS_AVAILABLE(10_11, NA) @interface iTermMetalRendererTransientState : NSObject @property (nonatomic, strong, readonly) __kindof iTermRenderConfiguration *configuration; @property (nonatomic, strong) id vertexBuffer; -@property (nonatomic, strong) id vvertexBuffer; +@property (nonatomic, strong) id verticalGuideVertexBuffer; @property (nonatomic, readonly) iTermMetalBufferPoolContext *poolContext; @property (nonatomic, weak) iTermMetalDebugInfo *debugInfo; @property (nonatomic, strong) NSImage *renderedOutputForDebugging; diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.h b/sources/Metal/Renderers/iTermCursorGuideRenderer.h index d0dbc6963a..ea8574fba2 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.h +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.h @@ -11,7 +11,7 @@ NS_ASSUME_NONNULL_BEGIN @interface iTermCursorGuideRenderer : NSObject -@property (nonatomic) BOOL enabled; +@property (nonatomic) BOOL horizontalEnabled; @property (nonatomic) BOOL verticalEnabled; - (nullable instancetype)initWithDevice:(id)device NS_DESIGNATED_INITIALIZER; diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.m b/sources/Metal/Renderers/iTermCursorGuideRenderer.m index cc176bad24..691e913ac2 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.m +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.m @@ -98,7 +98,7 @@ - (iTermMetalFrameDataStat)createTransientStateStat { - (nullable __kindof iTermMetalRendererTransientState *)createTransientStateForCellConfiguration:(iTermCellRenderConfiguration *)configuration commandBuffer:(id)commandBuffer { - if (!_enabled) { + if (!_horizontalEnabled && !_verticalEnabled) { return nil; } __kindof iTermMetalCellRendererTransientState * _Nonnull transientState = @@ -131,7 +131,7 @@ - (void)drawWithFrameData:(iTermMetalFrameData *)frameData } [tState initializeVerticesWithPool:_cellRenderer.verticesPool]; - if (tState.row >= 0 && self.enabled) { + if (tState.row >= 0 && self.horizontalEnabled) { [_cellRenderer drawWithTransientState:tState renderEncoder:frameData.renderEncoder numberOfVertices:6 diff --git a/sources/Metal/iTermMetalDriver.h b/sources/Metal/iTermMetalDriver.h index 0936f0aee4..4fbf1eb461 100644 --- a/sources/Metal/iTermMetalDriver.h +++ b/sources/Metal/iTermMetalDriver.h @@ -60,7 +60,7 @@ NS_CLASS_AVAILABLE(10_11, NA) @property (nonatomic, nullable, readonly) iTermMetalIMEInfo *imeInfo; @property (nonatomic, readonly) BOOL showBroadcastStripes; @property (nonatomic, readonly) NSColor *cursorGuideColor; -@property (nonatomic, readonly) BOOL cursorGuideEnabled; +@property (nonatomic, readonly) BOOL cursorHorizontalGuideEnabled; @property (nonatomic, readonly) BOOL cursorVerticalGuideEnabled; @property (nonatomic, readonly) vector_float4 fullScreenFlashColor; @property (nonatomic, readonly) BOOL timestampsEnabled; diff --git a/sources/Metal/iTermMetalDriver.m b/sources/Metal/iTermMetalDriver.m index 802f48f666..19c7ef8cbd 100644 --- a/sources/Metal/iTermMetalDriver.m +++ b/sources/Metal/iTermMetalDriver.m @@ -644,7 +644,7 @@ - (BOOL)shouldCreateIntermediateRenderPassDescriptor:(iTermMetalFrameData *)fram if (!_broadcastStripesRenderer.rendererDisabled && frameData.perFrameState.showBroadcastStripes) { return YES; } - if (!_cursorGuideRenderer.rendererDisabled && (frameData.perFrameState.cursorGuideEnabled || + if (!_cursorGuideRenderer.rendererDisabled && (frameData.perFrameState.cursorHorizontalGuideEnabled || frameData.perFrameState.cursorVerticalGuideEnabled)) { return YES; } @@ -970,7 +970,7 @@ - (void)updateCursorGuideRendererForFrameData:(iTermMetalFrameData *)frameData { return; } [_cursorGuideRenderer setColor:frameData.perFrameState.cursorGuideColor]; - _cursorGuideRenderer.enabled = frameData.perFrameState.cursorGuideEnabled; + _cursorGuideRenderer.horizontalEnabled = frameData.perFrameState.cursorHorizontalGuideEnabled; _cursorGuideRenderer.verticalEnabled = frameData.perFrameState.cursorVerticalGuideEnabled; } diff --git a/sources/PTYSession.m b/sources/PTYSession.m index 5726695ce9..2cd7e3fe25 100644 --- a/sources/PTYSession.m +++ b/sources/PTYSession.m @@ -1177,7 +1177,7 @@ + (void)finishInitializingArrangementOriginatedSession:(PTYSession *)aSession aSession.textview.highlightCursorLine = [arrangement[SESSION_ARRANGEMENT_CURSOR_GUIDE] boolValue]; } if (arrangement[SESSION_ARRANGEMENT_VERTICAL_CURSOR_GUIDE]) { - aSession.textview.highlightCursorLine = [arrangement[SESSION_ARRANGEMENT_VERTICAL_CURSOR_GUIDE] boolValue]; + aSession.textview.highlightCursorColumn = [arrangement[SESSION_ARRANGEMENT_VERTICAL_CURSOR_GUIDE] boolValue]; } aSession->_lastMark = [aSession.screen.lastMark retain]; aSession.lastRemoteHost = aSession.screen.lastRemoteHost; diff --git a/sources/iTermMetalPerFrameState.m b/sources/iTermMetalPerFrameState.m index 359c1c9b91..09479f0d7a 100644 --- a/sources/iTermMetalPerFrameState.m +++ b/sources/iTermMetalPerFrameState.m @@ -578,8 +578,8 @@ - (vector_float4)fullScreenFlashColor { return _configuration->_fullScreenFlashColor; } -- (BOOL)cursorGuideEnabled { - return _configuration->_cursorGuideColor && _configuration->_cursorGuideEnabled; +- (BOOL)cursorHorizontalGuideEnabled { + return _configuration->_cursorGuideColor && _configuration->_cursorHorizontalGuideEnabled; } - (BOOL)cursorVerticalGuideEnabled { diff --git a/sources/iTermMetalPerFrameStateConfiguration.h b/sources/iTermMetalPerFrameStateConfiguration.h index c34c4b36ee..5e557aeb6d 100644 --- a/sources/iTermMetalPerFrameStateConfiguration.h +++ b/sources/iTermMetalPerFrameStateConfiguration.h @@ -61,7 +61,7 @@ NS_ASSUME_NONNULL_BEGIN // Cursor BOOL _shouldDrawFilledInCursor; - BOOL _cursorGuideEnabled; + BOOL _cursorHorizontalGuideEnabled; BOOL _cursorVerticalGuideEnabled; // Size diff --git a/sources/iTermMetalPerFrameStateConfiguration.m b/sources/iTermMetalPerFrameStateConfiguration.m index 2d41083775..da19fb65aa 100644 --- a/sources/iTermMetalPerFrameStateConfiguration.m +++ b/sources/iTermMetalPerFrameStateConfiguration.m @@ -55,7 +55,7 @@ - (void)loadSettingsWithDrawingHelper:(iTermTextDrawingHelper *)drawingHelper _transparencyAffectsOnlyDefaultBackgroundColor = drawingHelper.transparencyAffectsOnlyDefaultBackgroundColor; // Cursor guide - _cursorGuideEnabled = drawingHelper.highlightCursorLine; + _cursorHorizontalGuideEnabled = drawingHelper.highlightCursorLine; _cursorVerticalGuideEnabled = drawingHelper.highlightCursorColumn; _cursorGuideColor = drawingHelper.cursorGuideColor; From 683f7183f237a6759dc04c27ffc4ca2839490d44 Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Sun, 7 Apr 2019 00:29:40 -0700 Subject: [PATCH 08/30] Remove extraneous shared vertex buffer in favor of keeping more in the cursor guide renderer. Create additional texture for vertical cursor guide. Create additional vertex buffers for vertical and split-vertical (used for vertical when both vertical and horizontal guides are enabled) drawing of the vertical cursor guide. --- .../Metal/Infrastructure/iTermMetalRenderer.h | 1 - .../Renderers/iTermCursorGuideRenderer.m | 180 ++++++++++++------ 2 files changed, 125 insertions(+), 56 deletions(-) diff --git a/sources/Metal/Infrastructure/iTermMetalRenderer.h b/sources/Metal/Infrastructure/iTermMetalRenderer.h index ec26f63902..aee0e34db4 100644 --- a/sources/Metal/Infrastructure/iTermMetalRenderer.h +++ b/sources/Metal/Infrastructure/iTermMetalRenderer.h @@ -46,7 +46,6 @@ NS_CLASS_AVAILABLE(10_11, NA) @interface iTermMetalRendererTransientState : NSObject @property (nonatomic, strong, readonly) __kindof iTermRenderConfiguration *configuration; @property (nonatomic, strong) id vertexBuffer; -@property (nonatomic, strong) id verticalGuideVertexBuffer; @property (nonatomic, readonly) iTermMetalBufferPoolContext *poolContext; @property (nonatomic, weak) iTermMetalDebugInfo *debugInfo; @property (nonatomic, strong) NSImage *renderedOutputForDebugging; diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.m b/sources/Metal/Renderers/iTermCursorGuideRenderer.m index 691e913ac2..5107b1b9e1 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.m +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.m @@ -1,14 +1,17 @@ #import "iTermCursorGuideRenderer.h" @interface iTermCursorGuideRendererTransientState() -@property (nonatomic, strong) id texture; +@property (nonatomic, strong) id horizontalTexture, verticalTexture; @property (nonatomic) int row; @property (nonatomic) int column; +@property (nonatomic) id horizontalVertexBuffer, verticalVertexBuffer, upperVertexBuffer, lowerVertexBuffer; @end @implementation iTermCursorGuideRendererTransientState { int _row; int _column; + id _horizontalVertexBuffer, _verticalVertexBuffer; + id _upperVertexBuffer, _lowerVertexBuffer; } - (void)setCursorCoord:(VT100GridCoord)coord within:(VT100GridSize)bounds { @@ -16,45 +19,78 @@ - (void)setCursorCoord:(VT100GridCoord)coord within:(VT100GridSize)bounds { _column = (0 <= coord.x && coord.x < bounds.width) ? coord.x : -1; } -- (void)initializeVerticesWithPool:(iTermMetalBufferPool *)verticesPool { +- (void)initializeVerticesWithPool:(iTermMetalBufferPool *)verticesPool + horizontal:(BOOL)horizontal + vertical:(BOOL)vertical { CGSize cellSize = self.cellConfiguration.cellSize; VT100GridSize gridSize = self.cellConfiguration.gridSize; - const CGRect quad = CGRectMake(self.margins.left, - self.margins.top + (gridSize.height - self.row - 1) * cellSize.height, - cellSize.width * gridSize.width, - cellSize.height); const CGRect textureFrame = CGRectMake(0, 0, 1, 1); - const iTermVertex vertices[] = { - // Pixel Positions Texture Coordinates - { { CGRectGetMaxX(quad), CGRectGetMinY(quad) }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { CGRectGetMinX(quad), CGRectGetMinY(quad) }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { CGRectGetMinX(quad), CGRectGetMaxY(quad) }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - - { { CGRectGetMaxX(quad), CGRectGetMinY(quad) }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { CGRectGetMinX(quad), CGRectGetMaxY(quad) }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - { { CGRectGetMaxX(quad), CGRectGetMaxY(quad) }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, - }; - self.vertexBuffer = [verticesPool requestBufferFromContext:self.poolContext - withBytes:vertices - checkIfChanged:YES]; - - const CGRect verticalGuideQuad = CGRectMake(self.margins.left + self.column * cellSize.width, - self.margins.top, - cellSize.width, - cellSize.height * gridSize.height); - const iTermVertex verticalGuideVertices[] = { - { { CGRectGetMaxX(verticalGuideQuad), CGRectGetMinY(verticalGuideQuad) }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { CGRectGetMinX(verticalGuideQuad), CGRectGetMinY(verticalGuideQuad) }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { CGRectGetMinX(verticalGuideQuad), CGRectGetMaxY(verticalGuideQuad) }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - - { { CGRectGetMaxX(verticalGuideQuad), CGRectGetMinY(verticalGuideQuad) }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { CGRectGetMinX(verticalGuideQuad), CGRectGetMaxY(verticalGuideQuad) }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - { { CGRectGetMaxX(verticalGuideQuad), CGRectGetMaxY(verticalGuideQuad) }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, - }; - self.verticalGuideVertexBuffer = [verticesPool requestBufferFromContext:self.poolContext - withBytes:verticalGuideVertices - checkIfChanged:YES]; + + CGFloat viewMinX = self.margins.left, viewMinY = self.margins.top; + CGFloat viewMaxX = viewMinX + cellSize.width*gridSize.width, viewMaxY = viewMinY + cellSize.height*gridSize.height; + + CGFloat cursorMinX = self.margins.left + self.column * cellSize.width, cursorMinY = self.margins.top + (gridSize.height - self.row - 1) * cellSize.height; + CGFloat cursorMaxX = cursorMinX + cellSize.width, cursorMaxY = cursorMinY + cellSize.height; + + if (horizontal) { + const iTermVertex vertices[] = { + // Pixel Positions Texture Coordinates + { { viewMaxX, cursorMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { viewMinX, cursorMinY }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { viewMinX, cursorMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, + + { { viewMaxX, cursorMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { viewMinX, cursorMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, + { { viewMaxX, cursorMaxY }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, + }; + self.horizontalVertexBuffer = [verticesPool requestBufferFromContext:self.poolContext + withBytes:vertices + checkIfChanged:YES]; + } + + if (horizontal && vertical) { + const iTermVertex lowerVertices[] = { + // Pixel Positions Texture Coordinates + { { cursorMaxX, viewMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { cursorMinX, viewMinY }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { cursorMinX, cursorMinY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, + + { { cursorMaxX, viewMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { cursorMinX, cursorMinY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, + { { cursorMaxX, cursorMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, + }; + self.lowerVertexBuffer = [verticesPool requestBufferFromContext:self.poolContext + withBytes:lowerVertices + checkIfChanged:YES]; + const iTermVertex upperVertices[] = { + // Pixel Positions Texture Coordinates + { { cursorMaxX, cursorMaxY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { cursorMinX, cursorMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { cursorMinX, viewMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, + + { { cursorMaxX, cursorMaxY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { cursorMinX, viewMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, + { { cursorMaxX, viewMaxY }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, + }; + self.upperVertexBuffer = [verticesPool requestBufferFromContext:self.poolContext + withBytes:upperVertices + checkIfChanged:YES]; + } else if (vertical) { + const iTermVertex vertices[] = { + // Pixel Positions Texture Coordinates + { { cursorMaxX, viewMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { cursorMinX, viewMinY }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { cursorMinX, viewMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, + + { { cursorMaxX, viewMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { cursorMinX, viewMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, + { { cursorMaxX, viewMaxY }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, + }; + self.verticalVertexBuffer = [verticesPool requestBufferFromContext:self.poolContext + withBytes:vertices + checkIfChanged:YES]; + } } - (void)writeDebugInfoToFolder:(NSURL *)folder { @@ -69,7 +105,7 @@ - (void)writeDebugInfoToFolder:(NSURL *)folder { @implementation iTermCursorGuideRenderer { iTermMetalCellRenderer *_cellRenderer; - id _texture; + id _horizontalTexture, _verticalTexture; NSColor *_color; CGSize _lastCellSize; } @@ -110,10 +146,14 @@ - (nullable __kindof iTermMetalRendererTransientState *)createTransientStateForC - (void)initializeTransientState:(iTermCursorGuideRendererTransientState *)tState { if (!CGSizeEqualToSize(tState.cellConfiguration.cellSize, _lastCellSize)) { - _texture = [self newCursorGuideTextureWithTransientState:tState]; + _horizontalTexture = [self newCursorGuideTextureWithTransientState:tState + isHorizontal:YES]; + _verticalTexture = [self newCursorGuideTextureWithTransientState:tState + isHorizontal:NO]; _lastCellSize = tState.cellConfiguration.cellSize; } - tState.texture = _texture; + tState.horizontalTexture = _horizontalTexture; + tState.verticalTexture = _verticalTexture; } - (void)setColor:(NSColor *)color { @@ -126,37 +166,59 @@ - (void)setColor:(NSColor *)color { - (void)drawWithFrameData:(iTermMetalFrameData *)frameData transientState:(__kindof iTermMetalCellRendererTransientState *)transientState { iTermCursorGuideRendererTransientState *tState = transientState; - if (tState.row < 0 || tState.column < 0) { + if (tState.row < 0 && tState.column < 0) { return; } - [tState initializeVerticesWithPool:_cellRenderer.verticesPool]; - if (tState.row >= 0 && self.horizontalEnabled) { + if (tState.row >= 0 && tState.column >= 0 && self.horizontalEnabled && self.verticalEnabled) { + [tState initializeVerticesWithPool:_cellRenderer.verticesPool horizontal:TRUE vertical:TRUE]; [_cellRenderer drawWithTransientState:tState renderEncoder:frameData.renderEncoder numberOfVertices:6 numberOfPIUs:0 - vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.vertexBuffer } + vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.horizontalVertexBuffer } fragmentBuffers:@{} - textures:@{ @(iTermTextureIndexPrimary): tState.texture } ]; - } - - if (tState.column >= 0 && self.verticalEnabled) { + textures:@{ @(iTermTextureIndexPrimary): tState.horizontalTexture } ]; [_cellRenderer drawWithTransientState:tState renderEncoder:frameData.renderEncoder numberOfVertices:6 numberOfPIUs:0 - vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.verticalGuideVertexBuffer } + vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.upperVertexBuffer } fragmentBuffers:@{} - textures:@{ @(iTermTextureIndexPrimary): tState.texture } ]; + textures:@{ @(iTermTextureIndexPrimary): tState.verticalTexture } ]; + [_cellRenderer drawWithTransientState:tState + renderEncoder:frameData.renderEncoder + numberOfVertices:6 + numberOfPIUs:0 + vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.lowerVertexBuffer } + fragmentBuffers:@{} + textures:@{ @(iTermTextureIndexPrimary): tState.verticalTexture } ]; + } else if (tState.row >= 0 && self.horizontalEnabled && !self.verticalEnabled) { + [tState initializeVerticesWithPool:_cellRenderer.verticesPool horizontal:TRUE vertical:FALSE]; + [_cellRenderer drawWithTransientState:tState + renderEncoder:frameData.renderEncoder + numberOfVertices:6 + numberOfPIUs:0 + vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.horizontalVertexBuffer } + fragmentBuffers:@{} + textures:@{ @(iTermTextureIndexPrimary): tState.horizontalTexture } ]; + } else if (tState.column >= 0 && !self.horizontalEnabled && self.verticalEnabled) { + [tState initializeVerticesWithPool:_cellRenderer.verticesPool horizontal:FALSE vertical:TRUE]; + [_cellRenderer drawWithTransientState:tState + renderEncoder:frameData.renderEncoder + numberOfVertices:6 + numberOfPIUs:0 + vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.verticalVertexBuffer } + fragmentBuffers:@{} + textures:@{ @(iTermTextureIndexPrimary): tState.verticalTexture } ]; } } #pragma mark - Private -- (id)newCursorGuideTextureWithTransientState:(iTermCursorGuideRendererTransientState *)tState { +- (id)newCursorGuideTextureWithTransientState:(iTermCursorGuideRendererTransientState *)tState + isHorizontal:(BOOL)isHorizontal { NSImage *image = [[NSImage alloc] initWithSize:tState.cellConfiguration.cellSize]; - [image lockFocus]; { [_color set]; @@ -166,11 +228,19 @@ - (void)drawWithFrameData:(iTermMetalFrameData *)frameData tState.cellConfiguration.cellSize.height); NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); - rect.size.height = tState.cellConfiguration.scale; - NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); + if (isHorizontal) { + rect.size.height = tState.cellConfiguration.scale; + NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); - rect.origin.y += tState.cellConfiguration.cellSize.height - tState.cellConfiguration.scale; - NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); + rect.origin.y += tState.cellConfiguration.cellSize.height - tState.cellConfiguration.scale; + NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); + } else { + rect.size.width = tState.cellConfiguration.scale; + NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); + + rect.origin.x += tState.cellConfiguration.cellSize.width - tState.cellConfiguration.scale; + NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); + } } [image unlockFocus]; From 7af2a5030900bac984d1fc3c5d3ba272d0760d80 Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Sun, 7 Apr 2019 00:32:36 -0700 Subject: [PATCH 09/30] Remove bad boolean checks. --- sources/Metal/Renderers/iTermCursorGuideRenderer.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.m b/sources/Metal/Renderers/iTermCursorGuideRenderer.m index 5107b1b9e1..598e53d6a8 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.m +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.m @@ -193,7 +193,7 @@ - (void)drawWithFrameData:(iTermMetalFrameData *)frameData vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.lowerVertexBuffer } fragmentBuffers:@{} textures:@{ @(iTermTextureIndexPrimary): tState.verticalTexture } ]; - } else if (tState.row >= 0 && self.horizontalEnabled && !self.verticalEnabled) { + } else if (tState.row >= 0 && self.horizontalEnabled) { [tState initializeVerticesWithPool:_cellRenderer.verticesPool horizontal:TRUE vertical:FALSE]; [_cellRenderer drawWithTransientState:tState renderEncoder:frameData.renderEncoder @@ -202,7 +202,7 @@ - (void)drawWithFrameData:(iTermMetalFrameData *)frameData vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.horizontalVertexBuffer } fragmentBuffers:@{} textures:@{ @(iTermTextureIndexPrimary): tState.horizontalTexture } ]; - } else if (tState.column >= 0 && !self.horizontalEnabled && self.verticalEnabled) { + } else if (tState.column >= 0 && self.verticalEnabled) { [tState initializeVerticesWithPool:_cellRenderer.verticesPool horizontal:FALSE vertical:TRUE]; [_cellRenderer drawWithTransientState:tState renderEncoder:frameData.renderEncoder From c8743a86284de59877b95650834d967ce75892de Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Sun, 7 Apr 2019 01:00:08 -0700 Subject: [PATCH 10/30] Use bounds from iTermCursorGuideRendererTransientState's cellConfiguration instead of requiring them to be passed into the method. --- sources/Metal/Renderers/iTermCursorGuideRenderer.h | 2 +- sources/Metal/Renderers/iTermCursorGuideRenderer.m | 3 ++- sources/Metal/iTermMetalDriver.m | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.h b/sources/Metal/Renderers/iTermCursorGuideRenderer.h index ea8574fba2..37af18ac29 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.h +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.h @@ -6,7 +6,7 @@ NS_ASSUME_NONNULL_BEGIN @interface iTermCursorGuideRendererTransientState : iTermMetalCellRendererTransientState -- (void)setCursorCoord:(VT100GridCoord)coord within:(VT100GridSize)bounds; +- (void)setCursorCoord:(VT100GridCoord)coord; @end @interface iTermCursorGuideRenderer : NSObject diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.m b/sources/Metal/Renderers/iTermCursorGuideRenderer.m index 598e53d6a8..d7129c73a1 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.m +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.m @@ -14,7 +14,8 @@ @implementation iTermCursorGuideRendererTransientState { id _upperVertexBuffer, _lowerVertexBuffer; } -- (void)setCursorCoord:(VT100GridCoord)coord within:(VT100GridSize)bounds { +- (void)setCursorCoord:(VT100GridCoord)coord { + VT100GridSize bounds = self.cellConfiguration.gridSize; _row = (0 <= coord.y && coord.y < bounds.height) ? coord.y : -1; _column = (0 <= coord.x && coord.x < bounds.width) ? coord.x : -1; } diff --git a/sources/Metal/iTermMetalDriver.m b/sources/Metal/iTermMetalDriver.m index 19c7ef8cbd..d5f24d0220 100644 --- a/sources/Metal/iTermMetalDriver.m +++ b/sources/Metal/iTermMetalDriver.m @@ -1222,7 +1222,7 @@ - (void)populateHighlightRowRendererTransientStateWithFrameData:(iTermMetalFrame - (void)populateCursorGuideRendererTransientStateWithFrameData:(iTermMetalFrameData *)frameData { iTermCursorGuideRendererTransientState *tState = [frameData transientStateForRenderer:_cursorGuideRenderer]; VT100GridCoord coord = frameData.perFrameState.metalDriverCursorInfo.coord; - [tState setCursorCoord:coord within:frameData.gridSize]; + [tState setCursorCoord:coord]; } - (void)populateTimestampsRendererTransientStateWithFrameData:(iTermMetalFrameData *)frameData { From 1706bf1a9012408cbc4d19491b0871707190ba29 Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Sun, 7 Apr 2019 11:55:41 -0700 Subject: [PATCH 11/30] Since [...textView setNeedsDisplayOnColumn...] is expensive (causes a complete redraw), do not cause the redraw unless there is good reason to do so (ie the vertical cursor guide is enabled). --- sources/PTYTextView.m | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/sources/PTYTextView.m b/sources/PTYTextView.m index f58abe35af..06db5d52ee 100644 --- a/sources/PTYTextView.m +++ b/sources/PTYTextView.m @@ -979,7 +979,13 @@ - (void)setNeedsDisplayOnLine:(int)line } - (void)setNeedsDisplayOnColumn:(int)column { - [self setNeedsDisplayOnColumn:column inRange:VT100GridRangeMake(0, _dataSource.height)]; + // We can only draw whole lines, not individual characters. Consequently + // a request to redraw a column should only cause an update if there is + // something in the column outside the row that needs an update, such as the + // vertical cursor guide. + if ([self highlightCursorColumn]) { + [self setNeedsDisplayOnColumn:column inRange:VT100GridRangeMake(0, _dataSource.height)]; + } } // Overrides an NSView method. @@ -6407,21 +6413,13 @@ - (void)setNeedsDisplayOnLine:(int)y inRange:(VT100GridRange)range { } - (void)setNeedsDisplayOnColumn:(int)x inRange:(VT100GridRange)range { - NSRect dirtyRect; - const int y = range.location; - const int maxY = range.location + range.length; - - dirtyRect.origin.y = [iTermAdvancedSettingsModel terminalMargin] + y * _lineHeight; // _charHeightWithoutSpacing; - dirtyRect.origin.x = x * _charWidth; - dirtyRect.size.height = (maxY - y) * _lineHeight; //- _charHeightWithoutSpacing; - dirtyRect.size.width = _charWidth; - - // Expand the rect in case we're drawing a changed cell with an oversize glyph. - dirtyRect = [self rectWithHalo:dirtyRect]; - - DLog(@"Column %d is dirty in range [%d, %d), set rect %@ dirty", - x, y, maxY, [NSValue valueWithRect:dirtyRect]); - [self setNeedsDisplayInRect:dirtyRect]; + // We can only draw whole lines, not individual characters. Consequently + // a request to redraw a column should only cause an update if there is + // something in the column outside the row that needs an update, such as the + // vertical cursor guide. + if ([self highlightCursorColumn]) { + [self setNeedsDisplay:YES]; + } } // WARNING: Do not call this function directly. Call From 933ed96fcf9053ee8c1b948fa774707d48f56d2b Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Sun, 7 Apr 2019 12:35:41 -0700 Subject: [PATCH 12/30] Factor out rectangle tessellation and vertex buffer creation. --- .../Renderers/iTermCursorGuideRenderer.m | 90 ++++++++----------- 1 file changed, 37 insertions(+), 53 deletions(-) diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.m b/sources/Metal/Renderers/iTermCursorGuideRenderer.m index d7129c73a1..33bc1b230c 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.m +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.m @@ -14,6 +14,26 @@ @implementation iTermCursorGuideRendererTransientState { id _upperVertexBuffer, _lowerVertexBuffer; } +- (id)tessellateRect:(CGRect)rect withTexture:(CGRect)textureRect withPool:(iTermMetalBufferPool *)verticesPool { + // Tesselates an axis-aligned rectangle into a sequence of vertices + // representing two adjacent triangles that share the diagonal of the + // rectangle: + // top-right, top-left, bottom-left, top-right, bottom-left, bottom-right + const iTermVertex vertices[] = { + // Pixel Positions Texture Coordinates + { { CGRectGetMaxX(rect), CGRectGetMinY(rect) }, { CGRectGetMaxX(textureRect), CGRectGetMinY(textureRect) } }, + { { CGRectGetMinX(rect), CGRectGetMinY(rect) }, { CGRectGetMinX(textureRect), CGRectGetMinY(textureRect) } }, + { { CGRectGetMinX(rect), CGRectGetMaxY(rect) }, { CGRectGetMinX(textureRect), CGRectGetMaxY(textureRect) } }, + + { { CGRectGetMaxX(rect), CGRectGetMinY(rect) }, { CGRectGetMaxX(textureRect), CGRectGetMinY(textureRect) } }, + { { CGRectGetMinX(rect), CGRectGetMaxY(rect) }, { CGRectGetMinX(textureRect), CGRectGetMaxY(textureRect) } }, + { { CGRectGetMaxX(rect), CGRectGetMaxY(rect) }, { CGRectGetMaxX(textureRect), CGRectGetMaxY(textureRect) } }, + }; + return [verticesPool requestBufferFromContext:self.poolContext + withBytes:vertices + checkIfChanged:YES]; +} + - (void)setCursorCoord:(VT100GridCoord)coord { VT100GridSize bounds = self.cellConfiguration.gridSize; _row = (0 <= coord.y && coord.y < bounds.height) ? coord.y : -1; @@ -32,65 +52,29 @@ - (void)initializeVerticesWithPool:(iTermMetalBufferPool *)verticesPool CGFloat viewMaxX = viewMinX + cellSize.width*gridSize.width, viewMaxY = viewMinY + cellSize.height*gridSize.height; CGFloat cursorMinX = self.margins.left + self.column * cellSize.width, cursorMinY = self.margins.top + (gridSize.height - self.row - 1) * cellSize.height; - CGFloat cursorMaxX = cursorMinX + cellSize.width, cursorMaxY = cursorMinY + cellSize.height; + CGFloat cursorMaxY = cursorMinY + cellSize.height; if (horizontal) { - const iTermVertex vertices[] = { - // Pixel Positions Texture Coordinates - { { viewMaxX, cursorMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { viewMinX, cursorMinY }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { viewMinX, cursorMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - - { { viewMaxX, cursorMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { viewMinX, cursorMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - { { viewMaxX, cursorMaxY }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, - }; - self.horizontalVertexBuffer = [verticesPool requestBufferFromContext:self.poolContext - withBytes:vertices - checkIfChanged:YES]; + self.horizontalVertexBuffer = [self tessellateRect:CGRectMake(viewMinX, cursorMinY, + viewMaxX - viewMinX, cellSize.height) + withTexture:textureFrame + withPool:verticesPool]; } if (horizontal && vertical) { - const iTermVertex lowerVertices[] = { - // Pixel Positions Texture Coordinates - { { cursorMaxX, viewMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { cursorMinX, viewMinY }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { cursorMinX, cursorMinY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - - { { cursorMaxX, viewMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { cursorMinX, cursorMinY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - { { cursorMaxX, cursorMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, - }; - self.lowerVertexBuffer = [verticesPool requestBufferFromContext:self.poolContext - withBytes:lowerVertices - checkIfChanged:YES]; - const iTermVertex upperVertices[] = { - // Pixel Positions Texture Coordinates - { { cursorMaxX, cursorMaxY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { cursorMinX, cursorMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { cursorMinX, viewMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - - { { cursorMaxX, cursorMaxY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { cursorMinX, viewMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - { { cursorMaxX, viewMaxY }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, - }; - self.upperVertexBuffer = [verticesPool requestBufferFromContext:self.poolContext - withBytes:upperVertices - checkIfChanged:YES]; + self.lowerVertexBuffer = [self tessellateRect:CGRectMake(cursorMinX, viewMinY, + cellSize.width, cursorMinY - viewMinY) + withTexture:textureFrame + withPool:verticesPool]; + self.upperVertexBuffer = [self tessellateRect:CGRectMake(cursorMinX, cursorMaxY, + cellSize.width, viewMaxY - cursorMaxY) + withTexture:textureFrame + withPool:verticesPool]; } else if (vertical) { - const iTermVertex vertices[] = { - // Pixel Positions Texture Coordinates - { { cursorMaxX, viewMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { cursorMinX, viewMinY }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { cursorMinX, viewMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - - { { cursorMaxX, viewMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { cursorMinX, viewMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - { { cursorMaxX, viewMaxY }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, - }; - self.verticalVertexBuffer = [verticesPool requestBufferFromContext:self.poolContext - withBytes:vertices - checkIfChanged:YES]; + self.verticalVertexBuffer = [self tessellateRect:CGRectMake(cursorMinX, viewMinY, + cellSize.width, viewMaxY - viewMinY) + withTexture:textureFrame + withPool:verticesPool]; } } From 7540e63f094d769abef5ca21ac0c8836752714ef Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Sun, 7 Apr 2019 19:17:46 -0700 Subject: [PATCH 13/30] Do not double-draw the cursor guide under the cursor. --- sources/iTermTextDrawingHelper.m | 38 +++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/sources/iTermTextDrawingHelper.m b/sources/iTermTextDrawingHelper.m index 568c3396b8..025f92e2ff 100644 --- a/sources/iTermTextDrawingHelper.m +++ b/sources/iTermTextDrawingHelper.m @@ -644,26 +644,38 @@ - (void)drawAccessoriesInRect:(NSRect)bgRect { // Highlight cursor line if the cursor is on this line and it's on. int cursorLine = _cursorCoord.y + _numberOfScrollbackLines; - const BOOL drawCursorGuide = (self.highlightCursorLine && - cursorLine >= coordRange.start.y && - cursorLine < coordRange.end.y); - if (drawCursorGuide) { - CGFloat y = cursorLine * _cellSize.height; - [self drawCursorGuideForColumns:NSMakeRange(coordRange.start.x, - coordRange.end.x - coordRange.start.x) - y:y]; - } - - // Highlight cursor column if the cursor is in this column and it's on. int cursorColumn = _cursorCoord.x; + const BOOL drawHorizontalCursorGuide = (self.highlightCursorLine && + cursorLine >= coordRange.start.y && + cursorLine < coordRange.end.y); const BOOL drawVerticalCursorGuide = (self.highlightCursorColumn && cursorColumn >= coordRange.start.x && cursorColumn < coordRange.end.x); - if (drawVerticalCursorGuide) { + + if (drawHorizontalCursorGuide && !drawVerticalCursorGuide) { + CGFloat y = cursorLine * _cellSize.height; + [self drawCursorGuideForColumns:NSMakeRange(coordRange.start.x, + coordRange.end.x - coordRange.start.x) + y:y]; + } else if (!drawHorizontalCursorGuide && drawVerticalCursorGuide) { CGFloat x = cursorColumn * _cellSize.width; [self drawCursorGuideForRows:NSMakeRange(coordRange.start.y, coordRange.end.y - coordRange.start.y) x:x]; + [self.delegate setNeedsDisplay:YES]; + } else if (drawHorizontalCursorGuide && drawVerticalCursorGuide) { + CGFloat x = cursorColumn * _cellSize.width; + CGFloat y = cursorLine * _cellSize.height; + [self drawCursorGuideForColumns:NSMakeRange(coordRange.start.x, + coordRange.end.x - coordRange.start.x) + y:y]; + [self drawCursorGuideForRows:NSMakeRange(coordRange.start.y, + cursorLine - coordRange.start.y) + x:x]; + [self drawCursorGuideForRows:NSMakeRange(cursorLine + 1, + coordRange.end.y - _cursorCoord.y) + x:x]; + [self.delegate setNeedsDisplay:YES]; } } @@ -692,7 +704,7 @@ - (void)drawCursorGuideForRows:(NSRange)range x:(CGFloat)xOrigin { } [_cursorGuideColor set]; NSPoint textOrigin = NSMakePoint(xOrigin + [iTermAdvancedSettingsModel terminalMargin], - [iTermAdvancedSettingsModel terminalMargin] + range.location * _cellSize.height); + range.location * _cellSize.height); NSRect rect = NSMakeRect(textOrigin.x, textOrigin.y, _cellSize.width, From b7b94301b476ad9be97b503a03a82a5029f920bf Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Tue, 26 Mar 2019 01:05:23 -0700 Subject: [PATCH 14/30] Render a vertical guide over the column the cursor is in (Metal View implementation). --- .../Metal/Infrastructure/iTermMetalRenderer.h | 1 + .../Renderers/iTermCursorGuideRenderer.h | 4 +- .../Renderers/iTermCursorGuideRenderer.m | 53 +++++++++++++++---- sources/Metal/iTermMetalDriver.m | 9 +--- 4 files changed, 47 insertions(+), 20 deletions(-) diff --git a/sources/Metal/Infrastructure/iTermMetalRenderer.h b/sources/Metal/Infrastructure/iTermMetalRenderer.h index aee0e34db4..4206a8299e 100644 --- a/sources/Metal/Infrastructure/iTermMetalRenderer.h +++ b/sources/Metal/Infrastructure/iTermMetalRenderer.h @@ -46,6 +46,7 @@ NS_CLASS_AVAILABLE(10_11, NA) @interface iTermMetalRendererTransientState : NSObject @property (nonatomic, strong, readonly) __kindof iTermRenderConfiguration *configuration; @property (nonatomic, strong) id vertexBuffer; +@property (nonatomic, strong) id vvertexBuffer; @property (nonatomic, readonly) iTermMetalBufferPoolContext *poolContext; @property (nonatomic, weak) iTermMetalDebugInfo *debugInfo; @property (nonatomic, strong) NSImage *renderedOutputForDebugging; diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.h b/sources/Metal/Renderers/iTermCursorGuideRenderer.h index d9178e07c6..cb9cb27faf 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.h +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.h @@ -1,12 +1,12 @@ #import #import "iTermMetalCellRenderer.h" +#import "VT100GridTypes.h" NS_ASSUME_NONNULL_BEGIN @interface iTermCursorGuideRendererTransientState : iTermMetalCellRendererTransientState -// set to -1 if cursor's row is not currently visible. -- (void)setRow:(int)row; +- (void)setCursorCoord:(VT100GridCoord)coord within:(VT100GridSize)bounds; @end @interface iTermCursorGuideRenderer : NSObject diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.m b/sources/Metal/Renderers/iTermCursorGuideRenderer.m index b7326aaf78..1c842b52a9 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.m +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.m @@ -3,14 +3,17 @@ @interface iTermCursorGuideRendererTransientState() @property (nonatomic, strong) id texture; @property (nonatomic) int row; +@property (nonatomic) int col; @end @implementation iTermCursorGuideRendererTransientState { int _row; + int _col; } -- (void)setRow:(int)row { - _row = row; +- (void)setCursorCoord:(VT100GridCoord)coord within:(VT100GridSize)bounds { + _row = (0 <= coord.y && coord.y < bounds.height) ? coord.y : -1; + _col = (0 <= coord.x && coord.x < bounds.width) ? coord.x : -1; } - (void)initializeVerticesWithPool:(iTermMetalBufferPool *)verticesPool { @@ -35,6 +38,23 @@ - (void)initializeVerticesWithPool:(iTermMetalBufferPool *)verticesPool { self.vertexBuffer = [verticesPool requestBufferFromContext:self.poolContext withBytes:vertices checkIfChanged:YES]; + + const CGRect vQuad = CGRectMake(self.margins.left + self.col * cellSize.width, + self.margins.top, + cellSize.width, + cellSize.height * gridSize.height); + const iTermVertex vvertices[] = { + { { CGRectGetMaxX(vQuad), CGRectGetMinY(vQuad) }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { CGRectGetMinX(vQuad), CGRectGetMinY(vQuad) }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { CGRectGetMinX(vQuad), CGRectGetMaxY(vQuad) }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, + + { { CGRectGetMaxX(vQuad), CGRectGetMinY(vQuad) }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { CGRectGetMinX(vQuad), CGRectGetMaxY(vQuad) }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, + { { CGRectGetMaxX(vQuad), CGRectGetMaxY(vQuad) }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, + }; + self.vvertexBuffer = [verticesPool requestBufferFromContext:self.poolContext + withBytes:vvertices + checkIfChanged:YES]; } - (void)writeDebugInfoToFolder:(NSURL *)folder { @@ -106,19 +126,30 @@ - (void)setColor:(NSColor *)color { - (void)drawWithFrameData:(iTermMetalFrameData *)frameData transientState:(__kindof iTermMetalCellRendererTransientState *)transientState { iTermCursorGuideRendererTransientState *tState = transientState; - if (tState.row < 0) { - // Cursor is offscreen. We set it to -1 to signal this. + if (tState.row < 0 || tState.col < 0) { return; } [tState initializeVerticesWithPool:_cellRenderer.verticesPool]; - [_cellRenderer drawWithTransientState:tState - renderEncoder:frameData.renderEncoder - numberOfVertices:6 - numberOfPIUs:0 - vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.vertexBuffer } - fragmentBuffers:@{} - textures:@{ @(iTermTextureIndexPrimary): tState.texture } ]; + if (tState.row >= 0 && self.enabled) { + [_cellRenderer drawWithTransientState:tState + renderEncoder:frameData.renderEncoder + numberOfVertices:6 + numberOfPIUs:0 + vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.vertexBuffer } + fragmentBuffers:@{} + textures:@{ @(iTermTextureIndexPrimary): tState.texture } ]; + } + + if (tState.col >= 0 && self.enabled) { + [_cellRenderer drawWithTransientState:tState + renderEncoder:frameData.renderEncoder + numberOfVertices:6 + numberOfPIUs:0 + vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.vvertexBuffer } + fragmentBuffers:@{} + textures:@{ @(iTermTextureIndexPrimary): tState.texture } ]; + } } #pragma mark - Private diff --git a/sources/Metal/iTermMetalDriver.m b/sources/Metal/iTermMetalDriver.m index 0d48797703..904e73a31d 100644 --- a/sources/Metal/iTermMetalDriver.m +++ b/sources/Metal/iTermMetalDriver.m @@ -1219,13 +1219,8 @@ - (void)populateHighlightRowRendererTransientStateWithFrameData:(iTermMetalFrame - (void)populateCursorGuideRendererTransientStateWithFrameData:(iTermMetalFrameData *)frameData { iTermCursorGuideRendererTransientState *tState = [frameData transientStateForRenderer:_cursorGuideRenderer]; - iTermMetalCursorInfo *cursorInfo = frameData.perFrameState.metalDriverCursorInfo; - if (cursorInfo.coord.y >= 0 && - cursorInfo.coord.y < frameData.gridSize.height) { - [tState setRow:frameData.perFrameState.metalDriverCursorInfo.coord.y]; - } else { - [tState setRow:-1]; - } + VT100GridCoord coord = frameData.perFrameState.metalDriverCursorInfo.coord; + [tState setCursorCoord:coord within:frameData.gridSize]; } - (void)populateTimestampsRendererTransientStateWithFrameData:(iTermMetalFrameData *)frameData { From 516e4bb84befb4549a8f993ac63408c25241cdca Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Tue, 26 Mar 2019 01:21:01 -0700 Subject: [PATCH 15/30] Separate control of the vertical cursor guide from the horizontal guide. --- Interfaces/MainMenu.xib | 6 ++++ Interfaces/PreferencePanel.xib | 17 ++++++++-- iTerm2XCTests/VT100ScreenTest.m | 6 ++++ sources/ITAddressBookMgr.h | 1 + .../Renderers/iTermCursorGuideRenderer.h | 1 + .../Renderers/iTermCursorGuideRenderer.m | 2 +- sources/Metal/iTermMetalDriver.h | 1 + sources/Metal/iTermMetalDriver.m | 4 ++- sources/PTYSession.h | 1 + sources/PTYSession.m | 33 +++++++++++++++++++ sources/PTYTextView.h | 3 ++ sources/PTYTextView.m | 8 +++++ .../ProfilesColorsPreferencesViewController.m | 5 +++ sources/PseudoTerminal.m | 9 +++++ sources/VT100Screen.m | 4 +++ sources/VT100ScreenDelegate.h | 1 + sources/VT100Terminal.m | 2 ++ sources/VT100TerminalDelegate.h | 1 + sources/iTermMetalPerFrameState.m | 4 +++ .../iTermMetalPerFrameStateConfiguration.h | 1 + .../iTermMetalPerFrameStateConfiguration.m | 1 + sources/iTermProfilePreferences.m | 3 +- sources/iTermTextDrawingHelper.h | 3 ++ 23 files changed, 112 insertions(+), 5 deletions(-) diff --git a/Interfaces/MainMenu.xib b/Interfaces/MainMenu.xib index 39b2e2fccd..eedfcfe25a 100644 --- a/Interfaces/MainMenu.xib +++ b/Interfaces/MainMenu.xib @@ -668,6 +668,12 @@ Gw + + + + + + diff --git a/Interfaces/PreferencePanel.xib b/Interfaces/PreferencePanel.xib index 52f94a9548..f994c2983e 100644 --- a/Interfaces/PreferencePanel.xib +++ b/Interfaces/PreferencePanel.xib @@ -1471,6 +1471,7 @@ DQ + @@ -2206,7 +2207,7 @@ DQ - + @@ -2257,7 +2258,7 @@ DQ + diff --git a/iTerm2XCTests/VT100ScreenTest.m b/iTerm2XCTests/VT100ScreenTest.m index 5474e776d1..b1b5aa68c0 100644 --- a/iTerm2XCTests/VT100ScreenTest.m +++ b/iTerm2XCTests/VT100ScreenTest.m @@ -748,6 +748,12 @@ - (void)screenSetHighlightCursorLine:(BOOL)highlight { - (void)screenCursorDidMoveToLine:(int)line { } +- (void)screenSetHighlightCursorCol:(BOOL)highlight { +} + +- (void)screenCursorDidMoveToCol:(int)line { +} + - (void)screenSaveScrollPosition { } diff --git a/sources/ITAddressBookMgr.h b/sources/ITAddressBookMgr.h index 27a0d667c8..41724ed936 100644 --- a/sources/ITAddressBookMgr.h +++ b/sources/ITAddressBookMgr.h @@ -114,6 +114,7 @@ #define KEY_USE_UNDERLINE_COLOR @"Use Underline Color" #define KEY_CURSOR_BOOST @"Cursor Boost" #define KEY_USE_CURSOR_GUIDE @"Use Cursor Guide" +#define KEY_USE_VERT_CURSOR_GUIDE @"Use Vertical Cursor Guide" #define KEY_CURSOR_GUIDE_COLOR @"Cursor Guide Color" #define KEY_BADGE_COLOR @"Badge Color" diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.h b/sources/Metal/Renderers/iTermCursorGuideRenderer.h index cb9cb27faf..92e4d448c8 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.h +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.h @@ -12,6 +12,7 @@ NS_ASSUME_NONNULL_BEGIN @interface iTermCursorGuideRenderer : NSObject @property (nonatomic) BOOL enabled; +@property (nonatomic) BOOL venabled; - (nullable instancetype)initWithDevice:(id)device NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE; diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.m b/sources/Metal/Renderers/iTermCursorGuideRenderer.m index 1c842b52a9..16dcad904f 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.m +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.m @@ -141,7 +141,7 @@ - (void)drawWithFrameData:(iTermMetalFrameData *)frameData textures:@{ @(iTermTextureIndexPrimary): tState.texture } ]; } - if (tState.col >= 0 && self.enabled) { + if (tState.col >= 0 && self.venabled) { [_cellRenderer drawWithTransientState:tState renderEncoder:frameData.renderEncoder numberOfVertices:6 diff --git a/sources/Metal/iTermMetalDriver.h b/sources/Metal/iTermMetalDriver.h index c3e724ff94..d2e04157f6 100644 --- a/sources/Metal/iTermMetalDriver.h +++ b/sources/Metal/iTermMetalDriver.h @@ -61,6 +61,7 @@ NS_CLASS_AVAILABLE(10_11, NA) @property (nonatomic, readonly) BOOL showBroadcastStripes; @property (nonatomic, readonly) NSColor *cursorGuideColor; @property (nonatomic, readonly) BOOL cursorGuideEnabled; +@property (nonatomic, readonly) BOOL cursorVGuideEnabled; @property (nonatomic, readonly) vector_float4 fullScreenFlashColor; @property (nonatomic, readonly) BOOL timestampsEnabled; @property (nonatomic, readonly) NSColor *timestampsBackgroundColor; diff --git a/sources/Metal/iTermMetalDriver.m b/sources/Metal/iTermMetalDriver.m index 904e73a31d..41d14444bc 100644 --- a/sources/Metal/iTermMetalDriver.m +++ b/sources/Metal/iTermMetalDriver.m @@ -644,7 +644,8 @@ - (BOOL)shouldCreateIntermediateRenderPassDescriptor:(iTermMetalFrameData *)fram if (!_broadcastStripesRenderer.rendererDisabled && frameData.perFrameState.showBroadcastStripes) { return YES; } - if (!_cursorGuideRenderer.rendererDisabled && frameData.perFrameState.cursorGuideEnabled) { + if (!_cursorGuideRenderer.rendererDisabled && (frameData.perFrameState.cursorGuideEnabled + || frameData.perFrameState.cursorVGuideEnabled)) { return YES; } @@ -970,6 +971,7 @@ - (void)updateCursorGuideRendererForFrameData:(iTermMetalFrameData *)frameData { } [_cursorGuideRenderer setColor:frameData.perFrameState.cursorGuideColor]; _cursorGuideRenderer.enabled = frameData.perFrameState.cursorGuideEnabled; + _cursorGuideRenderer.venabled = frameData.perFrameState.cursorVGuideEnabled; } - (void)updateTimestampsRendererForFrameData:(iTermMetalFrameData *)frameData { diff --git a/sources/PTYSession.h b/sources/PTYSession.h index 97576a25ba..b48d2c4eb8 100644 --- a/sources/PTYSession.h +++ b/sources/PTYSession.h @@ -422,6 +422,7 @@ typedef enum { @property(nonatomic, readonly) BOOL hasSelection; @property(nonatomic, assign) BOOL highlightCursorLine; +@property(nonatomic, assign) BOOL highlightCursorCol; // Used to help remember total ordering on views while one is maximized @property(nonatomic, assign) NSPoint savedRootRelativeOrigin; diff --git a/sources/PTYSession.m b/sources/PTYSession.m index 1ae32f0e44..0b8e0e3c65 100644 --- a/sources/PTYSession.m +++ b/sources/PTYSession.m @@ -207,6 +207,7 @@ static NSString *const SESSION_ARRANGEMENT_DIRECTORIES = @"Directories"; // Array of strings static NSString *const SESSION_ARRANGEMENT_HOSTS = @"Hosts"; // Array of VT100RemoteHost static NSString *const SESSION_ARRANGEMENT_CURSOR_GUIDE = @"Cursor Guide"; // BOOL +static NSString *const SESSION_ARRANGEMENT_VCURSOR_GUIDE = @"Vertical Cursor Guide"; // BOOL static NSString *const SESSION_ARRANGEMENT_LAST_DIRECTORY = @"Last Directory"; // NSString static NSString *const SESSION_ARRANGEMENT_LAST_DIRECTORY_IS_UNSUITABLE_FOR_OLD_PWD = @"Last Directory Is Remote"; // BOOL static NSString *const SESSION_ARRANGEMENT_SELECTION = @"Selection"; // Dictionary for iTermSelection. @@ -1185,6 +1186,9 @@ + (void)finishInitializingArrangementOriginatedSession:(PTYSession *)aSession if (arrangement[SESSION_ARRANGEMENT_CURSOR_GUIDE]) { aSession.textview.highlightCursorLine = [arrangement[SESSION_ARRANGEMENT_CURSOR_GUIDE] boolValue]; } + if (arrangement[SESSION_ARRANGEMENT_VCURSOR_GUIDE]) { + aSession.textview.highlightCursorLine = [arrangement[SESSION_ARRANGEMENT_VCURSOR_GUIDE] boolValue]; + } aSession->_lastMark = [aSession.screen.lastMark retain]; aSession.lastRemoteHost = aSession.screen.lastRemoteHost; if (arrangement[SESSION_ARRANGEMENT_LAST_DIRECTORY]) { @@ -3473,6 +3477,8 @@ - (void)loadInitialColorTable } _textview.highlightCursorLine = [iTermProfilePreferences boolForKey:KEY_USE_CURSOR_GUIDE inProfile:_profile]; + _textview.highlightCursorCol = [iTermProfilePreferences boolForKey:KEY_USE_VERT_CURSOR_GUIDE + inProfile:_profile]; } - (NSColor *)tabColorInProfile:(NSDictionary *)profile @@ -3655,6 +3661,8 @@ - (void)setPreferencesFromAddressBookEntry:(NSDictionary *)aePrefs { if (!_cursorGuideSettingHasChanged) { _textview.highlightCursorLine = [iTermProfilePreferences boolForKey:KEY_USE_CURSOR_GUIDE inProfile:aDict]; + _textview.highlightCursorCol = [iTermProfilePreferences boolForKey:KEY_USE_VERT_CURSOR_GUIDE + inProfile:aDict]; } for (i = 0; i < 16; i++) { @@ -4381,6 +4389,7 @@ - (NSDictionary *)arrangementWithContents:(BOOL)includeContents { [NSDictionary dictionaryWithGridCoordRange:range]; result[SESSION_ARRANGEMENT_ALERT_ON_NEXT_MARK] = @(_alertOnNextMark); result[SESSION_ARRANGEMENT_CURSOR_GUIDE] = @(_textview.highlightCursorLine); + result[SESSION_ARRANGEMENT_VCURSOR_GUIDE] = @(_textview.highlightCursorCol); if (self.lastDirectory) { result[SESSION_ARRANGEMENT_LAST_DIRECTORY] = self.lastDirectory; result[SESSION_ARRANGEMENT_LAST_DIRECTORY_IS_UNSUITABLE_FOR_OLD_PWD] = @(self.lastDirectoryIsUnsuitableForOldPWD); @@ -8388,6 +8397,8 @@ - (void)screenDidReset { _cursorGuideSettingHasChanged = NO; _textview.highlightCursorLine = [iTermProfilePreferences boolForKey:KEY_USE_CURSOR_GUIDE inProfile:_profile]; + _textview.highlightCursorCol = [iTermProfilePreferences boolForKey:KEY_USE_VERT_CURSOR_GUIDE + inProfile:_profile]; [_textview setNeedsDisplay:YES]; _screen.trackCursorLineMovement = NO; } @@ -8660,6 +8671,28 @@ - (BOOL)highlightCursorLine { return _textview.highlightCursorLine; } +- (void)screenCursorDidMoveToCol:(int)col { + if (_textview.cursorVisible) { + [_textview setNeedsDisplayOnCol:col]; + } +} + +- (void)screenSetHighlightCursorCol:(BOOL)highlight { + _cursorGuideSettingHasChanged = YES; + self.highlightCursorCol = highlight; +} + +- (void)setHighlightCursorCol:(BOOL)highlight { + _cursorGuideSettingHasChanged = YES; + _textview.highlightCursorCol = highlight; + [_textview setNeedsDisplay:YES]; + _screen.trackCursorColMovement = highlight; +} + +- (BOOL)highlightCursorCol { + return _textview.highlightCursorCol; +} + - (BOOL)screenHasView { return _textview != nil; } diff --git a/sources/PTYTextView.h b/sources/PTYTextView.h index ea3971a2bf..d5bb5b18b6 100644 --- a/sources/PTYTextView.h +++ b/sources/PTYTextView.h @@ -235,6 +235,9 @@ typedef NS_ENUM(NSInteger, PTYTextViewSelectionExtensionUnit) { // Draw a highlight along the entire line the cursor is on. @property(nonatomic, assign) BOOL highlightCursorLine; +// Draw a highlight along the entire column the cursor is in. +@property(nonatomic, assign) BOOL highlightCursorCol; + // Use the non-ascii font? If not set, use the regular font for all characters. @property(nonatomic, assign) BOOL useNonAsciiFont; diff --git a/sources/PTYTextView.m b/sources/PTYTextView.m index aa49b9424a..df57a4b905 100644 --- a/sources/PTYTextView.m +++ b/sources/PTYTextView.m @@ -581,6 +581,14 @@ - (BOOL)highlightCursorLine { return _drawingHelper.highlightCursorLine; } +- (void)setHighlightCursorCol:(BOOL)highlightCursorCol { + _drawingHelper.highlightCursorCol = highlightCursorCol; +} + +- (BOOL)highlightCursorCol { + return _drawingHelper.highlightCursorCol; +} + - (void)setUseNonAsciiFont:(BOOL)useNonAsciiFont { _drawingHelper.useNonAsciiFont = useNonAsciiFont; _useNonAsciiFont = useNonAsciiFont; diff --git a/sources/ProfilesColorsPreferencesViewController.m b/sources/ProfilesColorsPreferencesViewController.m index e8e6d7ef3a..cc21b6b40d 100644 --- a/sources/ProfilesColorsPreferencesViewController.m +++ b/sources/ProfilesColorsPreferencesViewController.m @@ -79,6 +79,7 @@ @implementation ProfilesColorsPreferencesViewController { IBOutlet NSMenu *_presetsMenu; IBOutlet NSButton *_useGuide; + IBOutlet NSButton *_useVGuide; IBOutlet CPKColorWell *_guideColor; IBOutlet NSPopUpButton *_presetsPopupButton; @@ -203,6 +204,10 @@ - (void)awakeFromNib { relatedView:nil type:kPreferenceInfoTypeCheckbox]; + [self defineControl:_useVGuide + key:KEY_USE_VERT_CURSOR_GUIDE + type:kPreferenceInfoTypeCheckbox]; + info = [self defineControl:_useBrightBold key:KEY_USE_BOLD_COLOR displayName:@"Custom color for bold text" diff --git a/sources/PseudoTerminal.m b/sources/PseudoTerminal.m index c40012a692..f2f80e858d 100644 --- a/sources/PseudoTerminal.m +++ b/sources/PseudoTerminal.m @@ -1787,6 +1787,11 @@ - (IBAction)toggleCursorGuide:(id)sender { session.highlightCursorLine = !session.highlightCursorLine; } +- (IBAction)toggleVCursorGuide:(id)sender { + PTYSession *session = [self currentSession]; + session.highlightCursorCol = !session.highlightCursorCol; +} + - (IBAction)toggleSelectionRespectsSoftBoundaries:(id)sender { iTermController *controller = [iTermController sharedInstance]; controller.selectionRespectsSoftBoundaries = !controller.selectionRespectsSoftBoundaries; @@ -8603,6 +8608,10 @@ - (BOOL)validateMenuItem:(NSMenuItem *)item { PTYSession *session = [self currentSession]; [item setState:session.highlightCursorLine ? NSOnState : NSOffState]; result = YES; + } else if ([item action] == @selector(toggleVCursorGuide:)) { + PTYSession *session = [self currentSession]; + [item setState:session.highlightCursorCol ? NSOnState : NSOffState]; + result = YES; } else if ([item action] == @selector(toggleSelectionRespectsSoftBoundaries:)) { [item setState:[[iTermController sharedInstance] selectionRespectsSoftBoundaries] ? NSOnState : NSOffState]; result = YES; diff --git a/sources/VT100Screen.m b/sources/VT100Screen.m index 4be6d3e4b8..2f03f079e4 100644 --- a/sources/VT100Screen.m +++ b/sources/VT100Screen.m @@ -4139,6 +4139,10 @@ - (void)terminalSetHighlightCursorLine:(BOOL)highlight { [delegate_ screenSetHighlightCursorLine:highlight]; } +- (void)terminalSetHighlightCursorCol:(BOOL)highlight { + [delegate_ screenSetHighlightCursorCol:highlight]; +} + - (void)terminalPromptDidStart { [self promptDidStartAt:VT100GridAbsCoordMake(currentGrid_.cursor.x, currentGrid_.cursor.y + self.numberOfScrollbackLines + self.totalScrollbackOverflow)]; diff --git a/sources/VT100ScreenDelegate.h b/sources/VT100ScreenDelegate.h index 1936e9f128..2f48145ae7 100644 --- a/sources/VT100ScreenDelegate.h +++ b/sources/VT100ScreenDelegate.h @@ -185,6 +185,7 @@ - (void)screenSetCursorVisible:(BOOL)visible; - (void)screenSetHighlightCursorLine:(BOOL)highlight; +- (void)screenSetHighlightCursorCol:(BOOL)highlight; // Only called if the trackCursorLineMovement property is set. - (void)screenCursorDidMoveToLine:(int)line; diff --git a/sources/VT100Terminal.m b/sources/VT100Terminal.m index 562a197006..ac9f46526e 100644 --- a/sources/VT100Terminal.m +++ b/sources/VT100Terminal.m @@ -2367,6 +2367,8 @@ - (void)executeXtermSetKvp:(VT100Token *)token { [delegate_ terminalAddNote:(NSString *)value show:NO]; } else if ([key isEqualToString:@"HighlightCursorLine"]) { [delegate_ terminalSetHighlightCursorLine:value.length ? [value boolValue] : YES]; + } else if ([key isEqualToString:@"HighlightCursorCol"]) { + [delegate_ terminalSetHighlightCursorCol:value.length ? [value boolValue] : YES]; } else if ([key isEqualToString:@"CopyToClipboard"]) { if ([delegate_ terminalIsTrusted]) { [delegate_ terminalSetPasteboard:value]; diff --git a/sources/VT100TerminalDelegate.h b/sources/VT100TerminalDelegate.h index 5908d40c35..91e0aedbdf 100644 --- a/sources/VT100TerminalDelegate.h +++ b/sources/VT100TerminalDelegate.h @@ -366,6 +366,7 @@ typedef NS_ENUM(int, VT100TerminalColorIndex) { - (void)terminalSetCursorVisible:(BOOL)visible; - (void)terminalSetHighlightCursorLine:(BOOL)highlight; +- (void)terminalSetHighlightCursorCol:(BOOL)highlight; // FinalTerm features - (void)terminalPromptDidStart; diff --git a/sources/iTermMetalPerFrameState.m b/sources/iTermMetalPerFrameState.m index fa12ee3f3c..f85feb501d 100644 --- a/sources/iTermMetalPerFrameState.m +++ b/sources/iTermMetalPerFrameState.m @@ -582,6 +582,10 @@ - (BOOL)cursorGuideEnabled { return _configuration->_cursorGuideColor && _configuration->_cursorGuideEnabled; } +- (BOOL)cursorVGuideEnabled { + return _configuration->_cursorGuideColor && _configuration->_cursorVGuideEnabled; +} + - (NSColor *)cursorGuideColor { return _configuration->_cursorGuideColor; } diff --git a/sources/iTermMetalPerFrameStateConfiguration.h b/sources/iTermMetalPerFrameStateConfiguration.h index 9223b3b038..967666d5a7 100644 --- a/sources/iTermMetalPerFrameStateConfiguration.h +++ b/sources/iTermMetalPerFrameStateConfiguration.h @@ -62,6 +62,7 @@ NS_ASSUME_NONNULL_BEGIN // Cursor BOOL _shouldDrawFilledInCursor; BOOL _cursorGuideEnabled; + BOOL _cursorVGuideEnabled; // Size VT100GridSize _gridSize; diff --git a/sources/iTermMetalPerFrameStateConfiguration.m b/sources/iTermMetalPerFrameStateConfiguration.m index 0ccdce7f73..8b72b8c381 100644 --- a/sources/iTermMetalPerFrameStateConfiguration.m +++ b/sources/iTermMetalPerFrameStateConfiguration.m @@ -56,6 +56,7 @@ - (void)loadSettingsWithDrawingHelper:(iTermTextDrawingHelper *)drawingHelper // Cursor guide _cursorGuideEnabled = drawingHelper.highlightCursorLine; + _cursorVGuideEnabled = drawingHelper.highlightCursorCol; _cursorGuideColor = drawingHelper.cursorGuideColor; // Background image diff --git a/sources/iTermProfilePreferences.m b/sources/iTermProfilePreferences.m index 308ec7753d..4247767789 100644 --- a/sources/iTermProfilePreferences.m +++ b/sources/iTermProfilePreferences.m @@ -184,7 +184,7 @@ + (BOOL)valueIsLegal:(id)value forKey:(NSString *)key { KEY_CURSOR_GUIDE_COLOR, KEY_BADGE_COLOR, KEY_TAB_COLOR, KEY_UNDERLINE_COLOR ]; - NSArray *number = @[ KEY_USE_CURSOR_GUIDE, KEY_USE_TAB_COLOR, KEY_USE_UNDERLINE_COLOR, + NSArray *number = @[ KEY_USE_CURSOR_GUIDE, KEY_USE_VERT_CURSOR_GUIDE, KEY_USE_TAB_COLOR, KEY_USE_UNDERLINE_COLOR, KEY_SMART_CURSOR_COLOR, KEY_MINIMUM_CONTRAST, KEY_CURSOR_BOOST, KEY_CURSOR_TYPE, KEY_BLINKING_CURSOR, KEY_USE_BOLD_FONT, KEY_THIN_STROKES, KEY_ASCII_LIGATURES, KEY_NON_ASCII_LIGATURES, KEY_USE_BOLD_COLOR, @@ -268,6 +268,7 @@ + (NSDictionary *)defaultValueMap { KEY_CURSOR_GUIDE_COLOR: [[NSColor colorWithCalibratedRed:0.650 green:0.910 blue:1.000 alpha:0.25] dictionaryValue], KEY_BADGE_COLOR: [[NSColor colorWithCalibratedRed:1.0 green:0.000 blue:0.000 alpha:0.5] dictionaryValue], KEY_USE_CURSOR_GUIDE: @NO, + KEY_USE_VERT_CURSOR_GUIDE: @NO, KEY_TAB_COLOR: [NSNull null], KEY_USE_TAB_COLOR: @NO, KEY_UNDERLINE_COLOR: [NSNull null], diff --git a/sources/iTermTextDrawingHelper.h b/sources/iTermTextDrawingHelper.h index d06f90137b..c5ba2c9b13 100644 --- a/sources/iTermTextDrawingHelper.h +++ b/sources/iTermTextDrawingHelper.h @@ -180,6 +180,9 @@ BOOL CheckFindMatchAtIndex(NSData *findMatches, int index); // Should the cursor guide be shown? @property(nonatomic, assign) BOOL highlightCursorLine; +// Should the vertical cursor guide be shown? +@property(nonatomic, assign) BOOL highlightCursorCol; + // Minimum contrast level, 0-1. @property(nonatomic, assign) double minimumContrast; From e99e6600ad2eb9e7f3d21cb8bf5d4e41ada7e51e Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Tue, 26 Mar 2019 01:25:58 -0700 Subject: [PATCH 16/30] Render a vertical cursor guide in the software rendered view. --- iTerm2XCTests/PTYTextViewTest.m | 15 +++++++++++++++ sources/PTYSession.m | 2 ++ sources/PTYTextView.h | 1 + sources/PTYTextView.m | 23 +++++++++++++++++++++++ sources/iTermTextDrawingHelper.m | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 73 insertions(+) diff --git a/iTerm2XCTests/PTYTextViewTest.m b/iTerm2XCTests/PTYTextViewTest.m index 15e32aef92..471b0c5ed1 100644 --- a/iTerm2XCTests/PTYTextViewTest.m +++ b/iTerm2XCTests/PTYTextViewTest.m @@ -991,6 +991,21 @@ - (void)testCursorGuide { size:VT100GridSizeMake(5, 5)]; } +// Draws a cursor guide on the col with b. +- (void)testVCursorGuide { + [self doGoldenTestForInput:@"abcd\x1b[2A" + name:NSStringFromSelector(_cmd) + hook:^(PTYTextView *textView) { + textView.drawingHook = ^(iTermTextDrawingHelper *helper) { + helper.shouldDrawFilledInCursor = YES; + helper.highlightCursorCol = YES; + }; + } + profileOverrides:nil + createGolden:YES + size:VT100GridSizeMake(5, 5)]; +} + // Draws a badge which blends with nondefault background colors. - (void)testBadge { [self doGoldenTestForInput:@"\n\n\n\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\x1b[42mabc" diff --git a/sources/PTYSession.m b/sources/PTYSession.m index 0b8e0e3c65..ac03ed5134 100644 --- a/sources/PTYSession.m +++ b/sources/PTYSession.m @@ -2374,6 +2374,7 @@ - (void)writeTaskNoBroadcast:(NSString *)string - (void)handleKeyPressInCopyMode:(NSEvent *)event { [self.textview setNeedsDisplayOnLine:_copyModeState.coord.y]; + [self.textview setNeedsDisplayOnCol:_copyModeState.coord.x]; BOOL wasSelecting = _copyModeState.selecting; NSString *string = event.charactersIgnoringModifiers; unichar code = [string length] > 0 ? [string characterAtIndex:0] : 0; @@ -2525,6 +2526,7 @@ - (void)handleKeyPressInCopyMode:(NSEvent *)event { [_textview scrollLineNumberRangeIntoView:VT100GridRangeMake(_copyModeState.coord.y, 1)]; } [self.textview setNeedsDisplayOnLine:_copyModeState.coord.y]; + [self.textview setNeedsDisplayOnCol:_copyModeState.coord.x]; } } diff --git a/sources/PTYTextView.h b/sources/PTYTextView.h index d5bb5b18b6..30fdd978ca 100644 --- a/sources/PTYTextView.h +++ b/sources/PTYTextView.h @@ -464,6 +464,7 @@ typedef void (^PTYTextViewDrawingHookBlock)(iTermTextDrawingHelper *); // onscreen is blinking. - (BOOL)refresh; - (void)setNeedsDisplayOnLine:(int)line; +- (void)setNeedsDisplayOnCol:(int)col; - (void)setCursorNeedsDisplay; // selection diff --git a/sources/PTYTextView.m b/sources/PTYTextView.m index df57a4b905..2ac5d285ba 100644 --- a/sources/PTYTextView.m +++ b/sources/PTYTextView.m @@ -978,6 +978,11 @@ - (void)setNeedsDisplayOnLine:(int)line [self setNeedsDisplayOnLine:line inRange:VT100GridRangeMake(0, _dataSource.width)]; } +- (void)setNeedsDisplayOnCol:(int)col +{ + [self setNeedsDisplayOnCol:col inRange:VT100GridRangeMake(0, _dataSource.height)]; +} + // Overrides an NSView method. - (NSRect)adjustScroll:(NSRect)proposedVisibleRect { proposedVisibleRect.origin.y = (int)(proposedVisibleRect.origin.y / _lineHeight + 0.5) * _lineHeight; @@ -6409,6 +6414,24 @@ - (void)setNeedsDisplayOnLine:(int)y inRange:(VT100GridRange)range { [self setNeedsDisplayInRect:dirtyRect]; } +- (void)setNeedsDisplayOnCol:(int)x inRange:(VT100GridRange)range { + NSRect dirtyRect; + const int y = range.location; + const int maxY = range.location + range.length; + + dirtyRect.origin.y = [iTermAdvancedSettingsModel terminalMargin] + y * _lineHeight; // _charHeightWithoutSpacing; + dirtyRect.origin.x = x * _charWidth; + dirtyRect.size.height = (maxY - y) * _lineHeight; //- _charHeightWithoutSpacing; + dirtyRect.size.width = _charWidth; + + // Expand the rect in case we're drawing a changed cell with an oversize glyph. + dirtyRect = [self rectWithHalo:dirtyRect]; + + DLog(@"Column %d is dirty in range [%d, %d), set rect %@ dirty", + x, y, maxY, [NSValue valueWithRect:dirtyRect]); + [self setNeedsDisplayInRect:dirtyRect]; +} + // WARNING: Do not call this function directly. Call // -[refresh] instead, as it ensures scrollback overflow // is dealt with so that this function can dereference diff --git a/sources/iTermTextDrawingHelper.m b/sources/iTermTextDrawingHelper.m index 29167a88d3..f37291727c 100644 --- a/sources/iTermTextDrawingHelper.m +++ b/sources/iTermTextDrawingHelper.m @@ -653,6 +653,18 @@ - (void)drawAccessoriesInRect:(NSRect)bgRect { coordRange.end.x - coordRange.start.x) y:y]; } + + // Highlight cursor column if the cursor is in this column and it's on. + int cursorCol = _cursorCoord.x; + const BOOL drawVCursorGuide = (self.highlightCursorCol && + cursorCol >= coordRange.start.x && + cursorCol < coordRange.end.x); + if (drawVCursorGuide) { + CGFloat x = cursorCol * _cellSize.width; + [self drawCursorGuideForRows:NSMakeRange(coordRange.start.y, + coordRange.end.y - coordRange.start.y) + x:x]; + } } - (void)drawCursorGuideForColumns:(NSRange)range y:(CGFloat)yOrigin { @@ -674,6 +686,26 @@ - (void)drawCursorGuideForColumns:(NSRange)range y:(CGFloat)yOrigin { NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); } +- (void)drawCursorGuideForRows:(NSRange)range x:(CGFloat)xOrigin { + if (!_cursorVisible) { + return; + } + [_cursorGuideColor set]; + NSPoint textOrigin = NSMakePoint(xOrigin + [iTermAdvancedSettingsModel terminalMargin], + [iTermAdvancedSettingsModel terminalMargin] + range.location * _cellSize.height); + NSRect rect = NSMakeRect(textOrigin.x, + textOrigin.y, + _cellSize.width, + range.length * _cellSize.height); + NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); + + rect.size.width = 1; + NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); + + rect.origin.x += _cellSize.width - 1; + NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); +} + + (NSRect)frameForMarkContainedInRect:(NSRect)container cellSize:(CGSize)cellSize cellSizeWithoutSpacing:(CGSize)cellSizeWithoutSpacing From 139103bb04bff9f2470cd8b460fbe41ac255afe7 Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Tue, 26 Mar 2019 01:26:53 -0700 Subject: [PATCH 17/30] Fill out cursor column tracking API. --- Interfaces/MainMenu.xib | 2 +- Interfaces/PreferencePanel.xib | 2 +- iTerm2XCTests/PTYTextViewTest.m | 4 +- iTerm2XCTests/VT100GridTest.m | 3 ++ iTerm2XCTests/VT100ScreenTest.m | 4 +- sources/ITAddressBookMgr.h | 2 +- .../Renderers/iTermCursorGuideRenderer.h | 2 +- .../Renderers/iTermCursorGuideRenderer.m | 42 +++++++++---------- sources/Metal/iTermMetalDriver.h | 2 +- sources/Metal/iTermMetalDriver.m | 6 +-- sources/PTYSession.h | 2 +- sources/PTYSession.m | 39 ++++++++--------- sources/PTYTextView.h | 4 +- sources/PTYTextView.m | 15 ++++--- .../ProfilesColorsPreferencesViewController.m | 6 +-- sources/PseudoTerminal.m | 8 ++-- sources/VT100Grid.h | 1 + sources/VT100Grid.m | 1 + sources/VT100Screen.h | 1 + sources/VT100Screen.m | 13 +++++- sources/VT100ScreenDelegate.h | 5 ++- sources/VT100Terminal.m | 4 +- sources/VT100TerminalDelegate.h | 2 +- sources/iTermMetalPerFrameState.m | 4 +- .../iTermMetalPerFrameStateConfiguration.h | 2 +- .../iTermMetalPerFrameStateConfiguration.m | 2 +- sources/iTermProfilePreferences.m | 4 +- sources/iTermTextDrawingHelper.h | 2 +- sources/iTermTextDrawingHelper.m | 12 +++--- 29 files changed, 107 insertions(+), 89 deletions(-) diff --git a/Interfaces/MainMenu.xib b/Interfaces/MainMenu.xib index eedfcfe25a..db6e751c6a 100644 --- a/Interfaces/MainMenu.xib +++ b/Interfaces/MainMenu.xib @@ -671,7 +671,7 @@ Gw - + diff --git a/Interfaces/PreferencePanel.xib b/Interfaces/PreferencePanel.xib index f994c2983e..ba99cbc736 100644 --- a/Interfaces/PreferencePanel.xib +++ b/Interfaces/PreferencePanel.xib @@ -1471,7 +1471,7 @@ DQ - + diff --git a/iTerm2XCTests/PTYTextViewTest.m b/iTerm2XCTests/PTYTextViewTest.m index 471b0c5ed1..283a0e8666 100644 --- a/iTerm2XCTests/PTYTextViewTest.m +++ b/iTerm2XCTests/PTYTextViewTest.m @@ -992,13 +992,13 @@ - (void)testCursorGuide { } // Draws a cursor guide on the col with b. -- (void)testVCursorGuide { +- (void)testVerticalCursorGuide { [self doGoldenTestForInput:@"abcd\x1b[2A" name:NSStringFromSelector(_cmd) hook:^(PTYTextView *textView) { textView.drawingHook = ^(iTermTextDrawingHelper *helper) { helper.shouldDrawFilledInCursor = YES; - helper.highlightCursorCol = YES; + helper.highlightCursorColumn = YES; }; } profileOverrides:nil diff --git a/iTerm2XCTests/VT100GridTest.m b/iTerm2XCTests/VT100GridTest.m index c38e27dc7d..f6b106e713 100644 --- a/iTerm2XCTests/VT100GridTest.m +++ b/iTerm2XCTests/VT100GridTest.m @@ -53,6 +53,9 @@ - (screen_char_t)gridBackgroundColorCode { - (void)gridCursorDidChangeLine { } +- (void)gridCursorDidChangeColumn { +} + - (iTermUnicodeNormalization)gridUnicodeNormalizationForm { return iTermUnicodeNormalizationNone; } diff --git a/iTerm2XCTests/VT100ScreenTest.m b/iTerm2XCTests/VT100ScreenTest.m index b1b5aa68c0..24e6f08b39 100644 --- a/iTerm2XCTests/VT100ScreenTest.m +++ b/iTerm2XCTests/VT100ScreenTest.m @@ -748,10 +748,10 @@ - (void)screenSetHighlightCursorLine:(BOOL)highlight { - (void)screenCursorDidMoveToLine:(int)line { } -- (void)screenSetHighlightCursorCol:(BOOL)highlight { +- (void)screenSetHighlightCursorColumn:(BOOL)highlight { } -- (void)screenCursorDidMoveToCol:(int)line { +- (void)screenCursorDidMoveToColumn:(int)line { } - (void)screenSaveScrollPosition { diff --git a/sources/ITAddressBookMgr.h b/sources/ITAddressBookMgr.h index 41724ed936..12b6ef32b8 100644 --- a/sources/ITAddressBookMgr.h +++ b/sources/ITAddressBookMgr.h @@ -114,7 +114,7 @@ #define KEY_USE_UNDERLINE_COLOR @"Use Underline Color" #define KEY_CURSOR_BOOST @"Cursor Boost" #define KEY_USE_CURSOR_GUIDE @"Use Cursor Guide" -#define KEY_USE_VERT_CURSOR_GUIDE @"Use Vertical Cursor Guide" +#define KEY_USE_VERTICAL_CURSOR_GUIDE @"Use Vertical Cursor Guide" #define KEY_CURSOR_GUIDE_COLOR @"Cursor Guide Color" #define KEY_BADGE_COLOR @"Badge Color" diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.h b/sources/Metal/Renderers/iTermCursorGuideRenderer.h index 92e4d448c8..d0dbc6963a 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.h +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.h @@ -12,7 +12,7 @@ NS_ASSUME_NONNULL_BEGIN @interface iTermCursorGuideRenderer : NSObject @property (nonatomic) BOOL enabled; -@property (nonatomic) BOOL venabled; +@property (nonatomic) BOOL verticalEnabled; - (nullable instancetype)initWithDevice:(id)device NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE; diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.m b/sources/Metal/Renderers/iTermCursorGuideRenderer.m index 16dcad904f..cc176bad24 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.m +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.m @@ -3,17 +3,17 @@ @interface iTermCursorGuideRendererTransientState() @property (nonatomic, strong) id texture; @property (nonatomic) int row; -@property (nonatomic) int col; +@property (nonatomic) int column; @end @implementation iTermCursorGuideRendererTransientState { int _row; - int _col; + int _column; } - (void)setCursorCoord:(VT100GridCoord)coord within:(VT100GridSize)bounds { _row = (0 <= coord.y && coord.y < bounds.height) ? coord.y : -1; - _col = (0 <= coord.x && coord.x < bounds.width) ? coord.x : -1; + _column = (0 <= coord.x && coord.x < bounds.width) ? coord.x : -1; } - (void)initializeVerticesWithPool:(iTermMetalBufferPool *)verticesPool { @@ -39,22 +39,22 @@ - (void)initializeVerticesWithPool:(iTermMetalBufferPool *)verticesPool { withBytes:vertices checkIfChanged:YES]; - const CGRect vQuad = CGRectMake(self.margins.left + self.col * cellSize.width, - self.margins.top, - cellSize.width, - cellSize.height * gridSize.height); - const iTermVertex vvertices[] = { - { { CGRectGetMaxX(vQuad), CGRectGetMinY(vQuad) }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { CGRectGetMinX(vQuad), CGRectGetMinY(vQuad) }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { CGRectGetMinX(vQuad), CGRectGetMaxY(vQuad) }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - - { { CGRectGetMaxX(vQuad), CGRectGetMinY(vQuad) }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { CGRectGetMinX(vQuad), CGRectGetMaxY(vQuad) }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - { { CGRectGetMaxX(vQuad), CGRectGetMaxY(vQuad) }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, + const CGRect verticalGuideQuad = CGRectMake(self.margins.left + self.column * cellSize.width, + self.margins.top, + cellSize.width, + cellSize.height * gridSize.height); + const iTermVertex verticalGuideVertices[] = { + { { CGRectGetMaxX(verticalGuideQuad), CGRectGetMinY(verticalGuideQuad) }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { CGRectGetMinX(verticalGuideQuad), CGRectGetMinY(verticalGuideQuad) }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { CGRectGetMinX(verticalGuideQuad), CGRectGetMaxY(verticalGuideQuad) }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, + + { { CGRectGetMaxX(verticalGuideQuad), CGRectGetMinY(verticalGuideQuad) }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { CGRectGetMinX(verticalGuideQuad), CGRectGetMaxY(verticalGuideQuad) }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, + { { CGRectGetMaxX(verticalGuideQuad), CGRectGetMaxY(verticalGuideQuad) }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, }; - self.vvertexBuffer = [verticesPool requestBufferFromContext:self.poolContext - withBytes:vvertices - checkIfChanged:YES]; + self.verticalGuideVertexBuffer = [verticesPool requestBufferFromContext:self.poolContext + withBytes:verticalGuideVertices + checkIfChanged:YES]; } - (void)writeDebugInfoToFolder:(NSURL *)folder { @@ -126,7 +126,7 @@ - (void)setColor:(NSColor *)color { - (void)drawWithFrameData:(iTermMetalFrameData *)frameData transientState:(__kindof iTermMetalCellRendererTransientState *)transientState { iTermCursorGuideRendererTransientState *tState = transientState; - if (tState.row < 0 || tState.col < 0) { + if (tState.row < 0 || tState.column < 0) { return; } @@ -141,12 +141,12 @@ - (void)drawWithFrameData:(iTermMetalFrameData *)frameData textures:@{ @(iTermTextureIndexPrimary): tState.texture } ]; } - if (tState.col >= 0 && self.venabled) { + if (tState.column >= 0 && self.verticalEnabled) { [_cellRenderer drawWithTransientState:tState renderEncoder:frameData.renderEncoder numberOfVertices:6 numberOfPIUs:0 - vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.vvertexBuffer } + vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.verticalGuideVertexBuffer } fragmentBuffers:@{} textures:@{ @(iTermTextureIndexPrimary): tState.texture } ]; } diff --git a/sources/Metal/iTermMetalDriver.h b/sources/Metal/iTermMetalDriver.h index d2e04157f6..0936f0aee4 100644 --- a/sources/Metal/iTermMetalDriver.h +++ b/sources/Metal/iTermMetalDriver.h @@ -61,7 +61,7 @@ NS_CLASS_AVAILABLE(10_11, NA) @property (nonatomic, readonly) BOOL showBroadcastStripes; @property (nonatomic, readonly) NSColor *cursorGuideColor; @property (nonatomic, readonly) BOOL cursorGuideEnabled; -@property (nonatomic, readonly) BOOL cursorVGuideEnabled; +@property (nonatomic, readonly) BOOL cursorVerticalGuideEnabled; @property (nonatomic, readonly) vector_float4 fullScreenFlashColor; @property (nonatomic, readonly) BOOL timestampsEnabled; @property (nonatomic, readonly) NSColor *timestampsBackgroundColor; diff --git a/sources/Metal/iTermMetalDriver.m b/sources/Metal/iTermMetalDriver.m index 41d14444bc..802f48f666 100644 --- a/sources/Metal/iTermMetalDriver.m +++ b/sources/Metal/iTermMetalDriver.m @@ -644,8 +644,8 @@ - (BOOL)shouldCreateIntermediateRenderPassDescriptor:(iTermMetalFrameData *)fram if (!_broadcastStripesRenderer.rendererDisabled && frameData.perFrameState.showBroadcastStripes) { return YES; } - if (!_cursorGuideRenderer.rendererDisabled && (frameData.perFrameState.cursorGuideEnabled - || frameData.perFrameState.cursorVGuideEnabled)) { + if (!_cursorGuideRenderer.rendererDisabled && (frameData.perFrameState.cursorGuideEnabled || + frameData.perFrameState.cursorVerticalGuideEnabled)) { return YES; } @@ -971,7 +971,7 @@ - (void)updateCursorGuideRendererForFrameData:(iTermMetalFrameData *)frameData { } [_cursorGuideRenderer setColor:frameData.perFrameState.cursorGuideColor]; _cursorGuideRenderer.enabled = frameData.perFrameState.cursorGuideEnabled; - _cursorGuideRenderer.venabled = frameData.perFrameState.cursorVGuideEnabled; + _cursorGuideRenderer.verticalEnabled = frameData.perFrameState.cursorVerticalGuideEnabled; } - (void)updateTimestampsRendererForFrameData:(iTermMetalFrameData *)frameData { diff --git a/sources/PTYSession.h b/sources/PTYSession.h index b48d2c4eb8..392fe57bc7 100644 --- a/sources/PTYSession.h +++ b/sources/PTYSession.h @@ -422,7 +422,7 @@ typedef enum { @property(nonatomic, readonly) BOOL hasSelection; @property(nonatomic, assign) BOOL highlightCursorLine; -@property(nonatomic, assign) BOOL highlightCursorCol; +@property(nonatomic, assign) BOOL highlightCursorColumn; // Used to help remember total ordering on views while one is maximized @property(nonatomic, assign) NSPoint savedRootRelativeOrigin; diff --git a/sources/PTYSession.m b/sources/PTYSession.m index ac03ed5134..90575fd55f 100644 --- a/sources/PTYSession.m +++ b/sources/PTYSession.m @@ -207,7 +207,7 @@ static NSString *const SESSION_ARRANGEMENT_DIRECTORIES = @"Directories"; // Array of strings static NSString *const SESSION_ARRANGEMENT_HOSTS = @"Hosts"; // Array of VT100RemoteHost static NSString *const SESSION_ARRANGEMENT_CURSOR_GUIDE = @"Cursor Guide"; // BOOL -static NSString *const SESSION_ARRANGEMENT_VCURSOR_GUIDE = @"Vertical Cursor Guide"; // BOOL +static NSString *const SESSION_ARRANGEMENT_VERTICAL_CURSOR_GUIDE = @"Vertical Cursor Guide"; // BOOL static NSString *const SESSION_ARRANGEMENT_LAST_DIRECTORY = @"Last Directory"; // NSString static NSString *const SESSION_ARRANGEMENT_LAST_DIRECTORY_IS_UNSUITABLE_FOR_OLD_PWD = @"Last Directory Is Remote"; // BOOL static NSString *const SESSION_ARRANGEMENT_SELECTION = @"Selection"; // Dictionary for iTermSelection. @@ -1186,8 +1186,8 @@ + (void)finishInitializingArrangementOriginatedSession:(PTYSession *)aSession if (arrangement[SESSION_ARRANGEMENT_CURSOR_GUIDE]) { aSession.textview.highlightCursorLine = [arrangement[SESSION_ARRANGEMENT_CURSOR_GUIDE] boolValue]; } - if (arrangement[SESSION_ARRANGEMENT_VCURSOR_GUIDE]) { - aSession.textview.highlightCursorLine = [arrangement[SESSION_ARRANGEMENT_VCURSOR_GUIDE] boolValue]; + if (arrangement[SESSION_ARRANGEMENT_VERTICAL_CURSOR_GUIDE]) { + aSession.textview.highlightCursorLine = [arrangement[SESSION_ARRANGEMENT_VERTICAL_CURSOR_GUIDE] boolValue]; } aSession->_lastMark = [aSession.screen.lastMark retain]; aSession.lastRemoteHost = aSession.screen.lastRemoteHost; @@ -2374,7 +2374,7 @@ - (void)writeTaskNoBroadcast:(NSString *)string - (void)handleKeyPressInCopyMode:(NSEvent *)event { [self.textview setNeedsDisplayOnLine:_copyModeState.coord.y]; - [self.textview setNeedsDisplayOnCol:_copyModeState.coord.x]; + [self.textview setNeedsDisplayOnColumn:_copyModeState.coord.x]; BOOL wasSelecting = _copyModeState.selecting; NSString *string = event.charactersIgnoringModifiers; unichar code = [string length] > 0 ? [string characterAtIndex:0] : 0; @@ -2526,7 +2526,7 @@ - (void)handleKeyPressInCopyMode:(NSEvent *)event { [_textview scrollLineNumberRangeIntoView:VT100GridRangeMake(_copyModeState.coord.y, 1)]; } [self.textview setNeedsDisplayOnLine:_copyModeState.coord.y]; - [self.textview setNeedsDisplayOnCol:_copyModeState.coord.x]; + [self.textview setNeedsDisplayOnColumn:_copyModeState.coord.x]; } } @@ -3479,7 +3479,7 @@ - (void)loadInitialColorTable } _textview.highlightCursorLine = [iTermProfilePreferences boolForKey:KEY_USE_CURSOR_GUIDE inProfile:_profile]; - _textview.highlightCursorCol = [iTermProfilePreferences boolForKey:KEY_USE_VERT_CURSOR_GUIDE + _textview.highlightCursorColumn = [iTermProfilePreferences boolForKey:KEY_USE_VERTICAL_CURSOR_GUIDE inProfile:_profile]; } @@ -3663,7 +3663,7 @@ - (void)setPreferencesFromAddressBookEntry:(NSDictionary *)aePrefs { if (!_cursorGuideSettingHasChanged) { _textview.highlightCursorLine = [iTermProfilePreferences boolForKey:KEY_USE_CURSOR_GUIDE inProfile:aDict]; - _textview.highlightCursorCol = [iTermProfilePreferences boolForKey:KEY_USE_VERT_CURSOR_GUIDE + _textview.highlightCursorColumn = [iTermProfilePreferences boolForKey:KEY_USE_VERTICAL_CURSOR_GUIDE inProfile:aDict]; } @@ -4391,7 +4391,7 @@ - (NSDictionary *)arrangementWithContents:(BOOL)includeContents { [NSDictionary dictionaryWithGridCoordRange:range]; result[SESSION_ARRANGEMENT_ALERT_ON_NEXT_MARK] = @(_alertOnNextMark); result[SESSION_ARRANGEMENT_CURSOR_GUIDE] = @(_textview.highlightCursorLine); - result[SESSION_ARRANGEMENT_VCURSOR_GUIDE] = @(_textview.highlightCursorCol); + result[SESSION_ARRANGEMENT_VERTICAL_CURSOR_GUIDE] = @(_textview.highlightCursorColumn); if (self.lastDirectory) { result[SESSION_ARRANGEMENT_LAST_DIRECTORY] = self.lastDirectory; result[SESSION_ARRANGEMENT_LAST_DIRECTORY_IS_UNSUITABLE_FOR_OLD_PWD] = @(self.lastDirectoryIsUnsuitableForOldPWD); @@ -8399,10 +8399,11 @@ - (void)screenDidReset { _cursorGuideSettingHasChanged = NO; _textview.highlightCursorLine = [iTermProfilePreferences boolForKey:KEY_USE_CURSOR_GUIDE inProfile:_profile]; - _textview.highlightCursorCol = [iTermProfilePreferences boolForKey:KEY_USE_VERT_CURSOR_GUIDE - inProfile:_profile]; + _textview.highlightCursorColumn = [iTermProfilePreferences boolForKey:KEY_USE_VERTICAL_CURSOR_GUIDE + inProfile:_profile]; [_textview setNeedsDisplay:YES]; _screen.trackCursorLineMovement = NO; + _screen.trackCursorColumnMovement = NO; } - (void)screenDidAppendStringToCurrentLine:(NSString *)string { @@ -8673,26 +8674,26 @@ - (BOOL)highlightCursorLine { return _textview.highlightCursorLine; } -- (void)screenCursorDidMoveToCol:(int)col { +- (void)screenCursorDidMoveToColumn:(int)column { if (_textview.cursorVisible) { - [_textview setNeedsDisplayOnCol:col]; + [_textview setNeedsDisplayOnColumn:column]; } } -- (void)screenSetHighlightCursorCol:(BOOL)highlight { +- (void)screenSetHighlightCursorColumn:(BOOL)highlight { _cursorGuideSettingHasChanged = YES; - self.highlightCursorCol = highlight; + self.highlightCursorColumn = highlight; } -- (void)setHighlightCursorCol:(BOOL)highlight { +- (void)setHighlightCursorColumn:(BOOL)highlight { _cursorGuideSettingHasChanged = YES; - _textview.highlightCursorCol = highlight; + _textview.highlightCursorColumn = highlight; [_textview setNeedsDisplay:YES]; - _screen.trackCursorColMovement = highlight; + _screen.trackCursorColumnMovement = highlight; } -- (BOOL)highlightCursorCol { - return _textview.highlightCursorCol; +- (BOOL)highlightCursorColumn { + return _textview.highlightCursorColumn; } - (BOOL)screenHasView { diff --git a/sources/PTYTextView.h b/sources/PTYTextView.h index 30fdd978ca..de88b9f17a 100644 --- a/sources/PTYTextView.h +++ b/sources/PTYTextView.h @@ -236,7 +236,7 @@ typedef NS_ENUM(NSInteger, PTYTextViewSelectionExtensionUnit) { @property(nonatomic, assign) BOOL highlightCursorLine; // Draw a highlight along the entire column the cursor is in. -@property(nonatomic, assign) BOOL highlightCursorCol; +@property(nonatomic, assign) BOOL highlightCursorColumn; // Use the non-ascii font? If not set, use the regular font for all characters. @property(nonatomic, assign) BOOL useNonAsciiFont; @@ -464,7 +464,7 @@ typedef void (^PTYTextViewDrawingHookBlock)(iTermTextDrawingHelper *); // onscreen is blinking. - (BOOL)refresh; - (void)setNeedsDisplayOnLine:(int)line; -- (void)setNeedsDisplayOnCol:(int)col; +- (void)setNeedsDisplayOnColumn:(int)column; - (void)setCursorNeedsDisplay; // selection diff --git a/sources/PTYTextView.m b/sources/PTYTextView.m index 2ac5d285ba..f5c5d03dfc 100644 --- a/sources/PTYTextView.m +++ b/sources/PTYTextView.m @@ -581,12 +581,12 @@ - (BOOL)highlightCursorLine { return _drawingHelper.highlightCursorLine; } -- (void)setHighlightCursorCol:(BOOL)highlightCursorCol { - _drawingHelper.highlightCursorCol = highlightCursorCol; +- (void)setHighlightCursorColumn:(BOOL)highlightCursorColumn { + _drawingHelper.highlightCursorColumn = highlightCursorColumn; } -- (BOOL)highlightCursorCol { - return _drawingHelper.highlightCursorCol; +- (BOOL)highlightCursorColumn { + return _drawingHelper.highlightCursorColumn; } - (void)setUseNonAsciiFont:(BOOL)useNonAsciiFont { @@ -978,9 +978,8 @@ - (void)setNeedsDisplayOnLine:(int)line [self setNeedsDisplayOnLine:line inRange:VT100GridRangeMake(0, _dataSource.width)]; } -- (void)setNeedsDisplayOnCol:(int)col -{ - [self setNeedsDisplayOnCol:col inRange:VT100GridRangeMake(0, _dataSource.height)]; +- (void)setNeedsDisplayOnColumn:(int)column { + [self setNeedsDisplayOnColumn:column inRange:VT100GridRangeMake(0, _dataSource.height)]; } // Overrides an NSView method. @@ -6414,7 +6413,7 @@ - (void)setNeedsDisplayOnLine:(int)y inRange:(VT100GridRange)range { [self setNeedsDisplayInRect:dirtyRect]; } -- (void)setNeedsDisplayOnCol:(int)x inRange:(VT100GridRange)range { +- (void)setNeedsDisplayOnColumn:(int)x inRange:(VT100GridRange)range { NSRect dirtyRect; const int y = range.location; const int maxY = range.location + range.length; diff --git a/sources/ProfilesColorsPreferencesViewController.m b/sources/ProfilesColorsPreferencesViewController.m index cc21b6b40d..060bda9eec 100644 --- a/sources/ProfilesColorsPreferencesViewController.m +++ b/sources/ProfilesColorsPreferencesViewController.m @@ -79,7 +79,7 @@ @implementation ProfilesColorsPreferencesViewController { IBOutlet NSMenu *_presetsMenu; IBOutlet NSButton *_useGuide; - IBOutlet NSButton *_useVGuide; + IBOutlet NSButton *_useVerticalGuide; IBOutlet CPKColorWell *_guideColor; IBOutlet NSPopUpButton *_presetsPopupButton; @@ -204,8 +204,8 @@ - (void)awakeFromNib { relatedView:nil type:kPreferenceInfoTypeCheckbox]; - [self defineControl:_useVGuide - key:KEY_USE_VERT_CURSOR_GUIDE + [self defineControl:_useVerticalGuide + key:KEY_USE_VERTICAL_CURSOR_GUIDE type:kPreferenceInfoTypeCheckbox]; info = [self defineControl:_useBrightBold diff --git a/sources/PseudoTerminal.m b/sources/PseudoTerminal.m index f2f80e858d..255bd7053f 100644 --- a/sources/PseudoTerminal.m +++ b/sources/PseudoTerminal.m @@ -1787,9 +1787,9 @@ - (IBAction)toggleCursorGuide:(id)sender { session.highlightCursorLine = !session.highlightCursorLine; } -- (IBAction)toggleVCursorGuide:(id)sender { +- (IBAction)toggleVerticalCursorGuide:(id)sender { PTYSession *session = [self currentSession]; - session.highlightCursorCol = !session.highlightCursorCol; + session.highlightCursorColumn = !session.highlightCursorColumn; } - (IBAction)toggleSelectionRespectsSoftBoundaries:(id)sender { @@ -8608,9 +8608,9 @@ - (BOOL)validateMenuItem:(NSMenuItem *)item { PTYSession *session = [self currentSession]; [item setState:session.highlightCursorLine ? NSOnState : NSOffState]; result = YES; - } else if ([item action] == @selector(toggleVCursorGuide:)) { + } else if ([item action] == @selector(toggleVerticalCursorGuide:)) { PTYSession *session = [self currentSession]; - [item setState:session.highlightCursorCol ? NSOnState : NSOffState]; + [item setState:session.highlightCursorColumn ? NSOnState : NSOffState]; result = YES; } else if ([item action] == @selector(toggleSelectionRespectsSoftBoundaries:)) { [item setState:[[iTermController sharedInstance] selectionRespectsSoftBoundaries] ? NSOnState : NSOffState]; diff --git a/sources/VT100Grid.h b/sources/VT100Grid.h index 25eff122bb..6e1a72ef08 100644 --- a/sources/VT100Grid.h +++ b/sources/VT100Grid.h @@ -21,6 +21,7 @@ - (iTermUnicodeNormalization)gridUnicodeNormalizationForm; - (void)gridCursorDidMove; - (void)gridCursorDidChangeLine; +- (void)gridCursorDidChangeColumn; @end @interface VT100Grid : NSObject diff --git a/sources/VT100Grid.m b/sources/VT100Grid.m index 7c174d17e2..72090b0069 100644 --- a/sources/VT100Grid.m +++ b/sources/VT100Grid.m @@ -183,6 +183,7 @@ - (void)setCursorX:(int)cursorX { int newX = MIN(size_.width, MAX(0, cursorX)); if (newX != cursor_.x) { cursor_.x = newX; + [delegate_ gridCursorDidChangeColumn]; [delegate_ gridCursorDidMove]; } } diff --git a/sources/VT100Screen.h b/sources/VT100Screen.h index 11f570b98a..8f84967276 100644 --- a/sources/VT100Screen.h +++ b/sources/VT100Screen.h @@ -58,6 +58,7 @@ extern int kVT100ScreenMinRows; @property(nonatomic, assign) BOOL saveToScrollbackInAlternateScreen; @property(nonatomic, retain) DVR *dvr; @property(nonatomic, assign) BOOL trackCursorLineMovement; +@property(nonatomic, assign) BOOL trackCursorColumnMovement; @property(nonatomic, assign) BOOL appendToScrollbackWithStatusBar; @property(nonatomic, readonly) VT100GridAbsCoordRange lastCommandOutputRange; @property(nonatomic, assign) iTermUnicodeNormalization normalization; diff --git a/sources/VT100Screen.m b/sources/VT100Screen.m index 2f03f079e4..575464833c 100644 --- a/sources/VT100Screen.m +++ b/sources/VT100Screen.m @@ -52,6 +52,7 @@ NSString *const kScreenStateNextCommandOutputStartKey = @"Output Start"; NSString *const kScreenStateCursorVisibleKey = @"Cursor Visible"; NSString *const kScreenStateTrackCursorLineMovementKey = @"Track Cursor Line"; +NSString *const kScreenStateTrackCursorColumnMovementKey = @"Track Cursor Column"; NSString *const kScreenStateLastCommandOutputRangeKey = @"Last Command Output Range"; NSString *const kScreenStateShellIntegrationInstalledKey = @"Shell Integration Installed"; NSString *const kScreenStateLastCommandMarkKey = @"Last Command Mark"; @@ -4139,8 +4140,8 @@ - (void)terminalSetHighlightCursorLine:(BOOL)highlight { [delegate_ screenSetHighlightCursorLine:highlight]; } -- (void)terminalSetHighlightCursorCol:(BOOL)highlight { - [delegate_ screenSetHighlightCursorCol:highlight]; +- (void)terminalSetHighlightCursorColumn:(BOOL)highlight { + [delegate_ screenSetHighlightCursorColumn:highlight]; } - (void)terminalPromptDidStart { @@ -5307,6 +5308,12 @@ - (void)gridCursorDidChangeLine { } } +- (void)gridCursorDidChangeColumn { + if (_trackCursorColumnMovement) { + [delegate_ screenCursorDidMoveToColumn:currentGrid_.cursorX]; + } +} + - (iTermUnicodeNormalization)gridUnicodeNormalizationForm { return _normalization; } @@ -5364,6 +5371,7 @@ - (NSDictionary *)contentsDictionary { kScreenStateNextCommandOutputStartKey: [NSDictionary dictionaryWithGridAbsCoord:_startOfRunningCommandOutput], kScreenStateCursorVisibleKey: @(_cursorVisible), kScreenStateTrackCursorLineMovementKey: @(_trackCursorLineMovement), + kScreenStateTrackCursorColumnMovementKey: @(_trackCursorColumnMovement), kScreenStateLastCommandOutputRangeKey: [NSDictionary dictionaryWithGridAbsCoordRange:_lastCommandOutputRange], kScreenStateShellIntegrationInstalledKey: @(_shellIntegrationInstalled), kScreenStateLastCommandMarkKey: _lastCommandMark.guid ?: [NSNull null], @@ -5478,6 +5486,7 @@ - (void)restoreFromDictionary:(NSDictionary *)dictionary _startOfRunningCommandOutput = [screenState[kScreenStateNextCommandOutputStartKey] gridAbsCoord]; _cursorVisible = [screenState[kScreenStateCursorVisibleKey] boolValue]; _trackCursorLineMovement = [screenState[kScreenStateTrackCursorLineMovementKey] boolValue]; + _trackCursorColumnMovement = [screenState[kScreenStateTrackCursorColumnMovementKey] boolValue]; _lastCommandOutputRange = [screenState[kScreenStateLastCommandOutputRangeKey] gridAbsCoordRange]; _shellIntegrationInstalled = [screenState[kScreenStateShellIntegrationInstalledKey] boolValue]; diff --git a/sources/VT100ScreenDelegate.h b/sources/VT100ScreenDelegate.h index 2f48145ae7..21819d8b26 100644 --- a/sources/VT100ScreenDelegate.h +++ b/sources/VT100ScreenDelegate.h @@ -185,11 +185,14 @@ - (void)screenSetCursorVisible:(BOOL)visible; - (void)screenSetHighlightCursorLine:(BOOL)highlight; -- (void)screenSetHighlightCursorCol:(BOOL)highlight; +- (void)screenSetHighlightCursorColumn:(BOOL)highlight; // Only called if the trackCursorLineMovement property is set. - (void)screenCursorDidMoveToLine:(int)line; +// Only called if the trackCursorColMovement property is set. +- (void)screenCursorDidMoveToColumn:(int)column; + // Returns if there is a view. - (BOOL)screenHasView; diff --git a/sources/VT100Terminal.m b/sources/VT100Terminal.m index ac9f46526e..f8b6694321 100644 --- a/sources/VT100Terminal.m +++ b/sources/VT100Terminal.m @@ -2367,8 +2367,8 @@ - (void)executeXtermSetKvp:(VT100Token *)token { [delegate_ terminalAddNote:(NSString *)value show:NO]; } else if ([key isEqualToString:@"HighlightCursorLine"]) { [delegate_ terminalSetHighlightCursorLine:value.length ? [value boolValue] : YES]; - } else if ([key isEqualToString:@"HighlightCursorCol"]) { - [delegate_ terminalSetHighlightCursorCol:value.length ? [value boolValue] : YES]; + } else if ([key isEqualToString:@"HighlightCursorColumn"]) { + [delegate_ terminalSetHighlightCursorColumn:value.length ? [value boolValue] : YES]; } else if ([key isEqualToString:@"CopyToClipboard"]) { if ([delegate_ terminalIsTrusted]) { [delegate_ terminalSetPasteboard:value]; diff --git a/sources/VT100TerminalDelegate.h b/sources/VT100TerminalDelegate.h index 91e0aedbdf..9594b07835 100644 --- a/sources/VT100TerminalDelegate.h +++ b/sources/VT100TerminalDelegate.h @@ -366,7 +366,7 @@ typedef NS_ENUM(int, VT100TerminalColorIndex) { - (void)terminalSetCursorVisible:(BOOL)visible; - (void)terminalSetHighlightCursorLine:(BOOL)highlight; -- (void)terminalSetHighlightCursorCol:(BOOL)highlight; +- (void)terminalSetHighlightCursorColumn:(BOOL)highlight; // FinalTerm features - (void)terminalPromptDidStart; diff --git a/sources/iTermMetalPerFrameState.m b/sources/iTermMetalPerFrameState.m index f85feb501d..359c1c9b91 100644 --- a/sources/iTermMetalPerFrameState.m +++ b/sources/iTermMetalPerFrameState.m @@ -582,8 +582,8 @@ - (BOOL)cursorGuideEnabled { return _configuration->_cursorGuideColor && _configuration->_cursorGuideEnabled; } -- (BOOL)cursorVGuideEnabled { - return _configuration->_cursorGuideColor && _configuration->_cursorVGuideEnabled; +- (BOOL)cursorVerticalGuideEnabled { + return _configuration->_cursorGuideColor && _configuration->_cursorVerticalGuideEnabled; } - (NSColor *)cursorGuideColor { diff --git a/sources/iTermMetalPerFrameStateConfiguration.h b/sources/iTermMetalPerFrameStateConfiguration.h index 967666d5a7..c34c4b36ee 100644 --- a/sources/iTermMetalPerFrameStateConfiguration.h +++ b/sources/iTermMetalPerFrameStateConfiguration.h @@ -62,7 +62,7 @@ NS_ASSUME_NONNULL_BEGIN // Cursor BOOL _shouldDrawFilledInCursor; BOOL _cursorGuideEnabled; - BOOL _cursorVGuideEnabled; + BOOL _cursorVerticalGuideEnabled; // Size VT100GridSize _gridSize; diff --git a/sources/iTermMetalPerFrameStateConfiguration.m b/sources/iTermMetalPerFrameStateConfiguration.m index 8b72b8c381..2d41083775 100644 --- a/sources/iTermMetalPerFrameStateConfiguration.m +++ b/sources/iTermMetalPerFrameStateConfiguration.m @@ -56,7 +56,7 @@ - (void)loadSettingsWithDrawingHelper:(iTermTextDrawingHelper *)drawingHelper // Cursor guide _cursorGuideEnabled = drawingHelper.highlightCursorLine; - _cursorVGuideEnabled = drawingHelper.highlightCursorCol; + _cursorVerticalGuideEnabled = drawingHelper.highlightCursorColumn; _cursorGuideColor = drawingHelper.cursorGuideColor; // Background image diff --git a/sources/iTermProfilePreferences.m b/sources/iTermProfilePreferences.m index 4247767789..2600daf6c8 100644 --- a/sources/iTermProfilePreferences.m +++ b/sources/iTermProfilePreferences.m @@ -184,7 +184,7 @@ + (BOOL)valueIsLegal:(id)value forKey:(NSString *)key { KEY_CURSOR_GUIDE_COLOR, KEY_BADGE_COLOR, KEY_TAB_COLOR, KEY_UNDERLINE_COLOR ]; - NSArray *number = @[ KEY_USE_CURSOR_GUIDE, KEY_USE_VERT_CURSOR_GUIDE, KEY_USE_TAB_COLOR, KEY_USE_UNDERLINE_COLOR, + NSArray *number = @[ KEY_USE_CURSOR_GUIDE, KEY_USE_VERTICAL_CURSOR_GUIDE, KEY_USE_TAB_COLOR, KEY_USE_UNDERLINE_COLOR, KEY_SMART_CURSOR_COLOR, KEY_MINIMUM_CONTRAST, KEY_CURSOR_BOOST, KEY_CURSOR_TYPE, KEY_BLINKING_CURSOR, KEY_USE_BOLD_FONT, KEY_THIN_STROKES, KEY_ASCII_LIGATURES, KEY_NON_ASCII_LIGATURES, KEY_USE_BOLD_COLOR, @@ -268,7 +268,7 @@ + (NSDictionary *)defaultValueMap { KEY_CURSOR_GUIDE_COLOR: [[NSColor colorWithCalibratedRed:0.650 green:0.910 blue:1.000 alpha:0.25] dictionaryValue], KEY_BADGE_COLOR: [[NSColor colorWithCalibratedRed:1.0 green:0.000 blue:0.000 alpha:0.5] dictionaryValue], KEY_USE_CURSOR_GUIDE: @NO, - KEY_USE_VERT_CURSOR_GUIDE: @NO, + KEY_USE_VERTICAL_CURSOR_GUIDE: @NO, KEY_TAB_COLOR: [NSNull null], KEY_USE_TAB_COLOR: @NO, KEY_UNDERLINE_COLOR: [NSNull null], diff --git a/sources/iTermTextDrawingHelper.h b/sources/iTermTextDrawingHelper.h index c5ba2c9b13..cd3eeaeb06 100644 --- a/sources/iTermTextDrawingHelper.h +++ b/sources/iTermTextDrawingHelper.h @@ -181,7 +181,7 @@ BOOL CheckFindMatchAtIndex(NSData *findMatches, int index); @property(nonatomic, assign) BOOL highlightCursorLine; // Should the vertical cursor guide be shown? -@property(nonatomic, assign) BOOL highlightCursorCol; +@property(nonatomic, assign) BOOL highlightCursorColumn; // Minimum contrast level, 0-1. @property(nonatomic, assign) double minimumContrast; diff --git a/sources/iTermTextDrawingHelper.m b/sources/iTermTextDrawingHelper.m index f37291727c..d14852a0a4 100644 --- a/sources/iTermTextDrawingHelper.m +++ b/sources/iTermTextDrawingHelper.m @@ -655,12 +655,12 @@ - (void)drawAccessoriesInRect:(NSRect)bgRect { } // Highlight cursor column if the cursor is in this column and it's on. - int cursorCol = _cursorCoord.x; - const BOOL drawVCursorGuide = (self.highlightCursorCol && - cursorCol >= coordRange.start.x && - cursorCol < coordRange.end.x); - if (drawVCursorGuide) { - CGFloat x = cursorCol * _cellSize.width; + int cursorColumn = _cursorCoord.x; + const BOOL drawVerticalCursorGuide = (self.highlightCursorColumn && + cursorColumn >= coordRange.start.x && + cursorColumn < coordRange.end.x); + if (drawVerticalCursorGuide) { + CGFloat x = cursorColumn * _cellSize.width; [self drawCursorGuideForRows:NSMakeRange(coordRange.start.y, coordRange.end.y - coordRange.start.y) x:x]; From 025b02b67c9763f087528f66bb56e57e83577c0e Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Tue, 2 Apr 2019 01:22:33 -0700 Subject: [PATCH 18/30] Fix bug with variable name type ("...Line" should be "...Column"). Renamve vvertexBuffer into verticalGuideVertexBuffer. Finish separating out control over the horizontal cursor guide from the vertical cursor guide. --- sources/Metal/Infrastructure/iTermMetalRenderer.h | 2 +- sources/Metal/Renderers/iTermCursorGuideRenderer.h | 2 +- sources/Metal/Renderers/iTermCursorGuideRenderer.m | 4 ++-- sources/Metal/iTermMetalDriver.h | 2 +- sources/Metal/iTermMetalDriver.m | 4 ++-- sources/PTYSession.m | 2 +- sources/iTermMetalPerFrameState.m | 4 ++-- sources/iTermMetalPerFrameStateConfiguration.h | 2 +- sources/iTermMetalPerFrameStateConfiguration.m | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/sources/Metal/Infrastructure/iTermMetalRenderer.h b/sources/Metal/Infrastructure/iTermMetalRenderer.h index 4206a8299e..ec26f63902 100644 --- a/sources/Metal/Infrastructure/iTermMetalRenderer.h +++ b/sources/Metal/Infrastructure/iTermMetalRenderer.h @@ -46,7 +46,7 @@ NS_CLASS_AVAILABLE(10_11, NA) @interface iTermMetalRendererTransientState : NSObject @property (nonatomic, strong, readonly) __kindof iTermRenderConfiguration *configuration; @property (nonatomic, strong) id vertexBuffer; -@property (nonatomic, strong) id vvertexBuffer; +@property (nonatomic, strong) id verticalGuideVertexBuffer; @property (nonatomic, readonly) iTermMetalBufferPoolContext *poolContext; @property (nonatomic, weak) iTermMetalDebugInfo *debugInfo; @property (nonatomic, strong) NSImage *renderedOutputForDebugging; diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.h b/sources/Metal/Renderers/iTermCursorGuideRenderer.h index d0dbc6963a..ea8574fba2 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.h +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.h @@ -11,7 +11,7 @@ NS_ASSUME_NONNULL_BEGIN @interface iTermCursorGuideRenderer : NSObject -@property (nonatomic) BOOL enabled; +@property (nonatomic) BOOL horizontalEnabled; @property (nonatomic) BOOL verticalEnabled; - (nullable instancetype)initWithDevice:(id)device NS_DESIGNATED_INITIALIZER; diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.m b/sources/Metal/Renderers/iTermCursorGuideRenderer.m index cc176bad24..691e913ac2 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.m +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.m @@ -98,7 +98,7 @@ - (iTermMetalFrameDataStat)createTransientStateStat { - (nullable __kindof iTermMetalRendererTransientState *)createTransientStateForCellConfiguration:(iTermCellRenderConfiguration *)configuration commandBuffer:(id)commandBuffer { - if (!_enabled) { + if (!_horizontalEnabled && !_verticalEnabled) { return nil; } __kindof iTermMetalCellRendererTransientState * _Nonnull transientState = @@ -131,7 +131,7 @@ - (void)drawWithFrameData:(iTermMetalFrameData *)frameData } [tState initializeVerticesWithPool:_cellRenderer.verticesPool]; - if (tState.row >= 0 && self.enabled) { + if (tState.row >= 0 && self.horizontalEnabled) { [_cellRenderer drawWithTransientState:tState renderEncoder:frameData.renderEncoder numberOfVertices:6 diff --git a/sources/Metal/iTermMetalDriver.h b/sources/Metal/iTermMetalDriver.h index 0936f0aee4..4fbf1eb461 100644 --- a/sources/Metal/iTermMetalDriver.h +++ b/sources/Metal/iTermMetalDriver.h @@ -60,7 +60,7 @@ NS_CLASS_AVAILABLE(10_11, NA) @property (nonatomic, nullable, readonly) iTermMetalIMEInfo *imeInfo; @property (nonatomic, readonly) BOOL showBroadcastStripes; @property (nonatomic, readonly) NSColor *cursorGuideColor; -@property (nonatomic, readonly) BOOL cursorGuideEnabled; +@property (nonatomic, readonly) BOOL cursorHorizontalGuideEnabled; @property (nonatomic, readonly) BOOL cursorVerticalGuideEnabled; @property (nonatomic, readonly) vector_float4 fullScreenFlashColor; @property (nonatomic, readonly) BOOL timestampsEnabled; diff --git a/sources/Metal/iTermMetalDriver.m b/sources/Metal/iTermMetalDriver.m index 802f48f666..19c7ef8cbd 100644 --- a/sources/Metal/iTermMetalDriver.m +++ b/sources/Metal/iTermMetalDriver.m @@ -644,7 +644,7 @@ - (BOOL)shouldCreateIntermediateRenderPassDescriptor:(iTermMetalFrameData *)fram if (!_broadcastStripesRenderer.rendererDisabled && frameData.perFrameState.showBroadcastStripes) { return YES; } - if (!_cursorGuideRenderer.rendererDisabled && (frameData.perFrameState.cursorGuideEnabled || + if (!_cursorGuideRenderer.rendererDisabled && (frameData.perFrameState.cursorHorizontalGuideEnabled || frameData.perFrameState.cursorVerticalGuideEnabled)) { return YES; } @@ -970,7 +970,7 @@ - (void)updateCursorGuideRendererForFrameData:(iTermMetalFrameData *)frameData { return; } [_cursorGuideRenderer setColor:frameData.perFrameState.cursorGuideColor]; - _cursorGuideRenderer.enabled = frameData.perFrameState.cursorGuideEnabled; + _cursorGuideRenderer.horizontalEnabled = frameData.perFrameState.cursorHorizontalGuideEnabled; _cursorGuideRenderer.verticalEnabled = frameData.perFrameState.cursorVerticalGuideEnabled; } diff --git a/sources/PTYSession.m b/sources/PTYSession.m index 90575fd55f..e664c91efd 100644 --- a/sources/PTYSession.m +++ b/sources/PTYSession.m @@ -1187,7 +1187,7 @@ + (void)finishInitializingArrangementOriginatedSession:(PTYSession *)aSession aSession.textview.highlightCursorLine = [arrangement[SESSION_ARRANGEMENT_CURSOR_GUIDE] boolValue]; } if (arrangement[SESSION_ARRANGEMENT_VERTICAL_CURSOR_GUIDE]) { - aSession.textview.highlightCursorLine = [arrangement[SESSION_ARRANGEMENT_VERTICAL_CURSOR_GUIDE] boolValue]; + aSession.textview.highlightCursorColumn = [arrangement[SESSION_ARRANGEMENT_VERTICAL_CURSOR_GUIDE] boolValue]; } aSession->_lastMark = [aSession.screen.lastMark retain]; aSession.lastRemoteHost = aSession.screen.lastRemoteHost; diff --git a/sources/iTermMetalPerFrameState.m b/sources/iTermMetalPerFrameState.m index 359c1c9b91..09479f0d7a 100644 --- a/sources/iTermMetalPerFrameState.m +++ b/sources/iTermMetalPerFrameState.m @@ -578,8 +578,8 @@ - (vector_float4)fullScreenFlashColor { return _configuration->_fullScreenFlashColor; } -- (BOOL)cursorGuideEnabled { - return _configuration->_cursorGuideColor && _configuration->_cursorGuideEnabled; +- (BOOL)cursorHorizontalGuideEnabled { + return _configuration->_cursorGuideColor && _configuration->_cursorHorizontalGuideEnabled; } - (BOOL)cursorVerticalGuideEnabled { diff --git a/sources/iTermMetalPerFrameStateConfiguration.h b/sources/iTermMetalPerFrameStateConfiguration.h index c34c4b36ee..5e557aeb6d 100644 --- a/sources/iTermMetalPerFrameStateConfiguration.h +++ b/sources/iTermMetalPerFrameStateConfiguration.h @@ -61,7 +61,7 @@ NS_ASSUME_NONNULL_BEGIN // Cursor BOOL _shouldDrawFilledInCursor; - BOOL _cursorGuideEnabled; + BOOL _cursorHorizontalGuideEnabled; BOOL _cursorVerticalGuideEnabled; // Size diff --git a/sources/iTermMetalPerFrameStateConfiguration.m b/sources/iTermMetalPerFrameStateConfiguration.m index 2d41083775..da19fb65aa 100644 --- a/sources/iTermMetalPerFrameStateConfiguration.m +++ b/sources/iTermMetalPerFrameStateConfiguration.m @@ -55,7 +55,7 @@ - (void)loadSettingsWithDrawingHelper:(iTermTextDrawingHelper *)drawingHelper _transparencyAffectsOnlyDefaultBackgroundColor = drawingHelper.transparencyAffectsOnlyDefaultBackgroundColor; // Cursor guide - _cursorGuideEnabled = drawingHelper.highlightCursorLine; + _cursorHorizontalGuideEnabled = drawingHelper.highlightCursorLine; _cursorVerticalGuideEnabled = drawingHelper.highlightCursorColumn; _cursorGuideColor = drawingHelper.cursorGuideColor; From 921b5cf878ee4ba640e5ad13bce3743f8b58d6ef Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Sun, 7 Apr 2019 00:29:40 -0700 Subject: [PATCH 19/30] Remove extraneous shared vertex buffer in favor of keeping more in the cursor guide renderer. Create additional texture for vertical cursor guide. Create additional vertex buffers for vertical and split-vertical (used for vertical when both vertical and horizontal guides are enabled) drawing of the vertical cursor guide. --- .../Metal/Infrastructure/iTermMetalRenderer.h | 1 - .../Renderers/iTermCursorGuideRenderer.m | 180 ++++++++++++------ 2 files changed, 125 insertions(+), 56 deletions(-) diff --git a/sources/Metal/Infrastructure/iTermMetalRenderer.h b/sources/Metal/Infrastructure/iTermMetalRenderer.h index ec26f63902..aee0e34db4 100644 --- a/sources/Metal/Infrastructure/iTermMetalRenderer.h +++ b/sources/Metal/Infrastructure/iTermMetalRenderer.h @@ -46,7 +46,6 @@ NS_CLASS_AVAILABLE(10_11, NA) @interface iTermMetalRendererTransientState : NSObject @property (nonatomic, strong, readonly) __kindof iTermRenderConfiguration *configuration; @property (nonatomic, strong) id vertexBuffer; -@property (nonatomic, strong) id verticalGuideVertexBuffer; @property (nonatomic, readonly) iTermMetalBufferPoolContext *poolContext; @property (nonatomic, weak) iTermMetalDebugInfo *debugInfo; @property (nonatomic, strong) NSImage *renderedOutputForDebugging; diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.m b/sources/Metal/Renderers/iTermCursorGuideRenderer.m index 691e913ac2..598e53d6a8 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.m +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.m @@ -1,14 +1,17 @@ #import "iTermCursorGuideRenderer.h" @interface iTermCursorGuideRendererTransientState() -@property (nonatomic, strong) id texture; +@property (nonatomic, strong) id horizontalTexture, verticalTexture; @property (nonatomic) int row; @property (nonatomic) int column; +@property (nonatomic) id horizontalVertexBuffer, verticalVertexBuffer, upperVertexBuffer, lowerVertexBuffer; @end @implementation iTermCursorGuideRendererTransientState { int _row; int _column; + id _horizontalVertexBuffer, _verticalVertexBuffer; + id _upperVertexBuffer, _lowerVertexBuffer; } - (void)setCursorCoord:(VT100GridCoord)coord within:(VT100GridSize)bounds { @@ -16,45 +19,78 @@ - (void)setCursorCoord:(VT100GridCoord)coord within:(VT100GridSize)bounds { _column = (0 <= coord.x && coord.x < bounds.width) ? coord.x : -1; } -- (void)initializeVerticesWithPool:(iTermMetalBufferPool *)verticesPool { +- (void)initializeVerticesWithPool:(iTermMetalBufferPool *)verticesPool + horizontal:(BOOL)horizontal + vertical:(BOOL)vertical { CGSize cellSize = self.cellConfiguration.cellSize; VT100GridSize gridSize = self.cellConfiguration.gridSize; - const CGRect quad = CGRectMake(self.margins.left, - self.margins.top + (gridSize.height - self.row - 1) * cellSize.height, - cellSize.width * gridSize.width, - cellSize.height); const CGRect textureFrame = CGRectMake(0, 0, 1, 1); - const iTermVertex vertices[] = { - // Pixel Positions Texture Coordinates - { { CGRectGetMaxX(quad), CGRectGetMinY(quad) }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { CGRectGetMinX(quad), CGRectGetMinY(quad) }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { CGRectGetMinX(quad), CGRectGetMaxY(quad) }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - - { { CGRectGetMaxX(quad), CGRectGetMinY(quad) }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { CGRectGetMinX(quad), CGRectGetMaxY(quad) }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - { { CGRectGetMaxX(quad), CGRectGetMaxY(quad) }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, - }; - self.vertexBuffer = [verticesPool requestBufferFromContext:self.poolContext - withBytes:vertices - checkIfChanged:YES]; - - const CGRect verticalGuideQuad = CGRectMake(self.margins.left + self.column * cellSize.width, - self.margins.top, - cellSize.width, - cellSize.height * gridSize.height); - const iTermVertex verticalGuideVertices[] = { - { { CGRectGetMaxX(verticalGuideQuad), CGRectGetMinY(verticalGuideQuad) }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { CGRectGetMinX(verticalGuideQuad), CGRectGetMinY(verticalGuideQuad) }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { CGRectGetMinX(verticalGuideQuad), CGRectGetMaxY(verticalGuideQuad) }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - - { { CGRectGetMaxX(verticalGuideQuad), CGRectGetMinY(verticalGuideQuad) }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { CGRectGetMinX(verticalGuideQuad), CGRectGetMaxY(verticalGuideQuad) }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - { { CGRectGetMaxX(verticalGuideQuad), CGRectGetMaxY(verticalGuideQuad) }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, - }; - self.verticalGuideVertexBuffer = [verticesPool requestBufferFromContext:self.poolContext - withBytes:verticalGuideVertices - checkIfChanged:YES]; + + CGFloat viewMinX = self.margins.left, viewMinY = self.margins.top; + CGFloat viewMaxX = viewMinX + cellSize.width*gridSize.width, viewMaxY = viewMinY + cellSize.height*gridSize.height; + + CGFloat cursorMinX = self.margins.left + self.column * cellSize.width, cursorMinY = self.margins.top + (gridSize.height - self.row - 1) * cellSize.height; + CGFloat cursorMaxX = cursorMinX + cellSize.width, cursorMaxY = cursorMinY + cellSize.height; + + if (horizontal) { + const iTermVertex vertices[] = { + // Pixel Positions Texture Coordinates + { { viewMaxX, cursorMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { viewMinX, cursorMinY }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { viewMinX, cursorMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, + + { { viewMaxX, cursorMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { viewMinX, cursorMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, + { { viewMaxX, cursorMaxY }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, + }; + self.horizontalVertexBuffer = [verticesPool requestBufferFromContext:self.poolContext + withBytes:vertices + checkIfChanged:YES]; + } + + if (horizontal && vertical) { + const iTermVertex lowerVertices[] = { + // Pixel Positions Texture Coordinates + { { cursorMaxX, viewMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { cursorMinX, viewMinY }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { cursorMinX, cursorMinY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, + + { { cursorMaxX, viewMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { cursorMinX, cursorMinY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, + { { cursorMaxX, cursorMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, + }; + self.lowerVertexBuffer = [verticesPool requestBufferFromContext:self.poolContext + withBytes:lowerVertices + checkIfChanged:YES]; + const iTermVertex upperVertices[] = { + // Pixel Positions Texture Coordinates + { { cursorMaxX, cursorMaxY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { cursorMinX, cursorMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { cursorMinX, viewMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, + + { { cursorMaxX, cursorMaxY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { cursorMinX, viewMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, + { { cursorMaxX, viewMaxY }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, + }; + self.upperVertexBuffer = [verticesPool requestBufferFromContext:self.poolContext + withBytes:upperVertices + checkIfChanged:YES]; + } else if (vertical) { + const iTermVertex vertices[] = { + // Pixel Positions Texture Coordinates + { { cursorMaxX, viewMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { cursorMinX, viewMinY }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { cursorMinX, viewMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, + + { { cursorMaxX, viewMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, + { { cursorMinX, viewMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, + { { cursorMaxX, viewMaxY }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, + }; + self.verticalVertexBuffer = [verticesPool requestBufferFromContext:self.poolContext + withBytes:vertices + checkIfChanged:YES]; + } } - (void)writeDebugInfoToFolder:(NSURL *)folder { @@ -69,7 +105,7 @@ - (void)writeDebugInfoToFolder:(NSURL *)folder { @implementation iTermCursorGuideRenderer { iTermMetalCellRenderer *_cellRenderer; - id _texture; + id _horizontalTexture, _verticalTexture; NSColor *_color; CGSize _lastCellSize; } @@ -110,10 +146,14 @@ - (nullable __kindof iTermMetalRendererTransientState *)createTransientStateForC - (void)initializeTransientState:(iTermCursorGuideRendererTransientState *)tState { if (!CGSizeEqualToSize(tState.cellConfiguration.cellSize, _lastCellSize)) { - _texture = [self newCursorGuideTextureWithTransientState:tState]; + _horizontalTexture = [self newCursorGuideTextureWithTransientState:tState + isHorizontal:YES]; + _verticalTexture = [self newCursorGuideTextureWithTransientState:tState + isHorizontal:NO]; _lastCellSize = tState.cellConfiguration.cellSize; } - tState.texture = _texture; + tState.horizontalTexture = _horizontalTexture; + tState.verticalTexture = _verticalTexture; } - (void)setColor:(NSColor *)color { @@ -126,37 +166,59 @@ - (void)setColor:(NSColor *)color { - (void)drawWithFrameData:(iTermMetalFrameData *)frameData transientState:(__kindof iTermMetalCellRendererTransientState *)transientState { iTermCursorGuideRendererTransientState *tState = transientState; - if (tState.row < 0 || tState.column < 0) { + if (tState.row < 0 && tState.column < 0) { return; } - [tState initializeVerticesWithPool:_cellRenderer.verticesPool]; - if (tState.row >= 0 && self.horizontalEnabled) { + if (tState.row >= 0 && tState.column >= 0 && self.horizontalEnabled && self.verticalEnabled) { + [tState initializeVerticesWithPool:_cellRenderer.verticesPool horizontal:TRUE vertical:TRUE]; [_cellRenderer drawWithTransientState:tState renderEncoder:frameData.renderEncoder numberOfVertices:6 numberOfPIUs:0 - vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.vertexBuffer } + vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.horizontalVertexBuffer } fragmentBuffers:@{} - textures:@{ @(iTermTextureIndexPrimary): tState.texture } ]; - } - - if (tState.column >= 0 && self.verticalEnabled) { + textures:@{ @(iTermTextureIndexPrimary): tState.horizontalTexture } ]; [_cellRenderer drawWithTransientState:tState renderEncoder:frameData.renderEncoder numberOfVertices:6 numberOfPIUs:0 - vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.verticalGuideVertexBuffer } + vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.upperVertexBuffer } fragmentBuffers:@{} - textures:@{ @(iTermTextureIndexPrimary): tState.texture } ]; + textures:@{ @(iTermTextureIndexPrimary): tState.verticalTexture } ]; + [_cellRenderer drawWithTransientState:tState + renderEncoder:frameData.renderEncoder + numberOfVertices:6 + numberOfPIUs:0 + vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.lowerVertexBuffer } + fragmentBuffers:@{} + textures:@{ @(iTermTextureIndexPrimary): tState.verticalTexture } ]; + } else if (tState.row >= 0 && self.horizontalEnabled) { + [tState initializeVerticesWithPool:_cellRenderer.verticesPool horizontal:TRUE vertical:FALSE]; + [_cellRenderer drawWithTransientState:tState + renderEncoder:frameData.renderEncoder + numberOfVertices:6 + numberOfPIUs:0 + vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.horizontalVertexBuffer } + fragmentBuffers:@{} + textures:@{ @(iTermTextureIndexPrimary): tState.horizontalTexture } ]; + } else if (tState.column >= 0 && self.verticalEnabled) { + [tState initializeVerticesWithPool:_cellRenderer.verticesPool horizontal:FALSE vertical:TRUE]; + [_cellRenderer drawWithTransientState:tState + renderEncoder:frameData.renderEncoder + numberOfVertices:6 + numberOfPIUs:0 + vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.verticalVertexBuffer } + fragmentBuffers:@{} + textures:@{ @(iTermTextureIndexPrimary): tState.verticalTexture } ]; } } #pragma mark - Private -- (id)newCursorGuideTextureWithTransientState:(iTermCursorGuideRendererTransientState *)tState { +- (id)newCursorGuideTextureWithTransientState:(iTermCursorGuideRendererTransientState *)tState + isHorizontal:(BOOL)isHorizontal { NSImage *image = [[NSImage alloc] initWithSize:tState.cellConfiguration.cellSize]; - [image lockFocus]; { [_color set]; @@ -166,11 +228,19 @@ - (void)drawWithFrameData:(iTermMetalFrameData *)frameData tState.cellConfiguration.cellSize.height); NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); - rect.size.height = tState.cellConfiguration.scale; - NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); + if (isHorizontal) { + rect.size.height = tState.cellConfiguration.scale; + NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); - rect.origin.y += tState.cellConfiguration.cellSize.height - tState.cellConfiguration.scale; - NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); + rect.origin.y += tState.cellConfiguration.cellSize.height - tState.cellConfiguration.scale; + NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); + } else { + rect.size.width = tState.cellConfiguration.scale; + NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); + + rect.origin.x += tState.cellConfiguration.cellSize.width - tState.cellConfiguration.scale; + NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); + } } [image unlockFocus]; From cd25d8c98bc2dd5e8735bac8cd01030bc284d0bd Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Sun, 7 Apr 2019 12:35:41 -0700 Subject: [PATCH 20/30] Factor out rectangle tessellation and vertex buffer creation. --- .../Renderers/iTermCursorGuideRenderer.m | 93 ++++++++----------- 1 file changed, 39 insertions(+), 54 deletions(-) diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.m b/sources/Metal/Renderers/iTermCursorGuideRenderer.m index 598e53d6a8..33bc1b230c 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.m +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.m @@ -14,7 +14,28 @@ @implementation iTermCursorGuideRendererTransientState { id _upperVertexBuffer, _lowerVertexBuffer; } -- (void)setCursorCoord:(VT100GridCoord)coord within:(VT100GridSize)bounds { +- (id)tessellateRect:(CGRect)rect withTexture:(CGRect)textureRect withPool:(iTermMetalBufferPool *)verticesPool { + // Tesselates an axis-aligned rectangle into a sequence of vertices + // representing two adjacent triangles that share the diagonal of the + // rectangle: + // top-right, top-left, bottom-left, top-right, bottom-left, bottom-right + const iTermVertex vertices[] = { + // Pixel Positions Texture Coordinates + { { CGRectGetMaxX(rect), CGRectGetMinY(rect) }, { CGRectGetMaxX(textureRect), CGRectGetMinY(textureRect) } }, + { { CGRectGetMinX(rect), CGRectGetMinY(rect) }, { CGRectGetMinX(textureRect), CGRectGetMinY(textureRect) } }, + { { CGRectGetMinX(rect), CGRectGetMaxY(rect) }, { CGRectGetMinX(textureRect), CGRectGetMaxY(textureRect) } }, + + { { CGRectGetMaxX(rect), CGRectGetMinY(rect) }, { CGRectGetMaxX(textureRect), CGRectGetMinY(textureRect) } }, + { { CGRectGetMinX(rect), CGRectGetMaxY(rect) }, { CGRectGetMinX(textureRect), CGRectGetMaxY(textureRect) } }, + { { CGRectGetMaxX(rect), CGRectGetMaxY(rect) }, { CGRectGetMaxX(textureRect), CGRectGetMaxY(textureRect) } }, + }; + return [verticesPool requestBufferFromContext:self.poolContext + withBytes:vertices + checkIfChanged:YES]; +} + +- (void)setCursorCoord:(VT100GridCoord)coord { + VT100GridSize bounds = self.cellConfiguration.gridSize; _row = (0 <= coord.y && coord.y < bounds.height) ? coord.y : -1; _column = (0 <= coord.x && coord.x < bounds.width) ? coord.x : -1; } @@ -31,65 +52,29 @@ - (void)initializeVerticesWithPool:(iTermMetalBufferPool *)verticesPool CGFloat viewMaxX = viewMinX + cellSize.width*gridSize.width, viewMaxY = viewMinY + cellSize.height*gridSize.height; CGFloat cursorMinX = self.margins.left + self.column * cellSize.width, cursorMinY = self.margins.top + (gridSize.height - self.row - 1) * cellSize.height; - CGFloat cursorMaxX = cursorMinX + cellSize.width, cursorMaxY = cursorMinY + cellSize.height; + CGFloat cursorMaxY = cursorMinY + cellSize.height; if (horizontal) { - const iTermVertex vertices[] = { - // Pixel Positions Texture Coordinates - { { viewMaxX, cursorMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { viewMinX, cursorMinY }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { viewMinX, cursorMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - - { { viewMaxX, cursorMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { viewMinX, cursorMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - { { viewMaxX, cursorMaxY }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, - }; - self.horizontalVertexBuffer = [verticesPool requestBufferFromContext:self.poolContext - withBytes:vertices - checkIfChanged:YES]; + self.horizontalVertexBuffer = [self tessellateRect:CGRectMake(viewMinX, cursorMinY, + viewMaxX - viewMinX, cellSize.height) + withTexture:textureFrame + withPool:verticesPool]; } if (horizontal && vertical) { - const iTermVertex lowerVertices[] = { - // Pixel Positions Texture Coordinates - { { cursorMaxX, viewMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { cursorMinX, viewMinY }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { cursorMinX, cursorMinY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - - { { cursorMaxX, viewMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { cursorMinX, cursorMinY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - { { cursorMaxX, cursorMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, - }; - self.lowerVertexBuffer = [verticesPool requestBufferFromContext:self.poolContext - withBytes:lowerVertices - checkIfChanged:YES]; - const iTermVertex upperVertices[] = { - // Pixel Positions Texture Coordinates - { { cursorMaxX, cursorMaxY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { cursorMinX, cursorMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { cursorMinX, viewMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - - { { cursorMaxX, cursorMaxY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { cursorMinX, viewMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - { { cursorMaxX, viewMaxY }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, - }; - self.upperVertexBuffer = [verticesPool requestBufferFromContext:self.poolContext - withBytes:upperVertices - checkIfChanged:YES]; + self.lowerVertexBuffer = [self tessellateRect:CGRectMake(cursorMinX, viewMinY, + cellSize.width, cursorMinY - viewMinY) + withTexture:textureFrame + withPool:verticesPool]; + self.upperVertexBuffer = [self tessellateRect:CGRectMake(cursorMinX, cursorMaxY, + cellSize.width, viewMaxY - cursorMaxY) + withTexture:textureFrame + withPool:verticesPool]; } else if (vertical) { - const iTermVertex vertices[] = { - // Pixel Positions Texture Coordinates - { { cursorMaxX, viewMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { cursorMinX, viewMinY }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { cursorMinX, viewMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - - { { cursorMaxX, viewMinY }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { cursorMinX, viewMaxY }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - { { cursorMaxX, viewMaxY }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, - }; - self.verticalVertexBuffer = [verticesPool requestBufferFromContext:self.poolContext - withBytes:vertices - checkIfChanged:YES]; + self.verticalVertexBuffer = [self tessellateRect:CGRectMake(cursorMinX, viewMinY, + cellSize.width, viewMaxY - viewMinY) + withTexture:textureFrame + withPool:verticesPool]; } } From bdbe9182dabc0073f62ec378f1a71d3de7372169 Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Sun, 7 Apr 2019 01:00:08 -0700 Subject: [PATCH 21/30] Use bounds from iTermCursorGuideRendererTransientState's cellConfiguration instead of requiring them to be passed into the method. --- sources/Metal/Renderers/iTermCursorGuideRenderer.h | 2 +- sources/Metal/iTermMetalDriver.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.h b/sources/Metal/Renderers/iTermCursorGuideRenderer.h index ea8574fba2..37af18ac29 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.h +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.h @@ -6,7 +6,7 @@ NS_ASSUME_NONNULL_BEGIN @interface iTermCursorGuideRendererTransientState : iTermMetalCellRendererTransientState -- (void)setCursorCoord:(VT100GridCoord)coord within:(VT100GridSize)bounds; +- (void)setCursorCoord:(VT100GridCoord)coord; @end @interface iTermCursorGuideRenderer : NSObject diff --git a/sources/Metal/iTermMetalDriver.m b/sources/Metal/iTermMetalDriver.m index 19c7ef8cbd..d5f24d0220 100644 --- a/sources/Metal/iTermMetalDriver.m +++ b/sources/Metal/iTermMetalDriver.m @@ -1222,7 +1222,7 @@ - (void)populateHighlightRowRendererTransientStateWithFrameData:(iTermMetalFrame - (void)populateCursorGuideRendererTransientStateWithFrameData:(iTermMetalFrameData *)frameData { iTermCursorGuideRendererTransientState *tState = [frameData transientStateForRenderer:_cursorGuideRenderer]; VT100GridCoord coord = frameData.perFrameState.metalDriverCursorInfo.coord; - [tState setCursorCoord:coord within:frameData.gridSize]; + [tState setCursorCoord:coord]; } - (void)populateTimestampsRendererTransientStateWithFrameData:(iTermMetalFrameData *)frameData { From 48a48ccc560d6470300090ce582911bd0fc468fe Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Sun, 7 Apr 2019 11:55:41 -0700 Subject: [PATCH 22/30] Since [...textView setNeedsDisplayOnColumn...] is expensive (causes a complete redraw), do not cause the redraw unless there is good reason to do so (ie the vertical cursor guide is enabled). --- sources/PTYTextView.m | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/sources/PTYTextView.m b/sources/PTYTextView.m index f5c5d03dfc..8b40db901c 100644 --- a/sources/PTYTextView.m +++ b/sources/PTYTextView.m @@ -979,7 +979,13 @@ - (void)setNeedsDisplayOnLine:(int)line } - (void)setNeedsDisplayOnColumn:(int)column { - [self setNeedsDisplayOnColumn:column inRange:VT100GridRangeMake(0, _dataSource.height)]; + // We can only draw whole lines, not individual characters. Consequently + // a request to redraw a column should only cause an update if there is + // something in the column outside the row that needs an update, such as the + // vertical cursor guide. + if ([self highlightCursorColumn]) { + [self setNeedsDisplayOnColumn:column inRange:VT100GridRangeMake(0, _dataSource.height)]; + } } // Overrides an NSView method. @@ -6414,21 +6420,13 @@ - (void)setNeedsDisplayOnLine:(int)y inRange:(VT100GridRange)range { } - (void)setNeedsDisplayOnColumn:(int)x inRange:(VT100GridRange)range { - NSRect dirtyRect; - const int y = range.location; - const int maxY = range.location + range.length; - - dirtyRect.origin.y = [iTermAdvancedSettingsModel terminalMargin] + y * _lineHeight; // _charHeightWithoutSpacing; - dirtyRect.origin.x = x * _charWidth; - dirtyRect.size.height = (maxY - y) * _lineHeight; //- _charHeightWithoutSpacing; - dirtyRect.size.width = _charWidth; - - // Expand the rect in case we're drawing a changed cell with an oversize glyph. - dirtyRect = [self rectWithHalo:dirtyRect]; - - DLog(@"Column %d is dirty in range [%d, %d), set rect %@ dirty", - x, y, maxY, [NSValue valueWithRect:dirtyRect]); - [self setNeedsDisplayInRect:dirtyRect]; + // We can only draw whole lines, not individual characters. Consequently + // a request to redraw a column should only cause an update if there is + // something in the column outside the row that needs an update, such as the + // vertical cursor guide. + if ([self highlightCursorColumn]) { + [self setNeedsDisplay:YES]; + } } // WARNING: Do not call this function directly. Call From 262e70736f77e9d6f7871746f82c0b7a7def7703 Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Sun, 7 Apr 2019 19:17:46 -0700 Subject: [PATCH 23/30] Do not double-draw the cursor guide under the cursor. --- sources/iTermTextDrawingHelper.m | 38 +++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/sources/iTermTextDrawingHelper.m b/sources/iTermTextDrawingHelper.m index d14852a0a4..23650810ad 100644 --- a/sources/iTermTextDrawingHelper.m +++ b/sources/iTermTextDrawingHelper.m @@ -644,26 +644,38 @@ - (void)drawAccessoriesInRect:(NSRect)bgRect { // Highlight cursor line if the cursor is on this line and it's on. int cursorLine = _cursorCoord.y + _numberOfScrollbackLines; - const BOOL drawCursorGuide = (self.highlightCursorLine && - cursorLine >= coordRange.start.y && - cursorLine < coordRange.end.y); - if (drawCursorGuide) { - CGFloat y = cursorLine * _cellSize.height; - [self drawCursorGuideForColumns:NSMakeRange(coordRange.start.x, - coordRange.end.x - coordRange.start.x) - y:y]; - } - - // Highlight cursor column if the cursor is in this column and it's on. int cursorColumn = _cursorCoord.x; + const BOOL drawHorizontalCursorGuide = (self.highlightCursorLine && + cursorLine >= coordRange.start.y && + cursorLine < coordRange.end.y); const BOOL drawVerticalCursorGuide = (self.highlightCursorColumn && cursorColumn >= coordRange.start.x && cursorColumn < coordRange.end.x); - if (drawVerticalCursorGuide) { + + if (drawHorizontalCursorGuide && !drawVerticalCursorGuide) { + CGFloat y = cursorLine * _cellSize.height; + [self drawCursorGuideForColumns:NSMakeRange(coordRange.start.x, + coordRange.end.x - coordRange.start.x) + y:y]; + } else if (!drawHorizontalCursorGuide && drawVerticalCursorGuide) { CGFloat x = cursorColumn * _cellSize.width; [self drawCursorGuideForRows:NSMakeRange(coordRange.start.y, coordRange.end.y - coordRange.start.y) x:x]; + [self.delegate setNeedsDisplay:YES]; + } else if (drawHorizontalCursorGuide && drawVerticalCursorGuide) { + CGFloat x = cursorColumn * _cellSize.width; + CGFloat y = cursorLine * _cellSize.height; + [self drawCursorGuideForColumns:NSMakeRange(coordRange.start.x, + coordRange.end.x - coordRange.start.x) + y:y]; + [self drawCursorGuideForRows:NSMakeRange(coordRange.start.y, + cursorLine - coordRange.start.y) + x:x]; + [self drawCursorGuideForRows:NSMakeRange(cursorLine + 1, + coordRange.end.y - _cursorCoord.y) + x:x]; + [self.delegate setNeedsDisplay:YES]; } } @@ -692,7 +704,7 @@ - (void)drawCursorGuideForRows:(NSRange)range x:(CGFloat)xOrigin { } [_cursorGuideColor set]; NSPoint textOrigin = NSMakePoint(xOrigin + [iTermAdvancedSettingsModel terminalMargin], - [iTermAdvancedSettingsModel terminalMargin] + range.location * _cellSize.height); + range.location * _cellSize.height); NSRect rect = NSMakeRect(textOrigin.x, textOrigin.y, _cellSize.width, From 64bf5c458a1b0598a1b226a75c2ca7ff91de917e Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Fri, 12 Apr 2019 18:43:57 -0700 Subject: [PATCH 24/30] Fix style nits. --- .../Renderers/iTermCursorGuideRenderer.m | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.m b/sources/Metal/Renderers/iTermCursorGuideRenderer.m index 33bc1b230c..3903170ae5 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.m +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.m @@ -1,17 +1,23 @@ #import "iTermCursorGuideRenderer.h" @interface iTermCursorGuideRendererTransientState() -@property (nonatomic, strong) id horizontalTexture, verticalTexture; +@property (nonatomic, strong) id horizontalTexture; +@property (nonatomic, strong) id verticalTexture; @property (nonatomic) int row; @property (nonatomic) int column; -@property (nonatomic) id horizontalVertexBuffer, verticalVertexBuffer, upperVertexBuffer, lowerVertexBuffer; +@property (nonatomic) id horizontalVertexBuffer; +@property (nonatomic) id verticalVertexBuffer; +@property (nonatomic) id upperVertexBuffer; +@property (nonatomic) id lowerVertexBuffer; @end @implementation iTermCursorGuideRendererTransientState { int _row; int _column; - id _horizontalVertexBuffer, _verticalVertexBuffer; - id _upperVertexBuffer, _lowerVertexBuffer; + id _horizontalVertexBuffer; + id _verticalVertexBuffer; + id _upperVertexBuffer; + id _lowerVertexBuffer; } - (id)tessellateRect:(CGRect)rect withTexture:(CGRect)textureRect withPool:(iTermMetalBufferPool *)verticesPool { @@ -43,6 +49,7 @@ - (void)setCursorCoord:(VT100GridCoord)coord { - (void)initializeVerticesWithPool:(iTermMetalBufferPool *)verticesPool horizontal:(BOOL)horizontal vertical:(BOOL)vertical { + assert(horizontal || vertical); CGSize cellSize = self.cellConfiguration.cellSize; VT100GridSize gridSize = self.cellConfiguration.gridSize; @@ -90,7 +97,8 @@ - (void)writeDebugInfoToFolder:(NSURL *)folder { @implementation iTermCursorGuideRenderer { iTermMetalCellRenderer *_cellRenderer; - id _horizontalTexture, _verticalTexture; + id _horizontalTexture; + id _verticalTexture; NSColor *_color; CGSize _lastCellSize; } @@ -156,7 +164,7 @@ - (void)drawWithFrameData:(iTermMetalFrameData *)frameData } if (tState.row >= 0 && tState.column >= 0 && self.horizontalEnabled && self.verticalEnabled) { - [tState initializeVerticesWithPool:_cellRenderer.verticesPool horizontal:TRUE vertical:TRUE]; + [tState initializeVerticesWithPool:_cellRenderer.verticesPool horizontal:YES vertical:YES]; [_cellRenderer drawWithTransientState:tState renderEncoder:frameData.renderEncoder numberOfVertices:6 @@ -179,7 +187,7 @@ - (void)drawWithFrameData:(iTermMetalFrameData *)frameData fragmentBuffers:@{} textures:@{ @(iTermTextureIndexPrimary): tState.verticalTexture } ]; } else if (tState.row >= 0 && self.horizontalEnabled) { - [tState initializeVerticesWithPool:_cellRenderer.verticesPool horizontal:TRUE vertical:FALSE]; + [tState initializeVerticesWithPool:_cellRenderer.verticesPool horizontal:YES vertical:NO]; [_cellRenderer drawWithTransientState:tState renderEncoder:frameData.renderEncoder numberOfVertices:6 @@ -188,7 +196,7 @@ - (void)drawWithFrameData:(iTermMetalFrameData *)frameData fragmentBuffers:@{} textures:@{ @(iTermTextureIndexPrimary): tState.horizontalTexture } ]; } else if (tState.column >= 0 && self.verticalEnabled) { - [tState initializeVerticesWithPool:_cellRenderer.verticesPool horizontal:FALSE vertical:TRUE]; + [tState initializeVerticesWithPool:_cellRenderer.verticesPool horizontal:NO vertical:YES]; [_cellRenderer drawWithTransientState:tState renderEncoder:frameData.renderEncoder numberOfVertices:6 From 7c6142d974875867abaa11a85a9e61806b1e3fa6 Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Fri, 12 Apr 2019 18:51:56 -0700 Subject: [PATCH 25/30] Fix rebase conflict. --- sources/ProfilesColorsPreferencesViewController.m | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/ProfilesColorsPreferencesViewController.m b/sources/ProfilesColorsPreferencesViewController.m index 060bda9eec..9885b996a8 100644 --- a/sources/ProfilesColorsPreferencesViewController.m +++ b/sources/ProfilesColorsPreferencesViewController.m @@ -206,6 +206,7 @@ - (void)awakeFromNib { [self defineControl:_useVerticalGuide key:KEY_USE_VERTICAL_CURSOR_GUIDE + relatedView:nil type:kPreferenceInfoTypeCheckbox]; info = [self defineControl:_useBrightBold From 1618e458504a44f9a21de081fcd749ff85e1a11a Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Fri, 12 Apr 2019 19:39:07 -0700 Subject: [PATCH 26/30] Remove merge/conflict resolution detritus. --- sources/ProfilesColorsPreferencesViewController.m | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sources/ProfilesColorsPreferencesViewController.m b/sources/ProfilesColorsPreferencesViewController.m index cc3b783084..9885b996a8 100644 --- a/sources/ProfilesColorsPreferencesViewController.m +++ b/sources/ProfilesColorsPreferencesViewController.m @@ -209,10 +209,6 @@ - (void)awakeFromNib { relatedView:nil type:kPreferenceInfoTypeCheckbox]; - [self defineControl:_useVerticalGuide - key:KEY_USE_VERTICAL_CURSOR_GUIDE - type:kPreferenceInfoTypeCheckbox]; - info = [self defineControl:_useBrightBold key:KEY_USE_BOLD_COLOR displayName:@"Custom color for bold text" From 7f4a4a4f94c934510315aa8c3592dcc64a8f07e1 Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Fri, 12 Apr 2019 22:24:10 -0700 Subject: [PATCH 27/30] Remove unused variable that seems to be causing CI build fails. --- sources/PseudoTerminal.m | 1 - 1 file changed, 1 deletion(-) diff --git a/sources/PseudoTerminal.m b/sources/PseudoTerminal.m index 255bd7053f..a1bf23444e 100644 --- a/sources/PseudoTerminal.m +++ b/sources/PseudoTerminal.m @@ -5423,7 +5423,6 @@ - (void)tabView:(NSTabView *)aTabView closeWindowForLastTabViewItem:(NSTabViewIt - (NSImage *)imageFromSelectedTabView:(NSTabView *)aTabView tabViewItem:(NSTabViewItem *)tabViewItem { NSView *tabRootView = [tabViewItem view]; - NSRect tabFrame = [_contentView.tabBarControl frame]; NSRect contentFrame; NSRect viewRect; From 18c8e57836f4ae4cec7a233773c1c39a22f5ee05 Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Tue, 26 Mar 2019 01:05:23 -0700 Subject: [PATCH 28/30] Add ability to render a vertical guide over the column the cursor is in. --- Interfaces/MainMenu.xib | 6 + Interfaces/PreferencePanel.xib | 17 +- iTerm2XCTests/PTYTextViewTest.m | 15 ++ iTerm2XCTests/VT100GridTest.m | 3 + iTerm2XCTests/VT100ScreenTest.m | 6 + sources/ITAddressBookMgr.h | 1 + .../Renderers/iTermCursorGuideRenderer.h | 7 +- .../Renderers/iTermCursorGuideRenderer.m | 194 ++++++++++++++---- sources/Metal/iTermMetalDriver.h | 3 +- sources/Metal/iTermMetalDriver.m | 15 +- sources/PTYSession.h | 1 + sources/PTYSession.m | 192 +++++++++++++++++ sources/PTYTextView.h | 4 + sources/PTYTextView.m | 28 +++ .../ProfilesColorsPreferencesViewController.m | 6 + sources/PseudoTerminal.m | 10 +- sources/VT100Grid.h | 1 + sources/VT100Grid.m | 1 + sources/VT100Screen.h | 1 + sources/VT100Screen.m | 13 ++ sources/VT100ScreenDelegate.h | 4 + sources/VT100Terminal.m | 2 + sources/VT100TerminalDelegate.h | 1 + sources/iTermMetalPerFrameState.m | 12 +- .../iTermMetalPerFrameStateConfiguration.h | 3 +- .../iTermMetalPerFrameStateConfiguration.m | 3 +- sources/iTermProfilePreferences.m | 3 +- sources/iTermTextDrawingHelper.h | 3 + sources/iTermTextDrawingHelper.m | 87 +++++++- 29 files changed, 577 insertions(+), 65 deletions(-) diff --git a/Interfaces/MainMenu.xib b/Interfaces/MainMenu.xib index 39b2e2fccd..db6e751c6a 100644 --- a/Interfaces/MainMenu.xib +++ b/Interfaces/MainMenu.xib @@ -668,6 +668,12 @@ Gw + + + + + + diff --git a/Interfaces/PreferencePanel.xib b/Interfaces/PreferencePanel.xib index 52da7f29c4..ce56470620 100644 --- a/Interfaces/PreferencePanel.xib +++ b/Interfaces/PreferencePanel.xib @@ -1471,6 +1471,7 @@ DQ + @@ -2206,7 +2207,7 @@ DQ - + @@ -2257,7 +2258,7 @@ DQ + diff --git a/iTerm2XCTests/PTYTextViewTest.m b/iTerm2XCTests/PTYTextViewTest.m index 15e32aef92..283a0e8666 100644 --- a/iTerm2XCTests/PTYTextViewTest.m +++ b/iTerm2XCTests/PTYTextViewTest.m @@ -991,6 +991,21 @@ - (void)testCursorGuide { size:VT100GridSizeMake(5, 5)]; } +// Draws a cursor guide on the col with b. +- (void)testVerticalCursorGuide { + [self doGoldenTestForInput:@"abcd\x1b[2A" + name:NSStringFromSelector(_cmd) + hook:^(PTYTextView *textView) { + textView.drawingHook = ^(iTermTextDrawingHelper *helper) { + helper.shouldDrawFilledInCursor = YES; + helper.highlightCursorColumn = YES; + }; + } + profileOverrides:nil + createGolden:YES + size:VT100GridSizeMake(5, 5)]; +} + // Draws a badge which blends with nondefault background colors. - (void)testBadge { [self doGoldenTestForInput:@"\n\n\n\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\x1b[42mabc" diff --git a/iTerm2XCTests/VT100GridTest.m b/iTerm2XCTests/VT100GridTest.m index c38e27dc7d..f6b106e713 100644 --- a/iTerm2XCTests/VT100GridTest.m +++ b/iTerm2XCTests/VT100GridTest.m @@ -53,6 +53,9 @@ - (screen_char_t)gridBackgroundColorCode { - (void)gridCursorDidChangeLine { } +- (void)gridCursorDidChangeColumn { +} + - (iTermUnicodeNormalization)gridUnicodeNormalizationForm { return iTermUnicodeNormalizationNone; } diff --git a/iTerm2XCTests/VT100ScreenTest.m b/iTerm2XCTests/VT100ScreenTest.m index 5474e776d1..24e6f08b39 100644 --- a/iTerm2XCTests/VT100ScreenTest.m +++ b/iTerm2XCTests/VT100ScreenTest.m @@ -748,6 +748,12 @@ - (void)screenSetHighlightCursorLine:(BOOL)highlight { - (void)screenCursorDidMoveToLine:(int)line { } +- (void)screenSetHighlightCursorColumn:(BOOL)highlight { +} + +- (void)screenCursorDidMoveToColumn:(int)line { +} + - (void)screenSaveScrollPosition { } diff --git a/sources/ITAddressBookMgr.h b/sources/ITAddressBookMgr.h index b95b68be17..205083bab7 100644 --- a/sources/ITAddressBookMgr.h +++ b/sources/ITAddressBookMgr.h @@ -114,6 +114,7 @@ #define KEY_USE_UNDERLINE_COLOR @"Use Underline Color" #define KEY_CURSOR_BOOST @"Cursor Boost" #define KEY_USE_CURSOR_GUIDE @"Use Cursor Guide" +#define KEY_USE_VERTICAL_CURSOR_GUIDE @"Use Vertical Cursor Guide" #define KEY_CURSOR_GUIDE_COLOR @"Cursor Guide Color" #define KEY_BADGE_COLOR @"Badge Color" diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.h b/sources/Metal/Renderers/iTermCursorGuideRenderer.h index d9178e07c6..37af18ac29 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.h +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.h @@ -1,17 +1,18 @@ #import #import "iTermMetalCellRenderer.h" +#import "VT100GridTypes.h" NS_ASSUME_NONNULL_BEGIN @interface iTermCursorGuideRendererTransientState : iTermMetalCellRendererTransientState -// set to -1 if cursor's row is not currently visible. -- (void)setRow:(int)row; +- (void)setCursorCoord:(VT100GridCoord)coord; @end @interface iTermCursorGuideRenderer : NSObject -@property (nonatomic) BOOL enabled; +@property (nonatomic) BOOL horizontalEnabled; +@property (nonatomic) BOOL verticalEnabled; - (nullable instancetype)initWithDevice:(id)device NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE; diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.m b/sources/Metal/Renderers/iTermCursorGuideRenderer.m index b7326aaf78..cdf418b53d 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.m +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.m @@ -1,40 +1,108 @@ #import "iTermCursorGuideRenderer.h" @interface iTermCursorGuideRendererTransientState() -@property (nonatomic, strong) id texture; +@property (nonatomic, strong) id horizontalTexture; +@property (nonatomic, strong) id verticalTexture; @property (nonatomic) int row; +@property (nonatomic) int column; +@property (nonatomic) id horizontalVertexBuffer; +@property (nonatomic) id verticalVertexBuffer; +@property (nonatomic) id upperVertexBuffer; +@property (nonatomic) id lowerVertexBuffer; @end @implementation iTermCursorGuideRendererTransientState { int _row; + int _column; + id _horizontalVertexBuffer; + id _verticalVertexBuffer; + id _upperVertexBuffer; + id _lowerVertexBuffer; } -- (void)setRow:(int)row { - _row = row; +- (id)tessellateRect:(CGRect)rect withTexture:(CGRect)textureRect withPool:(iTermMetalBufferPool *)verticesPool { + // Tesselates an axis-aligned rectangle into a sequence of vertices + // representing two adjacent triangles that share the diagonal of the + // rectangle: + // top-right, top-left, bottom-left, top-right, bottom-left, bottom-right + const iTermVertex vertices[] = { + // Pixel Positions Texture Coordinates + { { CGRectGetMaxX(rect), CGRectGetMinY(rect) }, { CGRectGetMaxX(textureRect), CGRectGetMinY(textureRect) } }, + { { CGRectGetMinX(rect), CGRectGetMinY(rect) }, { CGRectGetMinX(textureRect), CGRectGetMinY(textureRect) } }, + { { CGRectGetMinX(rect), CGRectGetMaxY(rect) }, { CGRectGetMinX(textureRect), CGRectGetMaxY(textureRect) } }, + + { { CGRectGetMaxX(rect), CGRectGetMinY(rect) }, { CGRectGetMaxX(textureRect), CGRectGetMinY(textureRect) } }, + { { CGRectGetMinX(rect), CGRectGetMaxY(rect) }, { CGRectGetMinX(textureRect), CGRectGetMaxY(textureRect) } }, + { { CGRectGetMaxX(rect), CGRectGetMaxY(rect) }, { CGRectGetMaxX(textureRect), CGRectGetMaxY(textureRect) } }, + }; + return [verticesPool requestBufferFromContext:self.poolContext + withBytes:vertices + checkIfChanged:YES]; } -- (void)initializeVerticesWithPool:(iTermMetalBufferPool *)verticesPool { +- (id)tessellateRect:(CGRect)rect withTexture:(CGRect)textureRect withPool:(iTermMetalBufferPool *)verticesPool { + // Tesselates an axis-aligned rectangle into a sequence of vertices + // representing two adjacent triangles that share the diagonal of the + // rectangle: + // top-right, top-left, bottom-left, top-right, bottom-left, bottom-right + const iTermVertex vertices[] = { + // Pixel Positions Texture Coordinates + { { CGRectGetMaxX(rect), CGRectGetMinY(rect) }, { CGRectGetMaxX(textureRect), CGRectGetMinY(textureRect) } }, + { { CGRectGetMinX(rect), CGRectGetMinY(rect) }, { CGRectGetMinX(textureRect), CGRectGetMinY(textureRect) } }, + { { CGRectGetMinX(rect), CGRectGetMaxY(rect) }, { CGRectGetMinX(textureRect), CGRectGetMaxY(textureRect) } }, + + { { CGRectGetMaxX(rect), CGRectGetMinY(rect) }, { CGRectGetMaxX(textureRect), CGRectGetMinY(textureRect) } }, + { { CGRectGetMinX(rect), CGRectGetMaxY(rect) }, { CGRectGetMinX(textureRect), CGRectGetMaxY(textureRect) } }, + { { CGRectGetMaxX(rect), CGRectGetMaxY(rect) }, { CGRectGetMaxX(textureRect), CGRectGetMaxY(textureRect) } }, + }; + return [verticesPool requestBufferFromContext:self.poolContext + withBytes:vertices + checkIfChanged:YES]; +} + +- (void)setCursorCoord:(VT100GridCoord)coord { + VT100GridSize bounds = self.cellConfiguration.gridSize; + _row = (0 <= coord.y && coord.y < bounds.height) ? coord.y : -1; + _column = (0 <= coord.x && coord.x < bounds.width) ? coord.x : -1; +} + +- (void)initializeVerticesWithPool:(iTermMetalBufferPool *)verticesPool + horizontal:(BOOL)horizontal + vertical:(BOOL)vertical { + assert(horizontal || vertical); CGSize cellSize = self.cellConfiguration.cellSize; VT100GridSize gridSize = self.cellConfiguration.gridSize; - const CGRect quad = CGRectMake(self.margins.left, - self.margins.top + (gridSize.height - self.row - 1) * cellSize.height, - cellSize.width * gridSize.width, - cellSize.height); const CGRect textureFrame = CGRectMake(0, 0, 1, 1); - const iTermVertex vertices[] = { - // Pixel Positions Texture Coordinates - { { CGRectGetMaxX(quad), CGRectGetMinY(quad) }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { CGRectGetMinX(quad), CGRectGetMinY(quad) }, { CGRectGetMinX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { CGRectGetMinX(quad), CGRectGetMaxY(quad) }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - { { CGRectGetMaxX(quad), CGRectGetMinY(quad) }, { CGRectGetMaxX(textureFrame), CGRectGetMinY(textureFrame) } }, - { { CGRectGetMinX(quad), CGRectGetMaxY(quad) }, { CGRectGetMinX(textureFrame), CGRectGetMaxY(textureFrame) } }, - { { CGRectGetMaxX(quad), CGRectGetMaxY(quad) }, { CGRectGetMaxX(textureFrame), CGRectGetMaxY(textureFrame) } }, - }; - self.vertexBuffer = [verticesPool requestBufferFromContext:self.poolContext - withBytes:vertices - checkIfChanged:YES]; + CGFloat viewMinX = self.margins.left, viewMinY = self.margins.top; + CGFloat viewMaxX = viewMinX + cellSize.width*gridSize.width, viewMaxY = viewMinY + cellSize.height*gridSize.height; + + CGFloat cursorMinX = self.margins.left + self.column * cellSize.width, cursorMinY = self.margins.top + (gridSize.height - self.row - 1) * cellSize.height; + CGFloat cursorMaxY = cursorMinY + cellSize.height; + + if (horizontal) { + self.horizontalVertexBuffer = [self tessellateRect:CGRectMake(viewMinX, cursorMinY, + viewMaxX - viewMinX, cellSize.height) + withTexture:textureFrame + withPool:verticesPool]; + } + + if (horizontal && vertical) { + self.lowerVertexBuffer = [self tessellateRect:CGRectMake(cursorMinX, viewMinY, + cellSize.width, cursorMinY - viewMinY) + withTexture:textureFrame + withPool:verticesPool]; + self.upperVertexBuffer = [self tessellateRect:CGRectMake(cursorMinX, cursorMaxY, + cellSize.width, viewMaxY - cursorMaxY) + withTexture:textureFrame + withPool:verticesPool]; + } else if (vertical) { + self.verticalVertexBuffer = [self tessellateRect:CGRectMake(cursorMinX, viewMinY, + cellSize.width, viewMaxY - viewMinY) + withTexture:textureFrame + withPool:verticesPool]; + } } - (void)writeDebugInfoToFolder:(NSURL *)folder { @@ -49,7 +117,8 @@ - (void)writeDebugInfoToFolder:(NSURL *)folder { @implementation iTermCursorGuideRenderer { iTermMetalCellRenderer *_cellRenderer; - id _texture; + id _horizontalTexture; + id _verticalTexture; NSColor *_color; CGSize _lastCellSize; } @@ -78,7 +147,7 @@ - (iTermMetalFrameDataStat)createTransientStateStat { - (nullable __kindof iTermMetalRendererTransientState *)createTransientStateForCellConfiguration:(iTermCellRenderConfiguration *)configuration commandBuffer:(id)commandBuffer { - if (!_enabled) { + if (!_horizontalEnabled && !_verticalEnabled) { return nil; } __kindof iTermMetalCellRendererTransientState * _Nonnull transientState = @@ -90,10 +159,14 @@ - (nullable __kindof iTermMetalRendererTransientState *)createTransientStateForC - (void)initializeTransientState:(iTermCursorGuideRendererTransientState *)tState { if (!CGSizeEqualToSize(tState.cellConfiguration.cellSize, _lastCellSize)) { - _texture = [self newCursorGuideTextureWithTransientState:tState]; + _horizontalTexture = [self newCursorGuideTextureWithTransientState:tState + isHorizontal:YES]; + _verticalTexture = [self newCursorGuideTextureWithTransientState:tState + isHorizontal:NO]; _lastCellSize = tState.cellConfiguration.cellSize; } - tState.texture = _texture; + tState.horizontalTexture = _horizontalTexture; + tState.verticalTexture = _verticalTexture; } - (void)setColor:(NSColor *)color { @@ -106,26 +179,59 @@ - (void)setColor:(NSColor *)color { - (void)drawWithFrameData:(iTermMetalFrameData *)frameData transientState:(__kindof iTermMetalCellRendererTransientState *)transientState { iTermCursorGuideRendererTransientState *tState = transientState; - if (tState.row < 0) { - // Cursor is offscreen. We set it to -1 to signal this. + if (tState.row < 0 && tState.column < 0) { return; } - [tState initializeVerticesWithPool:_cellRenderer.verticesPool]; - [_cellRenderer drawWithTransientState:tState - renderEncoder:frameData.renderEncoder - numberOfVertices:6 - numberOfPIUs:0 - vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.vertexBuffer } - fragmentBuffers:@{} - textures:@{ @(iTermTextureIndexPrimary): tState.texture } ]; + if (tState.row >= 0 && tState.column >= 0 && self.horizontalEnabled && self.verticalEnabled) { + [tState initializeVerticesWithPool:_cellRenderer.verticesPool horizontal:YES vertical:YES]; + [_cellRenderer drawWithTransientState:tState + renderEncoder:frameData.renderEncoder + numberOfVertices:6 + numberOfPIUs:0 + vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.horizontalVertexBuffer } + fragmentBuffers:@{} + textures:@{ @(iTermTextureIndexPrimary): tState.horizontalTexture } ]; + [_cellRenderer drawWithTransientState:tState + renderEncoder:frameData.renderEncoder + numberOfVertices:6 + numberOfPIUs:0 + vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.upperVertexBuffer } + fragmentBuffers:@{} + textures:@{ @(iTermTextureIndexPrimary): tState.verticalTexture } ]; + [_cellRenderer drawWithTransientState:tState + renderEncoder:frameData.renderEncoder + numberOfVertices:6 + numberOfPIUs:0 + vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.lowerVertexBuffer } + fragmentBuffers:@{} + textures:@{ @(iTermTextureIndexPrimary): tState.verticalTexture } ]; + } else if (tState.row >= 0 && self.horizontalEnabled) { + [tState initializeVerticesWithPool:_cellRenderer.verticesPool horizontal:YES vertical:NO]; + [_cellRenderer drawWithTransientState:tState + renderEncoder:frameData.renderEncoder + numberOfVertices:6 + numberOfPIUs:0 + vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.horizontalVertexBuffer } + fragmentBuffers:@{} + textures:@{ @(iTermTextureIndexPrimary): tState.horizontalTexture } ]; + } else if (tState.column >= 0 && self.verticalEnabled) { + [tState initializeVerticesWithPool:_cellRenderer.verticesPool horizontal:NO vertical:YES]; + [_cellRenderer drawWithTransientState:tState + renderEncoder:frameData.renderEncoder + numberOfVertices:6 + numberOfPIUs:0 + vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.verticalVertexBuffer } + fragmentBuffers:@{} + textures:@{ @(iTermTextureIndexPrimary): tState.verticalTexture } ]; + } } #pragma mark - Private -- (id)newCursorGuideTextureWithTransientState:(iTermCursorGuideRendererTransientState *)tState { +- (id)newCursorGuideTextureWithTransientState:(iTermCursorGuideRendererTransientState *)tState + isHorizontal:(BOOL)isHorizontal { NSImage *image = [[NSImage alloc] initWithSize:tState.cellConfiguration.cellSize]; - [image lockFocus]; { [_color set]; @@ -135,11 +241,19 @@ - (void)drawWithFrameData:(iTermMetalFrameData *)frameData tState.cellConfiguration.cellSize.height); NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); - rect.size.height = tState.cellConfiguration.scale; - NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); + if (isHorizontal) { + rect.size.height = tState.cellConfiguration.scale; + NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); - rect.origin.y += tState.cellConfiguration.cellSize.height - tState.cellConfiguration.scale; - NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); + rect.origin.y += tState.cellConfiguration.cellSize.height - tState.cellConfiguration.scale; + NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); + } else { + rect.size.width = tState.cellConfiguration.scale; + NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); + + rect.origin.x += tState.cellConfiguration.cellSize.width - tState.cellConfiguration.scale; + NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); + } } [image unlockFocus]; diff --git a/sources/Metal/iTermMetalDriver.h b/sources/Metal/iTermMetalDriver.h index c3e724ff94..4fbf1eb461 100644 --- a/sources/Metal/iTermMetalDriver.h +++ b/sources/Metal/iTermMetalDriver.h @@ -60,7 +60,8 @@ NS_CLASS_AVAILABLE(10_11, NA) @property (nonatomic, nullable, readonly) iTermMetalIMEInfo *imeInfo; @property (nonatomic, readonly) BOOL showBroadcastStripes; @property (nonatomic, readonly) NSColor *cursorGuideColor; -@property (nonatomic, readonly) BOOL cursorGuideEnabled; +@property (nonatomic, readonly) BOOL cursorHorizontalGuideEnabled; +@property (nonatomic, readonly) BOOL cursorVerticalGuideEnabled; @property (nonatomic, readonly) vector_float4 fullScreenFlashColor; @property (nonatomic, readonly) BOOL timestampsEnabled; @property (nonatomic, readonly) NSColor *timestampsBackgroundColor; diff --git a/sources/Metal/iTermMetalDriver.m b/sources/Metal/iTermMetalDriver.m index 0d48797703..d5f24d0220 100644 --- a/sources/Metal/iTermMetalDriver.m +++ b/sources/Metal/iTermMetalDriver.m @@ -644,7 +644,8 @@ - (BOOL)shouldCreateIntermediateRenderPassDescriptor:(iTermMetalFrameData *)fram if (!_broadcastStripesRenderer.rendererDisabled && frameData.perFrameState.showBroadcastStripes) { return YES; } - if (!_cursorGuideRenderer.rendererDisabled && frameData.perFrameState.cursorGuideEnabled) { + if (!_cursorGuideRenderer.rendererDisabled && (frameData.perFrameState.cursorHorizontalGuideEnabled || + frameData.perFrameState.cursorVerticalGuideEnabled)) { return YES; } @@ -969,7 +970,8 @@ - (void)updateCursorGuideRendererForFrameData:(iTermMetalFrameData *)frameData { return; } [_cursorGuideRenderer setColor:frameData.perFrameState.cursorGuideColor]; - _cursorGuideRenderer.enabled = frameData.perFrameState.cursorGuideEnabled; + _cursorGuideRenderer.horizontalEnabled = frameData.perFrameState.cursorHorizontalGuideEnabled; + _cursorGuideRenderer.verticalEnabled = frameData.perFrameState.cursorVerticalGuideEnabled; } - (void)updateTimestampsRendererForFrameData:(iTermMetalFrameData *)frameData { @@ -1219,13 +1221,8 @@ - (void)populateHighlightRowRendererTransientStateWithFrameData:(iTermMetalFrame - (void)populateCursorGuideRendererTransientStateWithFrameData:(iTermMetalFrameData *)frameData { iTermCursorGuideRendererTransientState *tState = [frameData transientStateForRenderer:_cursorGuideRenderer]; - iTermMetalCursorInfo *cursorInfo = frameData.perFrameState.metalDriverCursorInfo; - if (cursorInfo.coord.y >= 0 && - cursorInfo.coord.y < frameData.gridSize.height) { - [tState setRow:frameData.perFrameState.metalDriverCursorInfo.coord.y]; - } else { - [tState setRow:-1]; - } + VT100GridCoord coord = frameData.perFrameState.metalDriverCursorInfo.coord; + [tState setCursorCoord:coord]; } - (void)populateTimestampsRendererTransientStateWithFrameData:(iTermMetalFrameData *)frameData { diff --git a/sources/PTYSession.h b/sources/PTYSession.h index f7275809e6..4033cb728a 100644 --- a/sources/PTYSession.h +++ b/sources/PTYSession.h @@ -422,6 +422,7 @@ typedef enum { @property(nonatomic, readonly) BOOL hasSelection; @property(nonatomic, assign) BOOL highlightCursorLine; +@property(nonatomic, assign) BOOL highlightCursorColumn; // Used to help remember total ordering on views while one is maximized @property(nonatomic, assign) NSPoint savedRootRelativeOrigin; diff --git a/sources/PTYSession.m b/sources/PTYSession.m index c37b6b3326..02593bdc12 100644 --- a/sources/PTYSession.m +++ b/sources/PTYSession.m @@ -208,6 +208,7 @@ static NSString *const SESSION_ARRANGEMENT_DIRECTORIES = @"Directories"; // Array of strings static NSString *const SESSION_ARRANGEMENT_HOSTS = @"Hosts"; // Array of VT100RemoteHost static NSString *const SESSION_ARRANGEMENT_CURSOR_GUIDE = @"Cursor Guide"; // BOOL +static NSString *const SESSION_ARRANGEMENT_VERTICAL_CURSOR_GUIDE = @"Vertical Cursor Guide"; // BOOL static NSString *const SESSION_ARRANGEMENT_LAST_DIRECTORY = @"Last Directory"; // NSString static NSString *const SESSION_ARRANGEMENT_LAST_DIRECTORY_IS_UNSUITABLE_FOR_OLD_PWD = @"Last Directory Is Remote"; // BOOL static NSString *const SESSION_ARRANGEMENT_SELECTION = @"Selection"; // Dictionary for iTermSelection. @@ -1158,6 +1159,9 @@ + (void)finishInitializingArrangementOriginatedSession:(PTYSession *)aSession if (arrangement[SESSION_ARRANGEMENT_CURSOR_GUIDE]) { aSession.textview.highlightCursorLine = [arrangement[SESSION_ARRANGEMENT_CURSOR_GUIDE] boolValue]; } + if (arrangement[SESSION_ARRANGEMENT_VERTICAL_CURSOR_GUIDE]) { + aSession.textview.highlightCursorColumn = [arrangement[SESSION_ARRANGEMENT_VERTICAL_CURSOR_GUIDE] boolValue]; + } aSession->_lastMark = [aSession.screen.lastMark retain]; aSession.lastRemoteHost = aSession.screen.lastRemoteHost; if (arrangement[SESSION_ARRANGEMENT_LAST_DIRECTORY]) { @@ -2341,6 +2345,164 @@ - (void)writeTaskNoBroadcast:(NSString *)string [self writeTaskImpl:string encoding:encoding forceEncoding:forceEncoding canBroadcast:NO]; } +- (void)handleKeyPressInCopyMode:(NSEvent *)event { + [self.textview setNeedsDisplayOnLine:_copyModeState.coord.y]; + [self.textview setNeedsDisplayOnColumn:_copyModeState.coord.x]; + BOOL wasSelecting = _copyModeState.selecting; + NSString *string = event.charactersIgnoringModifiers; + unichar code = [string length] > 0 ? [string characterAtIndex:0] : 0; + NSUInteger mask = (NSEventModifierFlagOption | NSEventModifierFlagControl | NSEventModifierFlagCommand); + BOOL moved = NO; + if ((event.modifierFlags & mask) == NSEventModifierFlagControl) { + switch (code) { + case 'b': // ^B + moved = [_copyModeState pageUp]; + break; + case 'f': // ^F + moved = [_copyModeState pageDown]; + break; + case ' ': + _copyModeState.selecting = !_copyModeState.selecting; + _copyModeState.mode = kiTermSelectionModeCharacter; + break; + case 'c': + self.copyMode = NO; + break; + case 'g': + self.copyMode = NO; + break; + case 'k': + [_textview copySelectionAccordingToUserPreferences]; + self.copyMode = NO; + break; + case 'v': + _copyModeState.selecting = !_copyModeState.selecting; + _copyModeState.mode = kiTermSelectionModeBox; + break; + } + } else if ((event.modifierFlags & mask) == NSEventModifierFlagOption) { + switch (code) { + case 'b': + case NSLeftArrowFunctionKey: + moved = [_copyModeState moveBackwardWord]; + break; + + case 'f': + case NSRightArrowFunctionKey: + moved = [_copyModeState moveForwardWord]; + break; + case 'm': + moved = [_copyModeState moveToStartOfIndentation]; + break; + } + } else if ((event.modifierFlags & mask) == 0) { + switch (code) { + case NSPageUpFunctionKey: + moved = [_copyModeState pageUp]; + break; + case NSPageDownFunctionKey: + moved = [_copyModeState pageDown]; + break; + case '\t': + if (event.modifierFlags & NSEventModifierFlagShift) { + moved = [_copyModeState moveBackwardWord]; + } else { + moved = [_copyModeState moveForwardWord]; + } + break; + case '\n': + case '\r': + moved = [_copyModeState moveToStartOfNextLine]; + break; + case 27: + case 'q': + self.copyMode = NO; + _copyModeState.selecting = NO; + moved = YES; + break; + case ' ': + case 'v': + _copyModeState.selecting = !_copyModeState.selecting; + _copyModeState.mode = kiTermSelectionModeCharacter; + break; + case 'b': + moved = [_copyModeState moveBackwardWord]; + break; + case '0': + moved = [_copyModeState moveToStartOfLine]; + break; + case 'H': + moved = [_copyModeState moveToTopOfVisibleArea]; + break; + case 'G': + moved = [_copyModeState moveToEnd]; + break; + case 'L': + moved = [_copyModeState moveToBottomOfVisibleArea]; + break; + case 'M': + moved = [_copyModeState moveToMiddleOfVisibleArea]; + break; + case 'V': + _copyModeState.selecting = !_copyModeState.selecting; + _copyModeState.mode = kiTermSelectionModeLine; + break; + case 'g': + moved = [_copyModeState moveToStart]; + break; + case 'h': + case NSLeftArrowFunctionKey: + moved = [_copyModeState moveLeft]; + break; + case 'j': + case NSDownArrowFunctionKey: + moved = [_copyModeState moveDown]; + break; + case 'k': + case NSUpArrowFunctionKey: + moved = [_copyModeState moveUp]; + break; + case 'l': + case NSRightArrowFunctionKey: + moved = [_copyModeState moveRight]; + break; + case 'o': + [_copyModeState swap]; + moved = YES; + break; + case 'w': + moved = [_copyModeState moveForwardWord]; + break; + case 'y': + [_textview copySelectionAccordingToUserPreferences]; + self.copyMode = NO; + break; + case '/': + [self showFindPanel]; + break; + case '[': + moved = [_copyModeState previousMark]; + break; + case ']': + moved = [_copyModeState nextMark]; + break; + case '^': + moved = [_copyModeState moveToStartOfIndentation]; + break; + case '$': + moved = [_copyModeState moveToEndOfLine]; + break; + } + } + if (moved || (_copyModeState.selecting != wasSelecting)) { + if (self.copyMode) { + [_textview scrollLineNumberRangeIntoView:VT100GridRangeMake(_copyModeState.coord.y, 1)]; + } + [self.textview setNeedsDisplayOnLine:_copyModeState.coord.y]; + [self.textview setNeedsDisplayOnColumn:_copyModeState.coord.x]; + } +} + - (void)handleKeypressInTmuxGateway:(NSEvent *)event { const unichar unicode = [event.characters length] > 0 ? [event.characters characterAtIndex:0] : 0; [self handleCharacterPressedInTmuxGateway:unicode]; @@ -3290,6 +3452,8 @@ - (void)loadInitialColorTable } _textview.highlightCursorLine = [iTermProfilePreferences boolForKey:KEY_USE_CURSOR_GUIDE inProfile:_profile]; + _textview.highlightCursorColumn = [iTermProfilePreferences boolForKey:KEY_USE_VERTICAL_CURSOR_GUIDE + inProfile:_profile]; } - (NSColor *)tabColorInProfile:(NSDictionary *)profile @@ -3472,6 +3636,8 @@ - (void)setPreferencesFromAddressBookEntry:(NSDictionary *)aePrefs { if (!_cursorGuideSettingHasChanged) { _textview.highlightCursorLine = [iTermProfilePreferences boolForKey:KEY_USE_CURSOR_GUIDE inProfile:aDict]; + _textview.highlightCursorColumn = [iTermProfilePreferences boolForKey:KEY_USE_VERTICAL_CURSOR_GUIDE + inProfile:aDict]; } for (i = 0; i < 16; i++) { @@ -4198,6 +4364,7 @@ - (NSDictionary *)arrangementWithContents:(BOOL)includeContents { [NSDictionary dictionaryWithGridCoordRange:range]; result[SESSION_ARRANGEMENT_ALERT_ON_NEXT_MARK] = @(_alertOnNextMark); result[SESSION_ARRANGEMENT_CURSOR_GUIDE] = @(_textview.highlightCursorLine); + result[SESSION_ARRANGEMENT_VERTICAL_CURSOR_GUIDE] = @(_textview.highlightCursorColumn); if (self.lastDirectory) { result[SESSION_ARRANGEMENT_LAST_DIRECTORY] = self.lastDirectory; result[SESSION_ARRANGEMENT_LAST_DIRECTORY_IS_UNSUITABLE_FOR_OLD_PWD] = @(self.lastDirectoryIsUnsuitableForOldPWD); @@ -8211,8 +8378,11 @@ - (void)screenDidReset { _cursorGuideSettingHasChanged = NO; _textview.highlightCursorLine = [iTermProfilePreferences boolForKey:KEY_USE_CURSOR_GUIDE inProfile:_profile]; + _textview.highlightCursorColumn = [iTermProfilePreferences boolForKey:KEY_USE_VERTICAL_CURSOR_GUIDE + inProfile:_profile]; [_textview setNeedsDisplay:YES]; _screen.trackCursorLineMovement = NO; + _screen.trackCursorColumnMovement = NO; } - (void)screenDidAppendStringToCurrentLine:(NSString *)string { @@ -8483,6 +8653,28 @@ - (BOOL)highlightCursorLine { return _textview.highlightCursorLine; } +- (void)screenCursorDidMoveToColumn:(int)column { + if (_textview.cursorVisible) { + [_textview setNeedsDisplayOnColumn:column]; + } +} + +- (void)screenSetHighlightCursorColumn:(BOOL)highlight { + _cursorGuideSettingHasChanged = YES; + self.highlightCursorColumn = highlight; +} + +- (void)setHighlightCursorColumn:(BOOL)highlight { + _cursorGuideSettingHasChanged = YES; + _textview.highlightCursorColumn = highlight; + [_textview setNeedsDisplay:YES]; + _screen.trackCursorColumnMovement = highlight; +} + +- (BOOL)highlightCursorColumn { + return _textview.highlightCursorColumn; +} + - (BOOL)screenHasView { return _textview != nil; } diff --git a/sources/PTYTextView.h b/sources/PTYTextView.h index ea3971a2bf..de88b9f17a 100644 --- a/sources/PTYTextView.h +++ b/sources/PTYTextView.h @@ -235,6 +235,9 @@ typedef NS_ENUM(NSInteger, PTYTextViewSelectionExtensionUnit) { // Draw a highlight along the entire line the cursor is on. @property(nonatomic, assign) BOOL highlightCursorLine; +// Draw a highlight along the entire column the cursor is in. +@property(nonatomic, assign) BOOL highlightCursorColumn; + // Use the non-ascii font? If not set, use the regular font for all characters. @property(nonatomic, assign) BOOL useNonAsciiFont; @@ -461,6 +464,7 @@ typedef void (^PTYTextViewDrawingHookBlock)(iTermTextDrawingHelper *); // onscreen is blinking. - (BOOL)refresh; - (void)setNeedsDisplayOnLine:(int)line; +- (void)setNeedsDisplayOnColumn:(int)column; - (void)setCursorNeedsDisplay; // selection diff --git a/sources/PTYTextView.m b/sources/PTYTextView.m index aa49b9424a..8b40db901c 100644 --- a/sources/PTYTextView.m +++ b/sources/PTYTextView.m @@ -581,6 +581,14 @@ - (BOOL)highlightCursorLine { return _drawingHelper.highlightCursorLine; } +- (void)setHighlightCursorColumn:(BOOL)highlightCursorColumn { + _drawingHelper.highlightCursorColumn = highlightCursorColumn; +} + +- (BOOL)highlightCursorColumn { + return _drawingHelper.highlightCursorColumn; +} + - (void)setUseNonAsciiFont:(BOOL)useNonAsciiFont { _drawingHelper.useNonAsciiFont = useNonAsciiFont; _useNonAsciiFont = useNonAsciiFont; @@ -970,6 +978,16 @@ - (void)setNeedsDisplayOnLine:(int)line [self setNeedsDisplayOnLine:line inRange:VT100GridRangeMake(0, _dataSource.width)]; } +- (void)setNeedsDisplayOnColumn:(int)column { + // We can only draw whole lines, not individual characters. Consequently + // a request to redraw a column should only cause an update if there is + // something in the column outside the row that needs an update, such as the + // vertical cursor guide. + if ([self highlightCursorColumn]) { + [self setNeedsDisplayOnColumn:column inRange:VT100GridRangeMake(0, _dataSource.height)]; + } +} + // Overrides an NSView method. - (NSRect)adjustScroll:(NSRect)proposedVisibleRect { proposedVisibleRect.origin.y = (int)(proposedVisibleRect.origin.y / _lineHeight + 0.5) * _lineHeight; @@ -6401,6 +6419,16 @@ - (void)setNeedsDisplayOnLine:(int)y inRange:(VT100GridRange)range { [self setNeedsDisplayInRect:dirtyRect]; } +- (void)setNeedsDisplayOnColumn:(int)x inRange:(VT100GridRange)range { + // We can only draw whole lines, not individual characters. Consequently + // a request to redraw a column should only cause an update if there is + // something in the column outside the row that needs an update, such as the + // vertical cursor guide. + if ([self highlightCursorColumn]) { + [self setNeedsDisplay:YES]; + } +} + // WARNING: Do not call this function directly. Call // -[refresh] instead, as it ensures scrollback overflow // is dealt with so that this function can dereference diff --git a/sources/ProfilesColorsPreferencesViewController.m b/sources/ProfilesColorsPreferencesViewController.m index e8e6d7ef3a..9885b996a8 100644 --- a/sources/ProfilesColorsPreferencesViewController.m +++ b/sources/ProfilesColorsPreferencesViewController.m @@ -79,6 +79,7 @@ @implementation ProfilesColorsPreferencesViewController { IBOutlet NSMenu *_presetsMenu; IBOutlet NSButton *_useGuide; + IBOutlet NSButton *_useVerticalGuide; IBOutlet CPKColorWell *_guideColor; IBOutlet NSPopUpButton *_presetsPopupButton; @@ -203,6 +204,11 @@ - (void)awakeFromNib { relatedView:nil type:kPreferenceInfoTypeCheckbox]; + [self defineControl:_useVerticalGuide + key:KEY_USE_VERTICAL_CURSOR_GUIDE + relatedView:nil + type:kPreferenceInfoTypeCheckbox]; + info = [self defineControl:_useBrightBold key:KEY_USE_BOLD_COLOR displayName:@"Custom color for bold text" diff --git a/sources/PseudoTerminal.m b/sources/PseudoTerminal.m index 101c792486..5eeeba7adf 100644 --- a/sources/PseudoTerminal.m +++ b/sources/PseudoTerminal.m @@ -1788,6 +1788,11 @@ - (IBAction)toggleCursorGuide:(id)sender { session.highlightCursorLine = !session.highlightCursorLine; } +- (IBAction)toggleVerticalCursorGuide:(id)sender { + PTYSession *session = [self currentSession]; + session.highlightCursorColumn = !session.highlightCursorColumn; +} + - (IBAction)toggleSelectionRespectsSoftBoundaries:(id)sender { iTermController *controller = [iTermController sharedInstance]; controller.selectionRespectsSoftBoundaries = !controller.selectionRespectsSoftBoundaries; @@ -5421,7 +5426,6 @@ - (void)tabView:(NSTabView *)aTabView closeWindowForLastTabViewItem:(NSTabViewIt - (NSImage *)imageFromSelectedTabView:(NSTabView *)aTabView tabViewItem:(NSTabViewItem *)tabViewItem { NSView *tabRootView = [tabViewItem view]; - NSRect tabFrame = [_contentView.tabBarControl frame]; NSRect contentFrame; NSRect viewRect; @@ -8607,6 +8611,10 @@ - (BOOL)validateMenuItem:(NSMenuItem *)item { PTYSession *session = [self currentSession]; [item setState:session.highlightCursorLine ? NSOnState : NSOffState]; result = YES; + } else if ([item action] == @selector(toggleVerticalCursorGuide:)) { + PTYSession *session = [self currentSession]; + [item setState:session.highlightCursorColumn ? NSOnState : NSOffState]; + result = YES; } else if ([item action] == @selector(toggleSelectionRespectsSoftBoundaries:)) { [item setState:[[iTermController sharedInstance] selectionRespectsSoftBoundaries] ? NSOnState : NSOffState]; result = YES; diff --git a/sources/VT100Grid.h b/sources/VT100Grid.h index 25eff122bb..6e1a72ef08 100644 --- a/sources/VT100Grid.h +++ b/sources/VT100Grid.h @@ -21,6 +21,7 @@ - (iTermUnicodeNormalization)gridUnicodeNormalizationForm; - (void)gridCursorDidMove; - (void)gridCursorDidChangeLine; +- (void)gridCursorDidChangeColumn; @end @interface VT100Grid : NSObject diff --git a/sources/VT100Grid.m b/sources/VT100Grid.m index 7c174d17e2..72090b0069 100644 --- a/sources/VT100Grid.m +++ b/sources/VT100Grid.m @@ -183,6 +183,7 @@ - (void)setCursorX:(int)cursorX { int newX = MIN(size_.width, MAX(0, cursorX)); if (newX != cursor_.x) { cursor_.x = newX; + [delegate_ gridCursorDidChangeColumn]; [delegate_ gridCursorDidMove]; } } diff --git a/sources/VT100Screen.h b/sources/VT100Screen.h index 11f570b98a..8f84967276 100644 --- a/sources/VT100Screen.h +++ b/sources/VT100Screen.h @@ -58,6 +58,7 @@ extern int kVT100ScreenMinRows; @property(nonatomic, assign) BOOL saveToScrollbackInAlternateScreen; @property(nonatomic, retain) DVR *dvr; @property(nonatomic, assign) BOOL trackCursorLineMovement; +@property(nonatomic, assign) BOOL trackCursorColumnMovement; @property(nonatomic, assign) BOOL appendToScrollbackWithStatusBar; @property(nonatomic, readonly) VT100GridAbsCoordRange lastCommandOutputRange; @property(nonatomic, assign) iTermUnicodeNormalization normalization; diff --git a/sources/VT100Screen.m b/sources/VT100Screen.m index 4be6d3e4b8..575464833c 100644 --- a/sources/VT100Screen.m +++ b/sources/VT100Screen.m @@ -52,6 +52,7 @@ NSString *const kScreenStateNextCommandOutputStartKey = @"Output Start"; NSString *const kScreenStateCursorVisibleKey = @"Cursor Visible"; NSString *const kScreenStateTrackCursorLineMovementKey = @"Track Cursor Line"; +NSString *const kScreenStateTrackCursorColumnMovementKey = @"Track Cursor Column"; NSString *const kScreenStateLastCommandOutputRangeKey = @"Last Command Output Range"; NSString *const kScreenStateShellIntegrationInstalledKey = @"Shell Integration Installed"; NSString *const kScreenStateLastCommandMarkKey = @"Last Command Mark"; @@ -4139,6 +4140,10 @@ - (void)terminalSetHighlightCursorLine:(BOOL)highlight { [delegate_ screenSetHighlightCursorLine:highlight]; } +- (void)terminalSetHighlightCursorColumn:(BOOL)highlight { + [delegate_ screenSetHighlightCursorColumn:highlight]; +} + - (void)terminalPromptDidStart { [self promptDidStartAt:VT100GridAbsCoordMake(currentGrid_.cursor.x, currentGrid_.cursor.y + self.numberOfScrollbackLines + self.totalScrollbackOverflow)]; @@ -5303,6 +5308,12 @@ - (void)gridCursorDidChangeLine { } } +- (void)gridCursorDidChangeColumn { + if (_trackCursorColumnMovement) { + [delegate_ screenCursorDidMoveToColumn:currentGrid_.cursorX]; + } +} + - (iTermUnicodeNormalization)gridUnicodeNormalizationForm { return _normalization; } @@ -5360,6 +5371,7 @@ - (NSDictionary *)contentsDictionary { kScreenStateNextCommandOutputStartKey: [NSDictionary dictionaryWithGridAbsCoord:_startOfRunningCommandOutput], kScreenStateCursorVisibleKey: @(_cursorVisible), kScreenStateTrackCursorLineMovementKey: @(_trackCursorLineMovement), + kScreenStateTrackCursorColumnMovementKey: @(_trackCursorColumnMovement), kScreenStateLastCommandOutputRangeKey: [NSDictionary dictionaryWithGridAbsCoordRange:_lastCommandOutputRange], kScreenStateShellIntegrationInstalledKey: @(_shellIntegrationInstalled), kScreenStateLastCommandMarkKey: _lastCommandMark.guid ?: [NSNull null], @@ -5474,6 +5486,7 @@ - (void)restoreFromDictionary:(NSDictionary *)dictionary _startOfRunningCommandOutput = [screenState[kScreenStateNextCommandOutputStartKey] gridAbsCoord]; _cursorVisible = [screenState[kScreenStateCursorVisibleKey] boolValue]; _trackCursorLineMovement = [screenState[kScreenStateTrackCursorLineMovementKey] boolValue]; + _trackCursorColumnMovement = [screenState[kScreenStateTrackCursorColumnMovementKey] boolValue]; _lastCommandOutputRange = [screenState[kScreenStateLastCommandOutputRangeKey] gridAbsCoordRange]; _shellIntegrationInstalled = [screenState[kScreenStateShellIntegrationInstalledKey] boolValue]; diff --git a/sources/VT100ScreenDelegate.h b/sources/VT100ScreenDelegate.h index 1936e9f128..21819d8b26 100644 --- a/sources/VT100ScreenDelegate.h +++ b/sources/VT100ScreenDelegate.h @@ -185,10 +185,14 @@ - (void)screenSetCursorVisible:(BOOL)visible; - (void)screenSetHighlightCursorLine:(BOOL)highlight; +- (void)screenSetHighlightCursorColumn:(BOOL)highlight; // Only called if the trackCursorLineMovement property is set. - (void)screenCursorDidMoveToLine:(int)line; +// Only called if the trackCursorColMovement property is set. +- (void)screenCursorDidMoveToColumn:(int)column; + // Returns if there is a view. - (BOOL)screenHasView; diff --git a/sources/VT100Terminal.m b/sources/VT100Terminal.m index 562a197006..f8b6694321 100644 --- a/sources/VT100Terminal.m +++ b/sources/VT100Terminal.m @@ -2367,6 +2367,8 @@ - (void)executeXtermSetKvp:(VT100Token *)token { [delegate_ terminalAddNote:(NSString *)value show:NO]; } else if ([key isEqualToString:@"HighlightCursorLine"]) { [delegate_ terminalSetHighlightCursorLine:value.length ? [value boolValue] : YES]; + } else if ([key isEqualToString:@"HighlightCursorColumn"]) { + [delegate_ terminalSetHighlightCursorColumn:value.length ? [value boolValue] : YES]; } else if ([key isEqualToString:@"CopyToClipboard"]) { if ([delegate_ terminalIsTrusted]) { [delegate_ terminalSetPasteboard:value]; diff --git a/sources/VT100TerminalDelegate.h b/sources/VT100TerminalDelegate.h index 5908d40c35..9594b07835 100644 --- a/sources/VT100TerminalDelegate.h +++ b/sources/VT100TerminalDelegate.h @@ -366,6 +366,7 @@ typedef NS_ENUM(int, VT100TerminalColorIndex) { - (void)terminalSetCursorVisible:(BOOL)visible; - (void)terminalSetHighlightCursorLine:(BOOL)highlight; +- (void)terminalSetHighlightCursorColumn:(BOOL)highlight; // FinalTerm features - (void)terminalPromptDidStart; diff --git a/sources/iTermMetalPerFrameState.m b/sources/iTermMetalPerFrameState.m index fa12ee3f3c..7deaafd892 100644 --- a/sources/iTermMetalPerFrameState.m +++ b/sources/iTermMetalPerFrameState.m @@ -578,8 +578,16 @@ - (vector_float4)fullScreenFlashColor { return _configuration->_fullScreenFlashColor; } -- (BOOL)cursorGuideEnabled { - return _configuration->_cursorGuideColor && _configuration->_cursorGuideEnabled; +- (BOOL)cursorHorizontalGuideEnabled { + return _configuration->_cursorGuideColor && _configuration->_cursorHorizontalGuideEnabled; +} + +- (BOOL)cursorVerticalGuideEnabled { + return _configuration->_cursorGuideColor && _configuration->_cursorVerticalGuideEnabled; +} + +- (BOOL)cursorVerticalGuideEnabled { + return _configuration->_cursorGuideColor && _configuration->_cursorVerticalGuideEnabled; } - (NSColor *)cursorGuideColor { diff --git a/sources/iTermMetalPerFrameStateConfiguration.h b/sources/iTermMetalPerFrameStateConfiguration.h index 9223b3b038..5e557aeb6d 100644 --- a/sources/iTermMetalPerFrameStateConfiguration.h +++ b/sources/iTermMetalPerFrameStateConfiguration.h @@ -61,7 +61,8 @@ NS_ASSUME_NONNULL_BEGIN // Cursor BOOL _shouldDrawFilledInCursor; - BOOL _cursorGuideEnabled; + BOOL _cursorHorizontalGuideEnabled; + BOOL _cursorVerticalGuideEnabled; // Size VT100GridSize _gridSize; diff --git a/sources/iTermMetalPerFrameStateConfiguration.m b/sources/iTermMetalPerFrameStateConfiguration.m index 0ccdce7f73..da19fb65aa 100644 --- a/sources/iTermMetalPerFrameStateConfiguration.m +++ b/sources/iTermMetalPerFrameStateConfiguration.m @@ -55,7 +55,8 @@ - (void)loadSettingsWithDrawingHelper:(iTermTextDrawingHelper *)drawingHelper _transparencyAffectsOnlyDefaultBackgroundColor = drawingHelper.transparencyAffectsOnlyDefaultBackgroundColor; // Cursor guide - _cursorGuideEnabled = drawingHelper.highlightCursorLine; + _cursorHorizontalGuideEnabled = drawingHelper.highlightCursorLine; + _cursorVerticalGuideEnabled = drawingHelper.highlightCursorColumn; _cursorGuideColor = drawingHelper.cursorGuideColor; // Background image diff --git a/sources/iTermProfilePreferences.m b/sources/iTermProfilePreferences.m index 308ec7753d..2600daf6c8 100644 --- a/sources/iTermProfilePreferences.m +++ b/sources/iTermProfilePreferences.m @@ -184,7 +184,7 @@ + (BOOL)valueIsLegal:(id)value forKey:(NSString *)key { KEY_CURSOR_GUIDE_COLOR, KEY_BADGE_COLOR, KEY_TAB_COLOR, KEY_UNDERLINE_COLOR ]; - NSArray *number = @[ KEY_USE_CURSOR_GUIDE, KEY_USE_TAB_COLOR, KEY_USE_UNDERLINE_COLOR, + NSArray *number = @[ KEY_USE_CURSOR_GUIDE, KEY_USE_VERTICAL_CURSOR_GUIDE, KEY_USE_TAB_COLOR, KEY_USE_UNDERLINE_COLOR, KEY_SMART_CURSOR_COLOR, KEY_MINIMUM_CONTRAST, KEY_CURSOR_BOOST, KEY_CURSOR_TYPE, KEY_BLINKING_CURSOR, KEY_USE_BOLD_FONT, KEY_THIN_STROKES, KEY_ASCII_LIGATURES, KEY_NON_ASCII_LIGATURES, KEY_USE_BOLD_COLOR, @@ -268,6 +268,7 @@ + (NSDictionary *)defaultValueMap { KEY_CURSOR_GUIDE_COLOR: [[NSColor colorWithCalibratedRed:0.650 green:0.910 blue:1.000 alpha:0.25] dictionaryValue], KEY_BADGE_COLOR: [[NSColor colorWithCalibratedRed:1.0 green:0.000 blue:0.000 alpha:0.5] dictionaryValue], KEY_USE_CURSOR_GUIDE: @NO, + KEY_USE_VERTICAL_CURSOR_GUIDE: @NO, KEY_TAB_COLOR: [NSNull null], KEY_USE_TAB_COLOR: @NO, KEY_UNDERLINE_COLOR: [NSNull null], diff --git a/sources/iTermTextDrawingHelper.h b/sources/iTermTextDrawingHelper.h index d06f90137b..cd3eeaeb06 100644 --- a/sources/iTermTextDrawingHelper.h +++ b/sources/iTermTextDrawingHelper.h @@ -180,6 +180,9 @@ BOOL CheckFindMatchAtIndex(NSData *findMatches, int index); // Should the cursor guide be shown? @property(nonatomic, assign) BOOL highlightCursorLine; +// Should the vertical cursor guide be shown? +@property(nonatomic, assign) BOOL highlightCursorColumn; + // Minimum contrast level, 0-1. @property(nonatomic, assign) double minimumContrast; diff --git a/sources/iTermTextDrawingHelper.m b/sources/iTermTextDrawingHelper.m index 29167a88d3..f2849f5522 100644 --- a/sources/iTermTextDrawingHelper.m +++ b/sources/iTermTextDrawingHelper.m @@ -644,14 +644,73 @@ - (void)drawAccessoriesInRect:(NSRect)bgRect { // Highlight cursor line if the cursor is on this line and it's on. int cursorLine = _cursorCoord.y + _numberOfScrollbackLines; - const BOOL drawCursorGuide = (self.highlightCursorLine && - cursorLine >= coordRange.start.y && - cursorLine < coordRange.end.y); - if (drawCursorGuide) { + int cursorColumn = _cursorCoord.x; + const BOOL drawHorizontalCursorGuide = (self.highlightCursorLine && + cursorLine >= coordRange.start.y && + cursorLine < coordRange.end.y); + const BOOL drawVerticalCursorGuide = (self.highlightCursorColumn && + cursorColumn >= coordRange.start.x && + cursorColumn < coordRange.end.x); + + if (drawHorizontalCursorGuide && !drawVerticalCursorGuide) { CGFloat y = cursorLine * _cellSize.height; [self drawCursorGuideForColumns:NSMakeRange(coordRange.start.x, coordRange.end.x - coordRange.start.x) y:y]; + } else if (!drawHorizontalCursorGuide && drawVerticalCursorGuide) { + CGFloat x = cursorColumn * _cellSize.width; + [self drawCursorGuideForRows:NSMakeRange(coordRange.start.y, + coordRange.end.y - coordRange.start.y) + x:x]; + [self.delegate setNeedsDisplay:YES]; + } else if (drawHorizontalCursorGuide && drawVerticalCursorGuide) { + CGFloat x = cursorColumn * _cellSize.width; + CGFloat y = cursorLine * _cellSize.height; + [self drawCursorGuideForColumns:NSMakeRange(coordRange.start.x, + coordRange.end.x - coordRange.start.x) + y:y]; + [self drawCursorGuideForRows:NSMakeRange(coordRange.start.y, + cursorLine - coordRange.start.y) + x:x]; + [self drawCursorGuideForRows:NSMakeRange(cursorLine + 1, + coordRange.end.y - _cursorCoord.y) + x:x]; + [self.delegate setNeedsDisplay:YES]; + } + + // Highlight cursor column if the cursor is in this column and it's on. + int cursorColumn = _cursorCoord.x; + const BOOL drawHorizontalCursorGuide = (self.highlightCursorLine && + cursorLine >= coordRange.start.y && + cursorLine < coordRange.end.y); + const BOOL drawVerticalCursorGuide = (self.highlightCursorColumn && + cursorColumn >= coordRange.start.x && + cursorColumn < coordRange.end.x); + + if (drawHorizontalCursorGuide && !drawVerticalCursorGuide) { + CGFloat y = cursorLine * _cellSize.height; + [self drawCursorGuideForColumns:NSMakeRange(coordRange.start.x, + coordRange.end.x - coordRange.start.x) + y:y]; + } else if (!drawHorizontalCursorGuide && drawVerticalCursorGuide) { + CGFloat x = cursorColumn * _cellSize.width; + [self drawCursorGuideForRows:NSMakeRange(coordRange.start.y, + coordRange.end.y - coordRange.start.y) + x:x]; + [self.delegate setNeedsDisplay:YES]; + } else if (drawHorizontalCursorGuide && drawVerticalCursorGuide) { + CGFloat x = cursorColumn * _cellSize.width; + CGFloat y = cursorLine * _cellSize.height; + [self drawCursorGuideForColumns:NSMakeRange(coordRange.start.x, + coordRange.end.x - coordRange.start.x) + y:y]; + [self drawCursorGuideForRows:NSMakeRange(coordRange.start.y, + cursorLine - coordRange.start.y) + x:x]; + [self drawCursorGuideForRows:NSMakeRange(cursorLine + 1, + coordRange.end.y - _cursorCoord.y) + x:x]; + [self.delegate setNeedsDisplay:YES]; } } @@ -674,6 +733,26 @@ - (void)drawCursorGuideForColumns:(NSRange)range y:(CGFloat)yOrigin { NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); } +- (void)drawCursorGuideForRows:(NSRange)range x:(CGFloat)xOrigin { + if (!_cursorVisible) { + return; + } + [_cursorGuideColor set]; + NSPoint textOrigin = NSMakePoint(xOrigin + [iTermAdvancedSettingsModel terminalMargin], + range.location * _cellSize.height); + NSRect rect = NSMakeRect(textOrigin.x, + textOrigin.y, + _cellSize.width, + range.length * _cellSize.height); + NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); + + rect.size.width = 1; + NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); + + rect.origin.x += _cellSize.width - 1; + NSRectFillUsingOperation(rect, NSCompositingOperationSourceOver); +} + + (NSRect)frameForMarkContainedInRect:(NSRect)container cellSize:(CGSize)cellSize cellSizeWithoutSpacing:(CGSize)cellSizeWithoutSpacing From 66cf5608fc700b51b5c00bf8c7e8a10feea3e638 Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Wed, 17 Apr 2019 23:26:05 -0700 Subject: [PATCH 29/30] Remove code duplicated as a result of merge with upstream branch. --- .../Renderers/iTermCursorGuideRenderer.m | 20 ------------------- sources/iTermMetalPerFrameState.m | 4 ---- sources/iTermTextDrawingHelper.m | 8 -------- 3 files changed, 32 deletions(-) diff --git a/sources/Metal/Renderers/iTermCursorGuideRenderer.m b/sources/Metal/Renderers/iTermCursorGuideRenderer.m index cdf418b53d..3903170ae5 100644 --- a/sources/Metal/Renderers/iTermCursorGuideRenderer.m +++ b/sources/Metal/Renderers/iTermCursorGuideRenderer.m @@ -40,26 +40,6 @@ @implementation iTermCursorGuideRendererTransientState { checkIfChanged:YES]; } -- (id)tessellateRect:(CGRect)rect withTexture:(CGRect)textureRect withPool:(iTermMetalBufferPool *)verticesPool { - // Tesselates an axis-aligned rectangle into a sequence of vertices - // representing two adjacent triangles that share the diagonal of the - // rectangle: - // top-right, top-left, bottom-left, top-right, bottom-left, bottom-right - const iTermVertex vertices[] = { - // Pixel Positions Texture Coordinates - { { CGRectGetMaxX(rect), CGRectGetMinY(rect) }, { CGRectGetMaxX(textureRect), CGRectGetMinY(textureRect) } }, - { { CGRectGetMinX(rect), CGRectGetMinY(rect) }, { CGRectGetMinX(textureRect), CGRectGetMinY(textureRect) } }, - { { CGRectGetMinX(rect), CGRectGetMaxY(rect) }, { CGRectGetMinX(textureRect), CGRectGetMaxY(textureRect) } }, - - { { CGRectGetMaxX(rect), CGRectGetMinY(rect) }, { CGRectGetMaxX(textureRect), CGRectGetMinY(textureRect) } }, - { { CGRectGetMinX(rect), CGRectGetMaxY(rect) }, { CGRectGetMinX(textureRect), CGRectGetMaxY(textureRect) } }, - { { CGRectGetMaxX(rect), CGRectGetMaxY(rect) }, { CGRectGetMaxX(textureRect), CGRectGetMaxY(textureRect) } }, - }; - return [verticesPool requestBufferFromContext:self.poolContext - withBytes:vertices - checkIfChanged:YES]; -} - - (void)setCursorCoord:(VT100GridCoord)coord { VT100GridSize bounds = self.cellConfiguration.gridSize; _row = (0 <= coord.y && coord.y < bounds.height) ? coord.y : -1; diff --git a/sources/iTermMetalPerFrameState.m b/sources/iTermMetalPerFrameState.m index 7deaafd892..09479f0d7a 100644 --- a/sources/iTermMetalPerFrameState.m +++ b/sources/iTermMetalPerFrameState.m @@ -586,10 +586,6 @@ - (BOOL)cursorVerticalGuideEnabled { return _configuration->_cursorGuideColor && _configuration->_cursorVerticalGuideEnabled; } -- (BOOL)cursorVerticalGuideEnabled { - return _configuration->_cursorGuideColor && _configuration->_cursorVerticalGuideEnabled; -} - - (NSColor *)cursorGuideColor { return _configuration->_cursorGuideColor; } diff --git a/sources/iTermTextDrawingHelper.m b/sources/iTermTextDrawingHelper.m index f2849f5522..b42231f016 100644 --- a/sources/iTermTextDrawingHelper.m +++ b/sources/iTermTextDrawingHelper.m @@ -679,14 +679,6 @@ - (void)drawAccessoriesInRect:(NSRect)bgRect { } // Highlight cursor column if the cursor is in this column and it's on. - int cursorColumn = _cursorCoord.x; - const BOOL drawHorizontalCursorGuide = (self.highlightCursorLine && - cursorLine >= coordRange.start.y && - cursorLine < coordRange.end.y); - const BOOL drawVerticalCursorGuide = (self.highlightCursorColumn && - cursorColumn >= coordRange.start.x && - cursorColumn < coordRange.end.x); - if (drawHorizontalCursorGuide && !drawVerticalCursorGuide) { CGFloat y = cursorLine * _cellSize.height; [self drawCursorGuideForColumns:NSMakeRange(coordRange.start.x, From ed738eb366a6a3b47711085b32fdbb88dbee2535 Mon Sep 17 00:00:00 2001 From: Andrew Helsley Date: Wed, 17 Apr 2019 23:27:19 -0700 Subject: [PATCH 30/30] Disable code that references an undeclared identifier (brought in from master/HEAD during rebase?). --- sources/PTYSession.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/PTYSession.m b/sources/PTYSession.m index 02593bdc12..d7243344c6 100644 --- a/sources/PTYSession.m +++ b/sources/PTYSession.m @@ -2345,6 +2345,7 @@ - (void)writeTaskNoBroadcast:(NSString *)string [self writeTaskImpl:string encoding:encoding forceEncoding:forceEncoding canBroadcast:NO]; } +#if 0 - (void)handleKeyPressInCopyMode:(NSEvent *)event { [self.textview setNeedsDisplayOnLine:_copyModeState.coord.y]; [self.textview setNeedsDisplayOnColumn:_copyModeState.coord.x]; @@ -2502,6 +2503,7 @@ - (void)handleKeyPressInCopyMode:(NSEvent *)event { [self.textview setNeedsDisplayOnColumn:_copyModeState.coord.x]; } } +#endif - (void)handleKeypressInTmuxGateway:(NSEvent *)event { const unichar unicode = [event.characters length] > 0 ? [event.characters characterAtIndex:0] : 0;