Skip to content

Commit dffce69

Browse files
authored
Merge pull request #1535 from ychin/mmtabs-fix-update-animation-scroll
Make GUI tabs track Vim tabs in updates and animate correctly
2 parents 8a68481 + 7fbb445 commit dffce69

File tree

9 files changed

+293
-149
lines changed

9 files changed

+293
-149
lines changed

src/MacVim/MMBackend.m

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -764,32 +764,36 @@ - (void)selectTab:(int)index
764764

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

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

772779
tabpage_T *tp;
780+
// 2. Unique id for all the tabs
781+
// Do these first so they appear as a consecutive memory block.
773782
for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) {
774-
// Count the number of windows in the tabpage.
775-
//win_T *wp = tp->tp_firstwin;
776-
//int wincount;
777-
//for (wincount = 0; wp != NULL; wp = wp->w_next, ++wincount);
778-
//[data appendBytes:&wincount length:sizeof(int)];
779-
780-
int tabProp = MMTabInfoCount;
781-
[data appendBytes:&tabProp length:sizeof(int)];
782-
for (tabProp = MMTabLabel; tabProp < MMTabInfoCount; ++tabProp) {
783+
[data appendBytes:&tp length:sizeof(void*)];
784+
}
785+
// Null terminate the unique IDs.
786+
tp = 0;
787+
[data appendBytes:&tp length:sizeof(void*)];
788+
// 3. Labels and tooltips of each tab
789+
for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) {
790+
for (int tabProp = MMTabLabel; tabProp < MMTabInfoCount; ++tabProp) {
783791
// This function puts the label of the tab in the global 'NameBuff'.
784792
get_tabline_label(tp, (tabProp == MMTabToolTip));
785-
NSString *s = [NSString stringWithVimString:NameBuff];
786-
int len = [s lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
787-
if (len < 0)
788-
len = 0;
789-
790-
[data appendBytes:&len length:sizeof(int)];
793+
size_t len = STRLEN(NameBuff);
794+
[data appendBytes:&len length:sizeof(size_t)];
791795
if (len > 0)
792-
[data appendBytes:[s UTF8String] length:len];
796+
[data appendBytes:NameBuff length:len];
793797
}
794798
}
795799

src/MacVim/MMTabline/MMTab.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ typedef enum : NSInteger {
1414

1515
@interface MMTab : NSView
1616

17+
@property (nonatomic, readwrite) NSInteger tag; ///< Unique identifier that caller can set for the tab
1718
@property (nonatomic, copy) NSString *title;
1819
@property (nonatomic, getter=isCloseButtonHidden) BOOL closeButtonHidden;
1920
@property (nonatomic) MMTabState state;

src/MacVim/MMTabline/MMTab.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ @implementation MMTab
2020
NSTextField *_titleLabel;
2121
}
2222

23+
@synthesize tag = _tag;
24+
2325
+ (id)defaultAnimationForKey:(NSAnimatablePropertyKey)key
2426
{
2527
if ([key isEqualToString:@"fillColor"]) {

src/MacVim/MMTabline/MMTabline.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010

1111
@interface MMTabline : NSView
1212

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

28+
/// Add a tab at the end. It's not selected automatically.
2729
- (NSInteger)addTabAtEnd;
30+
/// Add a tab after the selected one. It's not selected automatically.
2831
- (NSInteger)addTabAfterSelectedTab;
32+
/// Add a tab at specified index. It's not selected automatically.
2933
- (NSInteger)addTabAtIndex:(NSInteger)index;
34+
3035
- (void)closeTab:(MMTab *)tab force:(BOOL)force layoutImmediately:(BOOL)layoutImmediately;
36+
37+
/// Batch update all the tabs using tab tags as unique IDs. Tab line will handle
38+
/// creating / removing tabs as necessary, and moving tabs to their new
39+
/// positions.
40+
///
41+
/// The tags array has to have unique items only, and each existing MMTab also
42+
/// has to have unique tags.
43+
///
44+
/// @param tags The list of unique tags that are cross-referenced with each
45+
/// MMTab's tag. Order within the array indicates the desired tab order.
46+
/// @param len The length of the tags array.
47+
/// @param delayTabResize If true, do not resize tab widths until the the tab
48+
/// line loses focus. This helps preserve the relative tab positions and
49+
/// lines up the close buttons to the previous tab. This will also
50+
/// prevent scrolling to the new selected tab.
51+
- (void)updateTabsByTags:(NSInteger *)tags len:(NSUInteger)len delayTabResize:(BOOL)delayTabResize;
52+
3153
- (void)selectTabAtIndex:(NSInteger)index;
3254
- (MMTab *)tabAtIndex:(NSInteger)index;
3355
- (void)scrollTabToVisibleAtIndex:(NSInteger)index;

0 commit comments

Comments
 (0)