Added support for {DELAY=<delay>} to allow for custom delay in command execution instead of using dedicated UI and settings for this
This commit is contained in:
parent
3ef2c01859
commit
8d66621803
|
@ -26,6 +26,7 @@
|
|||
#import "MPAutotypeCommand.h"
|
||||
#import "MPAutotypeContext.h"
|
||||
#import "MPAutotypePaste.h"
|
||||
#import "MPAutotypeDelay.h"
|
||||
#import "MPPasteBoardController.h"
|
||||
#import "MPSettingsHelper.h"
|
||||
#import "MPAutotypeCandidateSelectionViewController.h"
|
||||
|
@ -319,18 +320,24 @@ static MPAutotypeDaemon *_sharedInstance;
|
|||
usleep(1 * NSEC_PER_MSEC);
|
||||
}
|
||||
|
||||
useconds_t delay = 0;
|
||||
if(nil != [NSUserDefaults.standardUserDefaults objectForKey:kMPSettingsKeyGlobalAutotypeDelay]) {
|
||||
/* limit the delay to 1000 ms */
|
||||
delay = (useconds_t)MIN([NSUserDefaults.standardUserDefaults integerForKey:kMPSettingsKeyGlobalAutotypeDelay], 1000);
|
||||
}
|
||||
|
||||
|
||||
useconds_t globalDelay = 0;
|
||||
for(MPAutotypeCommand *command in [MPAutotypeCommand commandsForContext:context]) {
|
||||
/*
|
||||
FIXME: Introduce a global state for execution to allow command to set state value
|
||||
e.g. [command executeWithContext:(MPCommandExectionContext *)context]
|
||||
and inside the command set the sate e.g. context.delay = myDelay
|
||||
then use this state in the command scheduling to set the global delay
|
||||
*/
|
||||
if([command isKindOfClass:MPAutotypeDelay.class]) {
|
||||
MPAutotypeDelay *delayCommand = (MPAutotypeDelay *)command;
|
||||
if(delayCommand.isGlobal) {
|
||||
globalDelay = (useconds_t)delayCommand.delay;
|
||||
}
|
||||
}
|
||||
/* dispatch commands to main thread since most of them translate key events which is disallowed on background thread */
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if(delay > 0) {
|
||||
usleep(delay * NSEC_PER_MSEC);
|
||||
if(globalDelay > 0) {
|
||||
usleep(globalDelay*NSEC_PER_USEC);
|
||||
}
|
||||
[command execute];
|
||||
});
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
@interface MPAutotypeDelay : MPAutotypeCommand
|
||||
|
||||
@property (readonly) NSUInteger delay;
|
||||
@property (readonly) BOOL isGlobal;
|
||||
/**
|
||||
* Creates an DelayCommand that delays the execution for n milliseconds
|
||||
*
|
||||
|
@ -33,5 +34,6 @@
|
|||
* @return <#return value description#>
|
||||
*/
|
||||
- (instancetype)initWithDelay:(NSUInteger)delay;
|
||||
- (instancetype)initWithGlobalDelay:(NSUInteger)delay;
|
||||
|
||||
@end
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
@implementation MPAutotypeDelay
|
||||
|
||||
- (id)init {
|
||||
self = [self initWithDelay:0];
|
||||
self = [self _initWithDelay:0 global:NO];
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -38,17 +38,32 @@
|
|||
}
|
||||
|
||||
- (instancetype)initWithDelay:(NSUInteger)delay {
|
||||
self = [self _initWithDelay:delay global:NO];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithGlobalDelay:(NSUInteger)delay {
|
||||
self = [self _initWithDelay:delay global:YES];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)_initWithDelay:(NSUInteger)delay global:(BOOL)global {
|
||||
self = [super init];
|
||||
if(self) {
|
||||
_isGlobal = global;
|
||||
/* Delays longer than a minute are a bit long */
|
||||
_delay = MIN(60*1000,delay);
|
||||
_delay = MIN(60*NSEC_PER_USEC,delay);
|
||||
}
|
||||
return self;
|
||||
|
||||
}
|
||||
|
||||
- (void)execute {
|
||||
/* milliseconds * 10000 = microseconds */
|
||||
usleep((useconds_t)(self.delay*1000));
|
||||
if(self.isGlobal) {
|
||||
return; // global delays should not be executed locally
|
||||
}
|
||||
usleep((useconds_t)(self.delay*NSEC_PER_USEC));
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -281,7 +281,7 @@ static CGKeyCode kMPNumpadKeyCodes[] = {
|
|||
static NSRegularExpression *delayRegExp;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSString *delayPattern = [[NSString alloc] initWithFormat:@"\\{(%@|%@)[ |=]+([0-9]+)\\}",
|
||||
NSString *delayPattern = [[NSString alloc] initWithFormat:@"\\{(%@|%@)([ |=])+([0-9]+)\\}",
|
||||
kKPKAutotypeDelay,
|
||||
kKPKAutotypeVirtualKey/*,
|
||||
kKPKAutotypeVirtualExtendedKey,
|
||||
|
@ -327,9 +327,10 @@ static CGKeyCode kMPNumpadKeyCodes[] = {
|
|||
// TODO: add {APPLICATION <appname>}
|
||||
/* Delay */
|
||||
NSTextCheckingResult *result = [delayRegExp firstMatchInString:commandString options:0 range:NSMakeRange(0, commandString.length)];
|
||||
if(result && (result.numberOfRanges == 3)) {
|
||||
if(result && (result.numberOfRanges == 4)) {
|
||||
NSString *uppercaseCommand = [[commandString substringWithRange:[result rangeAtIndex:1]] uppercaseString];
|
||||
NSString *valueString = [commandString substringWithRange:[result rangeAtIndex:2]];
|
||||
NSString *assignOrNot = [commandString substringWithRange:[result rangeAtIndex:2]];
|
||||
NSString *valueString = [commandString substringWithRange:[result rangeAtIndex:3]];
|
||||
NSScanner *numberScanner = [[NSScanner alloc] initWithString:valueString];
|
||||
NSInteger value;
|
||||
if([numberScanner scanInteger:&value]) {
|
||||
|
@ -337,7 +338,12 @@ static CGKeyCode kMPNumpadKeyCodes[] = {
|
|||
if(MAX(0, value) <= 0) {
|
||||
return; // Value too low, just skipp
|
||||
}
|
||||
[self.mutableCommands addObject:[[MPAutotypeDelay alloc] initWithDelay:value]];
|
||||
if([assignOrNot isEqualToString:@"="]) {
|
||||
[self.mutableCommands addObject:[[MPAutotypeDelay alloc] initWithGlobalDelay:value]];
|
||||
}
|
||||
else {
|
||||
[self.mutableCommands addObject:[[MPAutotypeDelay alloc] initWithDelay:value]];
|
||||
}
|
||||
return; // Done
|
||||
}
|
||||
else if([kKPKAutotypeVirtualKey isEqualToString:uppercaseCommand]) {
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testValidDelayCommands {
|
||||
- (void)testLocalDelayCommands {
|
||||
/* Command 1 */
|
||||
MPAutotypeContext *context = [[MPAutotypeContext alloc] initWithEntry:self.entry andSequence:@"{DELAY 200}"];
|
||||
NSArray *commands = [MPAutotypeCommand commandsForContext:context];
|
||||
|
@ -41,8 +41,23 @@
|
|||
XCTAssertTrue([commands.firstObject isKindOfClass:[MPAutotypeDelay class]], @"Command is Delay command");
|
||||
MPAutotypeDelay *delay = commands.firstObject;
|
||||
XCTAssertEqual(delay.delay, 200, @"Delay is 200 ms");
|
||||
XCTAssertFalse(delay.isGlobal, @"Delay is no global delay");
|
||||
}
|
||||
|
||||
- (void)testGlobalDelayCommands {
|
||||
/* Command 1 */
|
||||
MPAutotypeContext *context = [[MPAutotypeContext alloc] initWithEntry:self.entry andSequence:@"{DELAY=200}"];
|
||||
NSArray *commands = [MPAutotypeCommand commandsForContext:context];
|
||||
|
||||
XCTAssertEqual(commands.count, 1);
|
||||
/* {DELAY=200} */
|
||||
XCTAssertTrue([commands.firstObject isKindOfClass:MPAutotypeDelay.class], @"Command is Delay command");
|
||||
MPAutotypeDelay *delay = commands.firstObject;
|
||||
XCTAssertEqual(delay.delay, 200, @"Delay is 200 ms");
|
||||
XCTAssertTrue(delay.isGlobal, @"Delay is global delay");
|
||||
}
|
||||
|
||||
|
||||
- (void)testDelayExecution {
|
||||
MPAutotypeDelay *delay = [[MPAutotypeDelay alloc] initWithDelay:200];
|
||||
XCTestExpectation *expectation = [self expectationWithDescription:delay.description];
|
||||
|
|
Loading…
Reference in New Issue