Skip to content

Commit

Permalink
Merge pull request #1535 from ychin/mmtabs-fix-update-animation-scroll
Browse files Browse the repository at this point in the history
Make GUI tabs track Vim tabs in updates and animate correctly
  • Loading branch information
ychin authored Jan 27, 2025
2 parents 8a68481 + 7fbb445 commit dffce69
Show file tree
Hide file tree
Showing 9 changed files with 293 additions and 149 deletions.
36 changes: 20 additions & 16 deletions src/MacVim/MMBackend.m
Original file line number Diff line number Diff line change
Expand Up @@ -764,32 +764,36 @@ - (void)selectTab:(int)index

- (void)updateTabBar
{
// Update the tab bar with the most up-to-date info, including number of
// tabs and titles/tooltips. MacVim would also like to know which specific
// tabs were moved/added/deleted in order for animation to work, but Vim
// does not have specific callbacks to listen to that. Instead, since the
// tabpage_T memory address is constant per tab, we use that as a permanent
// identifier for each GUI tab so MacVim can do the association.
NSMutableData *data = [NSMutableData data];

// 1. Current selected tab index
int idx = tabpage_index(curtab) - 1;
[data appendBytes:&idx length:sizeof(int)];

tabpage_T *tp;
// 2. Unique id for all the tabs
// Do these first so they appear as a consecutive memory block.
for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) {
// Count the number of windows in the tabpage.
//win_T *wp = tp->tp_firstwin;
//int wincount;
//for (wincount = 0; wp != NULL; wp = wp->w_next, ++wincount);
//[data appendBytes:&wincount length:sizeof(int)];

int tabProp = MMTabInfoCount;
[data appendBytes:&tabProp length:sizeof(int)];
for (tabProp = MMTabLabel; tabProp < MMTabInfoCount; ++tabProp) {
[data appendBytes:&tp length:sizeof(void*)];
}
// Null terminate the unique IDs.
tp = 0;
[data appendBytes:&tp length:sizeof(void*)];
// 3. Labels and tooltips of each tab
for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) {
for (int tabProp = MMTabLabel; tabProp < MMTabInfoCount; ++tabProp) {
// This function puts the label of the tab in the global 'NameBuff'.
get_tabline_label(tp, (tabProp == MMTabToolTip));
NSString *s = [NSString stringWithVimString:NameBuff];
int len = [s lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
if (len < 0)
len = 0;

[data appendBytes:&len length:sizeof(int)];
size_t len = STRLEN(NameBuff);
[data appendBytes:&len length:sizeof(size_t)];
if (len > 0)
[data appendBytes:[s UTF8String] length:len];
[data appendBytes:NameBuff length:len];
}
}

Expand Down
1 change: 1 addition & 0 deletions src/MacVim/MMTabline/MMTab.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ typedef enum : NSInteger {

@interface MMTab : NSView

@property (nonatomic, readwrite) NSInteger tag; ///< Unique identifier that caller can set for the tab
@property (nonatomic, copy) NSString *title;
@property (nonatomic, getter=isCloseButtonHidden) BOOL closeButtonHidden;
@property (nonatomic) MMTabState state;
Expand Down
2 changes: 2 additions & 0 deletions src/MacVim/MMTabline/MMTab.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ @implementation MMTab
NSTextField *_titleLabel;
}

@synthesize tag = _tag;

+ (id)defaultAnimationForKey:(NSAnimatablePropertyKey)key
{
if ([key isEqualToString:@"fillColor"]) {
Expand Down
24 changes: 23 additions & 1 deletion src/MacVim/MMTabline/MMTabline.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@

@interface MMTabline : NSView

@property (nonatomic) NSInteger selectedTabIndex;
/// The index of the selected tab. Can be -1 if nothing is selected.
@property (nonatomic, readonly) NSInteger selectedTabIndex;
@property (nonatomic) NSInteger optimumTabWidth;
@property (nonatomic) NSInteger minimumTabWidth;
@property (nonatomic) BOOL showsAddTabButton;
Expand All @@ -24,10 +25,31 @@
@property (nonatomic, retain) NSColor *tablineFillFgColor;
@property (nonatomic, weak) id <MMTablineDelegate> delegate;

/// Add a tab at the end. It's not selected automatically.
- (NSInteger)addTabAtEnd;
/// Add a tab after the selected one. It's not selected automatically.
- (NSInteger)addTabAfterSelectedTab;
/// Add a tab at specified index. It's not selected automatically.
- (NSInteger)addTabAtIndex:(NSInteger)index;

- (void)closeTab:(MMTab *)tab force:(BOOL)force layoutImmediately:(BOOL)layoutImmediately;

/// Batch update all the tabs using tab tags as unique IDs. Tab line will handle
/// creating / removing tabs as necessary, and moving tabs to their new
/// positions.
///
/// The tags array has to have unique items only, and each existing MMTab also
/// has to have unique tags.
///
/// @param tags The list of unique tags that are cross-referenced with each
/// MMTab's tag. Order within the array indicates the desired tab order.
/// @param len The length of the tags array.
/// @param delayTabResize If true, do not resize tab widths until the the tab
/// line loses focus. This helps preserve the relative tab positions and
/// lines up the close buttons to the previous tab. This will also
/// prevent scrolling to the new selected tab.
- (void)updateTabsByTags:(NSInteger *)tags len:(NSUInteger)len delayTabResize:(BOOL)delayTabResize;

- (void)selectTabAtIndex:(NSInteger)index;
- (MMTab *)tabAtIndex:(NSInteger)index;
- (void)scrollTabToVisibleAtIndex:(NSInteger)index;
Expand Down
Loading

0 comments on commit dffce69

Please sign in to comment.