Skip to content
Snippets Groups Projects
Commit c7270d81 authored by George Nachman's avatar George Nachman
Browse files

Rate limit updates to the manpage touchbar button. Issue 5834

parent 8292c0ff
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -1525,6 +1525,8 @@
A66E5E591E62691F00E8FE35 /* iTermTouchBarButton.m in Sources */ = {isa = PBXBuildFile; fileRef = A68E332A1DE6AFC6003F1D8E /* iTermTouchBarButton.m */; };
A66E5E5D1E63625600E8FE35 /* iTermURLActionFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = A66E5E5B1E63625600E8FE35 /* iTermURLActionFactory.h */; };
A66E5E5E1E63625600E8FE35 /* iTermURLActionFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = A66E5E5C1E63625600E8FE35 /* iTermURLActionFactory.m */; };
A66EF82C1EF59CFC0005891A /* iTermRateLimitedUpdate.h in Headers */ = {isa = PBXBuildFile; fileRef = A66EF82A1EF59CFC0005891A /* iTermRateLimitedUpdate.h */; };
A66EF82D1EF59CFC0005891A /* iTermRateLimitedUpdate.m in Sources */ = {isa = PBXBuildFile; fileRef = A66EF82B1EF59CFC0005891A /* iTermRateLimitedUpdate.m */; };
A673BFDE1E16C54500FA2386 /* iTermKeyLabels.h in Headers */ = {isa = PBXBuildFile; fileRef = A673BFDC1E16C54500FA2386 /* iTermKeyLabels.h */; };
A673BFDF1E16C54500FA2386 /* iTermKeyLabels.m in Sources */ = {isa = PBXBuildFile; fileRef = A673BFDD1E16C54500FA2386 /* iTermKeyLabels.m */; };
A673BFE21E176AA300FA2386 /* PTYTextViewTest-golden-travis-testCustomUnderline.png in Resources */ = {isa = PBXBuildFile; fileRef = A673BFE01E1743F400FA2386 /* PTYTextViewTest-golden-travis-testCustomUnderline.png */; };
Loading
Loading
@@ -3391,6 +3393,8 @@
A66DB8411CA24E8800233E88 /* iTermAutoMasterParser.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = iTermAutoMasterParser.m; sourceTree = "<group>"; };
A66E5E5B1E63625600E8FE35 /* iTermURLActionFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iTermURLActionFactory.h; sourceTree = "<group>"; };
A66E5E5C1E63625600E8FE35 /* iTermURLActionFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = iTermURLActionFactory.m; sourceTree = "<group>"; };
A66EF82A1EF59CFC0005891A /* iTermRateLimitedUpdate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iTermRateLimitedUpdate.h; sourceTree = "<group>"; };
A66EF82B1EF59CFC0005891A /* iTermRateLimitedUpdate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = iTermRateLimitedUpdate.m; sourceTree = "<group>"; };
A673BFDC1E16C54500FA2386 /* iTermKeyLabels.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iTermKeyLabels.h; sourceTree = "<group>"; };
A673BFDD1E16C54500FA2386 /* iTermKeyLabels.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = iTermKeyLabels.m; sourceTree = "<group>"; };
A673BFE01E1743F400FA2386 /* PTYTextViewTest-golden-travis-testCustomUnderline.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "PTYTextViewTest-golden-travis-testCustomUnderline.png"; path = "tests/Goldens/PTYTextViewTest-golden-travis-testCustomUnderline.png"; sourceTree = "<group>"; };
Loading
Loading
@@ -5704,6 +5708,8 @@
A60BB37D1EB5149100D76C09 /* iTermCopyModeState.m */,
A60BB38C1EB6A08A00D76C09 /* iTermProcessCollection.h */,
A60BB38D1EB6A08A00D76C09 /* iTermProcessCollection.m */,
A66EF82A1EF59CFC0005891A /* iTermRateLimitedUpdate.h */,
A66EF82B1EF59CFC0005891A /* iTermRateLimitedUpdate.m */,
);
name = Helpers;
sourceTree = "<group>";
Loading
Loading
@@ -6870,6 +6876,7 @@
A66719501DCE36C3000CE608 /* iTermWebViewWrapperViewController.h in Headers */,
A66719511DCE36C3000CE608 /* iTermPreferences.h in Headers */,
53AFFC8F1DD2A04600E6CEC6 /* iTermLSOF.h in Headers */,
A66EF82C1EF59CFC0005891A /* iTermRateLimitedUpdate.h in Headers */,
A66719521DCE36C3000CE608 /* iTermRecentDirectoryMO+CoreDataProperties.h in Headers */,
A66719531DCE36C3000CE608 /* iTermSocketAddress.h in Headers */,
A66719541DCE36C3000CE608 /* SetDirectoryTrigger.h in Headers */,
Loading
Loading
@@ -8379,6 +8386,7 @@
A62A1F771E711BC000363EE9 /* iTermHelpMessageViewController.m in Sources */,
A62A1F721E6E724B00363EE9 /* iTermMenuOpener.m in Sources */,
A66719661DCE3772000CE608 /* iTermWebSocketFrame.m in Sources */,
A66EF82D1EF59CFC0005891A /* iTermRateLimitedUpdate.m in Sources */,
A66719601DCE3772000CE608 /* iTermAPIServer.m in Sources */,
A60BB38F1EB6A08A00D76C09 /* iTermProcessCollection.m in Sources */,
A66719631DCE3772000CE608 /* iTermSocketIPV4Address.m in Sources */,
Loading
Loading
@@ -35,6 +35,7 @@
#import "iTermProfilesWindowController.h"
#import "iTermPromptOnCloseReason.h"
#import "iTermQuickLookController.h"
#import "iTermRateLimitedUpdate.h"
#import "iTermRootTerminalView.h"
#import "iTermSelection.h"
#import "iTermShellHistoryController.h"
Loading
Loading
@@ -365,6 +366,10 @@ static NSRect iTermRectCenteredVerticallyWithinRect(NSRect frameToCenter, NSRect
BOOL _inWindowDidChangeScreen;
 
iTermPasswordManagerWindowController *_passwordManagerWindowController;
// Keeps the touch bar from updating on every keypress which is distracting.
iTermRateLimitedUpdate *_touchBarRateLimitedUpdate;
NSString *_previousTouchBarWord;
}
 
+ (void)registerSessionsInArrangement:(NSDictionary *)arrangement {
Loading
Loading
@@ -820,7 +825,10 @@ ITERM_WEAKLY_REFERENCEABLE
[_tabsTouchBarItem release];
[_autocompleteCandidateListItem release];
[_passwordManagerWindowController release];
[_touchBarRateLimitedUpdate invalidate];
[_touchBarRateLimitedUpdate release];
[_previousTouchBarWord release];
[super dealloc];
}
 
Loading
Loading
@@ -7908,7 +7916,18 @@ ITERM_WEAKLY_REFERENCEABLE
}
 
- (void)currentSessionWordAtCursorDidBecome:(NSString *)word {
[self updateTouchBarWithWordAtCursor:word];
if (word == _previousTouchBarWord || [word isEqualToString:_previousTouchBarWord]) {
return;
}
[_previousTouchBarWord release];
_previousTouchBarWord = [word copy];
if (_touchBarRateLimitedUpdate == nil) {
_touchBarRateLimitedUpdate = [[iTermRateLimitedUpdate alloc] init];
_touchBarRateLimitedUpdate.minimumInterval = 0.5;
}
[_touchBarRateLimitedUpdate performRateLimitedBlock:^{
[self updateTouchBarWithWordAtCursor:word];
}];
}
 
#pragma mark - Toolbelt
Loading
Loading
//
// iTermRateLimitedUpdate.h
// iTerm2
//
// Created by George Nachman on 6/17/17.
//
//
#import <Foundation/Foundation.h>
@interface iTermRateLimitedUpdate : NSObject
@property (nonatomic) NSTimeInterval minimumInterval;
// Do not perform a pending action.
- (void)invalidate;
// Performs the block immediately, or perhaps after up to minimumInterval time.
- (void)performRateLimitedBlock:(void (^)())block;
// A target/action version of the above.
- (void)performRateLimitedSelector:(SEL)selector
onTarget:(id)target
withObject:(id)object;
@end
//
// iTermRateLimitedUpdate.m
// iTerm2
//
// Created by George Nachman on 6/17/17.
//
//
#import "iTermRateLimitedUpdate.h"
@interface iTermTimerProxy : NSObject
- (void)performBlock:(NSTimer *)timer;
@end
// The timer keeps a strong reference to the proxy, while the proxy's block can
// hold a weak reference to the true target.
@implementation iTermTimerProxy
- (void)performBlock:(NSTimer *)timer {
void (^block)(NSTimer * _Nonnull) = timer.userInfo;
if (block != nil) {
block(timer);
}
}
@end
@interface NSTimer (iTerm)
+ (instancetype)it_scheduledTimerWithTimeInterval:(NSTimeInterval)timeInterval repeats:(BOOL)repeats block:(void (^_Nonnull)(NSTimer * _Nonnull timer))block;
+ (instancetype)it_weakTimerWithTimeInterval:(NSTimeInterval)timeInterval repeats:(BOOL)repeats target:(id)target selector:(SEL)selector;
@end
@implementation NSTimer (iTerm)
+ (instancetype)it_scheduledTimerWithTimeInterval:(NSTimeInterval)timeInterval
repeats:(BOOL)repeats
block:(void (^_Nonnull)(NSTimer * _Nonnull timer))block {
iTermTimerProxy *proxy = [[iTermTimerProxy alloc] init];
return [NSTimer scheduledTimerWithTimeInterval:timeInterval
target:proxy
selector:@selector(performBlock:)
userInfo:[block copy]
repeats:repeats];
}
+ (instancetype)it_weakTimerWithTimeInterval:(NSTimeInterval)timeInterval repeats:(BOOL)repeats target:(id)target selector:(SEL)selector {
__weak id weakTarget = target;
return [self it_scheduledTimerWithTimeInterval:timeInterval repeats:repeats block:^(NSTimer * _Nonnull timer) {
[timer it_performSelector:selector onTarget:weakTarget];
}];
}
- (void)it_performSelector:(SEL)selector onTarget:(id)target {
if (target) {
void (*func)(id, SEL, NSTimer *) = (void *)[target methodForSelector:selector];
func(target, selector, self);
}
}
@end
@implementation iTermRateLimitedUpdate {
// While nonnil, block will not be performed.
NSTimer *_timer;
void (^_block)();
}
- (void)invalidate {
[_timer invalidate];
_timer = nil;
_block = nil;
}
- (void)performRateLimitedBlock:(void (^)())block {
if (_timer == nil) {
block();
_timer = [NSTimer it_weakTimerWithTimeInterval:self.minimumInterval
repeats:NO
target:self
selector:@selector(performBlockIfNeeded:)];
} else {
_block = [block copy];
}
}
- (void)performRateLimitedSelector:(SEL)selector
onTarget:(id)target
withObject:(id)object {
__weak id weakTarget = target;
[self performRateLimitedBlock:^{
id strongTarget = weakTarget;
if (strongTarget) {
void (*func)(id, SEL, NSTimer *) = (void *)[weakTarget methodForSelector:selector];
func(weakTarget, selector, object);
}
}];
}
- (void)performBlockIfNeeded:(NSTimer *)timer {
_timer = nil;
if (_block != nil) {
void (^block)() = _block;
_block = nil;
block();
}
}
@end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment